Робота з графом сцени
Робота з графом сцени
Кожна 3D‑сцена у Aspose.3D для .NET організована як дерево Node об’єктів. Scene.RootNode є коренем цього дерева, і кожен елемент геометрії, матеріалу та трансформації розташовується під ним як дочірній елемент або нащадок.
Створення сцени та доступ до кореневого вузла
Scene ініціалізується автоматично з кореневим вузлом під назвою "RootNode":
using Aspose.ThreeD;
var scene = new Scene();
Node root = scene.RootNode; // always "RootNode"Додавання дочірніх вузлів
Викличте 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 operationsVisible = 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Наступні кроки
- Застосування трансформів — позиціонувати, обертати та масштабувати будь‑який вузол за допомогою його
Transform - Створення примітивної геометрії — використовуйте
Box,Sphere, іCylinderяк об’єкти сцени - Створення та робота з сітками — створюйте полігональну геометрію та приєднуйте її до вузлів
Коротка довідка API
| Член | Опис |
|---|---|
scene.RootNode | Корінь дерева сцени; завжди присутній після new Scene() |
node.CreateChildNode(name) | Створити іменований дочірній вузол без entity |
node.CreateChildNode(name, entity) | Створити іменований дочірній вузол з entity |
node.CreateChildNode(name, entity, material) | Створити іменований дочірній вузол з entity та material |
node.AddChildNode(node) | Прикріпити окремо сконструйоване Node |
node.GetChild(name) | Знайти прямого нащадка за іменем; повертає null якщо не знайдено |
node.GetChild(index) | Отримати прямого нащадка за заданим індексом |
node.ChildNodes | IList<Node> всіх прямих нащадків |
node.Accept(visitor) | Обійти цей вузол і всіх нащадків у глибину |
node.AddEntity(entity) | Прикріпити додаткову сутність до вузла |
node.Entities | IList<Entity> всіх сутностей у цьому вузлі |
node.Visible | Показати або сховати вузол |
node.Excluded | Включити або виключити вузол з експорту |
node.Merge(other) | Перемістити всіх дочірніх елементів та сутностей з other у цей вузол |
new Group(name) | Контейнерна сутність для логічного групування дочірніх вузлів |