MetaBox/Scripts/Animation/aTools/animTools/animBar/subUIs/keyTransform.py

1494 lines
70 KiB
Python
Raw Permalink Normal View History

2025-01-14 03:08:55 +08:00
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
Modified: Michael Klimenko
Requirements: aTools Package
------------------------------------------------------------------------------------------------------------------------
To install aTools, please follow the instructions in the file how_to_install.txt
------------------------------------------------------------------------------------------------------------------------
To unistall aTools, go to menu (the last button on the right), Uninstall
========================================================================================================================
'''
import importlib
from maya import cmds
from maya import mel
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import uiMod;
from aTools.commonMods import utilMod;
from aTools.commonMods import animMod;
from aTools.commonMods import commandsMod;
from aTools.commonMods import aToolsMod
from aTools.animTools.animBar.subUIs import tangents; importlib.reload(tangents)
from aTools.animTools.animBar.subUIs.specialTools_subUIs import mirror; importlib.reload(mirror)
Mirror = mirror.Mirror()
G.KT_pushClick = False
G.KT_sliderMode = None
class KeyTransform_Gui(uiMod.BaseSubUI):
def createLayout(self):
keyTransform = KeyTransform()
nudge = Nudge()
ts = KeyTransformSlider_Gui()
valueList = [0.01, 0.05, "", 0.10, 0.20, 0.50, "", 1.00, 1.50, 2.00, 3.00, 5.00, "", 10.00, 20.00]
cmds.rowLayout(numberOfColumns=22, parent=self.parentLayout)
# precision transform
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_-"), highlightImage= uiMod.getImagePath("keyTransform_- copy"), command=lambda *args: keyTransform.applyPrecise(keyTransform.getPrecisionValue()*-1), annotation="Decrease precise transform")
cmds.floatField ("precisionNumber", minValue=0.01, precision=2, step=.05, value=0.5, annotation="Set precise transform value\nRight click for pre-defined values")
cmds.popupMenu()
for loopValueList in valueList:
if loopValueList == "":
cmds.menuItem( divider=True )
else:
cmds.menuItem ("menu%s"%loopValueList, label=str(loopValueList), command=lambda loopValueList=loopValueList, *args: keyTransform.setPrecisionValue(loopValueList))
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_+"), highlightImage= uiMod.getImagePath("keyTransform_+ copy"), command=lambda *args: keyTransform.applyPrecise(keyTransform.getPrecisionValue()), annotation="Increase precise transform")
#reset
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_reset"), highlightImage= uiMod.getImagePath("keyTransform_reset copy"), command=keyTransform.resetValue, annotation="Reset value to default\nRight click for options")
cmds.popupMenu()
cmds.menuItem (label="Translate", command=lambda *args: keyTransform.resetValue(["Translate"]))
cmds.menuItem (label="Rotate", command=lambda *args: keyTransform.resetValue(["Rotate"]))
cmds.menuItem (label="Scale", command=lambda *args: keyTransform.resetValue(["Scale"]))
cmds.menuItem( divider=True )
cmds.menuItem (label="Translate, Rotate and Scale", command=lambda *args: keyTransform.resetValue(["Translate", "Rotate", "Scale"]))
#key
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_keykey"), highlightImage= uiMod.getImagePath("keyTransform_keykey copy"), command=keyTransform.shareEachOtherKeys, annotation="Share each other keys\nRight click for options")
cmds.popupMenu()
cmds.menuItem (label="All Keys", command=lambda *args: keyTransform.shareEachOtherKeys("all"))
#nudge
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_nudge_left"), highlightImage= uiMod.getImagePath("keyTransform_nudge_left copy"), command=lambda *args: nudge.nudgeKey(-1), annotation="Nudge key left\nRight click for options")
nudge.popupMenu("left")
cmds.floatField ("nudgeEnterField", minValue=1, precision=0, step=1, value=10, annotation="Set precise nudge value", visible=False, w=1)
cmds.popupMenu()
cmds.menuItem (label="Hide", command=lambda *args:nudge.toggleEnterField(False))
cmds.iconTextButton (style='iconAndTextVertical', w=self.wb, h=self.hb, image= uiMod.getImagePath("keyTransform_nudge_right"), highlightImage= uiMod.getImagePath("keyTransform_nudge_right copy"), command=lambda *args: nudge.nudgeKey(1), annotation="Nudge key right\nRight click for options")
nudge.popupMenu("right")
#slider
cmds.text( label=' ', h=1 )
ts.populateSlider()
cmds.text( label=' ', h=1 )
ts.setSliderMode(ts.getSliderMode()) # set the saved slider mode
ts.delWindows() # delete if open
# end createLayout
class KeyTransformSlider_Gui(object):
def __init__(self):
self.winName = "keyTransformSliderWin"
self.toolbarName = "keyTransformSliderToolbar"
self.allWin = [self.winName, self.toolbarName]
self.barOffset = 0
self.height = 60
self.defaultValues = {}
self.optimizedValues = {}
self.invertRules = None
self.maxSelObjs = 1
self.blendToFramelabelA = ' A '
self.blendToFramelabelB = ' B '
self.blendToFrameValuesA = []
self.blendToFrameValuesB = []
self.blendToFrameCurrentValueA = None
self.blendToFrameCurrentValueB = None
self.defaultMode = "blendToFrame"
self.defaultModifiers = {"shift" :"blendToNeighbors",
"ctrl" :"scaleFromNeighborLeft",
"alt" :"scaleFromNeighborRight",
"ctrlShift" :"blendToDefault",
"altShift" :"pullPush",
"altCtrl" :"easeInOut",
"altCtrlShift" :"blendToMirror"
}
self.modifiers = self.getModifiers()
self.modeDividers = [3, 7]
self.modesDict = [ {
"mode": "pullPush",
"icon": "pp",
"function": "setPushValues"
},{
"mode": "noise",
"icon": "no",
"function": "setNoiseValues"
},{
"mode": "easeInOut",
"icon": "ea",
"function": "setEaseInOut"
},{
"mode": "blendToDefault",
"icon": "bd",
"function": "setBlendScaleValues"
},{
"mode": "blendToNeighbors",
"icon": "bn",
"function": "setBlendScaleValues"
},{
"mode": "blendToMirror",
"icon": "bm",
"function": "setBlendScaleValues"
},{
"mode": "blendToFrame",
"icon": "bf",
"function": "setBlendScaleValues"
},{
"mode": "scaleFromDefault",
"icon": "sd",
"function": "setBlendScaleValues"
},{
"mode": "scaleFromAverage",
"icon": "sa",
"function": "setBlendScaleValues"
},{
"mode": "scaleFromNeighborLeft",
"icon": "sl",
"function": "setBlendScaleValues"
},{
"mode": "scaleFromNeighborRight",
"icon": "sr",
"function": "setBlendScaleValues"
}
]
def createWin(self):
self.mainWin = cmds.window(self.winName, sizeable=True)
self.buttonHeight = self.height -10
# Main frame
cmds.frameLayout("mainFrameLayout", labelVisible=False, w=10, borderVisible=False)
cmds.rowLayout(numberOfColumns=2, adjustableColumn=1, columnAttach=([2, 'right', self.barOffset]))
cmds.text(label="")
cmds.rowLayout("keyTransformSliderParentLayout", numberOfColumns=100)
self.populateButtons()
# shows toolbar
cmds.toolBar(self.toolbarName, area='bottom', content=self.mainWin, allowedArea=['bottom'], height=self.height)
def populateSlider(self, mode="default"):
keySliderW = 137 if mode=="default" else 111
imageW = 30
buttPerc = ((imageW/2)/(keySliderW/100.))
blendToFrameTxtA = None
blendToFrameAnn = "Left click: pick current frame\nRight click: pick from history or current objects keys"
labelA = self.blendToFramelabelA
labelB = self.blendToFramelabelB
if self.blendToFrameCurrentValueA: labelA = " %s"%self.blendToFrameCurrentValueA
if self.blendToFrameCurrentValueB: labelB = "%s "%self.blendToFrameCurrentValueB
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, h=32, w=keySliderW)
if mode == "default": textValue = cmds.text("keyTransformSliderText", label="100", visible=False)
else: textValue = cmds.text("keyTransformSliderText_%s"%mode, label="100", visible=False)
slider = cmds.floatSlider ('keyTransformSlider%s'%mode, w=keySliderW-1, min=0, max=2, value=1, dragCommand=lambda x, mode=mode, *args: self.applyKeyTransform('keyTransformSlider%s'%mode, mode), changeCommand=lambda x, mode=mode, *args: self.releaseKeyTransform('keyTransformSlider%s'%mode, mode))
if mode == "default":
modeButton = cmds.iconTextButton ("keyTransformSliderButton", style='iconAndTextVertical', w=imageW, h=16, annotation="Key Transform Slider Mode")
self.popUpModes()
blendToFrameTxtA = cmds.iconTextButton("keyTransformSliderBlendToFrameA", font="smallPlainLabelFont", style='iconAndTextCentered', w=45, label=labelA, align="left", command=lambda *args:self.blendToFrameSet('A'), ann=blendToFrameAnn); self.blendToFramePopUp('A')
blendToFrameTxtB = cmds.iconTextButton("keyTransformSliderBlendToFrameB", font="smallPlainLabelFont", style='iconAndTextCentered', w=45, label=labelB, align="right", command=lambda *args:self.blendToFrameSet('B'), ann=blendToFrameAnn); self.blendToFramePopUp('B')
else:
icon = self.getIcon(mode)
modeButton = cmds.iconTextButton("keyTransformSliderButton_%s"%mode, style='iconAndTextVertical', w=imageW, h=16, image= uiMod.getImagePath("keyTransform_%s"%icon), highlightImage= uiMod.getImagePath("keyTransform_%s copy"%icon), command=lambda mode=mode, *args:self.setSliderMode(mode), annotation="Set this mode in the main toolbar")
if mode == "blendToFrame":
blendToFrameTxtA = cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarA", font="smallPlainLabelFont", style='iconAndTextCentered', w=45, label=labelA, align="left", command=lambda *args:self.blendToFrameSet('A'), ann=blendToFrameAnn); self.blendToFramePopUp('A')
blendToFrameTxtB = cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarB", font="smallPlainLabelFont", style='iconAndTextCentered', w=45, label=labelB, align="right", command=lambda *args:self.blendToFrameSet('B'), ann=blendToFrameAnn); self.blendToFramePopUp('B')
#pre set buttons
preSetDict = {"values":[1., .50, .15, .05], "buttonPositions":[0,10,20,30]}
topPos = 60 if mode == "default" else 35
for n, loopValue in enumerate(preSetDict["values"]):
value = loopValue
buttonPosition = preSetDict["buttonPositions"][n]
b = cmds.iconTextButton(style='iconAndTextVertical', w=13, h=13, command=lambda value=value, mode=mode, slider=slider, *args: self.tickKeyTransform(slider, mode, (1.+(value*-1))), ann=int(value*100), image= uiMod.getImagePath('keyTransform_dot_a'), highlightImage= uiMod.getImagePath('keyTransform_dot_a copy'))
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, edit=True, attachPosition=[(b, 'top', 0, topPos), (b, 'left', 0, buttonPosition)])
b = cmds.iconTextButton(style='iconAndTextVertical', w=13, h=13, command=lambda value=value, mode=mode, slider=slider, *args: self.tickKeyTransform(slider, mode, (1.+value)), ann=int(value*100), image= uiMod.getImagePath('keyTransform_dot_a'), highlightImage= uiMod.getImagePath('keyTransform_dot_a copy'))
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, edit=True, attachPosition=[(b, 'top', 0, topPos), (b, 'right', 0, 100-buttonPosition)])
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, edit=True,
attachPosition=[
(modeButton, 'left', 0, 50-buttPerc),
(modeButton, 'right', 0, 100-(50-buttPerc)),
(modeButton, 'top', -5, 0),
(textValue, 'left', 0, 50-buttPerc),
(textValue, 'right', 0, 100-(50-buttPerc)),
(textValue, 'top', 21, 0),
(slider, 'top', -4, 45)
])
# blend to frame
if blendToFrameTxtA:
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, edit=True,
attachPosition=[
(blendToFrameTxtA, 'left', 0, 0),
(blendToFrameTxtB, 'right', 0, 100),
(blendToFrameTxtA, 'top', 0, 0),
(blendToFrameTxtB, 'top', 0, 0)
])
#ALT SHIFT CTRL
if mode != "default":
label = utilMod.toTitle(mode).replace("Right", "R").replace("Left", "L")
t1 = cmds.text( label=label, align='center', font="smallPlainLabelFont")
modButton = cmds.iconTextButton("keyTransformSliderModButton_%s"%mode, style='textOnly', font="smallObliqueLabelFont", label=" ", align="center")
self.popUpModifiers(mode)
cmds.formLayout ("keyTransformSliderFormLayout%s"%mode, edit=True, h=65, attachPosition=[
(t1, 'left', 0, 0),
(t1, 'right', 0, 100),
(t1, 'bottom', 15, 100),
(modButton, 'left', 0, 0),
(modButton, 'right', 0, 100),
(modButton, 'bottom', -5, 100),
(slider, 'top', 0, 18)
])
cmds.setParent('..')
def populateButtons(self):
for n, loopMode in enumerate(self.modesDict):
mode = loopMode["mode"]
divider = n in self.modeDividers
if divider: cmds.image(image=uiMod.getImagePath("keyTransform_divider"))
cmds.text( label=' ', h=1 )
self.populateSlider(mode)
cmds.text( label=' ', h=1 )
self.refreshModifiersButtons()
cmds.iconTextButton(style='iconOnly', h=25, w=25, image=uiMod.getImagePath("keyTransform_x"), highlightImage=uiMod.getImagePath("keyTransform_x copy"), command=self.toggleAllModesToolbar, annotation="Hide toolbar")
def delWindows(self):
for loopWin in self.allWin:
if cmds.window(loopWin, query=True, exists=True): cmds.deleteUI(loopWin)
if cmds.toolBar(loopWin, query=True, exists=True): cmds.deleteUI(loopWin)
def toggleAllModesToolbar(self, *args):
if cmds.toolBar(self.toolbarName, query=True, exists=True):
self.delWindows()
else:
self.createWin()
#=================================
def setBlendToFrameTxtVisible(self, mode, mod=False):
visible = (mode == "blendToFrame" and not mod)
cmds.iconTextButton("keyTransformSliderBlendToFrameA", edit=True, visible=visible)
cmds.iconTextButton("keyTransformSliderBlendToFrameB", edit=True, visible=visible)
def blendToFrameSet(self, aB, frame=None):
if not frame:
frame = int(cmds.currentTime(query=True))
exec("if %s not in self.blendToFrameValues%s: self.blendToFrameValues%s.append(%s)"%(frame, aB, aB, frame))
exec("self.blendToFrameCurrentValue%s = %s"%(aB, frame))
cmds.iconTextButton("keyTransformSliderBlendToFrame%s"%aB, edit=True, label=frame)
if cmds.iconTextButton("keyTransformSliderBlendToFrameToolbar%s"%aB, query=True, exists=True):
cmds.iconTextButton("keyTransformSliderBlendToFrameToolbar%s"%aB, edit=True, label=frame)
def blendToFrameClearHistory(self, *args):
self.blendToFrameValuesA = []
self.blendToFrameValuesB = []
self.blendToFrameCurrentValueA = None
self.blendToFrameCurrentValueB = None
labelA = self.blendToFramelabelA
labelB = self.blendToFramelabelB
cmds.iconTextButton("keyTransformSliderBlendToFrameA", edit=True, label=labelA)
if cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarA", query=True, exists=True):
cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarA", edit=True, label=labelA)
cmds.iconTextButton("keyTransformSliderBlendToFrameB", edit=True, label=labelB)
if cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarB", query=True, exists=True):
cmds.iconTextButton("keyTransformSliderBlendToFrameToolbarB", edit=True, label=labelB)
def blendToFramePopUp(self, aB):
menu = cmds.popupMenu()
cmds.popupMenu(menu, edit=True, postMenuCommand=lambda *args:self.populateBlendToFrameHistory(menu, aB))
def populateBlendToFrameHistory(self, menu, aB, *args):
uiMod.clearMenuItems(menu)
items = sorted(list(set(self.blendToFrameValuesA + self.blendToFrameValuesB)))
for loopItem in items:
cmds.menuItem(label=loopItem, command=lambda x, aB=aB, loopItem=loopItem, *args: self.blendToFrameSet(aB, loopItem), parent=menu)
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
keyTimes = sorted(utilMod.mergeLists(keyTimes))
if len(keyTimes) > 0:
cmds.menuItem(divider=True, parent=menu)
subMenu = cmds.menuItem(label="Select Key", subMenu=True, command=self.blendToFrameClearHistory, parent=menu)
divider = None
currFrame = cmds.currentTime(query=True)
for loopItem in keyTimes:
loopItem = int(loopItem)
if not divider:
if loopItem == currFrame: cmds.menuItem(divider=True, parent=subMenu)
elif loopItem > currFrame: divider = cmds.menuItem(divider=True, parent=subMenu)
cmds.menuItem(label=loopItem, command=lambda x, aB=aB, loopItem=loopItem, *args: self.blendToFrameSet(aB, loopItem), parent=subMenu)
if len(items) > 0:
cmds.menuItem(divider=True, parent=menu)
cmds.menuItem(label="Clear History", command=self.blendToFrameClearHistory, parent=menu)
#===================================================================
def getIcon(self, mode):
for loopMode in self.modesDict:
if mode == loopMode["mode"]:
return loopMode["icon"]
def popUpModes(self):
cmds.popupMenu(postMenuCommand=self.populateModes, button=1)
cmds.popupMenu(postMenuCommand=self.populateModes, button=3)
def populateModes(self, menu, *args):
uiMod.clearMenuItems(menu)
cmds.radioMenuItemCollection(parent=menu)
sliderMode = self.getSliderMode()
for n, loopMode in enumerate(self.modesDict):
mode = loopMode["mode"]
label = utilMod.toTitle(mode)
icon = loopMode["icon"]
radioSelected = (sliderMode == mode)
divider = n in self.modeDividers
if divider: cmds.menuItem(divider=True, parent=menu)
cmds.menuItem(label=label, radioButton=radioSelected, command=lambda x, mode=mode, *args: self.setSliderMode(mode), parent=menu)
cmds.menuItem(divider=True, parent=menu)
cmds.menuItem(label="Toggle All Modes Toolbar", command=self.toggleAllModesToolbar, parent=menu)
def popUpModifiers(self, mode):
menu = cmds.popupMenu(button=1)
cmds.popupMenu(menu, edit=True, postMenuCommand=lambda menu=menu, *args:self.populateModifiers(menu, mode))
menu = cmds.popupMenu(button=3)
cmds.popupMenu(menu, edit=True, postMenuCommand=lambda menu=menu, *args:self.populateModifiers(menu, mode))
def populateModifiers(self, menu, mode, *args):
uiMod.clearMenuItems(menu)
cmds.radioMenuItemCollection(parent=menu)
mod = ""
radioSelected = (self.getModeModifier(mode) == mod)
cmds.menuItem(label="None", radioButton=radioSelected, command=lambda x, mode=mode, mod=mod, *args: self.setModifier(mode, mod), parent=menu)
for loopKey in list(self.defaultModifiers.keys()):
mod = loopKey
label = utilMod.toTitle(mod).replace(" ", "+")
radioSelected = (self.getModeModifier(mode) == mod)
cmds.menuItem(label=label, radioButton=radioSelected, command=lambda x, mode=mode, mod=mod, *args: self.setModifier(mode, mod), parent=menu)
cmds.menuItem(divider=True, parent=menu)
cmds.menuItem(label="Load Defaults", command=self.loadDefaultModifiers, parent=menu)
def getSliderMode(self, *args):
if not G.KT_sliderMode:
G.KT_sliderMode = aToolsMod.loadInfoWithUser("userPrefs", "sliderMode")
if not G.KT_sliderMode:
G.KT_sliderMode = self.defaultMode
return G.KT_sliderMode
def setModifier(self, mode, mod):
for loopKey in list(self.defaultModifiers.keys()):
if self.modifiers[loopKey] == mode:
self.modifiers[loopKey] = ""
self.modifiers[mod] = mode
aToolsMod.saveInfoWithUser("userPrefs", "sliderModifiers", self.modifiers)
self.refreshModifiersButtons()
def loadDefaultModifiers(self, *args):
for loopMod in list(self.defaultModifiers.keys()):
mode = self.defaultModifiers[loopMod]
mod = loopMod
self.setModifier(mode, mod)
def refreshModifiersButtons(self):
for loopMode in self.modesDict:
mode = loopMode["mode"]
label = "(%s)"%utilMod.toTitle(self.getModeModifier(mode)).replace(" ", "+") if self.getModeModifier(mode) else "..."
cmds.iconTextButton("keyTransformSliderModButton_%s"%mode, edit=True, label=label)
self.setModifiersAnn()
def getModifiers(self):
modifiers = aToolsMod.loadInfoWithUser("userPrefs", "sliderModifiers")
if not modifiers: modifiers = self.defaultModifiers
return modifiers
def getModeModifier(self, mode, *args):
for loopKey in list(self.defaultModifiers.keys()):
if self.modifiers[loopKey] == mode:
return loopKey
return ""
def setModifiersAnn(self):
ann = ""
for loopKey in list(self.defaultModifiers.keys()):
loopMode = self.modifiers[loopKey]
if loopMode != "": ann += "%s: %s\n"%(utilMod.toTitle(loopKey).replace(" ", "+"), utilMod.toTitle(loopMode))
sliderAnnotation = "%s\n\n%s\nRight click for options"%(utilMod.toTitle(G.KT_sliderMode), ann)
cmds.iconTextButton ("keyTransformSliderButton", edit=True, ann=sliderAnnotation)
def getIndex(self, mode):
for n, loopMode in enumerate(self.modesDict):
if mode in loopMode["mode"]:
return n
def setSliderMode(self, mode, *args):
index = self.getIndex(mode)
if not index:
index = 0
mode = self.modesDict[index]["mode"]
label = utilMod.toTitle(mode)
icon = self.modesDict[index]["icon"]
G.KT_sliderMode = mode
cmds.iconTextButton ("keyTransformSliderButton", edit=True, image= uiMod.getImagePath("keyTransform_%s"%icon), highlightImage= uiMod.getImagePath("keyTransform_%s copy"%icon))
self.setBlendToFrameTxtVisible(mode)
self.setModifiersAnn()
aToolsMod.saveInfoWithUser("userPrefs", "sliderMode", mode)
def getKeyTransformValue(self, slider):
value = cmds.floatSlider(slider, query=True, value=True)
rValue = 1+((value-1)*abs(value-1))
return rValue
def tickKeyTransform(self, slider, mode, tValue, *args):
self.applyKeyTransform(slider, mode, tValue, unselectObjects=False)
#G.KT_pushClick = False
self.releaseKeyTransform(slider, mode)
def delayIcon(self, mode):
if mode == "default":
index = self.getIndex(G.KT_sliderMode)
icon = self.modesDict[index]["icon"]
cmds.text ("keyTransformSliderText", edit=True, visible=False)
cmds.iconTextButton ("keyTransformSliderButton", edit=True, image= uiMod.getImagePath("keyTransform_%s"%icon), highlightImage= uiMod.getImagePath("keyTransform_%s copy"%icon))
self.setBlendToFrameTxtVisible(G.KT_sliderMode, False)
else:
index = self.getIndex(mode)
icon = self.modesDict[index]["icon"]
cmds.text ("keyTransformSliderText_%s"%mode, edit=True, visible=False)
cmds.iconTextButton ("keyTransformSliderButton_%s"%mode, edit=True, image= uiMod.getImagePath("keyTransform_%s"%icon))
def releaseKeyTransform(self, slider, mode, *args):
function = lambda *args:self.releaseKeyTransformDef(slider, mode)
G.deferredManager.sendToQueue(function, 1, "KT_release")
def releaseKeyTransformDef(self, slider, mode, *args):
cmds.floatSlider(slider, edit=True, value=1)
mel.eval("toggleAutoLoad graphEditor1OutlineEd true;")
G.aToolsBar.timeoutInterval.setTimeout((lambda mode=mode, *args: self.delayIcon(mode)), .5)
cmds.undoInfo(stateWithoutFlush=False)
#round flat numbers
if G.KT_flatKeys:
tValue = int(G.KT_lastTValue)
G.KT_function(G.KT_gMode, G.KT_animCurves, G.KT_indexes, G.KT_keyValues, G.KT_keyTimes, G.KT_keysSel, G.KT_keyTangentsY, G.KT_keyTangentsX, tValue, G.KT_pushClick)
#reset stored values
self.optimizedValues = {}
G.KT_pushClick = False
if len(self.selObjs) > 0:
cmds.select(self.selObjs)
#cmds.undoInfo(closeChunk=True)
cmds.undoInfo(stateWithoutFlush=True)
def applyKeyTransform(self, slider, mode, tValue=None, unselectObjects=True, *args):
tValue = tValue if tValue is not None else self.getKeyTransformValue(slider)
if G.KT_pushClick:
if tValue == 0 or tValue == 2: G.KT_lockZero = True
if G.KT_lockZero and (.97 < tValue < 1.03):
cmds.floatSlider(slider, edit=True, value=1)
tValue = 1.0000001
showValue = abs(round((tValue-1.)*100., 2))
if showValue >= 1 or showValue == 0: showValue = int(round(showValue))
if mode == "default": cmds.text ("keyTransformSliderText", edit=True, label=showValue)
else: cmds.text ("keyTransformSliderText_%s"%mode, edit=True, label=showValue)
if not G.KT_pushClick: #first time
mel.eval("toggleAutoLoad graphEditor1OutlineEd false;")
G.KT_pushClickDef = False
G.KT_lockZero = False
G.KT_openChunk = True
if mode == "default": cmds.text ("keyTransformSliderText", edit=True, visible=True)
else: cmds.text ("keyTransformSliderText_%s"%mode, edit=True, visible=True)
mod = uiMod.getModKeyPressed()
if mode == "default":
mode = self.getSliderMode()
if mod:
allModifiers = self.getModifiers()
modeMod = allModifiers[mod]
if modeMod != "":
mode = modeMod
index = self.getIndex(mode)
icon = self.modesDict[index]["icon"]
cmds.iconTextButton ("keyTransformSliderButton", edit=True, image=uiMod.getImagePath("keyTransform_%s"%icon))
self.setBlendToFrameTxtVisible(mode, mod)
G.KT_gMode = mode
index = self.getIndex(mode)
function = self.modesDict[index]["function"]
G.KT_function = eval("self.%s"%function)
G.KT_animCurves = G.KT_indexes = G.KT_keyValues = G.KT_keyTimes = G.KT_keysSel = G.KT_keyTangentsY = G.KT_keyTangentsX = None
cmds.undoInfo(openChunk=True)
getCurves = animMod.getAnimCurves()
G.KT_animCurves = getCurves[0]
getFrom = getCurves[1]
self.selObjs = []
G.KT_keysSel = animMod.getTarget("keysSel", G.KT_animCurves, getFrom)
if G.KT_animCurves:
#create key
if utilMod.mergeLists(G.KT_keysSel) == []:
commandsMod.setSmartKey(animCurves=G.KT_animCurves)
G.KT_keysSel = animMod.getTarget("keysSel", G.KT_animCurves, getFrom)
G.KT_keyTimes = animMod.getTarget("keyTimes", G.KT_animCurves)
G.KT_keyValues = animMod.getTarget("keyValues", G.KT_animCurves)
lists = ["G.KT_animCurves", "G.KT_indexes", "G.KT_keyValues", "G.KT_keyTimes", "G.KT_keysSel"]
if function not in ["setBlendScaleValues", "setEaseInOut"] :
G.KT_keyTangentsY = animMod.getTarget("keyTangentsY", G.KT_animCurves)
G.KT_keyTangentsX = animMod.getTarget("keyTangentsX", G.KT_animCurves)
lists.extend(["G.KT_keyTangentsY", "G.KT_keyTangentsX"])
#unselect if multiple objects (faster)
if getFrom == "timeline":
self.selObjs = cmds.ls(selection=True)
if len(self.selObjs) > self.maxSelObjs and unselectObjects:
cmds.select(self.selObjs[-1])
else:
self.selObjs = []
# add tail and head keys for values and times
for n, loopCurve in enumerate(G.KT_animCurves):
if len(G.KT_keyTimes[n]) == 1:
inOffsetTime = 1
inOffsetVal = 0
outOffsetTime = 1
outOffsetVal = 0
else:
inOffsetTime = (G.KT_keyTimes[n][1]-G.KT_keyTimes[n][0])
inOffsetVal = (G.KT_keyValues[n][1]-G.KT_keyValues[n][0])
outOffsetTime = (G.KT_keyTimes[n][-1]-G.KT_keyTimes[n][-2])
outOffsetVal = (G.KT_keyValues[n][-1]-G.KT_keyValues[n][-2])
#head keys
G.KT_keyValues[n].insert(0, G.KT_keyValues[n][0]-inOffsetVal)
G.KT_keyTimes[n].insert(0, G.KT_keyTimes[n][0]-inOffsetTime)
G.KT_keyValues[n].insert(0, G.KT_keyValues[n][0]-inOffsetVal)
G.KT_keyTimes[n].insert(0, G.KT_keyTimes[n][0]-inOffsetTime)
#tail keys
G.KT_keyValues[n].append(G.KT_keyValues[n][-1]+outOffsetVal)
G.KT_keyTimes[n].append(G.KT_keyTimes[n][-1]+outOffsetTime)
G.KT_keyValues[n].append(G.KT_keyValues[n][-1]+outOffsetVal)
G.KT_keyTimes[n].append(G.KT_keyTimes[n][-1]+outOffsetTime)
G.KT_indexes = []
keysSelTmp = list(G.KT_keysSel)
for i, loopCurves in enumerate(G.KT_animCurves):
G.KT_indexes.append([])
firstTime = True
keysSelTmp[i] = list(G.KT_keysSel[i])
for n, loopkeyTimes in enumerate(G.KT_keyTimes[i]):
for loopKeySel in keysSelTmp[i]:
if keysSelTmp[i][0] == loopkeyTimes:
if firstTime:
G.KT_indexes[i].append([])
firstTime = False
G.KT_indexes[i][-1].append(n)
keysSelTmp[i].pop(0)
break
else:
firstTime = True
#add head and tail for G.KT_indexes
for i, loopA in enumerate(G.KT_indexes):#each curve
for ii, loopB in enumerate(loopA):#each segment
G.KT_indexes[i][ii].insert(0, ((G.KT_indexes[i][ii][0])-1))
G.KT_indexes[i][ii].append((G.KT_indexes[i][ii][-1])+1)
#===OPTIMIZATION=====
#optimize filter keys sel
"""
if not mode in ["blendToDefault", "scaleFromDefault", "blendToMirror", "blendToFrame"]:
for n, loopCurve in enumerate(G.KT_animCurves):
for s, segment in enumerate(G.KT_indexes[n]):
fi = G.KT_indexes[n][s][0]
li = G.KT_indexes[n][s][-1]
ti = li - fi
fv = G.KT_keyValues[n][fi]
lv = G.KT_keyValues[n][li]
for x in range(ti-2, -1, -1):
v = G.KT_keyValues[n][fi+x+1]
if v == fv == lv:
del G.KT_keysSel[n][x]
#delete empty G.KT_animCurves based on G.KT_keysSel
indexToDelete = []
keysSelTmp = list(G.KT_keysSel)
for n, loopKeysSel in enumerate(keysSelTmp):
if len(loopKeysSel) == 0: indexToDelete.append(n)
for loopList in lists:
for loopIndex in sorted(indexToDelete, reverse=True):
exec("del %s[%s]"%(loopList, loopIndex))
#===============================
"""
if G.KT_animCurves:
G.KT_pushClick = True
function = lambda *args:self.defApply(G.KT_function, [G.KT_gMode, G.KT_animCurves, G.KT_indexes, G.KT_keyValues, G.KT_keyTimes, G.KT_keysSel, G.KT_keyTangentsY, G.KT_keyTangentsX, tValue, G.KT_pushClickDef])
G.deferredManager.removeFromQueue("KT")
G.deferredManager.sendToQueue(function, 1, "KT")
def defApply(self, function, args):
functionStr = "function("
for n, loopArg in enumerate(args):
functionStr += "args[%s]"%n
if n == len(args)-1: functionStr += ")"
else: functionStr += ", "
if not G.KT_openChunk: cmds.undoInfo(stateWithoutFlush=False)
exec(functionStr)
if G.KT_openChunk:
cmds.undoInfo(closeChunk=True)
#cmds.undoInfo(stateWithoutFlush=False)
G.KT_openChunk = False
else: cmds.undoInfo(stateWithoutFlush=True)
G.KT_pushClickDef = True
def setPushValues(self, mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, tValue, pushClick):
# set values
for n, loopCurve in enumerate(animCurves):
for s, segment in enumerate(indexes[n]):
fv = keyValues[n][indexes[n][s][0]]
lv = keyValues[n][indexes[n][s][-1]]
tv = lv - fv
ff = keyTimes[n][indexes[n][s][0]]
lf = keyTimes[n][indexes[n][s][-1]]
tf = lf - ff
# angle when the slider value is 0
angle = animMod.getAngle(ff, lf, fv, lv)
p = tValue
for i, loopKeySel in enumerate(indexes[n][s]):
if 1 <= i <= len(indexes[n][s])-2:
index = indexes[n][s][i]-2
#key
v = keyValues[n][index+2]
#optimization
#if fv == lv == v: continue
f = keyTimes[n][index+2]
a = ((tv/tf)*(f-ff))+fv
nv = ((v-a)*p)+a
#tangent
iy = keyTangentsY[n][(index)*2]
oy = keyTangentsY[n][((index)*2)+1]
ix = keyTangentsX[n][(index)*2]
ox = keyTangentsX[n][((index)*2)+1]
inTangentType = cmds.keyTangent(loopCurve, query=True, index=(index, index), inTangentType=True)[0]
outTangentType = cmds.keyTangent(loopCurve, query=True, index=(index, index), outTangentType=True)[0]
if inTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), inAngle=angle)
if outTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), outAngle=angle)
zeroY = cmds.keyTangent(loopCurve, query=True, index=(index, index), iy=True, oy=True)
ziy = zeroY[0]
zoy = zeroY[1]
zeroX = cmds.keyTangent(loopCurve, query=True, index=(index, index), ix=True, ox=True)
zix = zeroX[0]
zox = zeroX[1]
if p <= 1:
niy = ziy + (iy * p) - (ziy * p)
noy = zoy + (oy * p) - (zoy * p)
nix = zix + (ix * p) - (zix * p)
nox = zox + (ox * p) - (zox * p)
else:
niy = iy * p
noy = oy * p
nix = ix
nox = ox
# apply
cmds.keyframe(loopCurve, index=(index, index), valueChange=nv)
if inTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), iy=niy, ix=nix)
if outTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), oy=noy, ox=nox)
def setNoiseValues(self, mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, tValue, pushClick):
# set values
for n, loopCurve in enumerate(animCurves):
for s, segment in enumerate(indexes[n]):
p = tValue
if p <=1: p=.5+(p/2)
for i, loopKeySel in enumerate(indexes[n][s]):
if 1 <= i <= len(indexes[n][s])-2:
index = indexes[n][s][i]-2
if index < len(keyValues[n])-4:
fv = keyValues[n][index+1]
lv = keyValues[n][index+3]
tv = lv - fv
ff = keyTimes[n][index+1]
lf = keyTimes[n][index+3]
tf = lf - ff
#key
v = keyValues[n][index+2]
f = keyTimes[n][index+2]
a = ((tv/tf)*(f-ff))+fv
newv = ((v-a)*p)+a
#calculate previous and next key
pfv = keyValues[n][index-1]
plv = keyValues[n][index+2-1]
ptv = plv - pfv
pff = keyTimes[n][index-1]
plf = keyTimes[n][index+2-1]
ptf = plf - pff
#key
pv = keyValues[n][index+2-1]
pf = keyTimes[n][index+2-1]
pa = ((ptv/ptf)*(pf-pff))+pfv
pnv = ((pv-pa)*.5)+pa
nfv = keyValues[n][index+1]
nlv = keyValues[n][index+2+1]
ntv = nlv - nfv
nff = keyTimes[n][index+1]
nlf = keyTimes[n][index+2+1]
ntf = nlf - nff
#key
nv = keyValues[n][index+2+1]
nf = keyTimes[n][index+2+1]
na = ((ntv/ntf)*(nf-nff))+nfv
nnv = ((nv-na)*.5)+na
# angle when the slider value is 0
angle = animMod.getAngle(pf, nf, pnv, nnv)
#tangent
iy = keyTangentsY[n][(index)*2]
oy = keyTangentsY[n][((index)*2)+1]
ix = keyTangentsX[n][(index)*2]
ox = keyTangentsX[n][((index)*2)+1]
inTangentType = cmds.keyTangent(loopCurve, query=True, index=(index, index), inTangentType=True)[0]
outTangentType = cmds.keyTangent(loopCurve, query=True, index=(index, index), outTangentType=True)[0]
#if pushClick: cmds.undoInfo(stateWithoutFlushG.KT_pushClick if inTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), inAngle=angle)
if outTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), outAngle=angle)
#if pushClick: cmds.undoInfo(stateWithoutFlush=True)
zeroY = cmds.keyTangent(loopCurve, query=True, index=(index, index), iy=True, oy=True)
ziy = zeroY[0]
zoy = zeroY[1]
zeroX = cmds.keyTangent(loopCurve, query=True, index=(index, index), ix=True, ox=True)
zix = zeroX[0]
zox = zeroX[1]
if p <= 1:
niy = ziy + (iy * tValue) - (ziy * tValue)
noy = zoy + (oy * tValue) - (zoy * tValue)
nix = zix + (ix * tValue) - (zix * tValue)
nox = zox + (ox * tValue) - (zox * tValue)
else:
niy = iy * p
noy = oy * p
nix = ix
nox = ox
# apply
#if pushClick: cmds.undoInfo(stateWithoutFlush=False)
cmds.keyframe(loopCurve, index=(index, index), valueChange=newv)
if inTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), iy=niy, ix=nix)
if outTangentType == "fixed": cmds.keyTangent(loopCurve, index=(index, index), oy=noy, ox=nox)
def setBlendScaleValues(self, mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, tValue, pushClick):
# set values
if pushClick: # avoid losing the middle point value
if G.KT_lastTValue > 1 and tValue < 1:
self.setBlendScaleValues(mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, 1.0000001, pushClick)
elif G.KT_lastTValue < 1 and tValue > 1:
self.setBlendScaleValues(mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, 1, pushClick)
if mode == "default": mode = self.getSliderMode()
p = tValue*2-1
if mode == "blendToMirror":
mirrorCurves = animMod.getMirrorObjs(animCurves)
if not pushClick: self.invertRules = Mirror.getInvertRules()
if mode == "blendToFrame":
if tValue <=1:
if not self.blendToFrameCurrentValueA:
if tValue <=.97: cmds.warning("You need to select a frame first. Please go to some frame and hit the button A")
return
else:
if not self.blendToFrameCurrentValueB:
if tValue >=1.03: cmds.warning("You need to select a frame first. Please go to some frame and hit the button B")
return
if "blend" in mode:
if tValue <=1: p = tValue
else: p = 2-tValue
if p == 0 and not G.KT_flatKeys:
p = 0.0000001
G.KT_flatKeys = True
else:
G.KT_flatKeys = False
if pushClick: # second time on
if G.KT_lastValue == 0: G.KT_scaleValue = p
else: G.KT_scaleValue = 1/G.KT_lastValue*p
else: #just first time
G.KT_scaleValue = p
for n, loopCurve in enumerate(animCurves):
if mode == "blendToFrame":
if tValue <=1: f = self.blendToFrameCurrentValueA
else: f = self.blendToFrameCurrentValueB
if loopCurve not in self.optimizedValues: self.optimizedValues[loopCurve] = {}
if f not in self.optimizedValues[loopCurve]:
self.optimizedValues[loopCurve][f] = cmds.keyframe(loopCurve, query=True, eval=True, time=(f,f), valueChange=True)[0]
pivot = self.optimizedValues[loopCurve][f]
if mode == "blendToDefault":
if loopCurve not in self.defaultValues:
pivot = animMod.getDefaultValue(loopCurve)
self.defaultValues[loopCurve] = pivot
else:
pivot = self.defaultValues[loopCurve]
if mode == "blendToMirror":
mCurve = mirrorCurves[n]
isCenterCurve = (mCurve == None)
if isCenterCurve: mCurve = loopCurve
if not cmds.objExists(mCurve): continue
if not pushClick:
mirrorInvertValue = Mirror.mirrorInvert(loopCurve, isCenterCurve, self.invertRules)
if mode == "scaleFromDefault":
if loopCurve not in self.defaultValues:
pivot = animMod.getDefaultValue(loopCurve)
self.defaultValues[loopCurve] = pivot
else:
pivot = self.defaultValues[loopCurve]
for s, segment in enumerate(indexes[n]):
if mode == "blendToNeighbors":
fv = keyValues[n][indexes[n][s][0]]
lv = keyValues[n][indexes[n][s][-1]]
if mode == "scaleFromAverage":
segValues = []
for loopIndex in indexes[n][s]:
segValues.append(keyValues[n][loopIndex])
segValues.pop(0)
segValues.remove(segValues[-1])
maxV = max(segValues)
minV = min(segValues)
pivot = (maxV+minV)/2
if mode == "scaleFromNeighborLeft":
fv = keyValues[n][indexes[n][s][0]]
pivot = fv
if mode == "scaleFromNeighborRight":
lv = keyValues[n][indexes[n][s][-1]]
pivot = lv
for i, loopKeySel in enumerate(indexes[n][s]):
if 1 <= i <= len(indexes[n][s])-2:
index = indexes[n][s][i]-2
v = keyValues[n][index+2]
if mode == "blendToNeighbors":
if tValue <=1: pivot = fv
else: pivot = lv
if mode == "blendToMirror":
f = keyTimes[n][index+2]
if not pushClick:
if isCenterCurve: pivot = v * mirrorInvertValue
else: pivot = cmds.keyframe(mCurve, query=True, eval=True, time=(f,f), valueChange=True)[0] * mirrorInvertValue
if mCurve not in self.optimizedValues: self.optimizedValues[mCurve] = {}
self.optimizedValues[mCurve][f] = pivot
else:
pivot = self.optimizedValues[mCurve][f]
#optimization
#if v == pivot: continue
# apply===============================================
cmds.scaleKey(loopCurve, index=(index, index), valuePivot=pivot, valueScale=G.KT_scaleValue)
G.KT_lastValue = p
G.KT_lastTValue = tValue
def setEaseInOut(self, mode, animCurves, indexes, keyValues, keyTimes, keysSel, keyTangentsY, keyTangentsX, tValue, pushClick):
for n, loopCurve in enumerate(animCurves):
for s, segment in enumerate(indexes[n]):
fv = keyValues[n][indexes[n][s][0]]
lv = keyValues[n][indexes[n][s][-1]]
tv = lv - fv
ff = keyTimes[n][indexes[n][s][0]]
lf = keyTimes[n][indexes[n][s][-1]]
tf = lf - ff
strenght = (tValue-1)*100
for i, loopKeySel in enumerate(indexes[n][s]):
if 1 <= i <= len(indexes[n][s])-2:
index = indexes[n][s][i]-2
currTime = keyTimes[n][index+2] - ff
timePos = currTime/tf
maxStr = 10.
str = (abs(strenght)/100.)*(maxStr-1)+1
outValue = tv*(((abs(timePos-1))**str)*-1 + 1) + fv
inValue = tv*(timePos**str) + fv
if strenght > 0: value = outValue
else: value = inValue
# apply
#if pushClick: cmds.undoInfo(stateWithoutFlush=False)
cmds.keyframe(loopCurve ,edit=True, index=(index, index), valueChange=value)
#if pushClick: cmds.undoInfo(stateWithoutFlush=True)
#==========================================================================
class KeyTransform(object):
def __init__(self):
if G.aToolsBar.keyTransform: return
G.aToolsBar.keyTransform = self
def setPrecisionValue(self, n, *args):
cmds.floatField("precisionNumber", edit=True, value=n)
def getPrecisionValue(self, *args):
return cmds.floatField("precisionNumber", query=True, value=True)
def applyPrecise(self, tValue, *args):
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
keyTimes = animMod.getTarget("keyTimes", animCurves)
if animCurves:
for n, loopCurve in enumerate(animCurves):
if getFrom == "timeline":
time = [animMod.getTimelineTime()]
else:
time = [(loopTime,loopTime) for loopTime in keysSel[n]]
for loopTime in time:
cmds.setKeyframe(loopCurve, time=loopTime, insert=True)
value = cmds.keyframe(loopCurve, query=True, time=loopTime, valueChange=True)[0]
cmds.keyframe(loopCurve, edit=True, time=loopTime, valueChange=value+tValue)
def resetValue(self, trs=[], *args):
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
for n, loopCurve in enumerate(animCurves):
if trs != []:
apply = False
for loopTrs in trs:
if eval("animMod.isAnimCurve%s(loopCurve)"%loopTrs):
apply = True
break
if not apply: continue
time = [(loopTime,loopTime) for loopTime in keysSel[n]]
value = animMod.getDefaultValue(loopCurve)
if getFrom == "timeline" and len(time) ==0:
time = [animMod.getTimelineTime()]
for loopTime in time:
cmds.setKeyframe(loopCurve, time=loopTime, insert=False)
cmds.keyframe(loopCurve, edit=True, time=loopTime, valueChange=value)
tangType = cmds.keyTangent(loopCurve, query=True, time=loopTime, inTangentType=True, outTangentType=True)
if tangType[1] != "step":
cmds.keyTangent(loopCurve, time=loopTime, inTangentType="auto", outTangentType="auto")
else:
objects = animMod.getObjsSel()
if objects:
channelboxSelObjs = animMod.channelBoxSel()
if channelboxSelObjs:
for loopObjAttr in channelboxSelObjs:
value = animMod.getDefaultValue(loopObjAttr)
cmds.setAttr(loopObjAttr, value)
else:
allChannels = animMod.getAllChannels(objects)
for n, loopObj in enumerate(allChannels):
if not loopObj or len(loopObj) == 0: continue
for loopAttr in loopObj:
objAttr = "%s.%s"%(objects[n], loopAttr)
if not cmds.objExists(objAttr):continue
if not cmds.getAttr(objAttr, settable=True): continue
value = animMod.getDefaultValue(objAttr)
cmds.setAttr(objAttr, value)
def shareEachOtherKeys(self, keys="selected", *args):
cmds.waitCursor(state=True)
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if keys == "selected":
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
else:
keysSel = animMod.getTarget("keyTimes", animCurves, getFrom)
blendKeys = utilMod.mergeLists(keysSel)
animMod.createDummyKey(select=True)
getCurves = animMod.getAnimCurves(True)
animCurves = getCurves[0]
#key
for loopKey in blendKeys:
if animCurves:
time = (loopKey, loopKey)
cmds.setKeyframe(animCurves, time=time, insert=True)
animMod.deleteDummyKey()
cmds.waitCursor(state=False)
def inbetween(self, value, mode="add", *args):
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
keysIndexSel = animMod.getTarget("keysIndexSel", animCurves, getFrom)
keyIndexTimes = animMod.getTarget("keyIndexTimes", animCurves)
currentTime = cmds.currentTime(query=True)
if animCurves:
for n, loopCurve in enumerate(animCurves):
maxIndex = max([max(key) for key in keyIndexTimes])
if len(keysIndexSel[n]) == 0:#no keys selected
prevKey = cmds.findKeyframe(loopCurve, time=(currentTime, currentTime), which="previous")
prevIndex = cmds.keyframe(loopCurve, query=True, time=(prevKey, prevKey), indexValue=True)[0]
keysIndexSel[n].append(prevIndex)
tailIndex = keysIndexSel[n][-1]+1
if tailIndex <= maxIndex and len(keysIndexSel[n]) == 1: keysIndexSel[n].append(tailIndex)
keysIndexSel[n].remove(keysIndexSel[n][0])
for loopIndex in keysIndexSel[n]:
seqIndex = (loopIndex, maxIndex)
if mode=="add":
#check intersection
cmds.keyframe(loopCurve, option="over", relative=True, index=seqIndex, timeChange=value)
elif mode=="set":
index = (loopIndex-1, loopIndex-1)
curKey = cmds.keyframe(loopCurve, query=True, index=index, timeChange=True)[0]
nextKey = cmds.findKeyframe(loopCurve, time=(curKey,curKey), which="next")
setValue = value-(nextKey-curKey)
cmds.keyframe(loopCurve, option="over", relative=True, index=seqIndex, timeChange=setValue)
def inbetweenUI(self, *args):
windowName = "setInbetweenWin"
widthHeight = (90, 90)
if cmds.window(windowName, query=True, exists=True): cmds.deleteUI(windowName)
window = cmds.window(windowName, title="Set Inbetween", widthHeight=widthHeight)
cmds.gridLayout(numberOfColumns=3, cellWidthHeight=(30, 30))
for n in range(9):
num = n+1
cmds.button(label=str(num), command=lambda num=num, *args: self.inbetween(num, "set"))
cmds.showWindow(window)
cmds.window(window, edit=True, widthHeight=widthHeight)
class Nudge(object):
def __init__(self):
if G.aToolsBar.nudge: return
G.aToolsBar.nudge = self
self.applyToEverything = False
def popupMenu(self, leftRight):
cmds.popupMenu(postMenuCommand=lambda *args:self.populateMenu(leftRight, args))
def populateMenu(self, leftRight, *args):
menu = args[0][0]
uiMod.clearMenuItems(menu)
values = [2,4,10,20,50,100]
for loopValue in values:
if leftRight == "left": loopValue = loopValue*-1
cmds.menuItem (label=abs(loopValue), command=lambda x, loopValue=loopValue, *args: self.nudgeKey(loopValue), parent=menu)
cmds.menuItem (label="Custom", command=lambda *args: self.toggleEnterField(True), parent=menu)
cmds.menuItem(divider=True, parent=menu )
cmds.menuItem (label="Nudge Everything in the Scene", checkBox=self.applyToEverything, command=lambda *args: self.toggleEnterField(True, args), parent=menu)
def toggleEnterField(self, onOff=True, *args):
self.applyToEverything = False
if len(args) > 0:
onOff = args[0][0]
self.applyToEverything = onOff
if onOff:
cmds.floatField ("nudgeEnterField", edit=True, visible=True, w=50)
return
cmds.floatField ("nudgeEnterField", edit=True, visible=False, w=1)
def nudgeKey(self, value, *args):
if cmds.floatField ("nudgeEnterField", query=True, visible=True):
if abs(value) == 1: value = cmds.floatField ("nudgeEnterField", query=True, value=True) * value
if self.applyToEverything:
self.nudgeEverything(value)
return
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
keyExists = None
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
if animCurves:
if getFrom == "timeline":
range = animMod.getTimelineRange()
time = (range[0], range[1])
prevKey = cmds.findKeyframe(time=(range[0],range[0]), which="previous")
nextKey = cmds.findKeyframe(time=(range[1]-1,range[1]-1), which="next")
currentTime = cmds.currentTime(query=True)
# prevents first and last keys bug
if prevKey >= time[0]: prevKey -=2
if nextKey <= time[1]: nextKey +=2
#check if keySel has something
for loopArray in keysSel:
if len(loopArray) > 0:
keyExists = True
break
if keyExists:
if time[0]+value > prevKey and time[1]+value < nextKey:
cmds.keyframe(animCurves, option="over", relative=True, time=time, timeChange=value)
cmds.currentTime(currentTime+value)
else:
if value > 0:
time = (prevKey, prevKey)
value = currentTime
else:
time = (nextKey, nextKey)
value = currentTime
cmds.keyframe(animCurves, option="over", relative=False, time=time, timeChange=value)
else:
cmds.keyframe(animation="keys", option="over", relative=True, timeChange=value)
cmds.snapKey(animation="keys")
#--------
self.toggleEnterField(False)
def nudgeEverything(self, value):
cmds.waitCursor(state=True)
allCurvesinScene = cmds.ls(type=["animCurveTA","animCurveTL","animCurveTT","animCurveTU"])
cmds.keyframe(allCurvesinScene, option="over", relative=True, timeChange=value)
self.toggleEnterField(False)
cmds.waitCursor(state=False)