Softimage SDK Programmer's Guide > Plug-in Development > Selection >

# Dealing with Hierarchy

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.

Note

For general information about hierarchy selection in Softimage, see Selecting Objects in a Hierarchy in the Softimage User's guide.

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

Note

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.

Tip

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 :

Note

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.

Important

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.

Hierarchy and SubComponents

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.

Examples

The following examples are available:

- JScript Example: Hierarchical selection with the SelectObj command

- Python Example: Hierarchical selection with the Selection.Add method

- JScript Example: Deleting a Model (Node vs. Branch)

- VBScript Example: Deleting a null in Branch

- Python Example: Testing selected items for Hierarchy

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