If you’re really curious as to where your time is going, you can always profile your code:
from cProfile import Profile
p = Profile()
sel = cmds.ls(sl=True)
p.run('bake_animation(sel, (0, 250))').print_stats('cumtime')
This should print out what portion of your code is taking the most cumulative time to execute.
Which should give you a starting point as to identifying what might be the culprit.
Because I got curious myself, running your code against 440 random objects and baking 300 frames, I got the following results.
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 27.482 27.482 <string>:1(<module>)
1 0.018 0.018 27.482 27.482 <maya console>:5(bake_animation)
1800 26.267 0.015 26.267 0.015 {built-in method setKeyframe}
1 0.979 0.979 0.979 0.979 {built-in method filterCurve}
300 0.154 0.001 0.154 0.001 {built-in method currentTime}
1 0.024 0.024 0.024 0.024 {built-in method modelPanel}
1 0.020 0.020 0.020 0.020 {built-in method scriptedPanel}
1 0.014 0.014 0.014 0.014 {built-in method select}
2 0.003 0.001 0.003 0.001 {built-in method setFocus}
1800 0.002 0.000 0.002 0.000 {method 'join' of 'str' objects}
3 0.001 0.000 0.001 0.000 {built-in method evaluationManager}
3 0.000 0.000 0.000 0.000 {built-in method getPanel}
2 0.000 0.000 0.000 0.000 {built-in method refresh}
2 0.000 0.000 0.000 0.000 {built-in method undoInfo}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Which means that setKeyframe
is where all your time is going.
One alteration you could make.
channels = ["translate", "rotate"]
axis = ["X", "Y", "Z"]
attributes = [''.join(c, x) for c in channels for x in axis]
for frame in xrange(frame_range[0], frame_range[1]):
cmds.currentTime(frame)
cmds.setKeyframe(attribute=attributes, time=frame)
This should reduce the number of calls you’ve got to setKeyframe
, and in turn should get you some time back. it shaved almost 10 seconds off of my trial runs.