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

# Object Model Examples

## Enumerating Properties

The following example shows how to enumerate the properties.

    oDefaultLight = Application.ActiveSceneRoot.Children( "light" )

    for oProp in oDefaultLight.Properties:
        Application.LogMessage( oProp.Name )

## Enumerating Edges

The following example shows how to enumerate the edges.

    oObj = Application.ActiveSceneRoot.AddGeometry("Cone","MeshSurface")
    oEdges = oObj.ActivePrimitive.Geometry.Edges

    for oEdge in oEdges:
    	   index = oEdge.Index
    	   Application.LogMessage( "Found edge %d" % index )

## Using the Math Library from Python

The following example shows how to use the math library.

    v3 = XSIMath.CreateVector3()

    #Vector can be set using its properties
    v3.X = 10.0

    #Or using this method
    v3.Set( 10.0, 20.0, 30.0)

    #Vector3 has many convenient methods
    v3.ScaleInPlace(2)

    #Read the vector values
    x=0
    y=0
    z=0
    x, y, z = v3.Get(x,y,z)
    valstr = '%(x).2f %(y).2f %(z).2f' % vars()

    Application.LogMessage( valstr ) ;

## Representing the Arrays as Tuples

The following example shows how the arrays are represented as tuples.

    oObject = Application.ActiveSceneRoot.AddGeometry( "Grid","MeshSurface","PolyMeshGetTest" )

    Application.SetValue(str(oObject) + ".polymsh.geom.subdivu", 1, "")
    Application.SetValue(str(oObject) + ".polymsh.geom.subdivv", 1, "")

    oGeometry = oObject.ActivePrimitive.Geometry

    aReturnArray = oGeometry.Get2() ;

    Application.LogMessage( repr(aReturnArray) ) ;

    aVertices = aReturnArray[0]		# 2D array of x,y,z
    aPolydata = aReturnArray[1]

    Application.LogMessage( repr(aVertices) ) ;
    Application.LogMessage( repr(aPolydata) ) ;

## Converting a Tuple to a List

If you want to modify array data that has more than one dimension such as, XYZ, UVW, or RGBA, you need to know how to convert from the immutable tuple returned by Softimage to a flattened mutable list. The following example shows how to convert the tuple.

    import win32com.client
    from win32com.client import constants
    import sys

    xsi = Application
    true=1
    false=0

    def main():
        Test1()

    # test1: turn a tuple into  a list
    def Test1():
        # immutable tuple i.e. read-only
        print "1 dimensional tuple example"
        w_tuple = ('W1','W2','W3','W4','W5')
        print repr(w_tuple)

        w_list = [w for w in w_tuple]
        print  repr(w_list)

        w_tuple = (0.25,0.26,0.27,0.28,0.29)
        print repr(w_tuple)

        w_list = [1.0-w for w in w_tuple]
        print  repr(w_list)

        print "2 dimensional tuple example (such as XYZ)"
        w_tuple = (('X1','X2','X3','X4'),('Y1','Y2','Y3','Y4'),('Z1','Z2','Z3','Z4'))
        print repr(w_tuple)

        w_list = [w_tuple[j][i] for i in range(len(w_tuple[0])) for j in range(len(w_tuple)) ]
        print  repr(w_list)

    # test2: turn a weightmap tuple into a list, invert and set back
    def Test2():
        obj = xsi.ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface", "TupleTest2" )
        wmap = xsi.CreateWeightMap("WeightMap", obj , "Weight Map", "Weight Map Property", false)(0)

        # get weightmap as tuple
        w_tuple = wmap.Elements.Array
        print "wmap as tuple: " + repr(w_tuple)

        # convert to list and invert
        w_list = [ 1-w for w in w_tuple[0] ]
        print "wmap as inverted list: " + repr(w_list)

        # set weightmap as list
        wmap.Elements.Array = w_list

    # test3: turn a uvw tuple into a list, invert and set back
    def Test3():
        obj = xsi.ActiveSceneRoot.AddGeometry( "Cube", "MeshSurface", "TupleTest3" )
        xsi.GenerateUniqueUVs(obj, "Texture_Projection", "", "", "", "", "", "", "")

        mesh = obj.ActivePrimitive.Geometry
        cluster= mesh.Clusters.Filter( "sample" )(0)
        uvw = cluster.Properties.Filter("uvspace")(0)

        uvw_tuple = uvw.Elements.Array
        print "uvw tuple: " + repr(uvw_tuple)

        uvw_list = [1-uvw_tuple[j][i] for i in range(len(uvw_tuple[0])) for j in range(len(uvw_tuple)) ]
        print "uvw list: " + repr(uvw_list)

        uvw.Elements.Array = uvw_list

    def XSITuple_toList(_tuple):
        return [_tuple[j][i] for i in range(len(_tuple[0])) for j in range(len(_tuple)) ]

    if __name__=='__ax_main__':
        class WritableObject:
            def __init__(self):
                self.content = ""
            def write(self, string):
                if (string=='\n'):
                    Application.Logmessage(self.content,32)
                    self.content=""
                else:
                    self.content+=string

        # example with redirection of sys.stdout
        sys.stdout = WritableObject()

    main()

## Creating a Clip

The following example shows how to create a clip containing the static values of the local position of an object.

    oRoot = Application.ActiveSceneRoot
    oCube = oRoot.AddGeometry( "Cube", "MeshSurface" )

    # Creating the first animation source
    sParams = "cube.kine.local.posx,cube.kine.local.posy,cube.kine.local.posz"
    oSource = Application.StoreAction( oRoot, sParams, 1, "StoredStaticPose", 1, 1, 5, 0, 0)

    # Creating the first clip
    oClip = Application.AddClip( oRoot, oSource )
    Application.LogMessage( "First created clip " + oClip.FullName )

    # Creating the second animation source
    oCube.Parameters("posx").Value = 3.0
    oSource2 = Application.StoreAction( oRoot, sParams, 1, "StoredStaticPose", 1, 7, 9, 0, 0 )

    # Creating the second clip
    oClip2 = Application.AddClip(oRoot, oSource2)
    Application.LogMessage("Second created clip " + oClip2.FullName)

## Accessing Geometry

The following example shows how to get the position of a point at a specific time frame.

    # Import the constants
    from win32com.client import constants as c

    import sys, types

    Application.NewScene("", 0)
    oGrid = Application.ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface" )
    Application.SetValue (oGrid.Name + ".polymsh.geom.subdivu", 1)
    Application.SetValue (oGrid.Name + ".polymsh.geom.subdivv", 1)
    Application.Scale( oGrid, 0.25, 0.25, 0.25, c.siAbsolute, c.siParent, c.siObj, c.siXYZ)

    startTimeInSeconds = 5 / 29.97
    duration = startTimeInSeconds * 2

    # Start at frame 5 & last 100 frames
    oClip = oGrid.ActivePrimitive.Geometry.SaveShapeKey(
    				startTimeInSeconds,
    				duration,
    				c.siShapeAbsoluteReferenceMode,
    				c.siShapeInstanceOnlyMode,
    				"Clip", ( 0,1,2,3),
    				( -4,0,-4,
    				  -4,0, 4,
    				   4,0, 0,
    				   4,0, 4 ))

    # Frame 3 must be the original grid
    oPoints = oGrid.ActivePrimitive.GetGeometry2(3,c.siConstructionModeSecondaryShape).Points
    oPos = oPoints[2].Position
    Application.LogMessage( "%f,%f,%f" % ( oPos.X,oPos.Y,oPos.Z ) )

    # Frame 10 must be the modified grid in the clip
    oPoints = oGrid.ActivePrimitive.GetGeometry2(10).Points
    oPos = oPoints[2].position
    Application.LogMessage( "%f,%f,%f" % ( oPos.X,oPos.Y,oPos.Z ) )

## Setting and Getting FCurve Keys

This example demonstrates how to set an fcurve on the posx parameter and how to access the keys through the FCurveKey object.

    Application.NewScene( "", 0 )

    oRoot = Application.ActiveProject.ActiveScene.Root
    oNull = oRoot.AddNull()
    oPosX = oNull.posx

    # Create and connect an fcurve to the position x
    oFCurve = oPosX.AddFCurve2( [1, 10, 50, 0, 100, 10] )

    # Set the zero slopes on the key tangents
    oFCurve.SetKeyTangents( [
    	-10.5, 0, 10.5, 0,
    	-10.5, 0, 10.5, 0,
    	-10.5, 0, 10.5, 0
    ])

    # Get the keys on the fcurve
    for oFCKey in oFCurve.Keys :
        Application.LogMessage( "oFCKey[" + str(oFCKey.Index) + "] at frame " + str(oFCKey.Time) + " = " + str(oFCKey.Value) )