Working with the Scene Graph

Working with the Scene Graph

Working with the Scene Graph

Every 3D scene in Aspose.3D for .NET is organized as a tree of Node objects. Scene.RootNode is the root of that tree and every piece of geometry, material, and transform lives under it as a child or descendant.


Creating the Scene and Accessing the Root Node

Scene initializes automatically with a root node named "RootNode":

using Aspose.ThreeD;

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

Adding Child Nodes

Call CreateChildNode() on any node to add a child. The method has three commonly used overloads:

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);

To attach a node constructed separately, use AddChildNode():

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

Querying Child Nodes

Find a direct child by name or by index, or iterate all direct children:

// 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) searches only direct children, not the full subtree. Use a recursive helper or Accept() to search the entire tree.


Traversing the Full Tree

For a full depth-first walk, iterate ChildNodes recursively:

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);

For early-exit traversal, node.Accept(NodeVisitor) is available and calls the visitor on every descendant until the visitor returns false.


Using Group to Organize Related Objects

Group is a container entity that logically organizes nodes without adding geometry. Attach it to a node whose children represent a logical unit:

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));

Moving roomNode transforms all furniture together because the children inherit its Transform.


Controlling Visibility and Export Exclusion

Nodes can be hidden or excluded from export without being removed from the hierarchy:

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 is a display hint. Excluded = true prevents the node from appearing in exported files regardless of format.


Attaching Multiple Entities to One Node

A node has a primary entity (Entity property), but can hold additional entities through AddEntity(). This is useful when different mesh pieces share a single 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);

Merging Nodes

Merge() moves all children, entities, and materials from a source node into the target node. The source node is left empty:

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

Next Steps


API Quick Reference

MemberDescription
scene.RootNodeRoot of the scene tree; always present after new Scene()
node.CreateChildNode(name)Create a named child node with no entity
node.CreateChildNode(name, entity)Create a named child node with an entity
node.CreateChildNode(name, entity, material)Create a named child node with entity and material
node.AddChildNode(node)Attach a separately constructed Node
node.GetChild(name)Find a direct child by name; returns null if not found
node.GetChild(index)Get the direct child at a given index
node.ChildNodesIList<Node> of all direct children
node.Accept(visitor)Walk this node and all descendants depth-first
node.AddEntity(entity)Attach an additional entity to the node
node.EntitiesIList<Entity> of all entities on this node
node.VisibleShow or hide the node
node.ExcludedInclude or exclude the node from export
node.Merge(other)Move all children and entities from other into this node
new Group(name)Container entity for logically grouping child nodes
 English