"""
bakeAnimation
==========================================
Module with methods to bake the movement/channels of one object
to another. Transform baking can be either in local or world space.
This can be usefull to bake camera movement resulting from hierarchies
into camera movement without hierarchies etc.
-----------------------
Usage
-----
::
from helga.maya.animation.bakeAnimation import bakeAnimation
reload(bakeAnimation)
#Create instance
bakeAnimationInstance = bakeAnimation.BakeAnimation()
#Select object_a and object_b and execute bakeAnimationTransformOnly
#to bake the animation from object_a to object_b for the frames 1 - 100
bakeAnimationInstance.bakeAnimationTransformOnly(1, 100)
-----------------------
"""
#Imports
#------------------------------------------------------------------
import pymel.core as pm
#BakeAnimation class
#------------------------------------------------------------------
class BakeAnimation():
[docs]
#Constructor
def __init__(self):
#Instance Vars
#------------------------------------------------------------------
self.verbose = True
#TopLevel Methods
#------------------------------------------------------------------
#bakeAnimationTransformOnly
def bakeAnimationTransformOnly(self, animationStartTime = 0, animationEndTime = 0, localSpace = False):
[docs] """
Bake animation of two objects (or master - slave pairs). Bakes animation of all
channels that are *keyable* and *not locked*. Also the channels need to be presents
in both objects. The selection order is the same as with constraints:
1. Master: Source of Movement
2. Slave: Gets baked to movement of master
:param animationStartTime: Beginning of sequence to bake
:type animationStartTime: int
:param animationEndTime: End of sequence to bake
:type animationEndTime: int
"""
#check if start and end time are equal
if(animationStartTime == animationEndTime):
if(self.verbose): print('Start time should not be end time. Please enter a valid range')
return None
#getSelection
selectedObjectsList = self.getSelection()
pm.select(cl = True)
#Check if there is any selection
if not(len(selectedObjectsList) > 1):
if(self.verbose): print('You have no or not enough objects selected')
return None
#Uneven number of objects selected
if not(len(selectedObjectsList) % 2 == 0):
if(self.verbose): print('You have an uneven number of objects selected, please select pairs of objects to bake (Order: 1.master 2.slave)')
return None
#get Masterlist
masterList = []
for master in selectedObjectsList[::2]:
masterList.append(master)
#get Slavelist
slaveList = []
for slave in selectedObjectsList[1::2]:
slaveList.append(slave)
pm.select(cl = True)
#get masterAttributeLists
masterAttributeLists = []
#iterate all masters and get a list of all attributes that are keyable and unlocked
#append this list to masterAttributeLists
for master in masterList:
masterAttributeLists.append(pm.listAttr(master, keyable = True, unlocked = True))
#get bakeAttributeLists
bakeAttributeLists = []
#iterate slaveList and get attributeList for each
for index in range(len(slaveList)):
#get slaveAttributeList
slaveAttributeList = pm.listAttr(slaveList[index], keyable = True, unlocked = True)
#bakeAttributeList
bakeAttributeList = []
#iterate masterAttributeList at index
for masterAttribute in masterAttributeLists[index]:
#if attribute in slaveAttributeList append to bakeAttributeList
if(masterAttribute in slaveAttributeList): bakeAttributeList.append(masterAttribute)
#append bakeAttributeList to bakeAttributeLists
bakeAttributeLists.append(bakeAttributeList)
#getCurrentAnimationRange
currentAnimationTime = pm.currentTime(q = True)
currentAnimationStart = pm.playbackOptions(ast = True, q = True)
currentAnimationEnd = pm.playbackOptions(aet = True, q = True)
currentAnimationRangeStart = pm.playbackOptions(minTime = True, q = True)
currentAnimationRangeEnd = pm.playbackOptions(maxTime = True, q = True)
#setTempNewAnimationRange
self.setAnimationRange(animationStartTime, animationEndTime, animationStartTime, animationEndTime)
#Bake animation for given range
for index in range(animationStartTime, animationEndTime + 1):
#set current time
pm.currentTime(index)
#iterate bakeAttributeLists
for indexBakeAttributeList in range(len(bakeAttributeLists)):
#iterate bakeAttributeList
for bakeAttribute in bakeAttributeLists[indexBakeAttributeList]:
#set attr
pm.setAttr(slaveList[indexBakeAttributeList] +'.' +bakeAttribute, pm.getAttr(masterList[indexBakeAttributeList] +'.' +bakeAttribute))
#keyframe
pm.setKeyframe(slaveList[indexBakeAttributeList])
#setAnimationRange back to old
self.setAnimationRange(currentAnimationStart, currentAnimationEnd, currentAnimationRangeStart, currentAnimationRangeEnd)
#set Current time back to old
pm.currentTime(currentAnimationTime)
#Print Success Msg
if(self.verbose): print('Successfully baked animation')
return None
#Methods
#------------------------------------------------------------------
#Shared Methods
#------------------------------------------------------------------
#getSelection
def getSelection(self):
[docs]
return pm.ls(sl = True, fl = True)
#setAnimationRange
def setAnimationRange(self, startTime, endTime, startRange, endRange):
[docs]
#setStartTime
pm.playbackOptions(ast = startTime, e = True)
pm.playbackOptions(minTime = startRange, e = True)
#setEndTime
pm.playbackOptions(aet = endTime, e = True)
pm.playbackOptions(maxTime = endRange, e = True)
#Test Execution
#------------------------------------------------------------------
'''
from kugeltiere.maya.bakeAnimation import bakeAnimation
doReload = True
if(doReload): reload(bakeAnimation)
#Create Instance
bakeAnimationInstance = bakeAnimation.BakeAnimation()
#Execute
bakeAnimationInstance.bakeAnimation(animationStartTime = 0, animationEndTime = 40)
'''