I need to be able to tell if a bone property has a keyframe on the current frame. I.e. the property box is yellow and not green.

I know you can evaluate an fcurve but how do you tell if it's a keyframe? Is there an easy way to do this?


There is no easy way, but you could extend the Object type by a method:

import bpy

def is_keyframe(ob, frame, data_path, array_index=-1):
    if ob is not None and ob.animation_data is not None and ob.animation_data.action is not None:
        for fcu in ob.animation_data.action.fcurves:
            if fcu.data_path == data_path:
                if array_index == -1 or fcu.array_index == array_index:
                    return frame in (p.co.x for p in fcu.keyframe_points)
    return False

bpy.types.Object.is_keyframe = is_keyframe    

ob = bpy.context.object
pbone = bpy.context.active_pose_bone

# True or False 
ob.is_keyframe(20, pbone.path_from_id("location"), array_index=2)

frame can be int or float, 20 will match a co.x of 20.0, but not a subframe like 20.1. If you want to check for full frames, use round(p.co.x) in the is_keyframe() function.

Talked to ideasman_42, and he may check on adding a native method to retrieve F-Curve and Keyframe objects more easily.

| improve this answer | |
  • $\begingroup$ Thank you, this looks awesome. I will try and finish my addon before asking for additions to the API. Its a proof of concept for a new workflow, so it can be messy under the hood for now. $\endgroup$ – MCHammond Apr 22 '14 at 10:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.