Numpy action slicer.
Script to roll thru the fcurves of an action and create a new one based on a new frame range. A condition to shift the frames of the copy is added.
I know I can copy the entire action and just delete the peripheral
frames
The rub here is that copying the action using Action.copy()
will AFAIK bring along all the fcurve modifiers and other stuff I have not added in here.
Test script, added a timer wrapper for testing.
import bpy
import numpy as np
def time_it(func):
import time
def wrapper(action, start_frame, end_frame, **kw):
print("-" * 44)
print("In:", action.name, "frame_range", action.frame_range[:])
print("Fcurves", len(action.fcurves))
print("Keyframes", sum(len(fc.keyframe_points) for fc in action.fcurves))
t1 = time.time()
copy = func(action, start_frame, end_frame, **kw)
t2 = time.time()
print("Out:", copy.name, "frame_range", copy.frame_range[:])
print("Fcurves", len(copy.fcurves))
print("Keyframes", sum(len(fc.keyframe_points) for fc in copy.fcurves))
print("Elapsed time", (t2 - t1))
print("-" * 44)
return copy
return wrapper
@time_it
def action_slice(action, start_frame, end_frame, shift=True):
copy = bpy.data.actions.new(action.name)
copy.id_root = action.id_root
for fcurve in action.fcurves:
kfs = np.empty(len(fcurve.keyframe_points) << 1)
fcurve.keyframe_points.foreach_get("co", kfs)
kfs = kfs.reshape((-1, 2))
_fc = copy.fcurves.new(
fcurve.data_path,
index = fcurve.array_index
)
_fc.keyframe_points.add(0)
_kfs = kfs[
np.logical_and(
kfs[:,0] >= start_frame,
kfs[:,0] <= end_frame
)
]
if shift:
_kfs[:,0] -= (start_frame - 1)
_fc.keyframe_points.add(_kfs.shape[0])
_fc.keyframe_points.foreach_set("co", _kfs.ravel())
return copy
action = bpy.data.actions.get("Jumping")
action_slice(action, 100, 300, shift=False)
action_slice(action, 100, 300)
Test run on CMU mocap file 01_01 Jumping.
Output.
--------------------------------------------
In: Jumping frame_range (1.0, 551.1978149414062)
Fcurves 96
Keyframes 264192
Out: Jumping.017 frame_range (100.19960021972656, 299.9988098144531)
Fcurves 96
Keyframes 96000
Elapsed time 0.1481459140777588
--------------------------------------------
--------------------------------------------
In: Jumping frame_range (1.0, 551.1978149414062)
Fcurves 96
Keyframes 264192
Out: Jumping.018 frame_range (1.1996002197265625, 200.99880981445312)
Fcurves 96
Keyframes 96000
Elapsed time 0.14278960227966309
--------------------------------------------
>>>