# -= ml_setKey.py =- # __ by Morgan Loomis # ____ ___ / / http://morganloomis.com # / __ `__ \/ / Revision 11 # / / / / / / / 2018-05-13 # /_/ /_/ /_/_/ _________ # /_________/ # # ______________ # - -/__ License __/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # Copyright 2018 Morgan Loomis # # Permission is hereby granted, free of charge, to any person obtaining a copy of # this software and associated documentation files (the "Software"), to deal in # the Software without restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the # Software, and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # ___________________ # - -/__ Installation __/- - - - - - - - - - - - - - - - - - - - - - - - - - # # Copy this file into your maya scripts directory, for example: # C:/Documents and Settings/user/My Documents/maya/scripts/ml_setKey.py # # Run the tool in a python shell or shelf button by importing the module, # and then calling the primary function: # # import ml_setKey # ml_setKey.ui() # # # __________________ # - -/__ Description __/- - - - - - - - - - - - - - - - - - - - - - - - - - - # # A more robust tool for setting keyframes in Maya, including setting keys on # selected channels, keyed channels, and several other options. # # ____________ # - -/__ Usage __/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # Run the tool, select the options, and press the Set Key button. Alternately, # set the options and press the "Create Hotkey" button to turn the current # functionality into a hotkey. # # _________ # - -/__ Ui __/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # [] Selected Channels : Only key channels that are selected in the Channel Box # [] Visible in Graph Editor : Only key curves visible in Graph Editor # [] Key Only Keyed Channels : Only set keys on channels that are already keyed # [] Delete Sub-Frames : Delete sub-frame keys surrounding the current frame # [] Insert Key : Insert key (preserve tangents) # [] Key Shapes : Set keyframes on shapes # [Set Key] : Set a keyframe. # # ___________________ # - -/__ Requirements __/- - - - - - - - - - - - - - - - - - - - - - - - - - # # This script requires the ml_utilities module, which can be downloaded here: # https://raw.githubusercontent.com/morganloomis/ml_tools/master/ml_utilities.py # # __________ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /_ Enjoy! _/- - - __author__ = 'Morgan Loomis' __license__ = 'MIT' __revision__ = 11 __category__ = 'animation' import maya.cmds as mc import maya.mel as mm from maya import OpenMaya try: import ml_utilities as utl utl.upToDateCheck(32) except ImportError: result = mc.confirmDialog( title='Module Not Found', message='This tool requires the ml_utilities module. Once downloaded you will need to restart Maya.', button=['Download Module','Cancel'], defaultButton='Cancel', cancelButton='Cancel', dismissString='Cancel' ) if result == 'Download Module': mc.showHelp('http://morganloomis.com/tool/ml_utilities/',absolute=True) hotkey = {'S':'setKey(deleteSubFrames=True, insert=True, selectedChannels=True, visibleInGraphEditor=True, keyKeyed=True, keyShapes=True)'} shelfButton = {'annotation': 'Open a UI to set keyframes with options.', 'command': 'import ml_setKey;ml_setKey.setKey(insert=True, deleteSubFrames=True, visibleInGraphEditor=True, keyShapes=False, selectedChannels=True, keyKeyed=True)', 'doubleClickCommand': 'import ml_setKey;ml_setKey.setKey(insert=True, deleteSubFrames=True, keyShapes=False, selectedChannels=True)', 'imageOverlayLabel': 'set', 'menuItem': [['Set Key UI', 'import ml_setKey;ml_setKey.ui()']], 'order': 5} def ui(): ''' User interface for ml_setKey ''' with utl.MlUi('ml_setKey', 'SetKey', width=400, height=220, info='''Press Set Key to set a keyframe with the current checkbox settings. Right click the button to create a hotkey or shelf button with the currently selected settings.''') as win: mc.checkBoxGrp('ml_setKey_chanBox_checkBox', label='Selected Channels', annotation='Only key channels that are selected in the Channel Box') mc.checkBoxGrp('ml_setKey_graphVis_checkBox', label='Visible in Graph Editor', annotation='Only key curves visible in Graph Editor') mc.checkBoxGrp('ml_setKey_keyKeyed_checkBox', label='Key Only Keyed Channels', annotation='Only set keys on channels that are already keyed') mc.checkBoxGrp('ml_setKey_subFrames_checkBox', label='Delete Sub-Frames', annotation='Delete sub-frame keys surrounding the current frame') mc.checkBoxGrp('ml_setKey_insert_checkBox', label='Insert Key', annotation='Insert key (preserve tangents)') mc.checkBoxGrp('ml_setKey_shapes_checkBox', label='Key Shapes', annotation='Set keyframes on shapes') win.ButtonWithPopup(label='Set Key', name=win.name, command=setKey, annotation='Set a keyframe.', readUI_toArgs={ 'selectedChannels':'ml_setKey_chanBox_checkBox', 'visibleInGraphEditor':'ml_setKey_graphVis_checkBox', 'keyKeyed':'ml_setKey_keyKeyed_checkBox', 'deleteSubFrames':'ml_setKey_subFrames_checkBox', 'insert':'ml_setKey_insert_checkBox', 'keyShapes':'ml_setKey_shapes_checkBox', }) def setKey(deleteSubFrames=False, insert=False, selectedChannels=False, visibleInGraphEditor=False, keyKeyed=False, keyShapes=False): ''' The main function arguments: deleteSubFrames: Delete sub-frame keys surrounding the current frame insert: Insert key (preserve tangents) selectedChannels: Only key channels that are selected in the Channel Box visibleInGraphEditor: Only key curves visible in Graph Editor keyKeyed: Only set keys on channels that are already keyed keyShapes: Set keyframes on shapes as well as transforms ''' keySel = utl.KeySelection() if selectedChannels and keySel.selectedChannels(): pass elif visibleInGraphEditor and keySel.visibleInGraphEditor(): pass elif keyKeyed and keySel.keyedChannels(includeShapes=keyShapes): pass else: keySel.selectedObjects() if not keySel.initialized: return #if the user has middle-mouse dragged, we don't want to insert #test this by comparing the current attribute value with the evaluated animation curve if keySel.curves and insert: #pretty sure curve and channel are linked properly, but this might be an issue. for curve, chan in zip(keySel.curves,keySel.channels): #chan = utl.getChannelFromAnimCurve(each) curveValue = mc.keyframe(curve, query=True, eval=True) if not curveValue: insert=False break if round(mc.getAttr(chan),3) != round(curveValue[0],3): insert=False break #set the actual keyframe keySel.setKeyframe(insert=insert, shape=keyShapes, deleteSubFrames=deleteSubFrames) if __name__ == '__main__': ui() # ______________________ # - -/__ Revision History __/- - - - - - - - - - - - - - - - - - - - - - - - # # Revision 4: 2012-03-11 : Added revision notes, updated to use ml_utilities, fixed a bug where tangents weren't being preserved, and fixed middle-mouse dragging. # # Revision 5: 2012-03-26 : Updated delete sub-frame option to work with other frame rates # # Revision 6: 2012-07-23 : Bug fixes. # # Revision 7: 2012-08-07 : Updating in parallel with ml_utilities to fix bug with keying keyed shapes. # # Revision 8: 2012-11-19 : updating to new KeySelection # # Revision 9: 2014-03-01 : adding category # # Revision 10: 2018-02-17 : Updating license to MIT. # # Revision 11: 2018-05-13 : shelf support