The first line of this script returns the list of selected items, making sure that branch-selected items are turned into node selections (SelectChildNodes). The spreadsheet scripts must return arrays, so this is why the collection returned by GetValue("SelectionList") and then SelectChildNodes must be transferred to an array in a loop. The array must be dimensioned with the right number of elements.
Function Current_Selection () Dim R(), SelList Set SelList = GetValue( "SelectionList" ) if SelList.Count = 0 then Current_Selection = R Exit Function end if Set SelList = SelectChildNodes( SelList, False ) Dim i ReDim R(SelList.Count - 1) for i = 0 to SelList.Count - 1 R(i) = SelList(i) next Current_Selection = R End Function
Column scripts also return arrays, but given that they do not return a list of scene elements, but rather a description of which parameter each column must show, a special syntax is required. As this example shows, the syntax is relatively simple because all columns display standard Softimage parameters. Each element in the array is a string composed of three values:
The parameter to display (for example, kine.local.posx, which will be appended to each item from each line).
The type of cell. In this case 'Default' is sufficient because Softimage knows what the type of the parameter is (float, integer, boolean, string. etc.)
The label to display at the top of the column. If left empty, the column title will use the name of the parameter. This is why for the first column containing the name of object (see example) we can omit the type and label information.
Function Object_Xfo () Dim R(9) R(0) = "Name" R(1) = "kine.local.posx:Default:Local posx" R(2) = "kine.local.posy:Default:Local posy" R(3) = "kine.local.posz:Default:Local posz" R(4) = "kine.local.rotx:Default:Local rotx" R(5) = "kine.local.roty:Default:Local roty" R(6) = "kine.local.rotz:Default:Local rotz" R(7) = "kine.local.sclx:Default:Local sclx" R(8) = "kine.local.scly:Default:Local scly" R(9) = "kine.local.sclz:Default:Local sclz" Object_Transformations = R End Function
The query file is a simple file that can be loaded in the Softimage spreadsheet to tell it which scripts to use. It can be stored anywhere.
For each tag, you supply the scripting language being used, the file where the script will be found, and the name of the function to call.
The script file can be any name, but it must be placed under the ..\Application\DSScripts folder (could be an absolute path too if needed).
Ex: Object_Xfo_Selected.query <version>{1} <line_def> { vbscript spreadsheet.vbs Current_Selection } <col_def> { vbscript spreadsheet.vbs Object_Xfo }
This example query counts the number of triangles, points, edges (segments) and polygons in the scene. This is the Geometry query used by the spreadsheet in Softimage. Given that there is no specific scene parameter that holds the number of each component, the spreadsheet must be given functions that return these values. These functions can be used to calculate any type of measure, such as the distance of an object to the camera, its the volume, etc.
Since you want all of the elements in the scene, the row script will be like the one shown below. The SIFilter command ensures we get only the 3D objects from the selection "*".
Function All_SceneObject () Dim R(), sceneObjectList set sceneObjectList = SIFilter( "*", "sceneobject",,siQuickSearch) if sceneObjectList.Count = 0 then All_SceneObject = R Exit Function end if End Function
The columns for cells that will contain custom information are defined using the following syntax:
Function Object_Geometry () Dim R(7) R(0) = "Name" R(1) = "Type:Script:vbscript~spreadsheet.vbs~GetObjType" R(2) = "Triangles:Script:vbscript~spreadsheet.vbs~GetNbrTriangles" R(3) = "Points:Script:vbscript~spreadsheet.vbs~GetNbPoints" R(4) = "Segments:Script:vbscript~spreadsheet.vbs~GetNbSegments" R(5) = "Facets:Script:vbscript~spreadsheet.vbs~GetNbFacets" R(6) = "Particles:Script:vbscript~spreadsheet.vbs~GetNbParticles" R(7) = "geomapprox.gapproxmosl:Default:Subdiv" Object_Geometry = R End Function
The following script functions are the ones used by the script column query above. These functions are called for each script cell and for each row. Results are cached for operations like sorting.
'---------------------------------------------------------------------- ' GetObject ' Function that converts an object string into a scripting object ' (for the object model) '---------------------------------------------------------------------- Function GetObject (in_obj) GetObject = "Nothing" if IsEmpty(in_obj) Then exit function end if dim l_coll set l_coll = CreateObject("XSI.Collection") l_coll.Add in_obj set GetObject = l_coll(0) ' returns a X3DObject End Function Function GetNbrTriangles( in_obj ) GetNbrTriangles = 0 Dim l_obj set l_obj = GetObject( in_obj ) if l_obj.type = "polymsh" Or l_obj.type = "surfmsh" Or l_obj.type = "crvlist" then GetNbrTriangles = GetNbTriangles( in_obj ) end if End Function Function GetNbPoints( in_obj ) GetNbPoints = 0 Dim l_obj, l_geom set l_obj = GetObject( in_obj ) if l_obj.type = "polymsh" Or l_obj.type = "surfmsh" Or l_obj.type = "crvlist" then set l_geom = l_obj.obj GetNbPoints = l_geom.nb0D end if End Function Function GetNbSegments( in_obj ) GetNbSegments = 0 Dim l_obj, l_geom set l_obj = GetObject( in_obj ) if l_obj.type = "polymsh" then set l_geom = l_obj.obj GetNbSegments = l_geom.nb1D end if End Function Function GetNbFacets( in_obj ) GetNbFacets = 0 Dim l_obj, l_geom set l_obj = GetObject( in_obj ) if l_obj.type = "polymsh" Or l_obj.type = "surfmsh" then set l_geom = l_obj.obj GetNbFacets = l_geom.nb2D end if End Function Function GetNbParticles( in_obj ) Dim myType, l_obj, l_part GetNbParticles = 0 myType = GetObjType( in_obj ) if myType = "cloud" then set l_obj = GetObject( in_obj ) set l_part = l_obj.particles GetNbParticles = l_part.count end if End Function
This example shows a two-level query. The first level lists all of the selected objects, which also display some visibility information. For each of these objects, their clusters will appear, if any. For each of these clusters, their name, their type and number of elements will appear.
This time, start with the query file. As you can see, there are three additional tags:
<relation>. This gives the name of the relation that you want to appear in the spreadsheet.
<relation_object_def>. This provides a script which will, for each item provided by the <line_def> script, define the row of second-level items to display in the spreadsheet
<relation_param_def>. This provides a script which will define the columns we want to display for the second-level items. Nothing prevents you from using the same script as the <col_def> tag; it just depends on the items you want to appear in each row and what columns you want to see.
<version>{1} <line_def> { vbscript spreadsheet.vbs Current_Selection } <col_def> { vbscript spreadsheet.vbs Object_Visibility } <relation> { Clusters } <relation_object_def> { vbscript spreadsheet.vbs ObjectClusters } <relation_param_def> { vbscript spreadsheet.vbs Cluster_Info } <sort_order> { asc:-1 }
This script receives the objects for each row and must return an array that contains the second-level items. Other than that, the script can pretty much do anything that regular scripting in Softimage can do, so you can define a wide variety of relations (for example, objects that are close to the camera, objects that are blue, clusters that have properties, etc.).
In the example below, the script (using the object model and not a command) accesses the geometry of the object, upon which we can find the list of clusters. It excludes texture support objects because these have a geometry but do not hold a cluster container.
Function ObjectClusters( in_obj ) Dim l_obj, i, l_geom, l_clusters, l_cluster set l_obj = GetObject( in_obj ) Dim l_cArray() if typename(l_obj) = "X3DObject" and not (l_obj.type = "Texture Support") then set l_geom = l_obj.activeprimitive.geometry set l_clusters = l_geom.clusters if ( l_clusters.count > 0 ) then ReDim l_cArray( l_clusters.count - 1 ) for i = 0 to l_clusters.count - 1 l_cArray(i) = l_clusters.Item(i) next else ReDim l_cArray(0) end if else ReDim l_cArray(0) end if ObjectClusters = l_cArray end function
The script displays the name, type, and number of components for each cluster. There's nothing specifically new here, so here are the needed scripts.
Function Cluster_Info () Dim R(2) R(0) = "Name" R(1) = "Type:Script:vbscript~spreadsheet.vbs~GetObjType" R(2) = "Components:Script:vbscript~spreadsheet.vbs~GetNbClsComponents" Cluster_Info = R End Function Function GetObjType (in_obj) Dim l_obj GetObjType = " " if IsEmpty(in_obj) Then exit function end if set l_obj = GetObject( in_obj ) GetObjType = l_obj.Type End Function Function GetNbClsComponents( in_cls ) Dim l_cls, l_elems GetNbClsComponents = 0 set l_cls = GetObject( in_cls ) if typename(l_cls) = "Cluster" then set l_elems = l_cls.elements GetNbClsComponents = l_elems.count end if End Function
Finally, the first-level columns use the following script. It uses an alternate syntax for the cell: instead of giving a label explicitly for the column, we use the GUID identification of the parameter (which can be found in the appropriate SPDL file). This seeks and displays the appropriate parameter name for you.
Function Object_Visibility () Dim R(4) R(0) = "Name" R(1) = "Type:Script:vbscript~spreadsheet.vbs~GetObjType" R(2) = "visibility.viewvis:Default:{D636F4D0-D94B-11D1-B0ED-00A024C79287}" R(3) = "visibility.rendvis:Default:{A9D242E0-D948-11D1-B0ED-00A024C79287}" R(4) = "visibility.selectability:Default:{4256027B-C691-11d2-B740-0008C7A011A6}" Object_Visibility = R End Function
One final thing we haven't covered is how to sort the results that are presented to the user when the query gets executed.
By default you can use the following information for the Sort tag. This will sort based on the line header. Use asc for ascendant sort and des for descendent.
<sort_order> { asc:-1 }
However you can have the query sorted on specific columns. In the example below, the query sorts in ascending order the eighth column, then the third in ascending order, and so on. Of course, the user can then sort the spreadsheet using the contextual menu sort command on any column (only one column sort can be sorted for now).
<sort_order> { asc: 8 des: 3 asc:-1 }
Here is a summary of the currently available syntax for the script columns, which we have seen in the examples in this case study.
A cell description can be given as one of the following options:
"<param name>:<cell type>:<param guid>" (automatic column labeling)
"<param name>:Script:<script language>~<script filename>~<name of the function to call>"
After you have written the queries and the query handler support scripts, perform these steps:
Put the scripts in the following location:
$factory/Application/DSScriptsPut the queries in the following location:
$factory/Application/QueriesExcept where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License