Arbeiten mit dem Szenengraph

Arbeiten mit dem Szenengraph

Arbeiten mit dem Szenengraph

Jede 3D‑Szene in Aspose.3D für .NET ist als Baum von Node Objekten. Scene.RootNode ist die Wurzel dieses Baumes und jedes Stück Geometrie, Material und Transformation befindet sich darunter als Kind oder Nachkomme.


Erstellen der Szene und Zugriff auf den Wurzelknoten

Scene initialisiert sich automatisch mit einem Wurzelknoten namens "RootNode":

using Aspose.ThreeD;

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

Hinzufügen von Kindknoten

Call CreateChildNode() auf jedem Knoten, um ein Kind hinzuzufügen. Die Methode hat drei häufig verwendete Überladungen:

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

Um einen separat konstruierten Knoten anzuhängen, verwenden Sie AddChildNode():

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

Abfragen von Kindknoten

Finden Sie ein direktes Kind nach Name oder Index, oder iterieren Sie über alle direkten Kinder:

// 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) sucht nur direkte Kinder, nicht den gesamten Teilbaum. Verwenden Sie einen rekursiven Helfer oder Accept() um den gesamten Baum zu durchsuchen.


Durchlaufen des gesamten Baums

Für einen vollständigen Tiefensuchlauf iterieren Sie ChildNodes rekursiv:

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

Für eine Traversierung mit frühem Abbruch, node.Accept(NodeVisitor) ist verfügbar und ruft den Besucher für jeden Nachkommen auf, bis der Besucher zurückkehrt false.


Verwendung von Group zur Organisation verwandter Objekte

Group ist eine Container‑Entität, die Knoten logisch organisiert, ohne Geometrie hinzuzufügen. Befestigen Sie sie an einem Knoten, dessen Kinder eine logische Einheit darstellen:

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

Verschieben roomNode transformiert alle Möbel zusammen, weil die Kinder dessen erben Transform.


Steuerung der Sichtbarkeit und des Exports‑Ausschlusses

Knoten können ausgeblendet oder vom Export ausgeschlossen werden, ohne aus der Hierarchie entfernt zu werden:

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 ist ein Anzeigehinweis. Excluded = true verhindert, dass der Knoten in exportierten Dateien erscheint, unabhängig vom Format.


Mehrere Entitäten an einem Knoten anhängen

Ein Knoten hat ein primäres Entität (Entity Eigenschaft), kann jedoch zusätzliche Entitäten über AddEntity(). Das ist nützlich, wenn verschiedene Mesh-Teile eine einzige Transformation teilen:

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

Knoten zusammenführen

Merge() verschiebt alle Kinder, Entitäten und Materialien von einem Quellknoten in den Zielknoten. Der Quellknoten bleibt leer:

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

Nächste Schritte


API‑Kurzreferenz

MitgliedBeschreibung
scene.RootNodeWurzel des Szenenbaums; immer vorhanden nach new Scene()
node.CreateChildNode(name)Erstelle einen benannten Kindknoten ohne Entität
node.CreateChildNode(name, entity)Erstelle einen benannten Kindknoten mit einer Entität
node.CreateChildNode(name, entity, material)Erstelle einen benannten Kindknoten mit Entität und Material
node.AddChildNode(node)Ein separat konstruiertes anhängen Node
node.GetChild(name)Finde ein direktes Kind nach Namen; gibt zurück null wenn nicht gefunden
node.GetChild(index)Hole das direkte Kind an einem gegebenen Index
node.ChildNodesIList<Node> von allen direkten Kindern
node.Accept(visitor)Durchlaufe diesen Knoten und alle Nachkommen in Tiefen‑Erste‑Reihenfolge
node.AddEntity(entity)Füge dem Knoten eine zusätzliche Entität hinzu
node.EntitiesIList<Entity> von allen Entitäten auf diesem Knoten
node.VisibleKnoten anzeigen oder ausblenden
node.ExcludedKnoten in den Export ein- oder ausschließen
node.Merge(other)Verschiebe alle Kinder und Entitäten von other in diesen Knoten
new Group(name)Container-Entität zum logischen Gruppieren von Kindknoten
 Deutsch