Getting specific bone f-curves

action = bpy.data.actions[‘ArmatureAction.001’]

print (action.groups[0].channels[0])
for (i, j) in enumerate(robo.pose.bones):
    print ('%s :: %s' % (i,j.name))
 
fcus = {}
for g in action.groups:
    print ('---

Group: %s’ % repr(g))
for fcu in g.channels:
print (‘Channel: %s’ % repr(fcu))

if fcu.data_path == ‘rotation_euler’:

        fcus[fcu.array_index] = fcu
print ('---

Available Fcurves:’)
print (len(fcus))Hi,

Searched through the API docs and through the forum, but couldn’t quite find a successful answer.

I’m trying to access an armature’s f-curves in order to retrieve some values to use elsewhere. To get the f-curves for a normal object, it is quite straight-forward:

    ob = bpy.data.objects['Cube']    action = ob.animation_data.action
 
    fcus = {}
    for fcu in action.fcurves:
        if fcu.data_path == 'location':
            fcus[fcu.array_index] = fcu


    d = fcus[1].evaluate(frame)

This works fine, retrieving the relevant action + f-curves through the object animation data.

When I try the same with an armature, animation_data comes up as a null object, even though it has a keyframed action assigned to it. Hacking in the action through bpy.data.actions gets me to the groups of f-curves, but then there’s no sure way of retrieving specific f-curves for specific bones (it all seems to be thrown together in one heap).

    action = bpy.data.actions['ArmatureAction']
     
    fcus = {}
    for g in action.groups:
        print ('---
Group: %s' % repr(g))
        for fcu in g.channels:
            print ('Channel: %s' % repr(fcu))            
            fcus[fcu.array_index] = fcu
    print ('---
Available Fcurves:')
    print (repr(fcus))

Any help would be very much appreciated…

animation_data.action works just fine for Armatures:

>>> bpy.context.object.animation_data.action
bpy.data.actions[‘ArmatureAction’]

Are you sure you are using the Armature OBJECT and not the Armature? (ob vs. ob.data)

for fcurve in action.fcurves:
    if fcurve.data_path.startswith("pose.bones"):
        try:
            tmp = fcurve.data_path.split("[", maxsplit=1)[1].split("]", maxsplit=1)
            bone_name = tmp[0][1:-1]
            keyframe_type = tmp[1][1:]
            print("Animated pose bone:", bone_name, "(%s, index %i)" % (keyframe_type, fcurve.array_index))
        except IndexError:
            continue

This is great! Thank you very much. I found the animation_data.action in the armature object afterwards, but this clears up how you identify which channel is which (x or y, for example). Cheers!