3D modellek betöltése Pythonban

3D modellek betöltése Pythonban

Aspose.3D FOSS for Python egyszerű API-t biztosít 3D fájlok megnyitásához, anélkül, hogy natív függőségek lennének. Egy fájl betöltése után egy Scene objektumba, bejárhatja a csomópont-hierarchiát, és nyers geometriai adatokat olvashat a jelenet minden hálójáról.

Lépésről‑lépésre útmutató

1. lépés: A csomag telepítése

Telepítse az Aspose.3D FOSS-t a PyPI-ról. Nem szükségesek további rendszerkönyvtárak.

pip install aspose-3d-foss

Támogatott Python verziók: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


2. lépés: A Scene osztály importálása

A Scene osztály a legfelső szintű tároló minden 3D adat számára. Importáld azt a szükséges betöltési opciós osztályokkal együtt.

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

Minden nyilvános osztály a aspose.threed vagy annak alcsomagjaiban (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities) található.


3. lépés: Fájl betöltése

Használja a statikus Scene.from_file() metódust bármely támogatott formátum megnyitásához. A könyvtár automatikusan felismeri a formátumot a fájlkiterjesztés alapján.

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

Alternatív megoldásként hozzon létre egy Scene példányt, és hívja meg a open()‑t; hasznos, ha betöltési beállításokat szeretne átadni, vagy hibákat explicit módon kezelni:

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

Mindkét módszer támogatja az OBJ, STL (bináris és ASCII), glTF 2.0 / GLB, COLLADA (DAE) és 3MF fájlokat.


4. lépés: Jelenet csomópontok bejárása

A betöltött jelenet egy Node objektumokból álló fa, amelynek gyökere scene.root_node. Rekurzívan iteráljon, hogy megtalálja az összes csomópontot:

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)

Minden Node nulla vagy több Entity objektumot (hálózatok, kamerák, fények) hordozhat. Ellenőrizze a node.entities‑t, hogy lássa, mi van csatolva.


5. lépés: Csúcs- és sokszögadatok elérése

Alakítsd át a csomópont entitását Mesh típusra, és olvasd ki a vezérlőpontjait (csúcspozíciók) és a poligonokat (felületindex-listák):

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 egy Vector4 objektumok listája; x, y, z a pozíciót hordozzák, és w a homogén koordináta (általában 1.0).

mesh.polygons egy listák listája egész számokból, ahol minden belső lista egy felülethez tartozó vezérlőpont-indexek rendezett halmaza.


6. lépés: Formátum-specifikus betöltési beállítások alkalmazása

Az OBJ fájl értelmezésének finomhangolt vezérléséhez adjon át egy ObjLoadOptions példányt a scene.open()‑nek:

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 fájlok esetén az ekvivalens osztály StlLoadOptions. glTF esetén használja GltfLoadOptions. Tekintse meg az API-referencia a teljes listáért.


Gyakori problémák és megoldások

FileNotFoundError a Scene.from_file() hívásakor

Az elérési útnak abszolútnak vagy a futási időben a munkakönyvtárhoz képest helyes relatívnak kell lennie. Használja a pathlib.Path‑t megbízható utak építéséhez:

from pathlib import Path
from aspose.threed import Scene

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

mesh.polygons üres az STL fájl betöltése után

Az STL fájlok háromszögeket nyers felületekként tárolják, nem indexelt hálóként. Betöltés után a poligonok ezekből a felületekből szintetizálódnak. Ha polygons üresnek jelenik meg, ellenőrizze len(mesh.control_points); ha a szám 3‑mal osztható, akkor a geometria nem indexelt formában van tárolva, és minden egymást követő három csúcs egy háromszöget alkot.

Koordináta‑rendszer eltérés (a modell elfordult vagy tükrözöttnek tűnik)

Különböző eszközök különböző konvenciókat használnak (Y-felfelé vs Z-felfelé, balkezes vs jobbkezes). Állítsa be ObjLoadOptions.flip_coordinate_system = True vagy alkalmazzon egy forgatást a gyökércsomópont Transform-jára a betöltés után.

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

Egy csomópont entitáslistája tartalmazhat nem‑mesh entitásokat (kamerákat, fényeket). Mindig védd isinstance(entity, Mesh)-vel a konvertálás előtt.


Gyakran Ismételt Kérdések (GYIK)

Milyen 3D formátumokat tölthetek be?

OBJ (Wavefront), STL (bináris és ASCII), glTF 2.0 / GLB, COLLADA (DAE) és 3MF. Az FBX fájl tokenizálása részben támogatott, de a teljes elemzés még nem készült el.

Az OBJ fájl betöltése is betölti a .mtl anyagot?

Igen, amikor ObjLoadOptions.enable_materials = True (az alapértelmezett). A könyvtár a .mtl fájlt keresi ugyanabban a könyvtárban, mint a .obj fájl. Ha a .mtl hiányzik, a geometria továbbra is betöltődik, és figyelmeztetés jelenik meg.

Betölthetek egy fájlt bájtfolyamból az útvonal helyett?

Igen. scene.open() elfogad bármilyen fájl-szerű objektumot egy .read() metódussal a fájlútvonal karakterlánc mellett. Adjon át egy nyitott bináris adatfolyamot (például io.BytesIO) közvetlenül. Scene.from_file() csak egy fájlútvonal karakterláncot fogad el.

Hogyan kapok felületi normálvektorokat?

Betöltés után ellenőrizze a mesh.get_element(VertexElementType.NORMAL)-t. Ez egy VertexElementNormal-t ad vissza, amelynek data listája minden hivatkozáshoz egy normálvektort tartalmaz, a mapping_mode és reference_mode szerint leképezve.

from aspose.threed.entities import Mesh, VertexElementType

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

A könyvtár szálbiztos a több fájl egyidejű betöltéséhez?

Minden Scene objektum független. Különálló fájlok betöltése különálló Scene példányokba külön szálakról biztonságos, amíg nem oszt meg egyetlen Scene‑t szálak között külső zárolás nélkül.

 Magyar