Funkcionalnosti i mogućnosti
Aspose.3D FOSS za Python pruža kompletan API za graf scenske strukture za čitanje, konstruisanje i upisivanje 3D sadržaja u više industrijskih standardnih formata. Ova stranica dokumentuje svaku glavnu oblast funkcionalnosti uz radne Python primere koda koji koriste stvarni API biblioteke.
Instalacija i podešavanje
Instalirajte biblioteku sa PyPI koristeći jednu komandu:
pip install aspose-3d-fossNisu potrebni dodatni sistemski paketi, nativna proširenja ili alati za kompajliranje. Biblioteka je čista Python i podržava Python 3.7 do 3.12 na Windows, macOS i Linux.
Da biste proverili instalaciju:
from aspose.threed import Scene
scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")Funkcionalnosti i mogućnosti
Podrška za formate
Aspose.3D FOSS za Python čita i piše sledeće formate:
| Format | Ekstenzija | Čitanje | Pisanje | Napomene |
|---|---|---|---|---|
| Wavefront OBJ | .obj | Da | Da | .Učitavanje .mtl materijala podržano |
| STL (binarni) | .stl | Da | Da | Kružni prolaz verifikovan (39 testova) |
| STL (ASCII) | .stl | Da | Da | Kružni prolaz verifikovan |
| glTF 2.0 | .gltf | Da | Da | Čitav graf scene je očuvan |
| GLB (binary glTF) | .glb | Da | Da | Binarni kontejner u jednoj datoteci |
| COLLADA | .dae | Da | Da | Hijerarhija scene i materijali |
| 3MF | .3mf | Da | Da | Format aditivne proizvodnje |
| FBX | .fbx | Delimično | Ne | Tokenizator radi; parser ima poznate greške |
Učitavanje OBJ sa opcijama
ObjLoadOptions kontroliše kako se OBJ fajlovi parsiraju:
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")Čuvanje u STL
StlSaveOptions kontroliše binarni vs. ASCII izlaz i druge STL‑specifične postavke:
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)Graf scene
Sav 3D sadržaj je organizovan kao stablo od Node objekata. Koreni čvor stabla je scene.root_node. Svaki čvor može da sadrži podčvorove i nosi Entity (mesh, kamera ili svetlo) plus a Transform.
Prolazak kroz hijerarhiju scene
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)Programatsko izgradnja scene
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")Pregled GlobalTransform
GlobalTransform daje transformaciju u svetskom prostoru čvora nakon akumulacije svih transformacija pretka:
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}")Mesh API
The Mesh entitet omogućava pristup podacima o geometriji, uključujući kontrolne tačke (vrhove), poligone i elemente vrhova za normale, UV‑koordinate i boje.
Čitanje geometrije mreže
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)}")Pristup elementima vrhova
Elementi vrhova nose podatke po vrhu ili po poligonu. Najčešći elementi su normali, UV‑koordinate, boje vrhova i grupe izglađivanja:
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)}")Sistem materijala
Aspose.3D FOSS podržava dva tipa materijala: LambertMaterial (difuzno osvetljenje) i PhongMaterial (specularno osvetljenje). Oboje se automatski učitavaju iz .mtl fajlova prilikom korišćenja ObjLoadOptions sa enable_materials = True.
Čitanje materijala iz 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}")Programatsko dodeljivanje materijala
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")Matematički alati
The aspose.threed.utilities modul pruža sve geometrijske matematičke tipove potrebne za izgradnju i inspekciju scene.
| Klasa | Svrha |
|---|---|
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 | Representacija rotacije bez gimbal lock‑a |
Matrix4 | 4×4 transformation matrix |
BoundingBox | Osa‑poravnata ograničavajuća kutija sa min/max uglovima |
Rad sa transformacijama
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}")Izračunavanje ograničavajuće kutije
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})")Animacija
Aspose.3D FOSS pruža model animacije zasnovan na AnimationClip, AnimationNode, KeyFrame, i KeyframeSequence. Podaci o animaciji pohranjeni u učitanim fajlovima (glTF, COLLADA) su dostupni kroz ove objekte.
Čitanje animacionih klipova
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}")Opcije učitavanja i čuvanja
Svaki podržani format ima odgovarajuću klasu opcija koja kontroliše ponašanje parsiranja i serijalizacije.
| Klasa | Format | Ključna svojstva |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Binarni vs. ASCII režim izlaza |
| (glTF koristi podrazumevane vrednosti) | glTF / GLB | Grafik scene i materijali se automatski čuvaju |
Primeri upotrebe
Primer 1: Konverzija OBJ u STL format
Konvertujte OBJ fajl (sa materijalima) u binarni STL, ispisujući statistiku mreže tokom procesa:
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")Primer 2: Pakovanje glTF u GLB u seriji
Ponovo sačuvajte direktorijum odvojenih glTF + teksturnih fajlova kao samostalne GLB binarne fajlove:
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)}")Primer 3: Inspekcija grafova scene i izveštaj o izvozu
Prođite kroz graf scene COLLADA fajla, sakupite statistiku po mreži i ispišite strukturisani izveštaj:
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}"
)Saveti i najbolje prakse
Izbor formata
- glTF 2.0 / GLB je preporučeni format za razmenu za scene koje uključuju materijale, animacije i složene hijerarhije. Preferirajte GLB (binarni) nad glTF (tekst + eksterni fajlovi) za prenosivost.
- STL je pravi izbor kada je krajnji potrošač slicer, CAD alat ili bilo koji alat koji treba samo geometriju. STL ne sadrži podatke o materijalu ili animaciji.
- OBJ je široko podržan i dobar izbor kada je potrebno razmenjivati podatke o materijalu sa starijim alatima. Uvek čuvajte .mtl fajl uz .obj fajl.
Koordinatni sistemi
- Različite aplikacije koriste različite konvencije desno‑ruke ili levo‑ruke koordinatne sisteme. Postavite
ObjLoadOptions.flip_coordinate_system = Trueprilikom uvoza OBJ fajlova iz alata koji koriste desno‑ruku koordinatni sistem ako vaš pipeline očekuje levo‑ruku koordinate, i obrnuto. - Proverite konvenciju osa izvornog sredstva pre nego što primenite bilo kakvo okretanje. Dvostruko okretanje proizvodi netačnu geometriju.
Normalizacija
- Uvek postavite
ObjLoadOptions.normalize_normal = Truekada downstream pipeline očekuje jedinične normale (na primer, prilikom prosleđivanja normala shaderu ili izvođenja osvetljavanja pomoću skalarnih proizvoda). Nenormalizovane normale iz loše formiranih OBJ fajlova uzrokuju artefakte u osvetljenju.
Performanse
- Učitajte fajlove jednom i transformišite graf scenske memorije umesto ponovnog učitavanja sa diska za svaki izlazni format. Jedan
Scene.from_file()poziv praćen višescene.save()pozivi su efikasniji od ponovljenog učitavanja. - Pri obradi velikih serija, konstruisite jedan
ObjLoadOptionsiliStlSaveOptionsinstancu i ponovo je koristite za sve fajlove umesto da za svaki fajl pravite novi objekat opcija.
Rukovanje greškama
- Uokvirite
scene.open()iscene.save()pozive utry/exceptblokove prilikom obrade nepouzdanih ili korisnički dostavljenih fajlova. Prijavite ime fajla u porukama izuzetaka kako biste pojednostavili otklanjanje grešaka u serijskim procesima.
Uobičajeni problemi
| Problem | Uzrok | Rešenje |
|---|---|---|
| Mreža izgleda zrcaljeno nakon učitavanja | Neslaganje orijentacije koordinatnog sistema | Prekidač ObjLoadOptions.flip_coordinate_system |
| Normale su nulte dužine | Izvorni fajl ima ne‑normalizovane normale | Postavi ObjLoadOptions.normalize_normal = True |
| Materijali nisu učitani iz OBJ | enable_materials je False (podrazumevano) | Postavi ObjLoadOptions.enable_materials = True |
| Scena se učitava, ali svi čvorovi su prazni | Datoteka koristi FBX format | FBX parser je u razvoju; koristite OBJ, STL ili glTF umesto |
| Model je izuzetno mali ili velik | Izvorna datoteka koristi ne-metričke jedinice | Primeni ObjLoadOptions.scale za konverziju u ciljnu jedinicu |
AttributeError na mesh.polygons | Entitet čvora nije Mesh | Zaštiti sa if node.entity is not None pre pristupa svojstvima entiteta |
| GLB fajl je odbijen od strane preglednika | Sačuvano sa .gltf ekstenzija | Koristite .glb ekstenziju prilikom pozivanja scene.save() da pokrene binarni kontejner |
Često postavljana pitanja
Koje Python verzije su podržane? Python 3.7, 3.8, 3.9, 3.10, 3.11 i 3.12 su svi podržani. Biblioteka je čista Python bez native extension, pa radi na bilo kojoj platformi na kojoj se izvršava CPython.
Da li biblioteka ima neke spoljne zavisnosti? Ne. Aspose.3D FOSS za Python koristi samo standardnu biblioteku Python. Instalira se kao jedinstvena pip install aspose-3d-foss komanda bez dodatnih koraka.
Da li je FBX podržan? FBX tokenizator je implementiran i može da parsira binarni FBX tok tokena, ali graditelj grafova scene iznad tokenizatora ima poznate greške i nije spreman za produkciju. Koristite OBJ, STL, glTF, COLLADA ili 3MF za pouzdanu upotrebu u produkciji.
Mogu li da koristim Aspose.3D FOSS u komercijalnom proizvodu? Da. Biblioteka je objavljena pod MIT licencom, koja dozvoljava korišćenje u vlasničkom i komercijalnom softveru bez plaćanja tantijema, pod uslovom da je obaveštenje o licenci uključeno.
Kako da prijavim grešku ili zatražim format? Otvorite issue u repozitorijumu. Uključite minimalni reprodukcioni fajl i Python verziju, operativni sistem i verziju biblioteke iz pip show aspose-3d-foss.
Sažetak API reference
Osnovne klase
Scene: Kontejner najvišeg nivoa za 3D scenu. Ulazna tačka zaopen(),from_file(), isave().Node: Čvor stabla u grafu scene. Sadržientity,transform,global_transform,material,child_nodes, iname.Entity: Bazna klasa za objekte prikačene na čvorove (Mesh, Camera, Light).Transform: Pozicija, rotacija (Quaternion) i skala u lokalnom prostoru za čvor.GlobalTransform: Transformacija u world-space režimu samo za čitanje, izračunata akumulacijom svih transformacija pretka.
Geometrija
Mesh: Poligonalna mreža sacontrol_points(lista vrhova) ipolygons.VertexElementNormal: Normalni vektori po vrhu ili po poligonu.VertexElementUV: UV koordinate teksture po vrhu.VertexElementVertexColor: Podaci o boji po vrhu.VertexElementSmoothingGroup: Dodela grupa zaglađivanja poligona.
Materijali
LambertMaterial: Difuzni model osvetljenja sadiffuse_coloriemissive_color.PhongMaterial: Dodavanje spekularnog modela senčenjaspecular_color: ishininess.
: Matematički alati (aspose.threed.utilities)
Vector2: 2D vektor.Vector3: 3D vektor dvostruke preciznosti.Vector4: 4D vektor dvostruke preciznosti.FVector3: 3D vektor jednostruke preciznosti.Quaternion: Rotacioni kvaternion safrom_angle_axis()ito_matrix().Matrix4: 4×4 матрица трансформације.BoundingBox: Оквир ограничења усмерен по осама саminimumиmaximumугловима.
Animacija
AnimationClip: Именовани контејнер за скуп канала анимације и њихових кључних кадрова.AnimationNode: Подаци о анимацији по-чворски унутар клипа.KeyFrame: Појединачни кључни кадар са временом и вредношћу.KeyframeSequence: Uređeni niz ključnih okvira za jedno animirano svojstvo.
Opcije učitavanja / čuvanja
ObjLoadOptions: OBJ‑specifična podešavanja učitavanja:enable_materials,flip_coordinate_system,normalize_normal,scale.StlSaveOptions: STL‑specifična podešavanja za čuvanje (binarni vs. ASCII režim).
Kamere i svetla
Camera: Entitet kamere sa podešavanjima projekcije, koji se može prikačiti na aNode.Light: Entitet izvora svetla, koji se može prikačiti na aNode.