Tips

 
 
 

Following are some helpful tips for working with Python.

Calling the Item Method of a Collection

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"] ) ;

Retrieving the Methods of an Object at Runtime

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"))

Determining if an SDK Object Supports a Particular Property or Method

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.

Unwrapping a Python Variable

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.

Exposing a Python Object to Other Languages

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

Print Statement

Since Softimage 2013, the print statement works only with the built-in Python version that ships with Softimage.

Using the vars([object]) function

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 )

Creative Commons License Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License