Following are some helpful tips for working with Python.
To access an item in a collection using an integer index, use the [] syntax as shown in the following example:
oObj = Application.ActiveSceneRoot.AddGeometry("Cube","MeshSurface") oEdges = oObj.ActivePrimitive.Geometry.Edges try: oEdge = oEdges.Item( 10 ) except: Application.LogMessage( "You cannot call .Item() method explicitly" ) ; # Instead do this oEdge = oEdges[10] Application.LogMessage( oEdge.Vertices.Count )
The following is another example.
XSIUtils.Environment["MYVAR"] = "bar" ; Application.LogMessage( XSIUtils.Environment["MYVAR"] ) ;
The following example shows how to retrieve the methods of a scripting object at runtime.
def GetFunctions( dynDisp ): """Returns a sorted and unique list of all functions defined in a dynamic dispatch""" dict = {} try: for iTI in xrange(0,dynDisp._oleobj_.GetTypeInfoCount()): typeInfo = dynDisp._oleobj_.GetTypeInfo(iTI) typeAttr = typeInfo.GetTypeAttr() for iFun in xrange(0,typeAttr.cFuncs): funDesc = typeInfo.GetFuncDesc(iFun) name = typeInfo.GetNames(funDesc.memid)[0] dict[name] = 1 except: pass ret = dict.keys() ret.sort() return ret import pprint funcs = GetFunctions(Application) Application.LogMessage(pprint.pformat(funcs)) funcs = GetFunctions(Application.ActiveSceneRoot) Application.LogMessage(pprint.pformat(funcs))
You can also generate some basic object model documentation from the information exposed by Python as follows:
def FormatDocumentation(typeInfo, funDesc): nameAndParms = typeInfo.GetNames(funDesc.memid) docum = typeInfo.GetDocumentation(funDesc.memid) import pythoncom # This differentiates between "functions" and "accessors" if funDesc.invkind == pythoncom.INVOKE_FUNC: docStr = nameAndParms[0] + "(" + ",".join(nameAndParms[1:]) + ")\n" else: docStr = nameAndParms[0] + "\n" if docum[1]: docStr += "\t" + docum[1] return docStr def GetDocumentation( dynDisp, funcName = None ): allTypeInfoDoc = [] for iTI in xrange(0,dynDisp._oleobj_.GetTypeInfoCount()): typeInfo = dynDisp._oleobj_.GetTypeInfo(iTI) typeAttr = typeInfo.GetTypeAttr() if funcName: for iFun in xrange(0,typeAttr.cFuncs): funDesc = typeInfo.GetFuncDesc(iFun) name = typeInfo.GetNames(funDesc.memid)[0] if name.upper() == funcName.upper(): return FormatDocumentation(typeInfo, funDesc) else: dict = {} className = dynDisp._oleobj_.GetTypeInfo(0).GetDocumentation(-1) classDoc = "class %s \n\t%s\n\n"%(className[0],className[1]) allFuncDoc = [] for iFun in xrange(0,typeAttr.cFuncs): funDesc = typeInfo.GetFuncDesc(iFun) name = typeInfo.GetNames(funDesc.memid)[0] if not dict.has_key(name): dict[name] = 1 allFuncDoc.append(FormatDocumentation(typeInfo, funDesc)) allFuncDoc.sort() allTypeInfoDoc.append(classDoc + "\n".join(allFuncDoc)) if funcName: return "Documentation not found for %s"%(funcName,) else: return "\n".join(allTypeInfoDoc) # There are two ways to call this: without a function name and with a function name # Without a function name, it retrieves documentation for all functions Application.LogMessage(GetDocumentation(Application)) # And with a function name, it tries to find the documentation for that function Application.LogMessage(GetDocumentation(Application, "StatusBar")) Application.LogMessage(GetDocumentation(Application, "NotThere"))
You can use getattr as shown in the following example to determine if the selected object supports the Properties property.
oObj = Application.Selection(0) if getattr(oObj, "Properties", None): Application.LogMessage("Yes") else: Application.LogMessage("No")
You can use exception handling to continue without errors even when the property or method is not supported.
The return value of a Python based custom command is always converted into an ActiveX safe object type.
If you are calling the Python based command from another Python script, you can use the unwrap function in win32com.server to get the pure Python object.
A Python custom command can return a Python object whose functions and attributes are available as methods and properties to VBScript and JScript. See Returning Python Types from Custom Commands
Since Softimage 2013, the print statement works only with the built-in Python version that ships with Softimage.
Without arguments, the vars() function returns a dictionary corresponding to the current local symbol table. With a module, class, or class instance object as argument (or anything else that has a __dict__ attribute), it returns a dictionary corresponding to the object's symbol table.
See the LogMessage call in the following example.
# Set up an SIVector3 math object v3 = XSIMath.CreateVector3() v3.Set( 10.0, 20.0, 30.0) v3.ScaleInPlace(2) # Initialize the variables (you need to initialize # variables to be used as input to SIVector3.Get) x=0 y=0 z=0 # Retrieve the three values from the SIVector3.Get method # (use the same variables as input) x, y, z = v3.Get(x, y, z) # Write the results to the Script Editor Application.LogMessage( '%(x).2f %(y).2f %(z).2f' % vars() )
Here, vars() is returning a dictionary with x, y, and z.
Additionally, consider the following example code.
x = 10.0 y = 20.0 z = 30.0 Application.LogMessage( '%(x).2f %(y).2f %(z).2f' % vars() )
This is same as the following code.
my_dict = { 'x':10.0, 'y' : 20.0, 'z' : 30.0 } Application.LogMessage( '%(x).2f %(y).2f %(z).2f' % my_dict )
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License