Travailler avec le graphe de scène

Travailler avec le graphe de scène

Travailler avec le graphe de scène

Chaque scène 3D dans Aspose.3D pour .NET est organisée comme un arbre de Node objets. Scene.RootNode est la racine de cet arbre et chaque morceau de géométrie, de matériau et de transformation vit sous elle en tant qu’enfant ou descendant.


Création de la scène et accès au nœud racine

Scene s’initialise automatiquement avec un nœud racine nommé "RootNode":

using Aspose.ThreeD;

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

Ajout de nœuds enfants

Call CreateChildNode() sur n’importe quel nœud pour ajouter un enfant. La méthode possède trois surcharges couramment utilisées :

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

Pour attacher un nœud construit séparément, utilisez AddChildNode():

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

Interrogation des nœuds enfants

Trouvez un enfant direct par nom ou par indice, ou parcourez tous les enfants directs :

// 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) recherche uniquement les enfants directs, pas l’arborescence complète. Utilisez un helper récursif ou Accept() pour parcourir l’arbre entier.


Parcourir l’arbre complet

Pour un parcours complet en profondeur, itérez ChildNodes récursivement :

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

Pour un parcours avec sortie anticipée, node.Accept(NodeVisitor) est disponible et appelle le visiteur sur chaque descendant jusqu’à ce que le visiteur renvoie false.


Utilisation de Group pour organiser les objets liés

Group est une entité conteneur qui organise logiquement les nœuds sans ajouter de géométrie. Attachez‑la à un nœud dont les enfants représentent une unité logique :

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

Déplacement roomNode transforme tous les meubles ensemble car les enfants héritent de son Transform.


Contrôle de la visibilité et exclusion à l’exportation

Les nœuds peuvent être masqués ou exclus de l’exportation sans être retirés de la hiérarchie :

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 est un indice d’affichage. Excluded = true empêche le nœud d’apparaître dans les fichiers exportés, quel que soit le format.


Attacher plusieurs entités à un même nœud

Un nœud possède un principal entité (Entity propriété), mais peut contenir des entités supplémentaires via AddEntity(). Ceci est utile lorsque différentes pièces de maillage partagent une même transformation :

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

Fusion de nœuds

Merge() déplace tous les enfants, entités et matériaux d’un nœud source vers le nœud cible. Le nœud source reste vide :

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

Étapes suivantes


Référence rapide de l’API

MembreDescription
scene.RootNodeRacine de l’arbre de scène ; toujours présent après new Scene()
node.CreateChildNode(name)Créer un nœud enfant nommé sans entité
node.CreateChildNode(name, entity)Créer un nœud enfant nommé avec une entité
node.CreateChildNode(name, entity, material)Créer un nœud enfant nommé avec une entité et un matériau
node.AddChildNode(node)Attacher un élément construit séparément Node
node.GetChild(name)Trouver un enfant direct par nom ; renvoie null si non trouvé
node.GetChild(index)Obtenir l’enfant direct à un indice donné
node.ChildNodesIList<Node> de tous les enfants directs
node.Accept(visitor)Parcourir ce nœud et tous ses descendants en profondeur
node.AddEntity(entity)Attacher une entité supplémentaire au nœud
node.EntitiesIList<Entity> de toutes les entités sur ce nœud
node.VisibleAfficher ou masquer le nœud
node.ExcludedInclure ou exclure le nœud de l’exportation
node.Merge(other)Déplacer tous les enfants et entités depuis other dans ce nœud
new Group(name)Entité conteneur pour regrouper logiquement les nœuds enfants
 Français