# Copyright 2009 Autodesk, Inc. All rights reserved. # Use of this software is subject to the terms of the Autodesk license agreement # provided at the time of installation or download, or which otherwise accompanies # this software in either electronic or hard copy form. # # Topic: FBTime, FCurve, FBFCurveKey # # Get the necessary symbols from pyfbsdk. from pyfbsdk import FBSystem, FBModelList, FBGetSelectedModels, FBTime # This recursive function finds the first and last keyframe of an # animation node. def FindLimits( pNode, pLLimit=None, pRLimit=None ): # First let's see if the node has any keys if pNode.FCurve: # Got thru the list, updating the first and last frame if necessary. # Limits are initialised on first comparaison attempt. for lKey in pNode.FCurve.Keys: if pLLimit: if lKey.Time.Get() < pLLimit.Get(): pLLimit.Set( lKey.Time.Get()) else: pLLimit = FBTime() pLLimit.Set( lKey.Time.Get()) if pRLimit: if lKey.Time.Get() > pRLimit.Get(): pRLimit.Set( lKey.Time.Get()) else: pRLimit = FBTime() pRLimit.Set( lKey.Time.Get()) # If the node has any children nodes, we navigate those. if pNode.Nodes: for lNode in pNode.Nodes: ( pLLimit, pRLimit ) = FindLimits( lNode, pLLimit, pRLimit ) return ( pLLimit, pRLimit ) # This function iterates thru the list of keys and offsets them according to # a given delta. The internal list of keys is sorted according to time. This # means that we have to be careful how we iterate the list to ensure that a # moved key will keep the same position in the list being modified. def OffsetKeys( pNode, pDelta ): # Modify all the keys of the current node. if pNode.FCurve: # Create a list of the keys. This new list can be re-sorted without # affecting the internal list. lKeys = [ lKey for lKey in pNode.FCurve.Keys ] # If the delta is positive, we need to move the keys starting with # the last. This prevent any changes in the order of the keys in the # internal list. if pDelta.Get() > 0: lKeys.reverse() # Set the new time value for all the keys. for lKey in lKeys: lTime = FBTime() lTime.Set( lKey.Time.Get() + pDelta.Get() ) lKey.Time = lTime # Now deal with all the children nodes. if pNode.Nodes: for lNode in pNode.Nodes: OffsetKeys( lNode, pDelta ) # Get the list of selected models, if any. lSystem = FBSystem() lModels = FBModelList() FBGetSelectedModels( lModels ) # Iterate the list of selected models. for lModel in lModels: # Find the earliest keyframe. ( lLTime, lRTime ) = FindLimits( lModel.AnimationNode ) # If we do have a first keyframe... if lLTime: # Compute the delta between the current time and the first key. lCurrentTime = lSystem.LocalTime lDelta = FBTime() lDelta.Set( lCurrentTime.Get() - lLTime.Get()) # Do the work... OffsetKeys( lModel.AnimationNode, lDelta ) # Cleanup of local variables. del( lCurrentTime, lDelta ) # Cleanup of local variables. del( lModel, lLTime, lRTime ) # Cleanup # Cleanup of local variable del( lSystem, lModels ) # Cleanup of local functions del( FindLimits, OffsetKeys ) # Cleanup of imported symbols del( FBSystem, FBModelList, FBGetSelectedModels, FBTime )