Finding Out Whats Currently Selected

There is a difference between how you get the list of selected objects vs. components. Basically, you can access selected objects by treating the Selection object/class as a collection or array of currently selected objects, so you can enumerate over them or access them directly as an item in the collection/array (see Accessing the List of Selected Objects).

 

You can also find out which selection filter is currently selected via the Selection object/class (see Getting the Current Selection Filter).

However, when components are selected, for C# and scripting you need to use the SubComponent interface to convert the selection to its relevant component collection (see Accessing the List of Selected Components via the Object Model). For the C++ API, it is more complicated, since the SubComponent class is not yet fully implemented, you need to use the CComAPIHandler to invoke the .NET/scripting implementation of SubComponent (see Accessing the List of Selected Components via the C++ API and Working with the Selection List as a CRefArray (C++ API only)).

Accessing the List of Selected Objects

- The Selection object/class is a kind of a specialized collection. Each selected object is a member and can be accessed via enumerating or using the Item property (object model) or one of the Selection::GetItem methods (C++ API):

// C++ API
Selection sel( Application().GetSelection() );
for( LONG i=0; i<sel.GetCount(); i++ ) 
{
   SIObject obj( sel[i] );
   Application().LogMessage( obj.GetName() );
}
SIObject objByIndex( sel.GetItem(0) ); // Access by index
SIObject objByName( sel.GetItem(L"grid") ); // Access by name

 

// C# (object model)
CXSIApplication app = new CXSIApplication();
foreach (CollectionItem itm in app.Selection)
{
   app.LogMessage(itm.Name, siSeverity.siInfo);
}
SIObject objByIndex = (SIObject)app.Selection[0];           // Access by index
SIObject objByName = (SIObject)app.Selection["cone"];       // Access by name

 

// JScript
var e = new Enumerator( Selection );
for( ; !e.atEnd(); !e.moveNext() ) 
{
   var obj = e.item();
   LogMessage( obj );
}
var objByIndex = Selection(0); // Access by index
var objByName = Selection("grid"); // Access by name

 

' VBScript
foreach obj in Selection
   LogMessage obj 
next
set objByIndex = Selection(0); ' Access by index
set objByName = Selection("grid"); ' Access by name

 

# Python
for obj in Application.Selection :
   Application.LogMessage( obj.Name )
objByIndex = Application.Selection(0) # Access by index
objByName = Application.Selection("grid") # Access by name

 

# Perl
for ( my $i=0; $i<$Application->Selection->Count; $i++ ) {
   $Application->LogMessage( $Application->Selection($i)->Name );
}
my $objByIndex = $Application->Selection(0); # Access by index
my $objByName = $Application->Selection("grid"); # Access by name

 

Related Scripting Commands

GetValue (used with "SelectionList")

PickElement, PickObject

SelectFilter, SelectEdgeFilter, SelectObjectFilter, SelectPolygonFilter, SelectSampledPointFilter, SelectVertexFilter

SetEdgeSelectionFilter, SetPointSelectionFilter, SetPolygonSelectionFilter, SetSampleSelectionFilter

Accessing the List of Selected Components via the Object Model

- When components are selected, the Selection.Item property returns a CollectionItem object which you can use to get the SubComponent object via the CollectionItem.SubComponent property. From there, the SubComponent.ComponentCollection property returns one of the geometry-specific component collections (VertexCollection, ControlPointCollection, EdgeCollection, etc.) containing the selected components:

// C# -- assuming sampled points are selected
CXSIApplication app = new CXSIApplication();
CollectionItem collitem = (CollectionItem)app.Selection[0];
SubComponent subcmp = (SubComponent)collitem.SubComponent;
SampleCollection smplcoll = (SampleCollection)subcmp.ComponentCollection;
app.LogMessage("There are " + smplcoll.Count.ToString() 
   + " selected samples.", siSeverity.siInfo);
foreach (Sample smpl in smplcoll)
{
   app.LogMessage("Current sample[" + smpl.Index.ToString()
       + "] (prev:[" + smpl.Navigate(siNavigateComponentType.siPreviousComponent).Index.ToString()
       + "]; next:[" + smpl.Navigate(siNavigateComponentType.siNextComponent).Index.ToString()
       + "])", siSeverity.siInfo);
}

 

// JScript -- assuming control points are selected
var subcmp = Selection(0).SubComponent;
var ctrlpts = subcmp.ComponentCollection;
for( var i=0; i<ctrlpts.Count; i++ ) 
{
   LogMessage( "Position of ctrlpt[" + ctrlpts(i).Index + "]: "
       + ctrlpts(i).X + "," 
       + ctrlpts(i).Y + "," 
       + ctrlpts(i).Z );
}

 

' VBScript -- assuming vertices are selected
set subcmp = Selection(0).SubComponent
for each vtx in subcmp.ComponentCollection
   LogMessage vtx.Index & " has " & vtx.Nodes.Count & " polygon nodes"
next

 

# Python -- assuming edges are selected
subcmp = Application.Selection(0).SubComponent
for edg in subcmp.ComponentCollection :
   Application.LogMessage( "edge[%s] is hard: %s" % (edg.Index,edg.IsHard) )

 

# Perl -- assuming Nurbs subsurfaces are selected
my $subcmp = $Application->Selection(0)->SubComponent;
my $coll = $subcmp->ComponentCollection;
for ( my $i=0; $i<$coll->Count; $i++ ) {
   $Application->LogMessage( $coll->Item($i)->TrimCount );
}

 

Related Scripting Commands

GetValue (used with "SelectionList")

PickElement, PickObject

SelectFilter, SelectEdgeFilter, SelectObjectFilter, SelectPolygonFilter, SelectSampledPointFilter, SelectVertexFilter

SetEdgeSelectionFilter, SetPointSelectionFilter, SetPolygonSelectionFilter, SetSampleSelectionFilter

Accessing the List of Selected Components via the C++ API

- Use the XSI Object Model SubComponent interface via the CComAPIHandler , which is a kind of a COM wrapper for the C++ API:

// C++ API -- iterating over the selected components
Application app;

// Make sure something is selected
Selection sel = app.GetSelection();
LONG lCount = sel.GetCount();
app.LogMessage(L"Found " + CString(lCount) + L" selected items.");
if ( lCount < LONG(1) )
{
   app.LogMessage( L"No components are selected" );
   return CStatus::OK;
}
for ( LONG i=0; i<lCount; i++ )
{
   if ( sel.GetItem(i).GetClassIDName() == L"X3DObject" )
   {
       X3DObject x3dobj(sel.GetItem(i));
       app.LogMessage(L"\titem[" + CString(i) + L"]: " + x3dobj.GetName() );
   }
   else
   {
       app.LogMessage(L"\titem[" + CString(i) + L"]: " + sel.GetItem(i).GetClassIDName() );
   }
}

// The collection of selected components exists in the first member
CComAPIHandler comCollItem( sel.GetItem(0) );
CComAPIHandler comSubComp( comCollItem.GetProperty(L"SubComponent") );
CValue subCompType = comSubComp.GetProperty( L"Type" );
app.LogMessage( L"Type of subcomponent: " + CString(subCompType) );

// Grab the component collection
CComAPIHandler comCompColl( comSubComp.GetProperty(L"ComponentCollection") );

// Now we can iterate over the component collection's members
LONG lCollCount( comCompColl.GetProperty(L"Count") );
app.LogMessage(L"Found " + CString(lCollCount) + L" selected components.");
for ( LONG j=0; j<lCollCount; j++ )
{
   CValue rtn;              // output from the Item property
   CValueArray idx; idx.Add(j); // set the index to use
   comCompColl.Invoke( L"Item", CComAPIHandler::PropertyGet, rtn, idx );

   // From the CRef class, we can convert it to the actual class
   CRef itm(rtn);
   if ( itm.GetClassID() == siVertexID )
   {
       Vertex vtx = Vertex(itm);
       app.LogMessage( L"Found a vertex at index " + CString(vtx.GetIndex()) );
   }
   if ( itm.GetClassID() == siSampleID )
   {
       Sample smp = Sample(itm);
       app.LogMessage( L"Found a sample at index " + CString(smp.GetIndex()) );
   }
   if ( itm.GetClassID() == siEdgeID )
   {
       Edge edg = Edge(itm);
       app.LogMessage( L"Found a edge at index " + CString(edg.GetIndex()) );
   }
   if ( itm.GetClassID() == siControlPointID )
   {
       ControlPoint ctrl = ControlPoint(itm);
       app.LogMessage( L"Found a control point at index " + CString(ctrl.GetIndex()) );
   }
   // etc.
}

 

Working with the Selection List as a CRefArray (C++ API only)

- The Selection class provides access to the selected items in a convenient CRefArray via the Selection::GetArray function:

// C++ API
CRefArray sellist = app.GetSelection().GetArray();
LONG lSelCount = sellist.GetCount();
for (LONG i=0; i<lSelCount; i++) {
   CRef currItem = sellist[i];
   if ( currItem.IsValid() ) {
       if ( currItem.GetClassIDName() == L"X3DObject" ) {
          X3DObject x3dobj(currItem);
          app.LogMessage(L"item[" + CString(i) + L"]: " + x3dobj.GetName() );
       } else {
          app.LogMessage(L"item[" + CString(i) + L"]: " + currItem.GetClassIDName() );
          // For components this will return 'Object' which is the generic object type
       }
   } else {
       app.LogMessage(L"item[" + CString(i) + L"] is not valid." );
   }
}

 

Getting the Current Selection Filter

- Use the Selection.Filter property (scripting) or the Selection::GetFilter function (C++ API):

// C++ API
Selection sel( Application().GetSelection() );
Filter myFilter = sel.GetFilter();

 

// C#
CXSIApplication app = new CXSIApplication();
Selection sel = app.Selection;
Filter myFilter = sel.Filter;

 

// JScript
var sel = Selection;
var myFilter = sel.Filter;

 

' VBScript
set sel = Selection
set myFilter = sel.Filter

 

# Python
sel = Application.Selection
myFilter = sel.Filter

 

# Perl
my $sel = $Application->Selection;
my $myFilter = $sel->Filter;

 

Related Scripting Commands

SelectFilter, SelectEdgeFilter, SelectObjectFilter, SelectPolygonFilter, SelectSampledPointFilter, SelectVertexFilter

SetEdgeSelectionFilter, SetPointSelectionFilter, SetPolygonSelectionFilter, SetSampleSelectionFilter



SOFTIMAGE|XSI v6.01     

Return to Softimage XSI Index