wrote a Blender script to auto-set curve interpolation by bone name: mech rigs shouldn't default to Bezier

399 views 2 replies

Working on a mech-suit character that has both servo-driven joints and organic muscle overlays on the same rig, and the interpolation defaults were driving me crazy. Blender defaults everything to Bezier, which is great for organic limb curves but completely wrong for pistons and hinges that should snap linearly between target positions. Visibility channels are even worse. You obviously don't want in-between values on something that's either shown or hidden.

Every time I'd key the mechanical parts I'd have to box-select in the graph editor, switch interpolation, and redo it all over again after any retiming pass. So I wrote a script to handle it automatically using regex patterns on bone names.

Rules are a list of (pattern, interpolation_type) pairs, first match wins:

import bpy
import re

BONE_INTERP_RULES = [
    (r'^mech_|^piston_|^hinge_|_IK$', 'LINEAR'),
    (r'^vis_|^blink_|^eye_lid', 'CONSTANT'),
    (r'.*', 'BEZIER'),  # fallback for everything else
]

def apply_interp_rules(action):
    if not action or not action.fcurves:
        return
    for fcurve in action.fcurves:
        if not fcurve.data_path.startswith('pose.bones'):
            continue
        match = re.match(r'pose\.bones\["(.+?)"\]', fcurve.data_path)
        if not match:
            continue
        bone_name = match.group(1)
        for pattern, interp_type in BONE_INTERP_RULES:
            if re.search(pattern, bone_name):
                for kp in fcurve.keyframe_points:
                    kp.interpolation = interp_type
                break

for action in bpy.data.actions:
    apply_interp_rules(action)
print("Done.")

Runs across all actions in the file, which is what I wanted. Consistent behavior everywhere without having to think about it per-session. Scope it to a single action easily if that fits your workflow better.

Current limitation: doesn't handle non-bone FCurves, so shape keys, object-level properties, and custom props are all out. The data path format is different and would need its own matching logic. Fine for bone-heavy rigs but worth knowing if your setup is more complex.

Curious how others handle mixed interpolation rigs. Do you just set it manually after every key pass? Is there a per-bone interpolation default hiding somewhere in Blender's preferences that I've completely missed?

the mech vs organic interpolation split is something i've been handling manually every session for months and it's tedious. been meaning to write exactly this.

one thing worth adding: if you have mirrored servo pairs (L_Piston_Knee / R_Piston_Knee, etc.), might be worth extending the check to verify matching bones on both sides share the same interpolation mode. had a subtle artifact where i'd manually tweaked one side's curves and they drifted apart from each other. took forever to spot because it only showed at certain poses and i kept blaming the mesh deform weights.

spot the difference fail
Replying to TurboSpark: the mech vs organic interpolation split is something i've been handling manually...

yeah and if your rig uses mirrored naming like arm_L / arm_R, the pattern match covers both sides automatically. you just normalize the name by stripping the side suffix before the lookup. i was writing duplicate rules for left and right for way longer than i care to admit before i realized i could just do that first.

facepalm embarrassed
Moonjump
Forum Search Shader Sandbox
Sign In Register