This was a bit of a fun exercise, but I’m not sure that it’s actually that practical. Since I’ve been working with a lot of baked animation from mocap data, I wanted a better way to reduce the number of keyframes without impacting the motion too much. One of the things I tried was to make a NURBS curve using the time and value of keyframes as x and y coordinates of the CVs, and then running Maya’s rebuildCurve on that and converting it back into keyframes. It worked to a certain extent, but I ended up getting better results from a different method. But I thought I’d post this anyway in case anyone was interested.
import maya.cmds as mc def rebuildAnimCurve(tolerance=1): #start by getting animation curves from selected objects sel = mc.ls(sl=True) animCurves = mc.keyframe(sel, query=True, name=True) #get the start and end frames keyTimes = mc.keyframe(sel, query=True, timeChange=True) keyTimes.sort() start = keyTimes end = keyTimes[-1] #bake the curve on ones mc.bakeResults(animCurves, sampleBy=1, time=(start,end)) for each in animCurves: #loop through the animation curves. #save the time and value as x and y coordinates x = mc.keyframe(each,query=True, timeChange=True) y = mc.keyframe(each,query=True, valueChange=True) points = list() numFrames = len(x) #put together the points argument for building the curve for i in range(numFrames): points.append([x[i],y[i],0.0]) #generate the nurbs curve curve = mc.curve(p=points,degree=1) #and rebuild it mc.rebuildCurve((curve), rebuildType=1, keepEndPoints=False, keepTangents=False, tolerance=tolerance ) #now cut the keyframes from the object, and create a new animCurve with the points from the NURBS curve. mc.cutKey(each,time=(start+1,end-1),clear=True) for i in range(mc.getAttr(curve+'.spans')): x = mc.pointPosition(curve+'.cv[%i]' % i)[:2] mc.setKeyframe(each, time=x, value=x) #delete the curve mc.delete(curve)
If you comment or remove that last “mc.delete” line, you’ll be able to see the curves that are generated at the origin. It was fun.