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.
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.
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:
// 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.
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
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); }
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
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
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
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License