Traversing Softimage Scenes (XSISDK)
Scene traversal is one of the most common tasks performed inside XSI scripts and C++ plug-ins.
The Scene is a graph of inter-related objects. To traverse the scene is to visit an object and then visit its inter-related objects, possibly in a recursive fashion. For example, a typical export plugin will travel through the scene finding objects to export.
The Scene Explorer View shows a hierarchical organization to all the data in the scene. Each object is located underneath another object, and it may have further objects nested beneath it. This basic relationship can be considered a "parent/child" relationship, but because X3DObject.Children only applies to X3DObjects, we often use the term "nested" instead of "children" to describe the more broad organization of the Scene.
There is another major structuring of the data of the scene which is created by the connections between operators. Each operator can have multiple inputs and outputs, which creates a web of relationships between the objects in the scene graph. Some Scene traversal will use the connections between operators and other objects to travel through a scene.
The FX Tree and Shader Trees are specialized portions of the scene graph.
Some relationships between objects are clearly exposed in the Object Model, other relationships take more knowledge to figure out. This page will attempt to give an overview of how to traverse the scene and cover special cases.
|Table of contents|
This is the building block for doing "generic" scene traversal. You can use this collection to find the "children" of an object, without needing to know exactly what type of object it is and what type of children it has. It was introduced in v.5.0 to provide a Object Model equivalent to the EnumElements command.
An example usage is to access the operators connected to an object. XSI has a specialized ConstructionHistory object for doing this, but it is only exposed on the Primitive object. However the more "generic" SIObject.NestedObjects can be used on any object to find its connected operators.
Here's a simple example (from Marc-André Belzile) to demonstrate a recursive traverser done with SIObject.NestedObjects:
indent = 0 set startObj = selection(0) Traverse startObj, indent sub Traverse ( obj, indent ) set list = obj.NestedObjects for each i in list if typename(i) = "parameter" then str = space(indent) & typename(i) & ":" & i.ScriptName else str = space(indent) & typename(i) & ":" & i.Name end if LogMessage str Traverse i, indent+1 next end sub
Performance Warning: it can be very slow to start at the SceneRoot and recursively call NestedObjects to travel through the entire Scene. In general the more you can "focus" the scene traversal the better. By "Focus" I mean only looking at a subset of the graph rather than the entire graph. For example if the scene traversal is not interested in any Shader data it should avoid traversing through all the shaders connected to each material. As a general suggestion, any recursive usage of SIObject.NestedObjects should be used only with great caution.
The companion to SIObject.NestedObjects is SIObject.Parent, which allows you to move up in the scene to the parent of an object. If you call this recursively you will eventually reach either the "SceneRoot" (a model) or the Application object itself.
Some objects can be nested under multiple parents. For example a branch applied property. Use ProjectItem.Owners to get the full list.
The FindObjects command is a little advanced but important for searching through the scene graph quickly. See the examples in the Command reference for more details.
Use the SDK Explorer to learn more about what properties each selected object has. A lot of these properties are related to scene traversal because they show children, parents and other related objects.
Use the GetMaster command to find the master of a instance. This command can be used to test whether a model is an instance or not because it will return an empty list for a regular model.</pre>
A Render tree is a graph of Shader nodes connected together, with the final output being a Material object. The output of a particular Shader will "drive" the Parameter value of another node. Use the Parameter.Source (http://softimage.wiki.softimage.com/sdkdocs/Parameter_Source.htm) property (Parameter::GetSource in C++ API) to find a Shader that drives a Parameter.
It is possible to do a recursive scan from the Material back to all the Shaders of the tree, using Parameter.Source. Because a single Shader can output to multiple shaders such a recursion may visit any particular node multiple times.
For example code see Shader Reference (http://softimage.wiki.softimage.com/sdkdocs/Shader.htm).