Python में 3D मॉडल कैसे लोड करें

Python में 3D मॉडल कैसे लोड करें

Aspose.3D FOSS for Python एक सरल API प्रदान करता है जो किसी भी मूल निर्भरताओं के बिना 3D फ़ाइलें खोलता है। फ़ाइल को Scene ऑब्जेक्ट में लोड करने के बाद, आप नोड पदानुक्रम को पार कर सकते हैं और दृश्य में प्रत्येक मेष के लिए कच्चा ज्यामिति डेटा पढ़ सकते हैं।

चरण-दर-चरण मार्गदर्शिका

चरण 1: पैकेज स्थापित करें

PyPI से Aspose.3D FOSS स्थापित करें। अतिरिक्त सिस्टम लाइब्रेरीज़ की आवश्यकता नहीं है।

pip install aspose-3d-foss

समर्थित Python संस्करण: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


चरण 2: सीन क्लास आयात करें

Scene क्लास सभी 3D डेटा के लिए शीर्ष-स्तर कंटेनर है। इसे उन सभी लोड‑ऑप्शन क्लासेज़ के साथ इम्पोर्ट करें जिनकी आपको आवश्यकता है।

from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions

सभी सार्वजनिक वर्ग aspose.threed या उसके उप‑पैकेजों (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities) के अंतर्गत रहते हैं।


चरण 3: फ़ाइल लोड करें

किसी भी समर्थित फ़ॉर्मेट को खोलने के लिए स्थैतिक Scene.from_file() मेथड का उपयोग करें। लाइब्रेरी फ़ाइल एक्सटेंशन से फ़ॉर्मेट को स्वचालित रूप से पहचानती है।

##Automatic format detection
scene = Scene.from_file("model.obj")

वैकल्पिक रूप से, एक Scene इंस्टेंस बनाएं और open() को कॉल करें; यह उपयोगी है जब आप लोड विकल्प पास करना चाहते हैं या त्रुटियों को स्पष्ट रूप से संभालना चाहते हैं:

scene = Scene()
scene.open("model.obj")

दोनों विधियों में OBJ, STL (बाइनरी और ASCII), glTF 2.0 / GLB, COLLADA (DAE), और 3MF फ़ाइलों का समर्थन किया जाता है।


चरण 4: सीन नोड्स को पार करें

एक लोडेड सीन Node वस्तुओं का एक पेड़ है जिसका मूल scene.root_node पर स्थित है। सभी नोड्स को खोजने के लिए पुनरावर्ती रूप से इटररेट करें:

from aspose.threed import Scene, Node

scene = Scene.from_file("model.obj")

def walk(node: Node, depth: int = 0) -> None:
    indent = "  " * depth
    print(f"{indent}Node: {node.name!r}")
    for child in node.child_nodes:
        walk(child, depth + 1)

walk(scene.root_node)

प्रत्येक Node शून्य या अधिक Entity ऑब्जेक्ट्स (मेशेज़, कैमरे, लाइट्स) ले जा सकता है। यह देखने के लिए node.entities देखें कि क्या जुड़ा है।


चरण 5: वर्टेक्स और पॉलीगॉन डेटा तक पहुँचें

एक नोड की एंटिटी को Mesh में कास्ट करें और उसके कंट्रोल पॉइंट्स (वर्टेक्स पोजीशन) और पॉलीगॉन्स (फेस इंडेक्स लिस्ट) पढ़ें:

from aspose.threed import Scene
from aspose.threed.entities import Mesh

scene = Scene.from_file("model.obj")

for node in scene.root_node.child_nodes:
    for entity in node.entities:
        if isinstance(entity, Mesh):
            mesh: Mesh = entity
            print(f"Mesh '{node.name}': "
                  f"{len(mesh.control_points)} vertices, "
                  f"{len(mesh.polygons)} polygons")

            # First vertex position
            if mesh.control_points:
                v = mesh.control_points[0]
                print(f"  First vertex: ({v.x:.4f}, {v.y:.4f}, {v.z:.4f})")

            # First polygon face (list of control-point indices)
            if mesh.polygons:
                print(f"  First polygon: {mesh.polygons[0]}")

mesh.control_points एक Vector4 वस्तुओं की सूची है; x, y, z स्थिति ले जाते हैं और w समरूप निर्देशांक है (आमतौर पर 1.0)।

mesh.polygons एक सूची है जो पूर्णांकों की सूचियों की सूची है, जहाँ प्रत्येक आंतरिक सूची एक चेहरे के लिए नियंत्रण‑बिंदु सूचकांकों का क्रमबद्ध सेट है।


चरण 6: फ़ॉर्मेट-विशिष्ट लोड विकल्प लागू करें

OBJ फ़ाइल की व्याख्या को सूक्ष्म-स्तर पर नियंत्रित करने के लिए, ObjLoadOptions का एक उदाहरण scene.open() को पास करें:

from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions

options = ObjLoadOptions()
options.flip_coordinate_system = True   # Convert right-hand Y-up to Z-up
options.scale = 0.01                    # Convert centimetres to metres
options.enable_materials = True         # Load .mtl material file
options.normalize_normal = True         # Normalize all normals to unit length

scene = Scene()
scene.open("model.obj", options)

STL फ़ाइलों के लिए, समतुल्य क्लास StlLoadOptions है। glTF के लिए, GltfLoadOptions का उपयोग करें। पूर्ण सूची के लिए API reference देखें।


सामान्य समस्याएँ और समाधान

FileNotFoundError जब Scene.from_file() को कॉल किया जाता है

पथ को पूर्ण या रनटाइम पर कार्य निर्देशिका के सापेक्ष सही होना चाहिए। विश्वसनीय पथ बनाने के लिए pathlib.Path का उपयोग करें:

from pathlib import Path
from aspose.threed import Scene

path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))

mesh.polygons STL फ़ाइल लोड करने के बाद खाली है

STL फ़ाइलें त्रिकोणों को कच्चे फ़ैसेट के रूप में संग्रहीत करती हैं, न कि अनुक्रमित मेष के रूप में। लोड करने के बाद, बहुभुज उन फ़ैसेट से संश्लेषित किए जाते हैं। यदि polygons खाली दिखता है, तो len(mesh.control_points) की जाँच करें; यदि गणना 3 का गुणज है तो ज्यामिति अनुक्रमित रूप में संग्रहीत होती है और प्रत्येक क्रमिक तीन शीर्ष बिंदु एक त्रिकोण बनाते हैं।

कोऑर्डिनेट सिस्टम में असंगति (मॉडल घुमाया या प्रतिबिंबित दिखता है)

विभिन्न टूल्स विभिन्न सम्मेलनों का उपयोग करते हैं (Y‑up बनाम Z‑up, बाएँ‑हाथ बनाम दाएँ‑हाथ)। लोड करने के बाद ObjLoadOptions.flip_coordinate_system = True सेट करें या रूट नोड के Transform पर एक घूर्णन लागू करें।

AttributeError: 'NoneType' object has no attribute 'polygons'

एक नोड की एंटिटी सूची में गैर‑मेष एंटिटीज़ (कैमरे, लाइट्स) हो सकती हैं। कास्ट करने से पहले हमेशा isinstance(entity, Mesh) के साथ गार्ड करें।


अक्सर पूछे जाने वाले प्रश्न (FAQ)

मैं कौन से 3D फ़ॉर्मेट लोड कर सकता हूँ?

OBJ (Wavefront), STL (binary and ASCII), glTF 2.0 / GLB, COLLADA (DAE), और 3MF। FBX फ़ाइल टोकनाइज़ेशन आंशिक रूप से समर्थित है लेकिन पूर्ण पार्सिंग अभी तक पूरी नहीं हुई है।

क्या OBJ फ़ाइल लोड करने से .mtl सामग्री भी लोड होती है?

हाँ, जब ObjLoadOptions.enable_materials = True (डिफ़ॉल्ट) हो। लाइब्रेरी .mtl फ़ाइल को उसी निर्देशिका में देखती है जहाँ .obj फ़ाइल है। यदि .mtl गायब है, तो ज्यामिति अभी भी लोड हो जाती है और एक चेतावनी जारी की जाती है।

क्या मैं फ़ाइल को पथ के बजाय बाइट स्ट्रीम से लोड कर सकता हूँ?

हाँ। scene.open() किसी भी फ़ाइल‑समतुल्य वस्तु को स्वीकार करता है जिसमें .read() मेथड हो, साथ ही फ़ाइल पाथ स्ट्रिंग भी। एक खुला बाइनरी स्ट्रीम (उदाहरण के लिए, io.BytesIO) सीधे पास करें। Scene.from_file() केवल फ़ाइल पाथ स्ट्रिंग को स्वीकार करता है।

मैं सतह के नॉर्मल्स कैसे प्राप्त करूँ?

लोड करने के बाद, mesh.get_element(VertexElementType.NORMAL) जाँचें। यह एक VertexElementNormal लौटाता है जिसका data सूची में प्रत्येक संदर्भ के लिए एक सामान्य वेक्टर होता है, जो mapping_mode और reference_mode के अनुसार मैप किया गया है।

from aspose.threed.entities import Mesh, VertexElementType

normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
    print(normals.data[0])  # First normal vector

क्या लाइब्रेरी एक साथ कई फ़ाइलों को लोड करने के लिए थ्रेड-सेफ़ है?

प्रत्येक Scene ऑब्जेक्ट स्वतंत्र है। अलग-अलग थ्रेड्स से अलग-अलग Scene इंस्टेंस में अलग-अलग फ़ाइलें लोड करना सुरक्षित है, बशर्ते आप बिना बाहरी लॉकिंग के थ्रेड्स के बीच एक ही Scene साझा न करें।

 हिन्दी