1
$\begingroup$

Adjacent keyframes / Camera cuts

I made a Cycles animation with motion blur enabled. Whenever the camera (and scene objects) "cuts/jumps" the render is a big, blurred sweep. How do I write a Python script that changes the interpolation mode of all adjacent keyframes to "constant"?

I have a lot of keyframes on numerous objects, and it would take a long time to manually set all of the cuts/jumps to constant.

$\endgroup$
1
  • 1
    $\begingroup$ The existing answer is good. I would like to stress that you have to consider the [time] spent creating the script. If it takes you 1h to automate the process, but selecting 50~ keyframes and setting them to constant only takes two minutes, it would only be worth it if this happens everyday for 30 days in a row. $\endgroup$
    – Leander
    Commented Dec 10, 2018 at 14:42

2 Answers 2

3
$\begingroup$

I don't think you need to write a script for that... If you want to set them to constant, just select them, press T and select "constant". However, when you work with motion blur (and multiple shots overall), you should always create multiple cameras and switch between them: to do so, duplicate you active camera and place it in the spot you want, in the timeline select the frame you want your cut to occur, press M to create a new marker (you can rename the marker if you like), then select the second camera and press CTRL-B, so that from that marker ahead the second camera will be the active one. This way you can have different settings between the 2 cameras without having to create useless keyframes and you won't have motion blur, because the camera doesn't jump in space to reach the new location (the blur you see is linked to the camera velocity, so even if the interpolation is constant you will always have some blurred frames when the camera jumps)

$\endgroup$
0
$\begingroup$

Here is a script I use in 3.6. Select all the objects and run it.
x is the interval between keyframes. Adjacent keyframes means x=1.

import bpy

def set_constant_interpolation(x):
    selected_objects = bpy.context.selected_objects
    if not selected_objects:
        return
    
    for obj in selected_objects:
        if obj.animation_data is None or obj.animation_data.action is None:
            continue
        
        action = obj.animation_data.action
        fcurves = action.fcurves
        
        for fcurve in fcurves:
            keyframes = fcurve.keyframe_points
            selected_keyframes = [kf for kf in keyframes if kf.select_control_point]
            
            if len(selected_keyframes) < 2:
                continue
            
            selected_keyframes.sort(key=lambda kf: kf.co.x)
            
            for i in range(len(selected_keyframes) - 1):
                current_frame = selected_keyframes[i].co.x
                next_frame = selected_keyframes[i + 1].co.x
                
                if next_frame - current_frame == x:
                    selected_keyframes[i].interpolation = 'CONSTANT'
    
    bpy.context.scene.frame_set(bpy.context.scene.frame_current)

set_constant_interpolation(1)
```
$\endgroup$

You must log in to answer this question.

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