Hogyan töltsünk be 3D modelleket a Python-ban

Hogyan töltsünk be 3D modelleket a Python-ban

Aspose.3D FOSS for Python egyszerű API-t biztosít 3D fájlok megnyitásához natív függőségek nélkül. A fájl betöltése után egy Scene objektumba, bejárhatja a node hierarchiát, és nyers geometriai adatokat olvashat a scene minden mesh‑jéről.

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

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

Telepítse a Aspose.3D FOSS-t a PyPI‑ról. Nem szükséges 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 class a legfelső szintű tároló minden 3D adat számára. Importálja azt a szükséges load‑option class‑okkal együtt.

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

Minden nyilvános classes a aspose.threed vagy annak sub‑packages (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).


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

Használja a static Scene.from_file() method bármely támogatott formátum megnyitásához. A library automatikusan felismeri a formátumot a fájl kiterjesztéséből.

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

Alternatívaként hozzon létre egy Scene instance, és hívja meg a open(); hasznos, ha load options‑t 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: A Scene csomópontok bejárása

A loaded scene egy fa a Node objects gyökere a scene.root_node. Iterate rekurzívan az összes node megtalálásához:

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 can nulla vagy több Entity objektumok (hálók, kamerák, fények). Ellenőrizze node.entities hogy lássa, mi van csatolva.


5. lépés: Csúcs és sokszög adatok elérése

Konvertálja egy csomópont entitását Mesh és olvassa el annak vezérlőpontjait (csúcspozíciók) és poligonjait (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 lista a Vector4 objektumok; x, y, z tartalmazzák a pozíciót é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 adott felülethez tartozó, rendezett vezérlőpont-indexek halmaza.


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

A finomhangolt vezérléshez, hogy egy OBJ fájlt hogyan értelmezzen, adjon át egy ObjLoadOptions példányt a 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 fájlok esetén az ekvivalens osztály StlLoadOptions. glTF esetén használja GltfLoadOptions. Lásd a API referencia a teljes listaért.


Gyakori problémák és megoldások

FileNotFoundError híváskor Scene.from_file()

Az elérési útnak abszolútnak vagy a futási időben a munkakönyvtárhoz képest helyesnek kell lennie. Használja pathlib.Path a megbízható utak felé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 egy 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 tűnik, ellenőrizze len(mesh.control_points); ha a szám háromszoros, a geometria index nélküli 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 elfordítottnak 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 jobboldali). Állítsa be ObjLoadOptions.flip_coordinate_system = True vagy alkalmazzon egy forgatást a gyökércsomópont Transform betöltés után.

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

Egy csomópont entitáslistája tartalmazhat nem-háló entitásokat (kamerák, fények). Mindig ellenőrizze a isinstance(entity, Mesh) castolás előtt.


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

Milyen 3D formátumokat tudok betölteni?

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.

Betölti-e egy OBJ fájl a .mtl materialt?

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

Betölthetek fájlt bájtos áramlásbó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 (pl., io.BytesIO) közvetlenül. Scene.from_file() csak egy fájlútvonal karakterláncot fogad el.

Hogyan szerezhetem meg a felületi normálvektorokat?

Betöltés után ellenőrizze mesh.get_element(VertexElementType.NORMAL). Ez visszaad egy VertexElementNormal amelynek data lista egy normál vektort tartalmaz referenciaenként, a következő szerint leképezve mapping_mode és reference_mode.

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álló szálakról biztonságos, amíg nem oszt meg egyetlen Scene szálak között külső zárolás nélkül.

 Magyar