Softimage SDK Programmer's Guide > Script Development > Python Scripting >

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