Selection recognizes four different levels of object hierarchy, or selection modes. Selection modes are important for certain operations (such as applying operators), as they change the scope of these operations:
Node: the specified 3d object is selected and subsequent operations are performed on only on that object.
Branch: the specified 3d object is selected and subsequent operations are performed on the specified 3d object as well as its children.
Tree: the highest 3D object in the hierarchy under the specified 3D object's model is selected and subsequent operations are performed on the newly selected object as well as its children.
Model: the model containing the specified 3D object is selected and subsequent operations are performed on the newly selected object as well as its children.
Specifying Hierarchy while Selecting
Both the SelectObj command or the Selection.Add or Selection::Add method provide a parameter which allows you to specify one of the hierarchical modes:
JScript Example: Hierarchical selection with the SelectObj command
Python Example: Hierarchical selection with the Selection.Add method
There are several other commands which support the hierarchical keywords: AddToSelection, ToggleSelection, SelectNeighborObj.
There are also a few convenience commands which you can use to specify a hierarchical selection: SelectBranch, SelectTree, SelectModel.
There is also another way to specify whether an item is branch-selected, independent of the selection:
When running a command that takes a string expression to identify an object, prefix its name with "B:". See VBScript Example: Deleting a null in Branch for an example using this technique.
Deleting Objects with Hierarchy
Most of the time deleting objects is a simple matter of passing the name of object to the DeleteObj command. But if the object contains other 3D object(s), you need to follow special procedures:
If the object you want to delete is a model or a null, you must branch-delete it in order to remove it and its children. If you don't branch-delete the model or null, nothing happens.
If the object you want to delete is any other 3D object (sphere, cone, etc.) and you branch-delete it, the object and all contained nodes are removed. If you node-delete it, the object is removed and replaced by a null with the same name (in order to preserve the hierarchy for the contained nodes.
To branch-delete an object you must either select it in branch and run the DeleteObj command without any arguments or use the "B:" branch prefix with the name of the object to delete. For example:
JScript Example: Deleting a Model (Node vs. Branch)
// Create a simple model containing a sphere
NewScene(null, false);
var sph = CreatePrim("Sphere", "MeshSurface");
var mdl = CreateModel(sph, "LocalModel")(0);
Application.LogMessage(Application.ActiveSceneRoot.Models.GetAsText());
// INFO : LocalModel
// First node-delete it (nothing happens)
DeleteObj(mdl);
Application.LogMessage(Application.ActiveSceneRoot.Models.GetAsText());
// INFO : LocalModel
// Then try branch-deleting it (it is removed)
SelectObj(mdl, "BRANCH")// models must be branch-selected when deleting
DeleteObj();
Application.LogMessage(Application.ActiveSceneRoot.Models.GetAsText());
// INFO :
For an example demonstrating how to use the "B:" prefix with the DeleteObj command, see VBScript Example: Deleting a null in Branch.
Testing the Selection for Hierarchy
Every 3d object stores its own ProjectItem.BranchFlag or ProjectItem::GetBranchFlag that remembers whether or not the object is node-selected or not. In other words, if the object is selected in branch, tree, or model, the branch flag is set to 1. If the object is node-selected only, the branch flag is set to 0.
Remember that parameters and compound properties cannot be selected at all: their owning 3dobject is selected and they are considered to be marked. In the SDK, parameters derive from the SIObject or SIObject class, but it is the ProjectItem or ProjectItem class which implements the ProjectItem.BranchFlag or ProjectItem::GetBranchFlag property.
For a demonstration of testing the selection for hierarchy in Python, see Python Example: Testing selected items for Hierarchy.
Points, edges, polygons, etc. do not support any hierarchical modes because they are individual SubComponents. Hierarchy is really only important in terms of operations that work on scene items, such as applying operators in branch.
The following examples are available:
JScript Example: Hierarchical selection with the SelectObj command
Python Example: Hierarchical selection with the Selection.Add method
JScript Example: Hierarchical selection with the SelectObj command
This example demonstrates how to use the SelectObj command to select an object in different hierchical modes:
// Set up a scene with lots of hierarchy
SetUpScene();
// Try the different modes with the SelectObj command
SelectObj("Herman.Larm", "NODE");
Application.LogMessage(Selection.GetAsText());
// INFO : Herman.LArm
SelectObj("Herman.Larm", "BRANCH");
Application.LogMessage(Selection.GetAsText());
// INFO : Herman.LArm
SelectObj("Herman.Larm", "TREE");
Application.LogMessage(Selection.GetAsText());
// INFO : Herman.Arms
SelectObj("Herman.Larm", "MODEL");
Application.LogMessage(Selection.GetAsText());
// INFO : Herman
// --------------------------
// Convenience function
//
function SetUpScene()
{
NewScene(null, false);
// Topmost level
CreateModel("", "Herman");
// General body parts
GetPrim("Null", "Head", "Herman");
GetPrim("Null", "Chest", "Herman");
GetPrim("Null", "Arms", "Herman");
GetPrim("Null", "Torso", "Herman");
GetPrim("Null", "Legs", "Herman");
// Individual body parts
GetPrim("Null", "LArm", "Herman.Arms");
GetPrim("Null", "RArm", "Herman.Arms");
// Specific body parts
CreatePrim("Sphere", "MeshSurface", "Bicep", "Herman.Larm");
Scale("Herman.Bicep", 0.35, 1, 0.35, siAbsolute, siPivot, siObj, siXZ);
}Python Example: Hierarchical selection with the Selection.Add method
You could also use the siSelectMode values with Selection.Add or Selection::Add instead of the SelectObj command:
from win32com.client import constants as xsi
app = Application
# --------------------------
# Convenience function
#
def SetUpScene() :
Application.NewScene("", 0)
# Topmost level
Application.CreateModel("", "Herman")
# General body parts
Application.GetPrim("Null", "Head", "Herman")
Application.GetPrim("Null", "Chest", "Herman")
Application.GetPrim("Null", "Arms", "Herman")
Application.GetPrim("Null", "Torso", "Herman")
Application.GetPrim("Null", "Legs", "Herman")
# Individual body parts
oRefObj = app.GetPrim("Null", "LArm", "Herman.Arms")
Application.GetPrim("Null", "RArm", "Herman.Arms")
# Specific body parts
Application.CreatePrim("Sphere", "MeshSurface", "Bicep", "Herman.Larm")
Application.Scale("Herman.Bicep", 0.35, 1, 0.35, "siAbsolute", "siPivot", "siObj", "siXZ")
return oRefObj
# --------------------------
# Hierarchical selection
#
# Set up a scene with lots of hierarchy
o3DSceneItem = SetUpScene()
# Try the different modes with the Selection.Add method
oSel = app.Selection
oSel.Clear()
oSel.Add(o3DSceneItem, xsi.siSelectNode)
app.LogMessage(oSel.GetAsText())
# INFO : Herman.LArm
oSel.Clear()
oSel.Add(o3DSceneItem, xsi.siSelectBranch)
app.LogMessage(oSel.GetAsText())
# INFO : Herman.LArm
oSel.Clear()
oSel.Add(o3DSceneItem, xsi.siSelectTree)
app.LogMessage(oSel.GetAsText())
# INFO : Herman.Arms
oSel.Clear()
oSel.Add(o3DSceneItem, xsi.siSelectModel)
app.LogMessage(oSel.GetAsText())
# INFO : Herman
VBScript Example: Deleting a null in Branch
This example demonstrates how to delete an object and all its children by prefixing the object's string expression with the "B:" branch designation:
set app = Application NewScene , false GetPrim "Null", "top" GetPrim "Null", "middle_1", "top" GetPrim "Null", "middle_2", "top" GetPrim "Null", "middle_3", "top" GetPrim "Null", "mid_2_bottom_1", "middle_2" GetPrim "Null", "way_low", "mid_2_bottom_1" GetPrim "Null", "mid_2_bottom_2", "middle_2" GetPrim "Null", "mid_3_bottom", "middle_3" SelectAll app.LogMessage "There are currently " & app.Selection.Count & " item(s) selected." for each sel_item in app.Selection app.LogMessage sel_item.Name next ' INFO : There are currently 12 item(s) selected. ' INFO : Camera_Root ' INFO : Camera ' INFO : Camera_Interest ' INFO : light ' INFO : top ' INFO : middle_1 ' INFO : middle_2 ' INFO : mid_2_bottom_1 ' INFO : way_low ' INFO : mid_2_bottom_2 ' INFO : middle_3 ' INFO : mid_3_bottom ' Now delete the entire middle_2 branch DeleteObj "B:middle_2" app.LogMessage "There are currently " & app.Selection.Count & " item(s) selected." for each sel_item in app.Selection app.LogMessage sel_item.Name next ' INFO : There are currently 8 item(s) selected. ' INFO : Camera_Root ' INFO : Camera ' INFO : Camera_Interest ' INFO : light ' INFO : top ' INFO : middle_1 ' INFO : middle_3 ' INFO : mid_3_bottom
Python Example: Testing selected items for Hierarchy
This example demonstrates how to iterate over the selection and test whether or not each item is node-selected:
app = Application
# --------------------------
# Convenience function
#
def SetUpMultiLevelNulls() :
app.NewScene("", 0)
app.CreateModel("", "TopDog")
# Create a hierarchy to test
app.CreateModel("", "NextLevel")
app.GetPrim("Null", "HigherLevel", "NextLevel")
targetObj = app.GetPrim("Null", "MidLevel", "NextLevel.HigherLevel")
app.GetPrim("Null", "LowerLevel", "NextLevel.MidLevel")
app.GetPrim("Null", "BottomFeeder", "NextLevel.LowerLevel")
app.CreateModel(app.ActiveSceneRoot.Models(0), "TopDog")
return targetObj
# --------------------------
# Hierarchical selection
#
def TestSelection() :
for thing in app.Selection :
if ( thing.BranchFlag ) :
app.LogMessage( thing.Name + " is selection in BRANCH" )
else :
app.LogMessage( thing.Name + " is selection in NODE" )
# --------------------------
# Logging results
#
# NODE-selected
refObj = SetUpMultiLevelNulls()
app.SelectObj( refObj.FullName )
TestSelection() # INFO : MidLevel is selection in NODE
# BRANCH-selected
refObj = SetUpMultiLevelNulls()
app.SelectObj( "B:" + refObj.FullName )
TestSelection() # INFO : MidLevel is selection in BRANCH
# TREE-selected
refObj = SetUpMultiLevelNulls()
app.SelectObj( "B:" + refObj.FullName, "TREE" )
TestSelection() # INFO : HigherLevel is selection in BRANCH
# MODEL-selected
refObj = SetUpMultiLevelNulls()
app.SelectObj( "B:" + refObj.FullName, "MODEL" )
TestSelection() # INFO : NextLevel is selection in BRANCH