Using EvaluateAt() instead of Changing the Current Frame
 
 
 

If you are writing a script that visits one or more objects at each (or several) frames in the timeline, you should consider using the EvaluateAt (ProjectItem) method instead of changing the current frame using the SetValue command:

	SetValue( "PlayControl.Current", <new_time> );

The EvaluateAt method is much faster than the SetValue method, in large part due to the fact that nothing gets logged when you run object model methods. The following example times the two methods, performing otherwise identical activities in the scene:

	// Set up a scene with a null
	NewScene( null, false );
	var root = ActiveSceneRoot;
	var obj = root.AddNull();

	// Add some animation on the null's position using an fcurve
	var xkeys = new Array( 1.0, -8.153, 50, 0.197, 100, 9.61 );
	var ykeys = new Array( 1.0, 7.015, 50, -1.92, 100, 7.015 );
	var zkeys = new Array( 1.0, -0.702, 50, 0.192, 100, -0.702 );

	var xfc = obj.posx.AddFCurve2( xkeys, siStandardFCurve );
	var yfc = obj.posy.AddFCurve2( ykeys, siStandardFCurve );
	var zfc = obj.posz.AddFCurve2( zkeys, siStandardFCurve );

	// For each frame in the scene, time how long it takes to get 
	// the object and set an SIVector3 object with both using
	// the Play Controls and the EvaluateAt method
	var evalobj, pos, posm, dt

	// ------------------------------------------------------------
	// EvaluateAt...
	var dt = new Date();
	var starttime = dt.getTime();

	for ( var i=1; i<=100; i++ )
	{
		evalobj = obj.EvaluateAt(i);
		pos = XSIMath.CreateVector3();
		posm = XSIMath.CreateVector3();
		posm.Set( .05, .1, .15 );

		pos.Set( evalobj.posx.Value, evalobj.posy.Value, evalobj.posz.Value );
		pos.AddInPlace( posm ); 
		evalobj.posx = pos.X;
		evalobj.posy = pos.Y;
		evalobj.posz = pos.Z;
	}

	dt = new Date();
	LogMessage( "EvaluateAt() took " + ( dt.getTime() - starttime ) 
			+ " milliseconds to complete." );


	// ------------------------------------------------------------
	// Play Controls...
	dt = new Date();
	starttime = dt.getTime();

	var currframe = 1;
	SetValue( "PlayControl.Current", currframe )
	while ( currframe < 100 )
	{
		pos = XSIMath.CreateVector3();
		posm = XSIMath.CreateVector3();
		posm.Set( .05, .1, .15 );

		pos.Set( obj.posx.Value, obj.posy.Value, obj.posz.Value );
		pos.AddInPlace( posm );
 
		obj.posx = pos.X;
		obj.posy = pos.Y;
		obj.posz = pos.Z;

		currframe += 1;
		SetValue( "PlayControl.Current", currframe )
	}

	dt = new Date();
	LogMessage( "Play Controls took " + ( dt.getTime() - starttime ) 
			+ " milliseconds to complete." );

	// ------------------------------------------------------------
	// Results.................
	//INFO : EvaluateAt() took 371 milliseconds to complete.
	//INFO : Play Controls took 1973 milliseconds to complete.