0
$\begingroup$

I need to keyframe thousands of frames. First I would like to keyframe the visibility for 1 object for all frames with the same value (let's say that I need to hide an object on all keyframes but I need the data_path=hide_viewport really keyframed to True I can't use the interpolation, it has to be keyframed for every frame.

I can do this through loop like this:

obj.hide_viewport = True
for kf in (start, end + 1):
 obj.keyframe_insert('hide_viewport', frame=kf) 

But this needs to loop through all of the keyframes just to set the same value. Is there an option to set the same value to let's say an array of keyframes so that loop is not necessary? This would greatly speed up the execution.

$\endgroup$
1
  • $\begingroup$ wouldn't it be easier to just set your keys in stepped interpolation where you need a change and then run a bake action to have keyframes at each frame? $\endgroup$
    – L0Lock
    Mar 4, 2023 at 20:30

1 Answer 1

2
$\begingroup$

Yes. keyframe_insert is the slowest (but easiest) way to set keyframes. It's faster to access the FCurve's keyframe points directly. The coordintes of the keyframes are located at action.fcurves[i].keyframe_points[j].co.

Here's an example that creates an FCurve for "hide_viewport" and sets all the keyframes from an array using foreach_set.

import bpy

def add_hide_fcurve(ob, keyframes):
    # Create animation data if it doesn't exist
    if not ob.animation_data:
        ob.animation_data_create()

    # Create action if it doesn't exist
    if not ob.animation_data.action:
        ob.animation_data.action = bpy.data.actions.new(f"{ob.name}Action")

    # Throws if an FCurve for hide_viewport already exists
    fcu = ob.animation_data.action.fcurves.new(data_path="hide_viewport")

    # Add the new keyframes
    fcu.keyframe_points.add(len(keyframes) // 2)

    # Set their times & values
    fcu.keyframe_points.foreach_set("co", keyframes)

keyframes = []
for kf in range(start, end + 1):
    keyframes.append(kf)  # keyframe time
    keyframes.append(1)   # keyframe value

add_hide_fcurve(bpy.context.object, keyframes)

There may be faster way to use keyframes, but this should already give you a big boost vs keyframe_insert.

$\endgroup$
1
  • $\begingroup$ This worked. I can not even express how fast this is compared to keyframe_insert & loops. Just a simple comparison for 1000 keyframes: looping with keyframe_insert: 28 seconds to complete your method: < 1 second Thanks a lot! $\endgroup$
    – Martin
    Mar 6, 2023 at 16:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .