Jelenet gráf
A jelenetgrafikon az alapvető adatmodellje a Aspose.3D FOSS számára Python. Minden 3D fájl, akár lemezről betöltött, akár memóriában létrehozott, egy fastruktúraként van ábrázolva, amely Node objektumok, amelyek gyökere Scene.root_node. Minden csomópont tárolhat gyermekcsomópontokat és egy vagy több Entity objektumok (hálók, kamerák, fények). A jelenet gráfjának megértése közvetlen hozzáférést biztosít a geometriai adatokhoz, anyagokhoz és a térbeli transzformációkhoz minden objektum esetében a jelenetben.
Telepítés és beállítás
Telepítsd a könyvtárat a PyPI-ról:
pip install aspose-3d-fossNem szükséges natív kiterjesztés, fordító vagy további rendszercsomag. A teljes telepítési útmutatóért lásd a Telepítési útmutató.
Áttekintés: Jelenetgrafikon fogalmak
A Aspose.3D FOSS jelenetgrafikona egy egyszerű tartalmazási hierarchiát követ:
Scene
└── root_node (Node)
├── child_node_A (Node)
│ ├── entity: Mesh
│ └── transform: translation, rotation, scale
├── child_node_B (Node)
│ └── child_node_C (Node)
│ └── entity: Mesh
└── ...| Objektum | Szerep |
|---|---|
Scene | Legfelső szintű tároló. Tartalmaz root_node, asset_info, animation_clips, és sub_scenes. |
Node | Nevzett fa csomópont. Van szülője, nulla vagy több gyermek, nulla vagy több entitás, és egy helyi Transform. |
Entity | Geometria vagy jelenetobjektum, amely egy csomóponthoz van csatolva. Gyakori entitástípusok: Mesh, Camera, Light. |
Transform | Helyi térbeli pozíció, forgatás és méretezés egy csomóponthoz. A világ-térbeli eredmény innen olvasható global_transform. |
Lépésről lépésre: Jelenetgrafikon programozott felépítése
1. lépés: Jelenet létrehozása
Egy új Scene mindig egy üres root_node:
from aspose.threed import Scene
scene = Scene()
print(scene.root_node.name) # "" (empty string — root node has no name by default)
print(len(scene.root_node.child_nodes)) # 0Scene az a belépési pont mindenhez: fájlok betöltése, fájlok mentése, animációs klipek létrehozása, és a csomófa elérése.
2. lépés: Gyermekcsomópontok létrehozása
Használd create_child_node(name) nevzett csomópontok hozzáadásához a fához:
from aspose.threed import Scene
scene = Scene()
parent = scene.root_node.create_child_node("parent")
child = parent.create_child_node("child")
print(parent.name) # "parent"
print(child.parent_node.name) # "parent"
print(len(scene.root_node.child_nodes)) # 1Alternatív megoldásként hozzon létre egy önálló Node és csatolja azt kifejezetten:
from aspose.threed import Scene, Node
scene = Scene()
node = Node("standalone")
scene.root_node.add_child_node(node)Mindkét megközelítés ugyanazt az eredményt adja. create_child_node tömörebb a beágyazott konstrukcióhoz.
3. lépés: Mesh entitás létrehozása és csatolása
Egy Mesh tárolja a csúcsadatokat (control_points) és a felület topológiát (polygons). Hozzon létre egyet, adjon hozzá geometriát, majd csatolja egy csomóponthoz:
from aspose.threed import Scene, Node
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3, Vector4
scene = Scene()
parent = scene.root_node.create_child_node("parent")
child = parent.create_child_node("child")
##Create a quad mesh (four vertices, one polygon)
# Note: control_points returns a copy of the internal list; append to
# _control_points directly to actually add vertices. This is a known
# library limitation — a public add_control_point() API is not yet available.
mesh = Mesh("cube")
mesh._control_points.append(Vector4(0, 0, 0, 1))
mesh._control_points.append(Vector4(1, 0, 0, 1))
mesh._control_points.append(Vector4(1, 1, 0, 1))
mesh._control_points.append(Vector4(0, 1, 0, 1))
mesh.create_polygon(0, 1, 2, 3)
child.add_entity(mesh)
print(f"Mesh name: {mesh.name}")
print(f"Vertex count: {len(mesh.control_points)}")
print(f"Polygon count: {mesh.polygon_count}")Vector4(x, y, z, w) egy homogén koordinátát jelöl. Használja a w=1 normál pontpozíciókhoz.
create_polygon(*indices) elfogadja a csúcsindexeket, és egy felületet regisztrál a poligonlistaban. Három indexet adjon meg háromszöghöz, négyet négyszöghez.
4. lépés: Csomópont transzformációk beállítása
Minden csomópont rendelkezik egy Transform amely szabályozza a pozícióját, orientációját és méretét a helyi térben:
from aspose.threed.utilities import Vector3, Quaternion
##Translate the node 2 units along the X axis
child.transform.translation = Vector3(2.0, 0.0, 0.0)
##Scale the node to half its natural size
child.transform.scaling = Vector3(0.5, 0.5, 0.5)
##Rotate 45 degrees around the Y axis using Euler angles
child.transform.euler_angles = Vector3(0.0, 45.0, 0.0)Az átalakítások kumulatívak: egy gyermekcsomópont világkoordinátás pozíciója a saját átalakításának és az összes ős átalakításának összetétele. Olvassa ki a kiértékelt világkoordinátás eredményt innen: node.global_transform (immutábilis, csak olvasható).
5. lépés: A jelenet gráfjának rekurzív bejárása
Járja be az egész fát rekurzív bejárással a node.child_nodes:
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)Példa kimenet a fent felépített jelenethez (a gyökércsomópont neve üres karakterlánc):
[None]
parent [None]
child [Mesh]Több entitást tartalmazó jeleneteknél csomópontonként iteráljon node.entities ehelyett node.entity:
def traverse_full(node, depth=0):
indent = " " * depth
entity_names = [type(e).__name__ for e in node.entities] or ["None"]
print(f"{indent}{node.name} [{', '.join(entity_names)}]")
for child in node.child_nodes:
traverse_full(child, depth + 1)
traverse_full(scene.root_node)6. lépés: A jelenet mentése
Adjon meg egy fájl elérési utat a scene.save(). A formátum a fájlkiterjesztésből kerül meghatározásra:
scene.save("scene.gltf") # JSON glTF 2.0
scene.save("scene.glb") # Binary GLB container
scene.save("scene.obj") # Wavefront OBJ
scene.save("scene.stl") # STLFormátum-specifikus beállításokhoz adj egy save-options objektumot második argumentumként:
from aspose.threed.formats import GltfSaveOptions
opts = GltfSaveOptions()
scene.save("scene.gltf", opts)Tippek és bevált gyakorlatok
- Adj nevet minden csomópontnak. A csomópontoknak értelmes neveket adni sokkal könnyebbé teszi a bejárások hibakeresését, és biztosítja, hogy a nevek megmaradjanak az exportált fájlban.
- Egy háló minden csomóponthoz. Az entitások 1:1 arányban tartása a csomópontokkal egyszerűsíti az átalakításokat és az ütközéslekérdezéseket.
- Használd
create_child_nodea kézi csatolás helyett. Automatikusan beállítja a szülő hivatkozást, és kevésbé hibára hajlamos. - Olvasd
global_transforma hierarchia felépítése után. A világkoordinátás eredmény csak akkor stabil, ha az összes szülő átalakítás be van állítva. - Ne módosítsd a fát a bejárás során. Gyermekcsomópontok hozzáadása vagy eltávolítása iterálás közben
child_nodesváratlan viselkedést eredményez. Először gyűjtsd össze a csomópontokat, majd módosíts. - A vezérlőpontok használják
Vector4, nemVector3. Mindig add átw=1szokásos csúcspozíciókhoz;w=0egy irányvektort jelöl (nem pont). mesh.control_pointsmásolatot ad vissza. Acontrol_pointstulajdonság visszaadjalist(self._control_points)— a visszaadott listához való hozzáfűzés nem módosítja a hálót. Mindig hozzáfűzzön amesh._control_pointsközvetlenül, amikor programozottan épít geometriát. Ez egy ismert könyvtári korlátozás; nyilvános módosítási API még nem létezik.
Gyakori problémák
| Probléma | Megoldás |
|---|---|
AttributeError: 'NoneType' object has no attribute 'polygons' | Védje a if node.entity is not None mielőtt hozzáférne az entitás tulajdonságokhoz. Egy entitások nélküli csomópontnak van entity = None. |
A háló az eredetben jelenik meg a beállítás ellenére translation | transform.translation helyi eltolást alkalmaz. Ha a szülőcsomópont maga nem identitás transzformációval rendelkezik, a világpozíció eltérhet. Ellenőrizze global_transform. |
Gyermekcsomópontok hiányoznak a scene.save() / újratöltés | Néhány formátum (OBJ) laposra hozza a hierarchiát. Használja a glTF-et vagy a COLLADA-t a teljes csomópontfa megőrzéséhez. |
polygon_count 0 lesz a mesh.create_polygon(...) | Ellenőrizze, hogy a csúcsindexek, amelyeket átadott a create_polygon a tartományon belül vannak (0 eddig len(control_points) - 1). |
Node.get_child(name) visszatér None | A név kis- és nagybetűérzékeny. Erősítse meg a létrehozáskor használt pontos névkarakterláncot. |
| A bejárás váratlan sorrendben látogatja meg a csomópontokat | child_nodes visszatér a gyermekekkel beszúrási sorrendben (a sorrend add_child_node / create_child_node nek hívták). |