4

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?

gandalf3
  • 157,169
  • 58
  • 601
  • 1,133
MCHammond
  • 451
  • 5
  • 16

1 Answers1

4

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    


# TEST
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.

CodeManX
  • 29,298
  • 3
  • 89
  • 128
  • 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. – MCHammond Apr 22 '14 at 10:22