6
$\begingroup$

Select even/odd keyframes

I want to automate the process of selecting only even/odd keyframes from dopesheet/action editor using python, anyone here can help me?

I also want to delete it after selecting only even/odd keyframes. Thanks to anyone who would share the knowledge of blender python.

$\endgroup$
5
$\begingroup$

The following script is a bit rough, but it should do what you're looking for. It creates two new operators that work in the Dope Sheet, one for selecting even keys and one for selecting odd ones. It uses islice() from Python's itertools module... someone more well-versed in Python might have a different/better method to iterate through the keys.

It uses extended indexing syntax ("slice notation") on a dictionary view object of the keyframe_points property collection (*phew*).

Fair warning: this actually iterates through all of the actions in your .blend file. It shouldn't be too difficult to limit it to the actions in your scene or the actions of the selected object, but this should be enough to get you started.

To use the script, copy it into Blender's Text Editor and press Alt+P (with your mouse in the Text Editor). Then, from the Dope Sheet, you should be able to find the operators using Spacebar search.

import bpy

def main(context, even_odd='ODD'):
    for action in bpy.data.actions:
        for channel in action.fcurves:
            if channel.select == True:
                #First deselect all keys in the channel
                for key in channel.keyframe_points:
                    key.select_control_point = False
                    key.select_left_handle = False
                    key.select_right_handle = False
                if even_odd == 'ODD':
                    #Select only odd keys
                    for key in channel.keyframe_points.values()[1::2]:
                        key.select_control_point = True
                else:
                    #Select only even keys
                    for key in channel.keyframe_points.values()[::2]:
                        key.select_control_point = True


class ChannelSelectEvenKey(bpy.types.Operator):
    '''Select even keys for selected channels in the dopesheet'''
    bl_idname = "anim.channel_select_even"
    bl_label = "Select even keys"
    bl_description = "Select even keys for selected channels in the dopesheet"

    @classmethod
    def poll(cls, context):
        return context.area.type == 'DOPESHEET_EDITOR'

    def execute(self, context):
        main(context, 'EVEN')
        return {'FINISHED'}


class ChannelSelectOddKey(bpy.types.Operator):
    '''Select odd keys for selected channels in the dopesheet'''
    bl_idname = "anim.channel_select_odd"
    bl_label = "Select odd keys"
    bl_description = "Select odd keys for selected channels in the dopesheet"

    @classmethod
    def poll(cls, context):
        return context.area.type == 'DOPESHEET_EDITOR'

    def execute(self, context):
        main(context, 'ODD')
        return {'FINISHED'}


def register():
    bpy.utils.register_class(ChannelSelectEvenKey)
    bpy.utils.register_class(ChannelSelectOddKey)


def unregister():
    bpy.utils.unregister_class(ChannelSelectEvenKey)
    bpy.utils.register_class(ChannelSelectOddKey)


if __name__ == "__main__":
    register()
| improve this answer | |
$\endgroup$
  • 2
    $\begingroup$ Here's the pythonic (py3) variant: for point in channel.keyframe_points.values()[::2] $\endgroup$ – CodeManX Oct 10 '13 at 19: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.