Funkce a vlastnosti
Aspose.3D FOSS pro Python poskytuje kompletní API pro scénový graf pro čtení, vytváření a zápis 3D obsahu v několika průmyslových standardních formátech. Tato stránka dokumentuje každou hlavní oblast funkcí s funkčními příklady kódu Python, které používají skutečné API knihovny.
Instalace a nastavení
Nainstalujte knihovnu z PyPI jedním příkazem:
pip install aspose-3d-fossNejsou vyžadovány žádné další systémové balíčky, nativní rozšíření ani kompilátorské toolchainy. Knihovna je čistý Python a podporuje Python 3.7 až 3.12 na Windows, macOS a Linuxu.
Pro ověření instalace:
from aspose.threed import Scene
scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")Funkce a vlastnosti
Podpora formátů
Aspose.3D FOSS pro Python čte a zapisuje následující formáty:
| Formát | Přípona | Číst | Zapisovat | Poznámky |
|---|---|---|---|---|
| Wavefront OBJ | .obj | Ano | Ano | .Načítání materiálu .mtl podporováno |
| STL (binární) | .stl | Ano | Ano | Roundtrip ověřeno (39 testů) |
| STL (ASCII) | .stl | Ano | Ano | Roundtrip ověřeno |
| glTF 2.0 | .gltf | Ano | Ano | Celý graf scény zachován |
| GLB (binární glTF) | .glb | Ano | Ano | Jednosouborový binární kontejner |
| COLLADA | .dae | Ano | Ano | Hierarchie scény a materiály |
| 3MF | .3mf | Ano | Ano | Formát aditivní výroby |
| FBX | .fbx | Částečný | Ne | Tokenizer funguje; parser má známé chyby |
Načítání OBJ s volbami
ObjLoadOptions řídí, jak jsou soubory OBJ parsovány:
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")Ukládání do STL
StlSaveOptions řídí binární vs. ASCII výstup a další nastavení specifická pro STL:
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)Scénový graf
Veškerý 3D obsah je organizován jako strom of Node objekty. Kořen stromu je scene.root_node. Každý uzel může obsahovat podřízené uzly a nést Entity (mesh, kamera nebo světlo) plus a Transform.
Procházení hierarchie scény
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)Programové vytváření scény
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")Prohlížení GlobalTransform
GlobalTransform udává transformaci v světovém prostoru uzlu po akumulaci všech transformací předků:
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 entita poskytuje přístup k geometrickým datům včetně řídicích bodů (vrcholů), polygonů a vrcholových prvků pro normály, UV a barvy.
Čtení geometrie Meshu
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)}")Přístup k prvkům vrcholů
Prvky vrcholů nesou data na úrovni vrcholu nebo polygonu. Nejčastějšími prvky jsou normály, UV souřadnice, barvy vrcholů a skupiny vyhlazování:
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)}")Systém materiálů
Aspose.3D FOSS podporuje dva typy materiálů: LambertMaterial (difúzní stínování) a PhongMaterial (speculární stínování). Oba jsou načteny automaticky ze souborů .mtl při použití ObjLoadOptions s enable_materials = True.
Čtení materiálů z 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}")Programové přiřazení materiálu
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")Matematické utility
The aspose.threed.utilities modul poskytuje všechny geometrické matematické typy potřebné pro tvorbu a inspekci scény.
| Třída | Účel |
|---|---|
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 | Reprezentace rotace bez gimbal locku |
Matrix4 | 4×4 transformation matrix |
BoundingBox | osově zarovnaný ohraničující kvádr s rohy min/max |
Práce s transformacemi
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}")Výpočet ohraničujícího boxu
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})")Animace
Aspose.3D FOSS poskytuje animační model založený na AnimationClip, AnimationNode, KeyFrame, a KeyframeSequence. Data animace uložená v načtených souborech (glTF, COLLADA) je přístupná prostřednictvím těchto objektů.
Čtení animačních klipů
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}")Možnosti načítání a ukládání
Každý podporovaný formát má odpovídající třídu možností, která řídí chování při parsování a serializaci.
| Třída | Formát | Klíčové vlastnosti |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Binární vs. ASCII režim výstupu |
| (glTF používá výchozí hodnoty) | glTF / GLB | Graf scény a materiály jsou automaticky zachovány |
Příklady použití
Příklad 1: Konverze formátu OBJ na STL
Převést soubor OBJ (s materiály) na binární STL a během toho vypisovat statistiky sítě:
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")Příklad 2: Dávkové balení glTF do GLB
Znovu uložit adresář samostatných souborů glTF + textur jako samostatné binární soubory GLB:
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)}")Příklad 3: Inspekce grafu scény a exportní zpráva
Procházet graf scény souboru COLLADA, sbírat statistiky pro každou síť a vytisknout strukturovanou zprávu:
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}"
)Tipy a osvědčené postupy
Výběr formátu
- glTF 2.0 / GLB je doporučený výměnný formát pro scény, které zahrnují materiály, animace a složité hierarchie. Upřednostněte GLB (binární) před glTF (text + externí soubory) pro přenositelnost.
- STL je správnou volbou, když je koncovým uživatelem slicer, CAD nástroj nebo jakýkoli nástroj, který potřebuje jen geometrii. STL neobsahuje žádná data o materiálech ani animacích.
- OBJ je široce podporován a je dobrá volba, když je třeba vyměňovat data o materiálech se staršími nástroji. Vždy uchovávejte soubor .mtl vedle souboru .obj.
Systémy souřadnic
- Různé aplikace používají různé konvence pravotočivosti. Nastavte
ObjLoadOptions.flip_coordinate_system = Truepři importu OBJ souborů z nástrojů, které používají pravotočivý souřadnicový systém, pokud váš pipeline očekává levotočivé souřadnice, a naopak. - Ověřte konvenci os zdrojového assetu před aplikací jakéhokoli převrácení. Dvojité převrácení vede k nesprávné geometrii.
Normalizace
- Vždy nastavte
ObjLoadOptions.normalize_normal = Truepokud koncová pipeline očekává jednotkové normály (například při předávání normálů shaderu nebo při výpočtech osvětlení pomocí skalárního součinu). Nenormované normály z špatně vytvořených OBJ souborů způsobují artefakty osvětlení.
Výkon
- Načtěte soubory jednou a transformujte graf scény v paměti místo opětovného načítání z disku pro každý výstupní formát. Jedna
Scene.from_file()volání následované vícescene.save()volání je efektivnější než opakované načítání. - Při zpracování velkých dávek vytvořte jediný
ObjLoadOptionsneboStlSaveOptionsinstanci a znovu ji použijte ve všech souborech místo vytváření nového objektu možností pro každý soubor.
Zpracování chyb
- Zabalit
scene.open()ascene.save()volání vtry/exceptbloky při zpracování nedůvěryhodných nebo uživatelem dodaných souborů. Uveďte název souboru ve zprávách výjimek, aby se usnadnilo ladění v dávkových pipelinech.
Běžné problémy
| Problém | Příčina | Řešení |
|---|---|---|
| Síť se po načtení jeví jako zrcadlená | Neshoda orientace souřadnicového systému | Přepnout ObjLoadOptions.flip_coordinate_system |
| Normály mají nulovou délku | Zdrojový soubor obsahuje nenormalizované normály | Nastavit ObjLoadOptions.normalize_normal = True |
| Materiály nebyly načteny z OBJ | enable_materials je False (výchozí) | Nastavit ObjLoadOptions.enable_materials = True |
| Scéna se načte, ale všechny uzly jsou prázdné | Soubor používá formát FBX | Parser FBX je ve vývoji; místo toho použijte OBJ, STL nebo glTF |
| Model je extrémně malý nebo velký | Zdrojový soubor používá nemetrické jednotky | Použít ObjLoadOptions.scale k převodu na cílovou jednotku |
AttributeError zapnuto mesh.polygons | Entita uzlu není Mesh | Chraňte pomocí if node.entity is not None před přístupem k vlastnostem entity |
| Soubor GLB byl odmítnut prohlížečem | Uloženo s .gltf příponou | Použijte .glb příponu při volání scene.save() k vyvolání binárního kontejneru |
Často kladené otázky
Jaké verze Python jsou podporovány? Python 3.7, 3.8, 3.9, 3.10, 3.11 a 3.12 jsou všechny podporovány. Knihovna je čistý Python bez nativních rozšíření, takže funguje na jakékoli platformě, kde běží CPython.
Má knihovna nějaké externí závislosti? Ne. Aspose.3D FOSS pro Python používá pouze standardní knihovnu Python. Instalace probíhá jako jediný pip install aspose-3d-foss příkaz bez dalších kroků.
Je FBX podporováno? Tokenizér FBX je implementován a dokáže parsovat binární tokenový proud FBX, ale scene-graph builder nad tokenizérem má známé chyby a není připraven pro produkční nasazení. Použijte OBJ, STL, glTF, COLLADA nebo 3MF pro spolehlivé produkční použití.
Mohu použít Aspose.3D FOSS v komerčním produktu? Ano. Knihovna je vydána pod licencí MIT, která umožňuje použití v proprietárním a komerčním softwaru bez licenčních poplatků, pokud je zahrnuto oznámení o licenci.
Jak mohu nahlásit chybu nebo požádat o formát? Otevřete issue v repozitáři. Přiložte minimální reprodukční soubor a verzi Python, operační systém a verzi knihovny z pip show aspose-3d-foss.
Shrnutí referenčního API
Základní třídy
Scene: Nadřazený kontejner pro 3D scénu. Vstupní bod proopen(),from_file(), asave().Node: Uzel stromu v grafu scény. Neseentity,transform,global_transform,material,child_nodes, aname.Entity: Základní třída pro objekty připojené k uzlům (Mesh, Camera, Light).Transform: Lokální pozice, rotace (Quaternion) a měřítko uzlu.GlobalTransform: Pouze pro čtení transformace ve světovém prostoru vypočtená akumulací všech transformací předků.
Geometrie
Mesh: Polygonální síť scontrol_points(seznam vrcholů) apolygons.VertexElementNormal: Normálové vektory na vrchol nebo na polygon.VertexElementUV: UV texturové souřadnice na vrchol.VertexElementVertexColor: Barevná data na vrchol.VertexElementSmoothingGroup: Přiřazení skupin vyhlazování polygonů.
Materiály
LambertMaterial: Difúzní model osvětlení sdiffuse_coloraemissive_color.PhongMaterial: Přidání spekulárního modelu stínováníspecular_colorashininess.
Matematické utility (aspose.threed.utilities)
Vector2: 2D vektor.Vector3: 3D vektor s dvojitou přesností.Vector4: 4D vektor s dvojitou přesností.FVector3: 3D vektor s jednoduchou přesností.Quaternion: Rotacní kvaternion sfrom_angle_axis()ato_matrix().Matrix4: 4×4 transformační matice.BoundingBox: Osa‑zarovnaná ohraničující krabice sminimumamaximum: rohy.
Animace
AnimationClip: Pojmenovaný kontejner pro sadu animačních kanálů a jejich klíčových snímků.AnimationNode: Animace na úrovni uzlu v rámci klipu.KeyFrame: Jednotlivý klíčový snímek s časem a hodnotou.KeyframeSequence: Uspořádaná sekvence klíčových snímků pro jedinou animovanou vlastnost.
Možnosti načítání / ukládání
ObjLoadOptions: Nastavení načítání specifická pro OBJ:enable_materials,flip_coordinate_system,normalize_normal,scale.StlSaveOptions: Nastavení ukládání specifická pro STL (binární vs. ASCII režim).
Kamery a světla
Camera: Entita kamery s nastavením projekce, připojitelná k aNode.Light: Entita světelného zdroje, připojitelná k aNode.