Eigenschaften und Funktionen
Ein komplettes Entwicklerguide für Aspose.3D FOSS für Python, das die Formatunterstützung, Scene-Graph-Konstruktion, Materialien, Mathe-Nutzungsanwendungen, Animation und Produktionsbest Practices umfasst.
Installation und Setup
Installieren Sie die Bibliothek von PyPI mit einem einzigen Kommandot:
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.Keine zusätzlichen Systempakete, native Erweiterungen oder Compiler-Toolketten sind erforderlich. Die Bibliothek ist sauber Python und unterstützt Python 3.7 bis 3.12 auf Windows, macOS und Linux.
Überprüfen Sie die Installation:
from aspose.threed import Scene
scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")Eigenschaften und Funktionen
Format Unterstützung
Aspose.3D FOSS für Python:
| Format | Erweiterung | Lesen | Schreiben | Notizen |
|---|---|---|---|---|
| OBJ | .obj | Ja Ja | Ja Ja | Wavefront OBJ; .mtl Materialladung unterstützt |
| STL | .stl | Ja Ja | Ja Ja | Binäre und ASCII Varianten; rundtrip verifiziert |
| Gltf | .gltf / .glb | Ja Ja | Ja Ja | GlTF 2.0 JSON und GLB binäre Container |
| COLLADA | .dae | Ja Ja | Ja Ja | Hierarchie und Materialien |
| 3MF | .3mf | Ja Ja | Ja Ja | Additive Produktionsformate |
| FBX | .fbx | Teilweise | No nicht | Tokenizer arbeitet; Parser hat bugs bekannt |
Laden OBJ mit Optionen
ObjLoadOptions Überprüft, wie OBJ-Dateien verpasst werden:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True # Load accompanying .mtl file
options.flip_coordinate_system = False # Preserve original handedness
options.normalize_normal = True # Normalize vertex normals to unit length
options.scale = 1.0 # Apply a uniform scale factor at load time
scene = Scene()
scene.open("model.obj", options)
print(f"Loaded {len(scene.root_node.child_nodes)} top-level nodes")Sparen Sie auf STL
StlSaveOptions Binäre vs. ASCII-Ausgang und andere STL-spezifische Einstellungen:
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)Scene Graf
Alle 3D-Inhalte werden als Baum organisiert Node Objekt: Die Wurzel des Baumes ist scene.root_node.Jede Knoten kann Kinderknoten enthalten und eine Entity (Mesh, Kamera oder Licht) plus A Transform.
Über die Szene Hierarchie
from aspose.threed import Scene
scene = Scene.from_file("model.glb")
def traverse(node, depth=0):
indent = " " * depth
entity_type = type(node.entity).__name__ if node.entity else "none"
print(f"{indent}{node.name} [{entity_type}]")
for child in node.child_nodes:
traverse(child, depth + 1)
traverse(scene.root_node)Eine Bühne programmatisch bauen
from aspose.threed import Scene, Node, Entity
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3
scene = Scene()
root = scene.root_node
##Create a child node and position it
child = root.create_child_node("my_object")
child.transform.translation = Vector3(1.0, 0.0, 0.0)
child.transform.scaling = Vector3(2.0, 2.0, 2.0)
scene.save("constructed.glb")Überprüfung GlobalTransform
GlobalTransform Er gibt die Welt-Raum-Transformation eines Knoten nach der Erhebung aller Vorfahren-Transformationen:
from aspose.threed import Scene
scene = Scene.from_file("model.dae")
for node in scene.root_node.child_nodes:
gt = node.global_transform
print(f"Node: {node.name}")
print(f" World translation: {gt.translation}")
print(f" World scale: {gt.scale}")Feuer Mesh
Die Mesh Die Entität gibt Zugang zu geometrischen Daten einschließlich Kontrollpunkte (Vertikeln), Polygone und Vertexelemente für Normale, UVs und Farben.
Lesen Sie Mesh Geometrie
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
options.flip_coordinate_system = False
scene = Scene()
scene.open("model.obj", options)
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
print(f"Mesh: {node.name}")
print(f" Vertices: {len(mesh.control_points)}")
print(f" Polygons: {len(mesh.polygons)}")Vertex-Elemente zu erreichern
Vertex-Elemente tragen per-vertex oder per-polygon-Daten. Die häufigsten Elemente sind normale, UV-Koordinate, Vertexfarben und Schweißgruppen:
from aspose.threed import Scene
from aspose.threed.entities import VertexElementNormal, VertexElementUV
scene = Scene.from_file("model.obj")
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
# Iterate vertex elements to find normals and UVs
for element in mesh.vertex_elements:
if isinstance(element, VertexElementNormal):
print(f" Normals count: {len(element.data)}")
elif isinstance(element, VertexElementUV):
print(f" UV count: {len(element.data)}")Materialsystem
Aspose.3D FOSS unterstützt zwei Materialienarten: LambertMaterial (Siehe Schatten) und PhongMaterial Beide werden automatisch aus .mtl-Dateien geladen, wenn sie verwendet werden ObjLoadOptions mit enable_materials = True.
Lesen von OBJ
from aspose.threed import Scene
from aspose.threed.shading import LambertMaterial, PhongMaterial
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
scene = Scene()
scene.open("model.obj", options)
for node in scene.root_node.child_nodes:
mat = node.material
if mat is None:
continue
print(f"Node: {node.name}")
if isinstance(mat, PhongMaterial):
print(f" Type: Phong")
print(f" Diffuse: {mat.diffuse_color}")
print(f" Specular: {mat.specular_color}")
elif isinstance(mat, LambertMaterial):
print(f" Type: Lambert")
print(f" Diffuse: {mat.diffuse_color}")Ein Material programmatisch zu verabreichen
from aspose.threed import Scene, Node
from aspose.threed.shading import PhongMaterial
from aspose.threed.utilities import Vector3
scene = Scene.from_file("model.glb")
material = PhongMaterial()
material.diffuse_color = Vector3(0.8, 0.2, 0.2) # Red diffuse
material.specular_color = Vector3(1.0, 1.0, 1.0) # White specular
##Apply to the first mesh node
for node in scene.root_node.child_nodes:
if node.entity is not None:
node.material = material
break
scene.save("recolored.glb")Mathematikn nutz
Die aspose.threed.utilities Modul bietet alle geometrischen Mathematikarten, die für die Bühne-Konstruktion und Inspektion benötigt werden.
| Klasse | Zweck |
|---|---|
Vector2 | 2D floating-point vector (UV coordinates) |
Vector3 | 3D double-precision vector (positions, normals) |
Vector4 | 4D double-precision vector (homogeneous coordinates) |
FVector3 | 3D single-precision vector (compact storage) |
Quaternion | Rotation ohne Gimbal-Lock |
Matrix4 | 4×4 transformation matrix |
BoundingBox | Axis-aligned Bootbox mit Min/max Winkel |
Transformationen
from aspose.threed.utilities import Vector3, Quaternion, Matrix4
import math
##Build a rotation quaternion from axis-angle
axis = Vector3(0.0, 1.0, 0.0) # Y-axis
angle_rad = math.radians(45.0)
q = Quaternion.from_angle_axis(angle_rad, axis)
print(f"Quaternion: x={q.x:.4f} y={q.y:.4f} z={q.z:.4f} w={q.w:.4f}")
##Convert to rotation matrix
mat = q.to_matrix()
print(f"Rotation matrix row 0: {mat[0, 0]:.4f} {mat[0, 1]:.4f} {mat[0, 2]:.4f}")Ein Bounding Box zu erstellen
from aspose.threed import Scene
scene = Scene.from_file("model.stl")
# NOTE: mesh.get_bounding_box() is a stub — it always returns an empty BoundingBox()
# regardless of geometry. Compute bounds manually from control_points:
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
pts = mesh.control_points # returns a copy of the vertex list
if not pts:
continue
xs = [p.x for p in pts]
ys = [p.y for p in pts]
zs = [p.z for p in pts]
print(f"Mesh: {node.name}")
print(f" Min: ({min(xs):.3f}, {min(ys):.3f}, {min(zs):.3f})")
print(f" Max: ({max(xs):.3f}, {max(ys):.3f}, {max(zs):.3f})")Animation
Aspose.3D FOSS bietet ein Animationsmodell auf der Grundlage AnimationClip, AnimationNode, KeyFrame,und KeyframeSequence. Animationsdaten, die in hochgeladenen Dateien gespeichert werden (glTF, COLLADA) sind über diese Objekte zugänglich.
Lesen Animation Clips
from aspose.threed import Scene
scene = Scene.from_file("animated.glb")
for clip in scene.animation_clips:
print(f"Clip: {clip.name} ({clip.start:.2f}s – {clip.stop:.2f}s)")
for anim_node in clip.animations:
print(f" Animation node: {anim_node.name}")
for sub in anim_node.sub_animations:
print(f" Sub-animation: {sub.name}")
for bp in anim_node.bind_points:
print(f" Bind point: {bp.name}")Laden und speichern Optionen
Jedes unterstützte Format hat eine entsprechende Optionsklasse, die Parsing und Serienverhalten kontrolliert.
| Klasse | Format | Schlüssel Eigenschaften |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Binär vs. ASCII Ausgangsmodus |
| (GMT verwendet Defekte) | GTT / GLB | Scene-Grafik und Materialien automatisch gespeichert |
Verwendung Beispiele
Beispiel 1: OBJ zum STL Format konvertiert
Konvertieren Sie eine OBJ Datei (mit Materialien) in binäre STL, Drucken Sie Messstatistik auf dem Weg:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
from aspose.threed.formats import StlSaveOptions
##Load OBJ with material support
load_opts = ObjLoadOptions()
load_opts.enable_materials = True
load_opts.flip_coordinate_system = False
load_opts.normalize_normal = True
scene = Scene()
scene.open("input.obj", load_opts)
##Report what was loaded
total_vertices = 0
total_polygons = 0
for node in scene.root_node.child_nodes:
if node.entity is not None:
mesh = node.entity
total_vertices += len(mesh.control_points)
total_polygons += len(mesh.polygons)
print(f" {node.name}: {len(mesh.control_points)} vertices, {len(mesh.polygons)} polygons")
print(f"Total: {total_vertices} vertices, {total_polygons} polygons")
##Save as STL
save_opts = StlSaveOptions()
scene.save("output.stl", save_opts)
print("Saved output.stl")Beispiel 2: Batch glTF zu GLB Packing
Wieder speichern Sie eine Liste von getrennten glTF + Texturdateien als selbstverhaltenen GLB-Binaren:
import os
from aspose.threed import Scene
input_dir = "gltf_files"
output_dir = "glb_files"
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.endswith(".gltf"):
continue
src = os.path.join(input_dir, filename)
dst = os.path.join(output_dir, filename.replace(".gltf", ".glb"))
scene = Scene.from_file(src)
scene.save(dst)
print(f"Packed {filename} -> {os.path.basename(dst)}")Beispiel 3: Scene Graph Inspection und Export Report
Wander ein Scene-Grafik des COLLADA-Datei, sammle pro-mesh-Statistik und drucken Sie einen strukturierten Bericht:
from aspose.threed import Scene
scene = Scene.from_file("assembly.dae")
report = []
def collect(node, path=""):
full_path = f"{path}/{node.name}" if node.name else path
if node.entity is not None:
mesh = node.entity
gt = node.global_transform
report.append({
"path": full_path,
"vertices": len(mesh.control_points),
"polygons": len(mesh.polygons),
"world_x": gt.translation.x,
"world_y": gt.translation.y,
"world_z": gt.translation.z,
})
for child in node.child_nodes:
collect(child, full_path)
collect(scene.root_node)
print(f"{'Path':<40} {'Verts':>6} {'Polys':>6} {'X':>8} {'Y':>8} {'Z':>8}")
print("-" * 78)
for entry in report:
print(
f"{entry['path']:<40} "
f"{entry['vertices']:>6} "
f"{entry['polygons']:>6} "
f"{entry['world_x']:>8.3f} "
f"{entry['world_y']:>8.3f} "
f"{entry['world_z']:>8.3f}"
)Tipps und beste Praktiken
Format Auswahl
- GlTF 2.0 / GLB ist das empfohlene Wechselformat für Szenen, die Materialien, Animationen und komplexe Hierarchien enthalten. Vorzugsweise GLB (binare) über glTF (Text + externe Dateien) für Portabilität.
- STL ist die richtige Wahl, wenn der Ablaufverbraucher ein Schleier, CAD-Tool oder jedes Werkzeug ist, das nur Geometrie benötigt. STL trägt keine Materialien oder Animationsdaten.
- OBJ ist weit unterstützt und eine gute Wahl, wenn Materialdaten mit älteren Tools ausgetauscht werden müssen. bewahren Sie immer die .mtl Datei neben der .obj Datei.
Koordinatorische Systeme
- Verschiedene Anwendungen verwenden verschiedene Handwerkkonventionen.
ObjLoadOptions.flip_coordinate_system = Truewenn Sie OBJ-Dateien aus Tools importieren, die ein koordinatsystem mit rechtshand verwenden, wenn Ihre Pipeline linken koordinaten erwartet, und umgekehrt. - Überprüfen Sie die Axis-Konvention des Quellvermögens vor der Anwendung eines Flips. Flipping zweimal produziert falsche Geometrie.
Normalisierung
- immer Set
ObjLoadOptions.normalize_normal = Truewenn die Abwärtsleitungsleitung einheitliche Normale erwartet (z.B. wenn Normale an einen Schatten übergeben oder Lichtberechnungen mit Punktprodukten durchgeführt werden).
Leistung
- Laden Sie Dateien einmal und verwandeln Sie das in-memory-Szenegraphen anstatt von der Disk für jedes Ausgangsformat neu zu laden.
Scene.from_file()Anruf folgt von Multiplescene.save()Die Anrufe sind effizienter als wiederholte Lasten. - Bei der Verarbeitung von großen Battchen, bauen Sie eine einzige
ObjLoadOptionsoderStlSaveOptionsBeispiel und neu verwenden Sie es über alle Dateien anstatt eine neue Optionen Objekt pro Datei zu bauen.
Fehlerbehandlung
- Wrap
scene.open()undscene.save()Anrufe intry/exceptBlöcke bei der Verarbeitung unvertrauertes oder von Benutzern unterstütztes Dateien. Berichten Sie den Dateinamen in Ausnahme-Nachrichten, um die Debugging in Batch-Pipelinen zu vereinfachen.
Gemeinsame Probleme
| Thema | Ursache | Resolution |
|---|---|---|
| Mesh erscheint nach der Ladung spiegeln | Koordinatorische Systemfunktion Missmatch | zusammen ObjLoadOptions.flip_coordinate_system |
| Normale sind Null-Länge | Quelldatei hat unnormalisierte Normale | Set ObjLoadOptions.normalize_normal = True |
| Materialien, die nicht von OBJ geladen sind | enable_materials wurde festgelegt False | Set ObjLoadOptions.enable_materials = True (Das ist schon die Default) |
| Die Bühne laden, aber alle Knoten sind leer | Datei verwendet FBX Format | FBX-Pars ist in Fortschritt; verwenden Sie OBJ, STL oder glTF stattdessen |
| Das Modell ist extrem klein oder groß | Quelldatei verwendet nicht-metrische Einheiten | Anwendung ObjLoadOptions.scale Umwandeln Sie sich in Ihre Zielgruppe |
AttributeError auf mesh.polygons | Node-Entität ist kein Mesh | Die Wartung mit if node.entity is not None Vor dem Zugriff auf Eigentumsvorteile |
| GLB-Datei wird von einem Viewer abgelehnt | Errettet mit .gltf Erweiterung | Gebrauch .glb Erweiterung beim Anrufen scene.save() Bündeln mit binären Container |
Häufig gestellte Fragen
Welche Python-Versionen werden unterstützt? Python 3.7, 3.8, 3.9, 3.10, 3.11 und 3.12 sind alle unterstützt. Die Bibliothek ist sauber Python mit kein natives Erweiterung, so dass es auf jeder Plattform funktioniert, wo CPython läuft.
Hat die Bibliothek eine äußere Abhängigkeit? No. Aspose.3D FOSS für Python verwendet nur die Python Standardbibliothek. pip install aspose-3d-foss Befehl ohne Folgen.
Ist FBX unterstützt? Der FBX-Tokenizer wird implementiert und kann den binären FBX-Tokenstrom verlieren, aber der Scene-Graph-Builder am oberen Top des Tokenizer hat Fehler bekannt und ist nicht produktionsbereit. Verwenden Sie OBJ, STL, glTF, COLLADA oder 3MF für zuverlässige Produktionsanwendungen.
Kann ich Aspose.3D FOSS in einem kommerziellen Produkt verwenden? Die Bibliothek wird unter der MIT-Lizenz veröffentlicht, die die Verwendung in proprietären und kommerziellen Software ohne Realitätsbezahlungen erlaubt, sofern die Lizenzmeldung enthalten ist.
Wie kann ich einen Bug melden oder ein Format anfordern? Öffnen Sie ein Problem im Repository. Inkludieren Sie eine minimale Reproduktionsdatei und die Python-Version, das Betriebssystem und die Bibliothek-Version von pip show aspose-3d-foss.
API Referenzabschnitt
Kernklassen
Scene: Top-Level-Kontaktor für eine 3D-Szenen. Eintrittspunkt füropen(),from_file(),undsave().Node: Holz Node in der Szene Graf.entity,transform,global_transform,material,child_nodes,undname.Entity: Basisklasse für Objekte, die an Knoten (Mesh, Kamera, Licht) angeschlossen sind.Transform: Lokale Raumposition, Rotation (Quaternion) und Skala für einen Knoten.GlobalTransform: Lesen Sie nur Weltraum-Transformation berechnet durch die Akkumulation aller Vorfahren Transformationen.
Geometrie
Mesh:Polygon Mesh mitcontrol_points(Vertex-Liste undpolygons.VertexElementNormal:Per-vertex oder per-polygon normale Vektoren.VertexElementUV:Per-vertex UV Textur Koordinaten.VertexElementVertexColor:Per-vertex Farbdaten.VertexElementSmoothingGroup:Polygon Schweißgruppe Aufgaben.
Materialien
LambertMaterial: Diffuse Schattenmodell mitdiffuse_colorundemissive_color.PhongMaterial: Spekulär Schattenmodell hinzufügenspecular_colorundshininess.
Die Mathematik (aspose.threed.utilities)
Vector2:2D Vektor.Vector3:3D Doppelpräzision Vektor.Vector4:4D Doppelpräzision Vektor.FVector3:3D-Einprecision Vektor für Einzelprecision.Quaternion:Rotation Quaternion mitfrom_angle_axis()undto_matrix().Matrix4:4×4 Transformationsmatrix.BoundingBox: Axis-aligned Bounding Box mitminimumundmaximumDie Korns.
Animation
AnimationClip: Namete Container für eine Reihe von Animationskanäle und ihre Schlüsselframe.AnimationNode: Per-node Animationsdaten innerhalb eines Klips.KeyFrame: Einheitliche Schlüsselframe mit Zeit und Wert.KeyframeSequence: Bestellte Folge von Schlüsselframes für eine einzelne animierte Eigenschaft.
Laden / Speichern Optionen
ObjLoadOptions: OBJ-spezifische Ladestellungen:enable_materials,flip_coordinate_system,normalize_normal,scale.StlSaveOptions: STL-spezifische Speicher-Einstellungen (binare vs. ASCII-Modus).
Kameras und Lichter
Camera: Kameraentität mit Projektionsinstellungen, die an eineNode.Light: Lichtquelle-Entität, die an eineNode.