I am building a tool to convert FBX files into sequence OBJ files in batches. But I need to be able to change the end of the timeline to the last frame of the selected meshes animation. It's the last part I need to finish this script up. Any help would be greatly appreciated.
1 Answer
This should be enough for simple use. If you use keyframes for example in materials, you will need to add more for
loops. At bottom of this page is the list, where you can find animation_data
property.
import bpy
import math
last = 1
def find_last_keyframe(what):
last = 0
if what.animation_data is not None and what.animation_data.action is not None:
for fcurve in what.animation_data.action.fcurves:
for keyframe in fcurve.keyframe_points:
last = max(last, keyframe.co[0])
return last
last = max(last, find_last_keyframe(bpy.context.scene))
# if you want to get all objects in scene, use
# for obj in bpy.context.scene.objects:
for obj in bpy.context.selected_objects:
last = max(last, find_last_keyframe(obj))
# use math.ceil instead of math.floor if you want to round the number up
bpy.context.scene.frame_end = math.floor(last)
update: ok, here is much simpler and cleaner solution:
import bpy
scene = bpy.context.scene
old_current_frame = scene.frame_current
while bpy.ops.screen.keyframe_jump(next=True) != {'CANCELLED'}:
pass
scene.frame_end = scene.frame_current
scene.frame_current = old_current_frame
-
$\begingroup$ Thanks for the help, I must be messing something up cus it just keeps moving the end of the timeline to whatever I have last = to. IE frame 1 in the example above or whatever I change the number too. $\endgroup$ Jul 11, 2022 at 19:46
-
$\begingroup$ edit that code works if the funky animation coming in from the fbx files $\endgroup$ Jul 11, 2022 at 19:53
-
$\begingroup$ You don't need the innermost loop. Keyframe_points is sorted on x, so
last = max(last, keyframe_points[-1].co[0])
is sufficient. Also, last should start at -1 in case the animation starts at 0. (Well, a very large negative number.) $\endgroup$ Jul 11, 2022 at 20:01 -
$\begingroup$ Also note that if FBX supports multiple actions on a mesh, then you're going to need to walk
what.animation_data.nla_tracks
to find the longest NLA strip. $\endgroup$ Jul 11, 2022 at 20:04 -
$\begingroup$ Actually, keyframes are not always in order, that's why I used
for
cycle instead of [-1]. For examplebpy.context.scene.animation_data.action.fcurves[0].keyframe_points.add(1)
. You can call fcurve.update() to make sure its keyframe_points are in correct order. $\endgroup$ Jul 12, 2022 at 19:52
bpy.
I remember now that I couldn't find the docs, what you can do is play around with python console autocomplete to figure out where that is at, probably inbpy.ops.
, whire are operator, but also maybe inbpy.data.scene
somewhere in the timeline's settings where a variable can be set. $\endgroup$