## ShapeClip

Object Hierarchy | Related C++ Class: ShapeClip

### Inheritance

###

SIObject

ProjectItem

Clip

ShapeClip

### Introduced

v1.5

### Description

A ShapeClip object is an instance of a shape key (source) at a particular position along a shape track in the animation mixer. You can create shape clips using the Geometry.SaveShapeKey method. To enumerate existing shape clips you must pass the full string path of the shape track's ClipList to the EnumElements command which returns a collection of ShapeClip objects.
You can create multiple clips of the same source (using the AddClip command), thereby returning to the same shape several times in the same animation, or rearrange the order of the shape clips on the tracks to change the shape animation completely.
The ShapeClip object allows you to access the shape animation stored in clusters by using the Clip.MappedItems method. Each MappedItem object returns the ShapeKey object (a specialized kind of ClusterProperty) from the MappedItem.Source2 method. ShapeKeys contain shape animation data and you can use the ShapeKey's base property SIObject.Parent to get the shape-animated Cluster object.
When you save a shape key in local reference mode (siShapeLocalReferenceMode) only the deltas to the point's local referential are stored. If you need to get the absolute position for each point in the shape you will need the local referential for the point and the original position of the point before the shape key was applied.
In order to get the local referential (Geometry0D.LocalReferenceFrame) and the original position for each point you will need to mute the shape combiner and all other operators above it using the DeactivateAbove command.

### Methods

AddCustomOp | AddICEAttribute | AddProperty | AddProperty2
AddScriptedOp | AddScriptedOpFromFile | AnimatedParameters2 | BelongsTo
EvaluateAt | GetICEAttributeFromName | IsA | IsAnimated2
IsClassOf | IsEqualTo | IsKindOf | IsLocked
IsSelected | LockOwners | RemoveICEAttribute | SetAsSelected
SetCapabilityFlag | SetLock | TaggedParameters | UnSetLock

### Properties

Application | BranchFlag | Capabilities | Categories
Effect | EvaluationID | Families | FullName
Help | HierarchicalEvaluationID | ICEAttributes | LockLevel
LockMasters | LockType | MappedItems | Model
Name | NestedObjects | ObjectID | Origin
OriginPath | Owners | PPGLayout | Parameters
Parent | Parent3DObject | Properties | Relations
Selected | Source | TimeControl | Type

### Examples

#### 1. VBScript Example

    '

    ' The following example illustrates how to access the position

    ' information stored in a shape key. Adding a shape key using

    ' local reference mode will store the positions as deltas to

    ' the local referential of each point. To calculate the

    ' absolute position for each point you need the local

    ' referential for the point and the original position before

    ' the shape was applied.

    '

    ' Create the scene with an object with a shape clip

    NewScene , false

    set root = ActiveSceneRoot

    set c1 = root.AddGeometry( "Cube", "MeshSurface" )

    set c2 = Duplicate( c1, , 2, 1, 1, 0, 0, 1, 0, 1 )(0)

    Translate c2, 10, 0, -2, siRelative, siView, siObj, siXYZ

    Translate c2 & ".pnt[2,3,6,LAST]", -6, -4, 4, siRelative, siView, siObj, siXYZ

    ' Add a shapeclip where the position data is stored as deltas to

    ' the point's local referential. You can also store the shape in

    ' absolute mode in which case the cluster property contains

    ' for the shape the actual point data or you can store it in

    ' object mode in which case deltas are stored in the object

    ' referential (i.e. the pose of the object).

    set key = SelectShapeKey( c1, c2, siShapeLocalReferenceMode )

    dim mix

    if root.HasMixer() then

    	set mix = root.Mixer

    else

    	set mix = root.AddMixer()

    end if

    set shapetrack = AddTrack( root, mix, 1 )

    AddClip root, key, , shapetrack, 1, , , , False

    '

    ' Get the shapeclip

    '

    dim clip

    for each c in mix.Clips

    	if c.Type = siClipShapeType then

    		set clip = c

    	end if

    next

    ' We need to mute the shape combiner and all the operators above it

    ' inorder to get the local reference frame and position of each

    ' point before the shape animation was applied to the geometry.

    ' (This gives the position values before the shape that was stored

    ' and does not include the result of deformations applied afterwards.)

    set geom = Nothing

    set oMatrix33 = XSIMath.CreateMatrix3

    set oDelta = XSIMath.CreateVector3

    set oXAxis = XSIMath.CreateVector3

    set oYAxis = XSIMath.CreateVector3

    set oZAxis = XSIMath.CreateVector3

    for idx=0 to clip.MappedItems.Count-1

    	set mi = clip.MappedItems(idx)

    	LogMessage TypeName(mi)

    	LogMessage TypeName(mi.Source2)

    	' Get the cluster property/shape key stored in the shapeclip

    	set clsprop = mi.Source2

    	' Since the geometry for each mappeditem will be

    	' the same we'll only need to get it once.

    	if TypeName(geom) = "Nothing" then

    		' Get the cluster, primitive and geometry from the

    		' cluster property

    		set cls = clsprop.Parent

    		set geom = cls.Parent

    		set prim = geom.Parent

    		' Deactivate all operators above and including the shape combiner

    		DeactivateAbove prim.FullName & ".clustershapecombiner", True

    		' Get the position array from the geometry

    		aPosition = geom.Points.PositionArray

    		' Get the old Geometry0D object to access

    		' the local reference frame for each point

    		set geomv1 = geom.Parent.Obj

    		set o0DGeometry = geomv1.Geometry0D

    	end if

    	' Assume that the number of cluster property elements

    	' matches the geometry and that they are same order i.e.

    	' point0 == clusterelement0

    	' Get the delta position array from the clusterproperty

    	aDelta = clsprop.Elements.Array

    	' Figure out the absolute position value using the deltas,

    	' the original point position and the local referential

    	' of each point

    	for i=LBound( aDelta, 2 ) to UBound( aDelta, 2 )

    		' Set a vector3 with the delta for the position

    		oDelta.Set aDelta( 0, i ), aDelta( 1, i ), aDelta( 2, i )

    		' Get the local reference frame for the point

    		o0DGeometry.LocalReferenceFrame i, _

    			oXAxis, oXAxisValid, _

    			oYAxis, oYAxisValid, _

    			oZAxis, oZAxisValid

    		' Get the transformation matrix to go from point

    		' local reference frame to object referential

    		oMatrix33.Set _

    				oXAxis.X , oXAxis.Y, oXAxis.Z, _

    				oYAxis.X , oYAxis.Y, oYAxis.Z, _

    				oZAxis.X , oZAxis.Y, oZAxis.Z

    		oDelta.MulByMatrix3 oDelta, oMatrix33

    		' Set a vector3 with the point position

    		set oPosition = XSIMath.CreateVector3

    		oPosition.Set _

    			aPosition( 0, i ), _

    			aPosition( 1, i ), _

    			aPosition( 2, i )

    		' Compute the absolute position by adding the delta

    		oPosition.AddInPlace oDelta

    		' Log the absolute position values for the point

    		LogMessage oPosition.X & "," & oPosition.Y & "," & oPosition.Z

    	next

    next

    ' Reactivate shapecombiner and all operators above it

    if TypeName(prim) <> "Nothing" then

    	DeactivateAbove prim.FullName & ".clustershapecombiner", False

    end if

    ' Enumerate the shapeclips under the mixer shape track.

    for each t in ActiveSceneRoot.Mixer.Tracks

    	if t.Type = siTrackShapeType then

    		set shapetrack = t

    		exit for

    	end if

    next

    for each shapeclip in shapetrack.Clips

    	LogMessage shapeclip

    next

    'Expected results:

    'INFO : MappedItem

    'INFO : ShapeKey

    'INFO : -4,-4,-4

    'INFO : 4,-4,-4

    'INFO : -10,1.33226762955019E-15,-1.33226762955019E-15

    'INFO : -2,1.33226762955019E-15,-1.33226762955019E-15

    'INFO : -4,-4,4

    'INFO : 4,-4,4

    'INFO : -10,8.88178419700125E-16,8

    'INFO : -2,8.88178419700125E-16,8

    'INFO : Mixer.Mixer_Shape_Track.cube1_ShapeKey_Clip

#### 2. JScript Example

    /*

    	This Shape Animation example demonstrates how to use GetDrivingActions()

    	to get at the ShapeClips which animate an object. It also demonstrates

    	how to access the fcurves on each clip

    */

    // Create a little sample scene with a simple animated sphere

    NewScene( null, false );

    // Make sure we are in Mixed Weight Mode

    SetUserPref( "ShapeInstancingMode", 1 );

    var oSphere = ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" );

    SaveShapeKey( "sphere", null, null, 1, null, null, null, null,

    	siShapeLocalReferenceMode );

    // Move a vertice and record that as the shape at frame 20

    SelectGeometryComponents( "sphere.pnt[33]" );

    Translate( null, 3, 0, 0, siRelative, siView, siObj, siXYZ );

    SaveShapeKey( oSphere + ".pnt[33]", null, null, 20, null, null, null, null,

    	siShapeLocalReferenceMode );

    // Move another point as shape for frame 30

    SelectGeometryComponents( "sphere.pnt[1]" );

    Translate( null, 0, 3, 0, siRelative, siView, siObj, siXYZ );

    SaveShapeKey( oSphere + ".pnt[1]", null, null, 30, null, null, null, null,

    	siShapeLocalReferenceMode );

    // Access the ShapeClips which have been created on the object

    var oClips = GetDrivingActions( oSphere, false, null, false, false );

    for ( var i=0; i<oClips.Count; i++ ) {

    	// Get the clip

    	var oClip = oClips(i);

    	// Access the animated parameter which controls the weight of the clip

    	// in the mixer

    	var oParam = Dictionary.GetObject( oClip + ".actionclip.weight" );

    	var oFCurve = oParam.Source;

    	// At frame 40 we will do an equal blend of all the shapes

    	oFCurve.AddKey( 40, 1 );

    	// Print out the keys

    	var oFCurveKeys = oFCurve.Keys;

    	LogMessage( "FCurve on " + oClip );

    	for ( var j=0; j<oFCurveKeys.Count; j++ ) {

    		var oFCurveKey = oFCurveKeys.Item( i );

    		LogMessage( "    Time:" + oFCurveKey.Time + "-" + oFCurveKey.Value );

    	}

    }

    // Expected result:

    //INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track3.ShapeKey2_Clip

    //INFO :     Time:20-0

    //INFO :     Time:20-0

    //INFO :     Time:20-0

    //INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track2.ShapeKey1_Clip

    //INFO :     Time:20-1

    //INFO :     Time:20-1

    //INFO :     Time:20-1

    //INFO :     Time:20-1

    //INFO : FCurve on Mixer.Mixer_Shape_Track.Shape_ClusterClip.Mixer_Shape_Track1.ShapeKey_Clip

    //INFO :     Time:40-1

    //INFO :     Time:40-1

    //INFO :     Time:40-1

### See Also

Geometry.SaveShapeKey GetDrivingActions EnumElements Dictionary.GetObject