Wie man 3D-Modelle in Python lädt
Aspose.3D FOSS für Python bietet eine einfache API zum Öffnen von 3D-Dateien ohne natürliche Abhängigkeiten. Nach dem Laden einer Datei in ein Scene Objekt, können Sie die Knotenhierarchie gehen und lesen Rohgeometrie Daten für jedes Netz in der Szene.
Schritt für Schritte
Schritt 1: Installieren des Pakets
Installieren Sie Aspose.3D FOSS von PyPI. Keine zusätzlichen Systembibliotheken erforderlich.
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
Unterstützte Python-Versionen: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Schritt 2: Importieren der Szenenklasse
Die Scene Importieren Sie es zusammen mit allen Ladeoptionsklassen, die Sie benötigen.
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptionsDie öffentlichen Klassen leben unter der aspose.threed oder deren Unterpakete (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).
Schritt 3: Laden einer Datei ein
Verwenden Sie die statische Scene.from_file() Die Bibliothek erkennt das Format automatisch aus der Dateierweiterung.
##Automatic format detection
scene = Scene.from_file("model.obj")Die Kommission hat die Scene Anruf und Aufforderung open(); nützlich, wenn Sie die Ladeoptionen übergeben oder Fehler explizit behandeln möchten:
scene = Scene()
scene.open("model.obj")Beide Methoden unterstützen OBJ-, STL- (binär und ASCII), glTF 2.0 / GLB, COLLADA (DAE) und 3MF-Dateien.
Schritt 4: Traverse-Szenenknoten
Eine geladene Szene ist ein Baum von Node Objekte, die auf der scene.root_node.Iterieren Sie rekursiv , um alle Knoten zu finden:
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)Jeder von ihnen Node kann null oder mehr tragen Entity Gegenstände (Maschen, Kameras, Lichter). node.entities um zu sehen, was angebracht ist.
Schritt 5: Zugriff auf Vertex- und Polygondaten
Die Entität eines Knoten auf die Mesh und die Kontrollpunkte (Spitzenpositionen) und Polygone (Fassaden-Indexlisten) lesen:
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 ist eine Liste von Vector4 Gegenstände; x, y, z die Position zu halten und w ist die homogene Koordinate (normalerweise 1,0).
mesh.polygons ist eine Liste von ganzen Zahlen, wobei jede innere Liste die geordnete Menge der Kontrollpunktindizes für eine Fläche darstellt.
Schritt 6: Anwendungen für Format-spezifische Ladeoptionen
Für eine detaillierte Kontrolle der Interpretation einer OBJ-Datei, geben Sie einen ObjLoadOptions In diesem Fall 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)Für STL-Dateien ist die entsprechende Klasse: StlLoadOptions.Für glTF: Verwenden GltfLoadOptions.- Sieh dir das an . Referenz zur API für eine vollständige Liste.
Häufige Probleme und Lösungen
FileNotFoundError beim Anrufen Scene.from_file()
Der Pfad muss zum Zeitpunkt der Ausführung absolut oder korrekt im Verhältnis zur Arbeitsmappe sein. pathlib.Path zuverlässige Wege aufzubauen:
from pathlib import Path
from aspose.threed import Scene
path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))mesh.polygons ist nach dem Laden einer STL-Datei leer.
STL-Dateien speichern Dreiecken als Rohfacetten, nicht als ein indiziertes Netz. Nach dem Laden werden Polygone aus diesen Facetts synthetisiert. Wenn polygons Erscheint leer, überprüfen Sie len(mesh.control_points);Wenn die Zahl ein Vielfaches von 3 ist, wird die Geometrie in unindexierter Form gespeichert und jedes aufeinanderfolgende Dreifach-Gipfel bildet ein Dreieck.
Nicht übereinstimmende Koordinatensysteme (Modell wird gedreht oder spiegeln)
Verschiedene Werkzeuge verwenden verschiedene Konventionen (Y-up vs. Z- up, links/rechts). Setzen Sie die Daten auf der Seite des Gerätes und setzen Sie sie in den Schaltfeld. ObjLoadOptions.flip_coordinate_system = True oder eine Rotation auf den Wurzelknoten anwenden Transform nach dem Laden.
AttributeError: 'NoneType' object has no attribute 'polygons'
Die Entitätsliste eines Knotenpunkts kann nicht-mesch entitäten (Kameras, Lichter) enthalten. isinstance(entity, Mesh) Vor dem Casting.
Häufig gestellte Fragen (FAQ)
Welche 3D-Formate kann ich laden?
OBJ (Wavefront), STL (binär und ASCII), glTF 2.0 / GLB, COLLADA (DAE) und 3MF. Die FBX-Datei Tokenisierung wird teilweise unterstützt, aber das vollständige Parsen ist noch nicht abgeschlossen.
Wird bei der Aufladung einer OBJ-Datei auch die .mtl Was ist das Material?
Ja, wenn… ObjLoadOptions.enable_materials = True Die Bibliothek sucht nach den .mtl Datei in demselben Verzeichnis wie die .obj Die Kommission hat die .mtl Die Geometrie ist noch geladen und eine Warnung wird ausgesendet.
Kann ich eine Datei aus einem Byte-Stream anstelle eines Pfades laden?
- Ja, das ist gut.
scene.open()Akzeptiert jedes Datei-ähnliche Objekt mit einem.read()Pass ein offenen binären Strom (z. B.,io.BytesIO) direkt.Scene.from_file()Akzeptiert nur einen Dateipfad-Zeichen.
Wie bekomme ich Oberflächennormale?
Nach dem Laden überprüfen Sie: mesh.get_element(VertexElementType.NORMAL).Das gibt eine VertexElementNormal deren data Liste enthält einen normalen Vektor pro Referenz, der nach den folgenden Kennzeichnungen abgebildet ist: mapping_mode und . reference_mode.
from aspose.threed.entities import Mesh, VertexElementType
normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
print(normals.data[0]) # First normal vectorIst das Library-Thread sicher für gleichzeitiges Laden mehrerer Dateien?
Jeder von ihnen Scene Objekt ist unabhängig. Lade einzelne Dateien in separate Scene Instanzen von separaten Threads ist sicher, solange Sie nicht teilen eine einzelne Scene über die Fäden ohne äußere Verriegelung.