2

When baking an action we can select which bones to bake, by choosing selected only option. But can you have more control over which types of channels to bake? For example if I would like to only bake translation and rotation channels of the bones, is this possible to achieve with or without scripting? Locking channels in the transform panel for each bone prevents those channels from being keyframed but they still get baked.

1 Answers1

2

Script Solution

Can look at the datapath of an fcurve of an action. Here is the fcurves of default armature object of single pose bone with a LocRotScale action

>>> a = C.object.animation_data.action

>>> for fc in a.fcurves:
...     fc.data_path
...     
'pose.bones["Bone"].location'
'pose.bones["Bone"].location'
'pose.bones["Bone"].location'
'pose.bones["Bone"].rotation_quaternion'
'pose.bones["Bone"].rotation_quaternion'
'pose.bones["Bone"].rotation_quaternion'
'pose.bones["Bone"].rotation_quaternion'
'pose.bones["Bone"].scale'
'pose.bones["Bone"].scale'
'pose.bones["Bone"].scale'

A script to convert any fcurve of an action to samples (bake it) that has a datapath that ends with "location" or "rotation_quaternion"

import bpy

context = bpy.context

ob = context.object
action = ob.animation_data.action

to_bake = ("location",
           "rotation_quaternion",
           )

fcs = (fc for fc in action.fcurves 
       if any(fc.data_path.endswith(p) for p in to_bake))

for fc in fcs:
    fc.convert_to_samples(*action.frame_range)

Further to this, can make a lookup dictionary of the fcurves, then use it based on selected pose bones

The first part of the datapath from a pose bone

>>> C.active_pose_bone.path_from_id()
'pose.bones["Bone"]'

Similar to above, but only baking the location and quat rot of selected pose bones.

import bpy
from collections import defaultdict

context = bpy.context

ob = context.object
action = ob.animation_data.action

to_bake = ("location",
           "rotation_quaternion",
           )

fcurves = defaultdict(list)

for fc in action.fcurves:
    fcurves[fc.data_path].append(fc)

for pb in context.selected_pose_bones:
    path = pb.path_from_id()
    for sfx in to_bake:
        fcs = fcurves[f"{path}.{sfx}"]
        for fc in fcs:
            print("Bake", fc.data_path, "xyzw"[fc.array_index]) 
            fc.convert_to_samples(*action.frame_range)
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • 1
    this is exactly what I needed thanks a lot! I was using bpy.ops.nla.bake() command to bake previously. Aside from it being restrictive, I don't like using these "context specific" commands in my script. Being able to bake each fcurve separately as needed and not having to rely on the correct context is really nice! –  Mar 29 '20 at 19:04
  • 1
    Cheers, added pose bone selection. – batFINGER Mar 29 '20 at 19:13
  • Awesome, thanks for the addition! Can I ask, converting to samples works nicely, but the baked keyframes do not seem to get visualised in the dopesheet, like they do with default baking. In graph editor I can see the curve but I can't seem to be able to tweak it. –  Mar 29 '20 at 19:30
  • 1
    Same result as bake audio to fcurve. AFAIK Have to convert back to keyframes to tweak. – batFINGER Mar 29 '20 at 19:32
  • Baking curves this way unfortunately doesn't seem to bake the bone constraint transformations as well. I guess I'll have to use bpy.ops.nla.bake() if I want that. –  Mar 29 '20 at 20:44
  • Can bake bone constraints and drivers too. This is baking existing fcurve, whereas I imagine you need iterate over frames, get the visual transforms make an fcurve and bake it, remove or disable constraints / drivers. Will add to answer later when not so sleepy, sleepy. – batFINGER Mar 29 '20 at 21:03
  • I understand thanks in advance! I assume this is also how nla baker works under the hood. I guess doing it this way is still preferable to using nla baker since it allows much more freedom. Definitely curious about how to construct new curves with script. Also sorry for keeping you up lol! –  Mar 29 '20 at 21:14
  • Solved here https://blender.stackexchange.com/questions/172919/bake-an-fcurve-with-visual-transforms –  Apr 13 '20 at 06:15