Работа с графа на сцената

Работа с графа на сцената

Всяка 3D сцена в Aspose.3D за .NET е организирана като дърво от Node обекти. Scene.RootNode е коренът на това дърво и всяка част от геометрия, материал и трансформация живее под него като дете или наследник.


Създаване на сцената и достъп до кореновия възел

Scene се инициализира автоматично с коренов възел, наречен "RootNode":

using Aspose.ThreeD;

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

Добавяне на дъщерни възли

Call CreateChildNode() на всеки възел, за да добавите дете. Методът има три често използвани претоварвания:

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

За да прикрепите възел, създаден отделно, използвайте AddChildNode():

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

Заявяване на дъщерни възли

Намерете директен дъщерен възел по име или по индекс, или итерирайте всички директни дъщерни възли:

// 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) търси само директни деца, а не цялото поддърво. Използвайте рекурсивен помощник или Accept() за търсене на цялото дърво.


Обхождане на цялото дърво

За пълен обход в дълбочина, итерирайте ChildNodes рекурсивно:

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

За обход с ранно излизане, node.Accept(NodeVisitor) е наличен и извиква посетителя за всеки наследник, докато посетителят върне false.


Използване на Group за организиране на свързани обекти

Group е контейнерна единица, която логически организира възлите без да добавя геометрия. Прикрепете я към възел, чиито деца представляват логическа единица:

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

Преместване roomNode трансформира цялата мебел заедно, защото децата наследяват неговото Transform.


Контрол на видимостта и изключване от експорта

Възлите могат да бъдат скрити или изключени от експорта, без да бъдат премахнати от йерархията:

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 е подсказка за показване. Excluded = true пречи на възела да се появява в експортираните файлове, независимо от формата.


Прикачване на множество ентитети към един възел

Възел има първичен ентитет (Entity свойство), но може да съдържа допълнителни ентитети чрез AddEntity(). Това е полезно, когато различни части от мрежата споделят един и същи трансформ:

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

Сливане на възли

Merge() премества всички деца, обекти и материали от изходен възел към целевия възел. Изходният възел остава празен:

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

Следващи стъпки


Бърз справочник за API

ЧленОписание
scene.RootNodeКорен на сценичното дърво; винаги присъства след new Scene()
node.CreateChildNode(name)Създаване на именуван дъщерен възел без обект
node.CreateChildNode(name, entity)Създаване на именуван дъщерен възел с обект
node.CreateChildNode(name, entity, material)Създаване на именуван дъщерен възел с обект и материал
node.AddChildNode(node)Прикрепете отделно създадено Node
node.GetChild(name)Намерете директно дете по име; връща null ако не е намерено
node.GetChild(index)Получете директното дете на даден индекс
node.ChildNodesIList<Node> от всички директни деца
node.Accept(visitor)Обходете този възел и всички наследници в дълбочина първо
node.AddEntity(entity)Прикрепете допълнителна единица към възела
node.EntitiesIList<Entity> от всички единици върху този възел
node.VisibleПоказване или скриване на възела
node.ExcludedВключване или изключване на възела от експорта
node.Merge(other)Преместване на всички деца и обекти от other в този възел
new Group(name)Контейнерен обект за логическо групиране на дъщерни възли
 Български