Hvordan laste inn 3D-modeller i Python
Aspose.3D FOSS for Python gir et enkelt API for å åpne 3D-filer uten noen native avhengigheter. Etter å ha lastet en fil inn i en Scene objekt, kan du gå gjennom nodehierarkiet og lese rå geometridata for hver mesh i scenen.
Steg-for-steg guide
Steg 1: Installer pakken
Installer Aspose.3D FOSS fra PyPI. Ingen ekstra systembiblioteker er påkrevd.
pip install aspose-3d-fossStøttede Python-versjoner: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Steg 2: Importer Scene-klassen
Den Scene klassen er den øverste beholderen for all 3D-data. Importer den sammen med eventuelle lastingsalternativklasser du trenger.
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptionsAlle offentlige klasser finnes under aspose.threed eller dens underpakker (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).
Steg 3: Last inn en fil
Bruk den statiske Scene.from_file() metoden for å åpne ethvert støttet format. Biblioteket oppdager formatet automatisk fra filendelsen.
##Automatic format detection
scene = Scene.from_file("model.obj")Alternativt, opprett en Scene instans og kall open(); nyttig når du vil sende inn lastingsalternativer eller håndtere feil eksplisitt:
scene = Scene()
scene.open("model.obj")Begge metodene støtter OBJ, STL (binær og ASCII), glTF 2.0 / GLB, COLLADA (DAE) og 3MF-filer.
Steg 4: Gå gjennom Scene-noder
En lastet scene er et tre av Node objekter med roten i scene.root_node. Gå rekursivt gjennom for å finne alle noder:
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)Hver Node kan inneholde null eller flere Entity objekter (mesher, kameraer, lys). Sjekk node.entities for å se hva som er festet.
Steg 5: Tilgang til vertex- og polygondata
Kast en nodes enhet til Mesh og les dens kontrollpunkter (vertex positions) og polygoner (face index lists):
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 er en liste over Vector4 objekter; x, y, z bærer posisjonen og w er den homogene koordinaten (vanligvis 1.0).
mesh.polygons er en liste av lister med heltall, hvor hver indre liste er den ordnede mengden av kontrollpunktindekser for én flate.
Steg 6: Bruk formatspesifikke lastingsalternativer
For finjustert kontroll over hvordan en OBJ-fil tolkes, send inn en ObjLoadOptions instans til 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)For STL-filer er den tilsvarende klassen StlLoadOptions. For glTF, bruk GltfLoadOptions. Se API-referansen for en fullstendig liste.
Vanlige problemer og løsninger
FileNotFoundError ved kall til Scene.from_file()
Stien må være absolutt eller korrekt relativ til arbeidskatalogen ved kjøring. Bruk pathlib.Path for å bygge pålitelige stier:
from pathlib import Path
from aspose.threed import Scene
path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))mesh.polygons er tom etter lasting av en STL-fil
STL-filer lagrer trekanter som rå flater, ikke som et indeksert nett. Etter innlasting blir polygoner syntetisert fra disse flatene. Hvis polygons ser tom ut, sjekk len(mesh.control_points); hvis antallet er et multiplum av 3, er geometrien lagret i uindeksert form, og hver påfølgende trippel av vertices danner en trekant.
Uoverensstemmelse i koordinatsystem (modellen ser rotert eller speilet ut)
Ulike verktøy bruker ulike konvensjoner (Y-opp vs Z-opp, venstrehånds vs høyrehånds). Angi ObjLoadOptions.flip_coordinate_system = True eller bruk en rotasjon på rotknutens Transform etter lasting.
AttributeError: 'NoneType' object has no attribute 'polygons'
En nodes entitetsliste kan inneholde ikke-mesh-entiteter (kameraer, lys). Beskytt alltid med isinstance(entity, Mesh) før casting.
Ofte stilte spørsmål (FAQ)
Hvilke 3D-formater kan jeg laste?
OBJ (Wavefront), STL (binær og ASCII), glTF 2.0 / GLB, COLLADA (DAE) og 3MF. FBX‑fil‑tokenisering støttes delvis, men full parsing er ennå ikke komplett.
Laster inn en OBJ-fil også inn .mtl materialet?
Ja, når ObjLoadOptions.enable_materials = True (standard). Biblioteket ser etter .mtl filen i samme katalog som .obj filen. Hvis .mtl mangler, blir geometrien fortsatt lastet inn og en advarsel blir gitt.
Kan jeg laste en fil fra en byte‑strøm i stedet for en sti?
Ja. scene.open() godtar ethvert fil‑lignende objekt med en .read() metode i tillegg til en filstistring. Send en åpen binærstrøm (f.eks., io.BytesIO) direkte. Scene.from_file() godtar kun en filstistring.
Hvordan får jeg overflatenormaler?
Etter lasting, sjekk mesh.get_element(VertexElementType.NORMAL). Dette returnerer en VertexElementNormal hvis data listen inneholder én normalvektor per referanse, kartlagt i henhold til mapping_mode og reference_mode.
from aspose.threed.entities import Mesh, VertexElementType
normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
print(normals.data[0]) # First normal vectorEr biblioteket trådsikkert for å laste flere filer samtidig?
Hver Scene objektet er uavhengig. Laster separate filer inn i separate Scene instanser fra separate tråder er trygt så lenge du ikke deler en enkelt Scene på tvers av tråder uten ekstern låsing.