Práce s grafem scény

Práce s grafem scény

Každá 3D scéna v Aspose.3D pro .NET je uspořádána jako strom Node objektů. Scene.RootNode je kořenem tohoto stromu a každý kus geometrie, materiálu a transformace žije pod ním jako potomek nebo následník.


Vytvoření scény a přístup ke kořenovému uzlu

Scene se automaticky inicializuje s kořenovým uzlem pojmenovaným "RootNode":

using Aspose.ThreeD;

var scene = new Scene();
Node root = scene.RootNode; // always "RootNode"

Přidávání podřízených uzlů

Call CreateChildNode() na libovolném uzlu pro přidání potomka. Metoda má tři běžně používané přetížení:

using Aspose.ThreeD;
using Aspose.ThreeD.Entities;

var scene = new Scene();
Node root = scene.RootNode;

// 1. Named node with no entity — useful as a pivot or transform container
Node pivot = root.CreateChildNode("pivot");

// 2. Named node with an entity
var box = new Box(2, 2, 2);
Node boxNode = root.CreateChildNode("box", box);

// 3. Named node with entity and material
var mat = new Aspose.ThreeD.Shading.PhongMaterial("red");
mat.Diffuse = new Vector4(0.8, 0.2, 0.2, 1.0);
Node decorated = pivot.CreateChildNode("red_box", box, mat);

Pro připojení uzlu vytvořeného samostatně použijte AddChildNode():

var detached = new Node("standalone");
root.AddChildNode(detached);

Dotazování na podřízené uzly

Najděte přímý podřízený uzel podle názvu nebo indexu, nebo iterujte všechny přímé podřízené:

// By name — returns null if no direct child has that name
Node? found = root.GetChild("box");
if (found != null)
    Console.WriteLine("Found: " + found.Name);

// By index
Node first = root.GetChild(0);

// Iterate all direct children
foreach (Node child in root.ChildNodes)
    Console.WriteLine(child.Name);

GetChild(string name) prohledává pouze přímé potomky, ne celý podstrom. Použijte rekurzivní pomocnou funkci nebo Accept() pro prohledání celého stromu.


Procházení celého stromu

Pro úplnou hloubkovou procházku iterujte ChildNodes rekurzivně:

static void Walk(Node node, int depth = 0)
{
    Console.WriteLine(new string(' ', depth * 2) + node.Name);
    foreach (var child in node.ChildNodes)
        Walk(child, depth + 1);
}

Walk(scene.RootNode);

Pro průchod s předčasným ukončením, node.Accept(NodeVisitor) je k dispozici a volá návštěvníka na každém následníkovi, dokud návštěvník nevrátí false.


Použití Group k organizaci souvisejících objektů

Group je kontejnerová entita, která logicky organizuje uzly bez přidání geometrie. Připojte ji k uzlu, jehož potomci představují logickou jednotku:

using Aspose.ThreeD;
using Aspose.ThreeD.Entities;

var scene = new Scene();

// A group node for all furniture in a room
var furnitureGroup = new Group("furniture");
Node roomNode = scene.RootNode.CreateChildNode("living_room", furnitureGroup);

// Child nodes under the group node
Node sofaNode  = roomNode.CreateChildNode("sofa",         new Box(3, 1, 1));
Node tableNode = roomNode.CreateChildNode("coffee_table", new Box(2, 0.5, 1));

Přesun roomNode transformuje veškerý nábytek najednou, protože potomci dědí jeho Transform.


Řízení viditelnosti a vyloučení z exportu

Uzly mohou být skryty nebo vyloučeny z exportu, aniž by byly odstraněny z hierarchie:

Node ground = scene.RootNode.CreateChildNode("ground_plane", new Box(100, 0.1, 100));
ground.Visible = false;       // hidden in viewport / renderer

Node helperNode = scene.RootNode.CreateChildNode("debug_arrow", new Box());
helperNode.Excluded = true;   // omitted from all export operations

Visible = false je nápověda pro zobrazení. Excluded = true zabraňuje tomu, aby se uzel objevil v exportovaných souborech bez ohledu na formát.


Připojení více entit k jednomu uzlu

Uzel má primární entitu (Entity vlastnost), ale může obsahovat další entity prostřednictvím AddEntity(). To je užitečné, když různé části sítě sdílejí jediný transform:

var bodyMesh  = new Mesh("body");
var wheelMesh = new Mesh("wheel");

Node carNode = scene.RootNode.CreateChildNode("car");
carNode.AddEntity(bodyMesh);
carNode.AddEntity(wheelMesh);

// Retrieve all entities on this node
foreach (Entity ent in carNode.Entities)
    Console.WriteLine(ent.GetType().Name + ": " + ent.Name);

Sloučení uzlů

Merge() přesune všechny podřízené, entity a materiály ze zdrojového uzlu do cílového uzlu. Zdrojový uzel zůstane prázdný:

Node lod0 = scene.RootNode.CreateChildNode("lod0");
lod0.CreateChildNode("mesh_high", new Box(1, 1, 1));

Node lod1 = scene.RootNode.CreateChildNode("lod1");
lod1.CreateChildNode("mesh_low", new Box(1, 1, 1));

// Consolidate lod0 children into lod1
lod1.Merge(lod0);
// lod1 now has both mesh_high and mesh_low; lod0 is empty

Další kroky


Rychlý přehled API

ČlenPopis
scene.RootNodeKořen stromu scény; vždy přítomen po new Scene()
node.CreateChildNode(name)Vytvořit pojmenovaný podřízený uzel bez entity
node.CreateChildNode(name, entity)Vytvořit pojmenovaný podřízený uzel s entitou
node.CreateChildNode(name, entity, material)Vytvořit pojmenovaný podřízený uzel s entitou a materiálem
node.AddChildNode(node)Připojit samostatně vytvořený Node
node.GetChild(name)Najít přímého potomka podle názvu; vrací null pokud nebyl nalezen
node.GetChild(index)Získat přímého potomka na zadaném indexu
node.ChildNodesIList<Node> všech přímých potomků
node.Accept(visitor)Procházet tento uzel a všechny potomky do hloubky
node.AddEntity(entity)Připojit další entitu k uzlu
node.EntitiesIList<Entity> všech entit na tomto uzlu
node.VisibleZobrazit nebo skrýt uzel
node.ExcludedZahrnout nebo vyloučit uzel z exportu
node.Merge(other)Přesunout všechny potomky a entity z other do tohoto uzlu
new Group(name)Kontejnerová entita pro logické seskupení podřízených uzlů
 Čeština