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-foss

Nem 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
    └── ...
ObjektumSzerep
SceneLegfelső szintű tároló. Tartalmaz root_node, asset_info, animation_clips, és sub_scenes.
NodeNevzett fa csomópont. Van szülője, nulla vagy több gyermek, nulla vagy több entitás, és egy helyi Transform.
EntityGeometria vagy jelenetobjektum, amely egy csomóponthoz van csatolva. Gyakori entitástípusok: Mesh, Camera, Light.
TransformHelyi 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))  # 0

Scene 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))     # 1

Alternatí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")    # STL

Formá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_node a kézi csatolás helyett. Automatikusan beállítja a szülő hivatkozást, és kevésbé hibára hajlamos.
  • Olvasd global_transform a 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_nodes vá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, nem Vector3. Mindig add át w=1 szokásos csúcspozíciókhoz; w=0 egy irányvektort jelöl (nem pont).
  • mesh.control_points másolatot ad vissza. A control_points tulajdonság visszaadja list(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 a mesh._control_points kö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émaMegoldá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 translationtransform.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ésNé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 NoneA 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ópontokatchild_nodes visszatér a gyermekekkel beszúrási sorrendben (a sorrend add_child_node / create_child_node nek hívták).
 Magyar