Thursday, February 21, 2013

clearFlats or SUPER DELETE STATIC CHANNELS

This script will look at the animation curves of all selected objects in your scene, and delete unnecessary keys. If the value of the previous and next key is the same as the current key, it will mark that key for  deletion. The result of is that it acts like Delete by Type > Static Channels, while also removing unnecessary keys on all your curves. Let me know if you find any bugs!

import maya.cmds as cmds

def clearFlats():
    '''
Clear keys that lie on flat sections of animation curves.
If no channels are selected, clear flats on all keyed channels.
'''
    
    nodes = cmds.ls(sl = True)
    
    cmds.undoInfo(openChunk = True) #Capture all changes in a single undo
    for node in nodes:
        #Make Sure we have channels to work on
        channels = cmds.channelBox('mainChannelBox',
                                   query = True,
                                   selectedMainAttributes = True)
        if not channels:
            keyable_attrs = cmds.listAttr(node, keyable = True)
            user_attrs = cmds.listAttr(node, userDefined = True)
            if user_attrs:
                keyable_attrs.extend(user_attrs)
            channels = [attr for attr in keyable_attrs
                        if cmds.keyframe('{0}.{1}'.format(node, attr),
                                                query = True,
                                                keyframeCount = True)]
        try:
            for channel in channels:
                keyValues = cmds.keyframe('{0}.{1}'.format(node, channel),
                                          q = True,
                                          valueChange = True)
                
                del_index = []
                if len(keyValues) == 1:
                    del_index.append((0,))
                else:
                    for i, keyValue in enumerate(keyValues):
                        if i == 0:
                            if keyValue == keyValues[i + 1]:
                                del_index.append((i,))
                        elif i == len(keyValues) - 1:
                            if keyValue == keyValues[i - 1]:
                                del_index.append((i,))
                        else:
                            if keyValues[i-1] == keyValues[i+1] == keyValue:
                                del_index.append((i,))
                if del_index:
                    cmds.cutKey(node,
                                attribute = channel,
                                index = del_index)
        except TypeError:
            pass
    cmds.undoInfo(closeChunk = True) #Close our undo chunk


if __name__ == '__main__':
    clearFlats()

3 comments:

  1. Hi. I'm a 3d animator. Thanks a lot for this. Works well and haven't found any bug yet. Again thank you so much for this.

    ReplyDelete
  2. Aaaaaaaaaaawsoooome! Thank youuuuuuuuu!!! (maya 2016)

    ReplyDelete