This commit is contained in:
2025-04-17 04:52:48 +08:00
commit 9985b73dc1
3708 changed files with 2387532 additions and 0 deletions

View File

@ -0,0 +1,177 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
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
========================================================================================================================
'''
from maya import cmds
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import utilMod
from aTools.commonMods import animMod
class Align(object):
def __init__(self):
if G.aToolsBar.align: return
G.aToolsBar.align = self
def popupMenu(self):
cmds.popupMenu()
cmds.menuItem(label="All Keys", command=self.alignAllKeys)
cmds.menuItem( divider=True )
cmds.menuItem(label="Align Position", command=lambda *args: self.alignSelection(True, False))
cmds.menuItem(label="Align Rotation", command=lambda *args: self.alignSelection(False, True))
def alignAllKeys(self, *args):
self.alignSelection(translate=True, rotate=True, all=True)
def alignSelection(self, translate=True, rotate=True, all=False):
selection = cmds.ls(selection=True)
if len(selection) < 2:
cmds.warning("You need to select at least 2 objects.")
return
sourceObjs = selection[0:-1]
targetObj = selection[-1]
frames = None
currFrame = cmds.currentTime(query=True)
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
showProgress = all
if animCurves:
if all: keysSel = animMod.getTarget("keyTimes", animCurves, getFrom)
else: keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
frames = utilMod.mergeLists(keysSel)
if frames == []:
frames = [currFrame]
else:
frames = [currFrame]
self.align(sourceObjs, targetObj, frames, translate, rotate, showProgress, selectSorceObjs=True)
def align(self, sourceObjs, targetObj, frames=None, translate=True, rotate=True, showProgress=False, selectSorceObjs=False):
if not sourceObjs or not targetObj: return
cmds.refresh(suspend=True)
currFrame = cmds.currentTime(query=True)
constraints = []
setValues = []
modes = []
status = "aTools - Aligning nodes..."
if translate: modes.append({"mode":"translate", "constrain":"pointConstraint"})
if rotate: modes.append({"mode":"rotate", "constrain":"orientConstraint"})
if showProgress: utilMod.startProgressBar(status)
if not frames:
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
frames = utilMod.mergeLists(keysSel)
if frames == []:
frames = [currFrame]
else:
frames = [currFrame]
if showProgress:
totalSteps = len(sourceObjs + frames)
firstStep = 0
thisStep = 0
estimatedTime = None
startChrono = None
#get values
for thisStep, loopSourceObj in enumerate(sourceObjs):
if showProgress: startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
setValues.append({"modes":[], "values":[], "skips":[]})
for loopMode in modes:
mode = loopMode["mode"]
constrainType = loopMode["constrain"]
allAttrs = cmds.listAttr(loopSourceObj, settable=True, keyable=True)
skip = [loopXyz for loopXyz in ["x", "y", "z"] if "%s%s"%(mode, loopXyz.upper()) not in allAttrs]
contrainFn = eval("cmds.%s"%constrainType)
with G.aToolsBar.createAToolsNode: constraints.append(contrainFn(targetObj, loopSourceObj, skip=skip)[0])
setValues[-1]["modes"].append(mode)
setValues[-1]["values"].append([cmds.getAttr("%s.%s"%(loopSourceObj, mode), time=loopKey)[0] for loopKey in frames])
setValues[-1]["skips"].append(skip)
if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
#del constraints
for loopConstrain in constraints: cmds.delete(loopConstrain)
for n, loopKey in enumerate(frames):
if showProgress:
thisStep = thisStep + n + 1
startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
for nn, loopSourceObj in enumerate(sourceObjs):
loopSetValue = setValues[nn]
values = loopSetValue["values"]
skips = loopSetValue["skips"]
for nnn, loopMode in enumerate(modes):
mode = loopMode["mode"]
xyz = [loopXyz for loopXyz in ["x", "y", "z"] if loopXyz not in skips[nnn]]
for nnnn, loopXyz in enumerate(xyz):
attr = "%s%s"%(mode, loopXyz.upper())
value = values[nnn][n][nnnn]
if len(frames) > 1:
cmds.setKeyframe(loopSourceObj, attribute=attr, time=(loopKey,loopKey), value=value)
if currFrame == loopKey: cmds.setAttr("%s.%s"%(loopSourceObj, attr), value)
#euler filter
if n == len(frames)-1 and rotate:
animCurves = utilMod.mergeLists([cmds.keyframe(loopSourceObj, query=True, name=True) for loopSourceObj in sourceObjs])
animMod.eulerFilterCurve(animCurves)
if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
if showProgress: utilMod.setProgressBar(endProgress=True)
if selectSorceObjs: cmds.select(sourceObjs)
cmds.refresh(suspend=False)

View File

@ -0,0 +1,116 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
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
========================================================================================================================
'''
from maya import cmds
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 aToolsMod
class AnimationCopier(object):
def popupMenu(self):
cmds.popupMenu()
cmds.menuItem( label="Copy All Animation", command=lambda *args: self.copyAnimation(range="all"))
cmds.menuItem( divider=True )
cmds.menuItem("onlySelectedNodesMenu", label="Paste To Selected", checkBox=False)
cmds.menuItem( label="Paste Animation in Place", command=lambda *args: self.pasteAnimation(pasteInPlace=True))
cmds.menuItem( label="Paste Original Animation", command=lambda *args: self.pasteAnimation(pasteInPlace=False))
cmds.menuItem( divider=True )
cmds.menuItem( label="Paste To Another Character", command=self.remapNamespaces)
def copyAnimation(self, range="selected", *args):
cmds.waitCursor(state=True)
if range == "all":
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
animData = animMod.getAnimData(animCurves, showProgress=True)
else:
animData = animMod.getAnimData(showProgress=True)
aToolsMod.saveInfoWithUser("copyPasteAnim", "animData", animData)
if cmds.window("remapNamespacesWindow", query=True, exists=True): self.remapNamespaces()
cmds.waitCursor(state=False)
def pasteAnimation(self, animData=None, pasteInPlace=True, onlySelectedNodes=None, *args):
cmds.waitCursor(state=True)
if not onlySelectedNodes: onlySelectedNodes = cmds.menuItem("onlySelectedNodesMenu", query=True, checkBox=True)
if not animData: animData = aToolsMod.loadInfoWithUser("copyPasteAnim", "animData")
animMod.applyAnimData(animData, pasteInPlace, onlySelectedNodes, showProgress=True)
cmds.waitCursor(state=False)
def remapNamespaces(self, *args):
winName = "remapNamespacesWindow"
if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
window = cmds.window( winName, title = "Remap Namespaces")
cmds.columnLayout(adjustableColumn=True)
cmds.rowColumnLayout( numberOfColumns=3)
animData = aToolsMod.loadInfoWithUser("copyPasteAnim", "animData")
inputNameSpaces = list(set(utilMod.getNameSpace(animData["objects"])[0]))
outputNameSpaces = utilMod.listAllNamespaces()
for loopNameSpace in inputNameSpaces:
nameSpace = loopNameSpace[:-1]
eval("cmds.text('input%s', align='right', w=150, h=26, label='%s: ')"%(nameSpace, nameSpace))
eval("cmds.textField('output%s', w=150, h=26, text='%s')"%(nameSpace, nameSpace))
eval("cmds.button('output%s', w=26, h=26, label='...')"%(nameSpace))
if outputNameSpaces:
cmds.popupMenu(button=1)
for loopOutput in outputNameSpaces:
cmds.menuItem ("menu%s"%loopOutput, label=str(loopOutput), command=lambda x, loopOutput=loopOutput, nameSpace=nameSpace, *args: self.setOutputValue(loopOutput, nameSpace))
cmds.setParent( '..' )
cmds.button(label="Paste Animation in Place", command=lambda *args: self.remapAndPasteAnimation(animData, inputNameSpaces, pasteInPlace=True))
cmds.button(label="Paste Original Animation", command=lambda *args: self.remapAndPasteAnimation(animData, inputNameSpaces, pasteInPlace=False))
cmds.showWindow( window )
def setOutputValue(self, output, nameSpace):
cmds.textField('output%s'%nameSpace, edit=True, text=str(output))
def remapAndPasteAnimation(self, animData, nameSpaces, pasteInPlace):
separator = ":"
for loopNameSpace in nameSpaces:
nameSpace = loopNameSpace[:-1]
input = nameSpace
output = cmds.textField('output%s'%nameSpace, query=True, text=True)
animStr = str(animData)
animData = eval(animStr.replace("%s%s"%(input, separator), "%s%s"%(output, separator)))
self.pasteAnimation(animData, pasteInPlace)

View File

@ -0,0 +1,236 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
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
========================================================================================================================
'''
from maya import cmds
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import uiMod
from aTools.commonMods import utilMod
from aTools.commonMods import animMod
class FakeConstrain(object):
def __init__(self):
self.copyCache = []
self.locators = []
self.locatorGroup = ""
self.locatorGroupName = "fakeConstrain_group"
self.selection = None
def popupMenu(self):
cmds.popupMenu(postMenuCommand=self.populateMenu)
def populateMenu(self, menu, *args):
uiMod.clearMenuItems(menu)
if self.copyCache != []:
cmds.menuItem(label='Copy', command=self.copy, parent=menu)
cmds.menuItem(label='Paste to All Frames' , command=lambda *args: self.paste('allFrames'), parent=menu)
cmds.menuItem(divider=True, parent=menu)
cmds.menuItem(label='Copy Relative to World' , command=self.copyWorld, parent=menu)
def copyPaste(self):
if len(self.copyCache) > 0: self.paste()
else: self.copy()
def copy(self, *args):
#print "copy"
self.selection = cmds.ls(selection=True)
if len(self.selection) < 1:
cmds.warning("You need to select at least 2 objects.")
return
if len(self.selection) == 1:
self.copyWorld()
return
if len(self.selection) > 20:
message = "Too many objects selected, continue?"
confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
if confirm != 'Yes': return
cmds.refresh(suspend=True)
cmds.undoInfo(stateWithoutFlush=False)
self.flushCopyCache(force=True)
self.scriptJob()
self.sourceObjs = self.selection[0:-1]
self.targetObj = self.selection[-1]
selObjects = utilMod.getNameSpace(self.selection)[1]
self.locators = []
self.locatorGroup = animMod.group(name=self.locatorGroupName)
G.aToolsBar.align.align([self.locatorGroup], self.targetObj)
self.locators.append(self.locatorGroup)
for loopObj in self.sourceObjs:
nameSpace = utilMod.getNameSpace([loopObj])
loopSelName = "%s_%s"%(nameSpace[0][0], nameSpace[1][0])
locatorName = "fakeConstrain_%s"%loopSelName
locator = animMod.createNull(locatorName)
self.locators.append(locator)
with G.aToolsBar.createAToolsNode: cmds.parent(locator, self.locatorGroup)
G.aToolsBar.align.align([locator], loopObj)
matrix = cmds.xform(locator, query=True, matrix=True)
self.copyCache.append(matrix)
self.clearLocators()
cmds.select(self.selection)
cmds.iconTextButton("fakeConstrainBtn", edit=True, image= uiMod.getImagePath("specialTools_fake_constrain_active"), highlightImage= uiMod.getImagePath("specialTools_fake_constrain_active copy"))
cmds.refresh(suspend=False)
cmds.undoInfo(stateWithoutFlush=True)
def copyWorld(self, *args):
#print "copyworld"
self.selection = cmds.ls(selection=True)
if len(self.selection) < 1: return
if len(self.selection) > 20:
message = "Too many objects selected, continue?"
confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
if confirm != 'Yes': return
cmds.refresh(suspend=True)
cmds.undoInfo(stateWithoutFlush=False)
self.flushCopyCache(force=True)
self.scriptJob()
self.sourceObjs = self.selection
self.targetObj = "world"
for loopObj in self.sourceObjs:
matrix = cmds.xform(loopObj, query=True, ws=True, matrix=True)
self.copyCache.append(matrix)
cmds.iconTextButton("fakeConstrainBtn", edit=True, image= uiMod.getImagePath("specialTools_fake_constrain_active"), highlightImage= uiMod.getImagePath("specialTools_fake_constrain_active copy"))
cmds.refresh(suspend=False)
cmds.undoInfo(stateWithoutFlush=True)
def paste(self, type="onlyKeys"):
cmds.refresh(suspend=True)
selObjects = utilMod.getNameSpace(self.selection)[1]
self.locators = []
if self.targetObj != "world":
#CREATE
self.locatorGroup = animMod.group(name=self.locatorGroupName)
for n, loopObj in enumerate(self.sourceObjs):
nameSpace = utilMod.getNameSpace([loopObj])
loopSelName = "%s_%s"%(nameSpace[0][0], nameSpace[1][0])
locatorName = "fakeConstrain_%s"%loopSelName
locator = animMod.createNull(locatorName)
self.locators.append(locator)
with G.aToolsBar.createAToolsNode: cmds.parent(locator, self.locatorGroup)
self.locators.append(self.locatorGroup)
currFrame = cmds.currentTime(query=True)
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
keysSel = utilMod.mergeLists(keysSel)
if keysSel == []:
keysSel = [currFrame]
else:
keysSel = [currFrame]
frames = keysSel
if type == "allFrames":
frameRange = animMod.getTimelineRange(float=False)
frames = list(range(int(frameRange[0]),int(frameRange[1])))
if self.targetObj != "world":
G.aToolsBar.align.align([self.locatorGroup], self.targetObj, frames=frames)
for n, loopObj in enumerate(self.sourceObjs):
matrix = self.copyCache[n]
if self.targetObj != "world":
cmds.xform(self.locators[n], matrix=matrix)
G.aToolsBar.align.align([loopObj], self.locators[n], frames=frames, showProgress=True)
else:
for loopFrame in frames:
cmds.currentTime(loopFrame)
cmds.xform(loopObj, ws=True, matrix=matrix)
cmds.currentTime(currFrame)
for loopFrame in frames:
for loopAttr in ["translate", "rotate"]:
breakdown = (loopFrame not in keysSel)
cmds.keyframe(loopObj, edit=True, attribute=loopAttr, time=(loopFrame, loopFrame), breakdown=breakdown)
if self.targetObj != "world":
self.clearLocators()
cmds.select(self.selection)
cmds.refresh(suspend=False)
def clearLocators(self):
for loopLocator in self.locators:
if cmds.objExists(loopLocator): cmds.delete(loopLocator)
if cmds.objExists(self.locatorGroup): cmds.delete(self.locatorGroup)
def flushCopyCache(self, force=False):
if not force and cmds.ls(selection=True) == self.selection:
self.scriptJob()
return
cmds.iconTextButton("fakeConstrainBtn", edit=True, image= uiMod.getImagePath("specialTools_fake_constrain"), highlightImage= uiMod.getImagePath("specialTools_fake_constrain copy"))
self.clearLocators()
self.copyCache = []
def scriptJob(self):
#scriptjob
cmds.scriptJob(runOnce = True, killWithScene = True, event =('SelectionChanged', self.flushCopyCache))

View File

@ -0,0 +1,321 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
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 aToolsMod
import maya.OpenMaya as om
#============================================================================================================
class MicroTransform(object):
utilMod.killScriptJobs("G.microTransformScriptJobs")
def __init__(self):
G.deferredManager.removeFromQueue("MT_blinking")
if G.aToolsBar.microTransform: return
G.aToolsBar.microTransform = self
self.attributes = ['translate', 'translateX','translateY','translateZ','rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX','scaleY','scaleZ']
self.multiplierValues = [ {"name":"ultraSlow", "value":.05
},{"name":"superSlow", "value":.2
},{"name":"slow", "value":.5
},{"name":"medium", "value":1
}]
self.defaultMultiplier = "slow"
self.microTransformStartTimer = {}
self.microTransformValues = {}
self.onOff = False
self.rotationOrientMode = cmds.manipRotateContext('Rotate', query=True, mode=True)
self.setMultiplier(self.getMultiplier())
self.removeMicroTransform()
self.blinkingButton(self.onOff)
def blinkingButton(self, onOff):
if onOff: G.aToolsBar.timeoutInterval.setInterval(self.toggleButtonActive, .3, id="MT_blinking")
else: G.aToolsBar.timeoutInterval.stopInterval("MT_blinking")
def toggleButtonActive(self):
onOff = "active" in cmds.iconTextButton("microTransformBtn", query=True, image=True)
self.setButtonImg(not onOff)
def setButtonImg(self, onOff):
if onOff:
cmds.iconTextButton("microTransformBtn", edit=True, image=uiMod.getImagePath("specialTools_micro_transform_active"), highlightImage= uiMod.getImagePath("specialTools_micro_transform_active"))
else:
cmds.iconTextButton("microTransformBtn", edit=True, image=uiMod.getImagePath("specialTools_micro_transform"), highlightImage= uiMod.getImagePath("specialTools_micro_transform copy"))
def switch(self):
self.onOff = (not self.onOff)
self.setButtonImg(self.onOff)
self.blinkingButton(self.onOff)
self.setMode(self.onOff)
def setMode(self, onOff):
utilMod.killScriptJobs("G.microTransformScriptJobs")
if onOff:
self.rotationOrientMode = cmds.manipRotateContext('Rotate', query=True, mode=True)
cmds.manipRotateContext('Rotate', edit=True, mode=2)#gimbal
#update values on turning on
self.addMicroTransform()
G.microTransformScriptJobs = []
# get the current selected object values
G.microTransformScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.addMicroTransform )))
G.microTransformScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.updateValues )))
G.microTransformScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('Undo', self.updateValues )))
G.microTransformScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('Redo', self.updateValues )))
G.microTransformScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('DragRelease', self.release )))
#print "microTransform is ON."
else:
cmds.manipRotateContext('Rotate', edit=True, mode=self.rotationOrientMode)
self.removeMicroTransform()
#print "microTransform is OFF."
def changedMicroTransform(self, msg, mplug, otherMplug, clientData):
#cmds.undoInfo(stateWithoutFlush=False)
if om.MNodeMessage.kAttributeSet == (om.MNodeMessage.kAttributeSet & msg) and not om.MGlobal.isUndoing() and not om.MGlobal.isRedoing():
nodeName, attrName = mplug.name().split('.')
#print "changed!"
if attrName not in self.attributes: return
nodeAttr = mplug.name()
val = cmds.getAttr(nodeAttr)
mtValue = self.microTransformValues["%s_%s"%(nodeName, attrName)]
if str(val) != str(mtValue):
#timer
if "%s"%nodeName not in self.microTransformStartTimer:
self.microTransformStartTimer["%s"%nodeName] = cmds.timerX()
microTransformTimer = cmds.timerX(startTime=self.microTransformStartTimer["%s"%nodeName])
self.microTransformStartTimer["%s"%nodeName] = cmds.timerX()
microTransformTimer *= 50
if microTransformTimer == 0: microTransformTimer = 1000
mult = self.multiplier/microTransformTimer
if mult >= self.multiplier: mult = self.multiplier
self.undoChunkFn("open")
#print "changedMicroTransform"
if type(val) is list:
temp = ()
for n, loopVal in enumerate(val[0]):
dif = loopVal-mtValue[0][n]
temp = temp + (mtValue[0][n]+(dif*mult),)
newVal = [temp]
self.microTransformValues["%s_%s"%(nodeName, attrName)] = newVal
#xyz
self.microTransformValues["%s_%sX"%(nodeName, attrName)] = newVal[0][0]
self.microTransformValues["%s_%sY"%(nodeName, attrName)] = newVal[0][1]
self.microTransformValues["%s_%sZ"%(nodeName, attrName)] = newVal[0][2]
eval("cmds.setAttr(nodeAttr, %s,%s,%s)"%(newVal[0][0],newVal[0][1],newVal[0][2]))
#xyz
cmds.setAttr("%sX"%nodeAttr, newVal[0][0])
cmds.setAttr("%sY"%nodeAttr, newVal[0][1])
cmds.setAttr("%sZ"%nodeAttr, newVal[0][2])
else:
dif = val-mtValue
newVal = mtValue+(dif*mult)
self.microTransformValues["%s_%s"%(nodeName, attrName)] = newVal
#xyz inverse
val = cmds.getAttr("%s.%s"%(nodeName, attrName[:-1]))
self.microTransformValues["%s_%s"%(nodeName, attrName[:-1])] = val
cmds.setAttr(nodeAttr, newVal)
else:
self.microTransformValues["%s_%s"%(nodeName, attrName)] = cmds.getAttr(nodeAttr)
if type(val) is list:
valX = cmds.getAttr("%s.%sX"%(nodeName, attrName))
valY = cmds.getAttr("%s.%sY"%(nodeName, attrName))
valZ = cmds.getAttr("%s.%sZ"%(nodeName, attrName))
#xyz
self.microTransformValues["%s_%sX"%(nodeName, attrName)] = valX
self.microTransformValues["%s_%sY"%(nodeName, attrName)] = valY
self.microTransformValues["%s_%sZ"%(nodeName, attrName)] = valZ
else:
#xyz inverse
val = cmds.getAttr("%s.%s"%(nodeName, attrName[:-1]))
self.microTransformValues["%s_%s"%(nodeName, attrName[:-1])] = val
#cmds.undoInfo(stateWithoutFlush=True)
def release(self):
self.undoChunkFn("close")
self.updateValues()
self.microTransformStartTimer = {}
def undoChunkFn(self, openClose):
if openClose == "open":
if self.undoChunk == "closed":
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
self.undoChunk = "open"
#print "openChunk"
else:
if self.undoChunk == "open":
cmds.undoInfo(closeChunk=True)
self.undoChunk = "closed"
#print "closeChunk"
def addMicroTransform(self):
self.updateValues()
cmds.undoInfo(stateWithoutFlush=False)
sel = cmds.ls(selection=True)
if G.MT_lastSel:
graphEditorFocus = cmds.getPanel(withFocus=True) == "graphEditor1"
if sel == G.MT_lastSel and graphEditorFocus:
cmds.undoInfo(stateWithoutFlush=True)
return
G.MT_lastSel = sel
if len(sel) <= 0:
cmds.undoInfo(stateWithoutFlush=True)
return
self.removeMicroTransform()
G.microTransformIds = []
self.undoChunk = "closed"
MSelectionList = om.MSelectionList()
om.MGlobal.getActiveSelectionList(MSelectionList)
node = om.MObject()
for n, loopSel in enumerate(sel):
MSelectionList.getDependNode(n, node)
clientData = None
G.microTransformIds.append(om.MNodeMessage.addAttributeChangedCallback(node, self.changedMicroTransform, clientData))
cmds.undoInfo(stateWithoutFlush=True)
def removeMicroTransform(self):
try:
for loopId in G.microTransformIds:
om.MNodeMessage.removeCallback(loopId)
except: pass
G.microTransformIds = None
def updateValues(self):
#print "updateValues"
self.microTransformValues = {}
sel = cmds.ls(selection=True)
for loopSel in sel:
for loopAttr in self.attributes:
val = cmds.getAttr("%s.%s"%(loopSel, loopAttr))
self.microTransformValues["%s_%s"%(loopSel, loopAttr)] = val
def setMultiplier(self, option):
name = None
for loopOption in self.multiplierValues:
if loopOption["name"] == option:
value = loopOption["value"]
name = loopOption["name"]
if not name: #in case file is corrupt
self.setMultiplier(self.defaultMultiplier)
return
self.multiplier = value
aToolsMod.saveInfoWithUser("userPrefs", "microTransform", name)
def getMultiplier(self):
name = aToolsMod.loadInfoWithUser("userPrefs", "microTransform")
if name == None: name = self.defaultMultiplier
return name
def popupMenu(self, *args):
menu = cmds.popupMenu()
cmds.popupMenu(menu, edit=True, postMenuCommand=self.populateMenu, postMenuCommandOnce=True)
def populateMenu(self, menu, *args):
cmds.radioMenuItemCollection(parent=menu)
for loopOption in self.multiplierValues:
radioSelected = (self.multiplier == loopOption["value"])
option = loopOption["name"]
cmds.menuItem (label=utilMod.toTitle(loopOption["name"]), radioButton=radioSelected, command=lambda x, option=option, *args: self.setMultiplier(option), parent=menu)

View File

@ -0,0 +1,319 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
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
========================================================================================================================
'''
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 aToolsMod
class Mirror(object):
utilMod.killScriptJobs("G.mirrorScriptJobs")
def __init__(self):
self.INVERT_RULES_PREFS = [{ "name":"invertRulesMirrorObjsTranslateX",
"default":True
},{ "name":"invertRulesMirrorObjsTranslateY",
"default":False
},{ "name":"invertRulesMirrorObjsTranslateZ",
"default":False
},{ "name":"invertRulesMirrorObjsRotateX",
"default":False
},{ "name":"invertRulesMirrorObjsRotateY",
"default":False
},{ "name":"invertRulesMirrorObjsRotateZ",
"default":False
},{ "name":"invertRulesCenterObjsTranslateX",
"default":True
},{ "name":"invertRulesCenterObjsTranslateY",
"default":False
},{ "name":"invertRulesCenterObjsTranslateZ",
"default":False
},{ "name":"invertRulesCenterObjsRotateX",
"default":False
},{ "name":"invertRulesCenterObjsRotateY",
"default":True
},{ "name":"invertRulesCenterObjsRotateZ",
"default":True
}]
def start(self):
mod = uiMod.getModKeyPressed()
if mod == "shift":
self.selectMirrorObjs(True)
elif mod == "ctrl":
self.selectMirrorObjs(False)
else:
sel = cmds.ls(selection=True)
if sel: self.applyMirror()
else: self.toggleAutoSelectMirrorObjects()
def popupMenu(self):
cmds.popupMenu()
cmds.menuItem("autoSelectMirrorObjectsMenu", label='Auto Select Mirror Objects' , checkBox=False, command=self.toggleAutoSelectMirrorObjects)
cmds.menuItem("invertRulesMenu", subMenu=True, label='Invert Rules' , tearOff=True)
for n, loopPref in enumerate(self.INVERT_RULES_PREFS):
name = loopPref["name"]
if n == 6: cmds.menuItem( divider=True )
cmds.menuItem('%sMenu'%name, label=utilMod.toTitle(name[11:]), command=lambda x, name=name, *args: aToolsMod.setPref(name, self.INVERT_RULES_PREFS), checkBox=aToolsMod.getPref(name, self.INVERT_RULES_PREFS))
cmds.menuItem( divider=True )
cmds.menuItem("loadDefaultsInvertRulesMenu", label="Load Defaults", command=lambda *args:utilMod.loadDefaultPrefs(self.INVERT_RULES_PREFS))
cmds.setParent( '..', menu=True )
cmds.menuItem( divider=True )
cmds.menuItem(label="Unselect Right", command=lambda *args: self.unselectMirrorObjs("right"))
cmds.menuItem(label="Unselect Left", command=lambda *args: self.unselectMirrorObjs("left"))
cmds.menuItem(label="Unselect Center", command=lambda *args: self.unselectMirrorObjs("center"))
cmds.menuItem( divider=True )
cmds.menuItem(label="Paste And Invert Cycle", command=lambda *args: self.applyMirror(pasteAndCycle=True))
def toggleAutoSelectMirrorObjects(self, *args):
onOff = not cmds.menuItem("autoSelectMirrorObjectsMenu", query=True , checkBox=True)
if args: onOff = not onOff #if checkbox pressed
if onOff: cmds.iconTextButton("mirrorBtn", edit=True, image=uiMod.getImagePath("specialTools_mirror_active"), highlightImage= uiMod.getImagePath("specialTools_mirror_active"))
else: cmds.iconTextButton("mirrorBtn", edit=True, image=uiMod.getImagePath("specialTools_mirror"), highlightImage= uiMod.getImagePath("specialTools_mirror copy"))
self.setAutoSelectMirrorObjects(onOff)
if not args:cmds.menuItem("autoSelectMirrorObjectsMenu", edit=True , checkBox=onOff)
def setAutoSelectMirrorObjects(self, onOff):
utilMod.killScriptJobs("G.mirrorScriptJobs")
if onOff:
self.autoSelectMirrorObjects()
G.mirrorScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.autoSelectMirrorObjects )))
def autoSelectMirrorObjects(self):
sel = cmds.ls(selection=True)
if sel: self.selectMirrorObjs(add=True, lastObj=sel[-1])
def getInvertRules(self):
invertRules = []
for loopPref in self.INVERT_RULES_PREFS:
name = loopPref["name"]
pref = aToolsMod.getPref(name, self.INVERT_RULES_PREFS)
mode = name[11:]
if pref: invertRules.append(mode)
return invertRules
def mirrorInvert(self, aCurve, isCenterCurve, invertRules):
transRot =["Translate", "Rotate"]
modes = ["x", "y", "z"]
value = 1
if isCenterCurve:
objType = "Center"
else:
objType = "Mirror"
for loopRule in invertRules:
for loopMode in modes:
for loopTransRot in transRot:
rule = "%sObjs%s%s"%(objType, loopTransRot, loopMode.title())
if loopRule == rule:
if eval("animMod.isNode%s('%s', '%s')"%(loopTransRot, aCurve, loopMode)):
value = -1
return value
def unselectMirrorObjs(self, side):
objects = animMod.getObjsSel()
if side == "center":
objs = animMod.getMirrorObjs(objects, side="left")
objects.extend(objs)
objs.extend(animMod.getMirrorObjs(objects, side="right"))
objects.extend(objs)
objs.extend(animMod.getMirrorObjs(objects, side="left"))
centerObjs = [loopObj for loopObj in objects if loopObj not in objs and loopObj and cmds.objExists(loopObj)]
if len(centerObjs) >0: cmds.select(centerObjs, deselect=True)
else:
if side == "left": side = "right"
elif side == "right": side = "left"
objs = animMod.getMirrorObjs(objects, side=side)
objs = [loopObj for loopObj in objs if loopObj and cmds.objExists(loopObj)]
if len(objs) > 0: cmds.select(objs, deselect=True)
def selectMirrorObjs(self, add, lastObj=None):
objects = animMod.getObjsSel()
mirrorObjs = animMod.getMirrorObjs(objects)
sel = []
if mirrorObjs:
for n, loopObj in enumerate(mirrorObjs):
if loopObj:
if cmds.objExists(loopObj): sel.append(loopObj)
else:
#central controller
sel.append(objects[n])
if len(sel) >0:
if lastObj:
cmds.select(sel, addFirst=add)
else:
cmds.select(sel, add=add)
def applyMirror(self, pasteAndCycle=False):
cmds.waitCursor(state=True)
range = animMod.getTimelineRange()
range[1] = int(range[1])
total = range[1]-range[0]
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
invertRules = self.getInvertRules()
if animCurves:
status = "aTools - Applying mirror..."
utilMod.startProgressBar(status)
totalSteps = len(animCurves)
firstStep = 0
thisStep = 0
estimatedTime = None
startChrono = None
mirrorCurves = animMod.getMirrorObjs(animCurves)
keyValues = animMod.getTarget("keyValues", animCurves, getFrom)
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
currValues = animMod.getTarget("currValues", animCurves, getFrom)
keysIndexSel = animMod.getTarget("keysIndexSel", animCurves, getFrom)
keyTangentsAngle = animMod.getTarget("keyTangentsAngle", animCurves, getFrom)
keyTangentsType = animMod.getTarget("keyTangentsType", animCurves, getFrom)
currTime = cmds.currentTime(query=True)
if keysIndexSel:
#create dummy key
#objects = animMod.getObjsSel()
#mirrorObjs = animMod.getMirrorObjs(objects)
#animMod.createDummyKey(mirrorObjs)
for thisStep, aCurve in enumerate(animCurves):
startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
mCurve = mirrorCurves[thisStep]
isCenterCurve = (mCurve == None)
mirrorInvertValue = self.mirrorInvert(aCurve, isCenterCurve, invertRules)
if mCurve and cmds.objExists(mCurve):
tCurve = mCurve
else:
tCurve = aCurve
if not cmds.objExists(tCurve): continue
animMod.createDummyKey([tCurve])
if len(keysIndexSel[thisStep]) > 0:
#delete keys
cmds.cutKey(tCurve, time=(keyTimes[thisStep][keysIndexSel[thisStep][0]],keyTimes[thisStep][keysIndexSel[thisStep][-1]]), clear=True)
for key in keysIndexSel[thisStep]:
keyValue = keyValues[thisStep][key] * mirrorInvertValue
inTangAngleValue = keyTangentsAngle[thisStep][key][0] * mirrorInvertValue
outTangAngleValue = keyTangentsAngle[thisStep][key][1] * mirrorInvertValue
#apply keys
if pasteAndCycle:
t = keyTimes[thisStep][key] + (total/2.)
if t == range[1]:
#repeat key at first frame
t1 = t-total
time = (t1,t1)
cmds.setKeyframe(tCurve, time=time, value=keyValue)
cmds.keyTangent(tCurve, time=time, inAngle=inTangAngleValue, outAngle=outTangAngleValue)
cmds.keyTangent(tCurve, time=time, inTangentType=keyTangentsType[thisStep][key][0], outTangentType=keyTangentsType[thisStep][key][1])
elif t > range[1]:
#fist half
t -= total
time = (t,t)
else:
time = (keyTimes[thisStep][key],keyTimes[thisStep][key])
cmds.setKeyframe(tCurve, time=time, value=keyValue)
cmds.keyTangent(tCurve, time=time, inAngle=inTangAngleValue, outAngle=outTangAngleValue)
cmds.keyTangent(tCurve, time=time, inTangentType=keyTangentsType[thisStep][key][0], outTangentType=keyTangentsType[thisStep][key][1])
else: #no keys#invert translate x
keyValue = currValues[thisStep] * mirrorInvertValue
#apply keys
cmds.setKeyframe(tCurve, time=(currTime,currTime), value=keyValue)
animMod.deleteDummyKey([tCurve])
estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
#delete dummy key
#animMod.deleteDummyKey(mirrorObjs)
self.selectMirrorObjs(False)
utilMod.setProgressBar(endProgress=True)
animMod.refresh()
cmds.waitCursor(state=False)

View File

@ -0,0 +1,303 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
from maya import cmds
from maya import mel
from aTools.commonMods import uiMod
from aTools.commonMods import utilMod
from aTools.commonMods import animMod
from aTools.commonMods import aToolsMod
class SpaceSwitch(object):
def popupMenu(self):
cmds.popupMenu(postMenuCommand=self.populateMenu, button=1)
def populateMenu(self, menu, *args):
uiMod.clearMenuItems(menu)
tokenCustomDivider = False
selObjects = cmds.ls(selection=True)
if not selObjects: return
channels = animMod.getAllChannels()
channelList = {}
tokenList = []
for n, loopObjectChannel in enumerate(channels):
obj = selObjects[n]
if loopObjectChannel:
for loopChannel in loopObjectChannel:
tokens = animMod.getTokens(obj, loopChannel)
if tokens and len(tokens) > 1:
if loopChannel not in channelList: channelList[loopChannel] = {"objects":[], "tokens":[]}
channelList[loopChannel]["objects"].append(obj)
channelList[loopChannel]["tokens"].append(tokens)
for loopChannelList in channelList:
newMenu = cmds.menuItem(subMenu=True, label=utilMod.toTitle(loopChannelList), parent=menu)
objects = channelList[loopChannelList]["objects"]
tokens = channelList[loopChannelList]["tokens"]
mergedTokens = utilMod.mergeLists(tokens)
tokenDict = []
for loopMergedTokens in mergedTokens:
tokenDict.append({"token":loopMergedTokens, "objects":[]})
for n, loopObject in enumerate(objects):
t = tokens[n]
if loopMergedTokens in t:
tokenDict[-1]["objects"].append(loopObject)
cmds.radioMenuItemCollection(parent=menu)
for n, loopTokenDict in enumerate(tokenDict):
tokenCustomDivider = True
token = loopTokenDict["token"]
objects = loopTokenDict["objects"]
selectedList = [cmds.getAttr("%s.%s"%(loopObj, loopChannelList)) for loopObj in objects]
radioSelected = False
if len(set(selectedList)) == 1:
if selectedList[0] == n:
radioSelected = True
cmds.menuItem(label=utilMod.toTitle(token), radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, channel=loopChannelList, token=token, *args:self.spaceSwitch([objects, channel, token]))
#ALL KEYS
cmds.menuItem( divider=True, parent=newMenu)
newMenu = cmds.menuItem(subMenu=True, label='All Keys', parent=newMenu)
cmds.radioMenuItemCollection(parent=newMenu)
for n, loopTokenDict in enumerate(tokenDict):
token = loopTokenDict["token"]
objects = loopTokenDict["objects"]
selectedList = [cmds.getAttr("%s.%s"%(loopObj, loopChannelList)) for loopObj in objects]
radioSelected = False
if len(set(selectedList)) == 1:
if selectedList[0] == n:
radioSelected = True
cmds.menuItem(label=utilMod.toTitle(token), radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, channel=loopChannelList, token=token, *args:self.spaceSwitch([objects, channel, token], all=True))
# CUSTOM SWITCH
allCustomSwitch = aToolsMod.loadInfoWithUser("spaceSwitch", "customSwitch") or []
channelboxSelObjs = animMod.channelBoxSel()
if channelboxSelObjs:
obj = ".".join(channelboxSelObjs[0].split(".")[:-1])
selectedSwitch = [loopAttr.split(".")[-1] for loopAttr in channelboxSelObjs if utilMod.isDynamic(obj, loopAttr.split(".")[-1])]
if len(selectedSwitch) > 0 and selectedSwitch not in allCustomSwitch:
allCustomSwitch.append(selectedSwitch)
aToolsMod.saveInfoWithUser("spaceSwitch", "customSwitch", allCustomSwitch)
# populate menu
if len(allCustomSwitch) > 0:
divider = False
customSwitchesAdded = []
customSwitchesMenu = []
for loopObj in selObjects:
for loopCustomSwitch in sorted(allCustomSwitch, key=len, reverse=True):
if len(loopCustomSwitch) == 0: continue
switchName = utilMod.getNameSpace([loopObj])[1][0].split(".")[0]
exit = False
for loopAttr in loopCustomSwitch:
objAttr = "%s.%s"%(loopObj, loopAttr)
if not cmds.objExists(objAttr):
exit = True
break
if exit: continue
customSwitchesMenu.append({"objects":[loopObj], "switches":loopCustomSwitch})
for loopMenu in customSwitchesMenu[:-1]:
if loopObj in loopMenu["objects"] and len(loopCustomSwitch) < len(loopMenu["switches"]) and utilMod.listIntersection(loopMenu["switches"], loopCustomSwitch) == loopCustomSwitch:
customSwitchesMenu.pop()
break
if loopCustomSwitch == loopMenu["switches"]:
loopMenu["objects"].append(loopObj)
customSwitchesMenu.pop()
break
for loopSwitchMenu in customSwitchesMenu:
objects = loopSwitchMenu["objects"]
switches = loopSwitchMenu["switches"]
switchName = ", ".join(list(set(utilMod.getNameSpace(objects)[1])))
if not divider and tokenCustomDivider: divider = cmds.menuItem(divider=True, parent=menu)
cmds.radioMenuItemCollection(parent=menu)
newMenu = cmds.menuItem(subMenu=True, label=switchName, parent=menu)
radioSelected = []
for loopCustomSwitchAttr in switches:
switchAttr = loopCustomSwitchAttr.split(".")[-1]
objAttr = "%s.%s"%(objects[0], switchAttr)
minValue = cmds.addAttr(objAttr, query=True, minValue=True)
maxValue = cmds.addAttr(objAttr, query=True, maxValue=True)
currValue = cmds.getAttr(objAttr)
radioSelected.append((currValue == maxValue))
cmds.menuItem(label=switchAttr, radioButton=radioSelected[-1], parent=newMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], mode="custom"))
switchAttr = "message"
radioSelected = (list(set(radioSelected)) == [False])
cmds.menuItem(label="None", radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], mode="custom"))
#ALL KEYS
cmds.menuItem( divider=True, parent=newMenu)
allMenu = cmds.menuItem(subMenu=True, label='All Keys', parent=newMenu)
radioSelected = []
cmds.radioMenuItemCollection(parent=menu)
for loopCustomSwitchAttr in switches:
switchAttr = loopCustomSwitchAttr.split(".")[-1]
objAttr = "%s.%s"%(objects[0], switchAttr)
minValue = cmds.addAttr(objAttr, query=True, minValue=True)
maxValue = cmds.addAttr(objAttr, query=True, maxValue=True)
currValue = cmds.getAttr(objAttr)
radioSelected.append((currValue == maxValue))
cmds.menuItem(label=switchAttr, radioButton=radioSelected[-1], parent=allMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], all=True, mode="custom"))
switchAttr = "message"
radioSelected = (list(set(radioSelected)) == [False])
cmds.menuItem(label="None", radioButton=radioSelected, parent=allMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], all=True, mode="custom"))
#DELETE
cmds.menuItem(label="Remove", parent=newMenu, command=lambda x, switches=switches, *args:self.removeCustomSwitch(switches))
def removeCustomSwitch(self, switch):
allCustomSwitch = aToolsMod.loadInfoWithUser("spaceSwitch", "customSwitch") or []
allCustomSwitch.remove(switch)
aToolsMod.saveInfoWithUser("spaceSwitch", "customSwitch", allCustomSwitch)
def spaceSwitch(self, args, all=False, mode="token"):
cmds.refresh(suspend=True)
if mode == "token": switch = self.spaceSwitchToken
elif mode == "custom": switch = self.spaceSwitchCustom
objects = args[0]
attr = args[1]
currSel = cmds.ls(selection=True)
currFrame = cmds.currentTime(query=True)
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
if all: keysSel = animMod.getTarget("keyTimes", animCurves, getFrom)
else: keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
keysSel = utilMod.mergeLists(keysSel)
if keysSel == []:
keysSel = [currFrame]
else:
keysSel = [currFrame]
frames = keysSel
for loopObj in currSel:
if loopObj not in objects: continue
if not cmds.objExists("%s.%s"%(loopObj, attr)):continue
animMod.createDummyKey([loopObj])
getCurves = animMod.getAnimCurves(True)
animCurves = getCurves[0]
animMod.deleteDummyKey([loopObj])
for loopFrame in frames:
cmds.currentTime(loopFrame)
matrix = cmds.xform(loopObj, query=True, ws=True, matrix=True)
rotation = cmds.xform(loopObj, query=True, ws=True, rotation=True)
switch(loopObj, args)
cmds.xform(loopObj, ws=True, matrix=matrix)
cmds.xform(loopObj, ws=True, rotation=rotation)
animMod.eulerFilterCurve(animCurves)
cmds.currentTime(currFrame)
cmds.refresh(suspend=False)
def spaceSwitchCustom(self, obj, args):
objects, attr, switchAttList = args
objAttr = "%s.%s"%(obj, attr)
for loopAttr in switchAttList:
loopObjAttr = "%s.%s"%(obj, loopAttr)
minValue = cmds.addAttr(loopObjAttr, query=True, minValue=True)
maxValue = cmds.addAttr(loopObjAttr, query=True, maxValue=True)
value = minValue if objAttr != loopObjAttr else maxValue
cmds.setAttr(loopObjAttr, value)
def spaceSwitchToken(self, obj, args):
objects, attr, switchTo = args
enumTokens = animMod.getTokens(obj, attr)
value = 0
switchToNum = None
for loopToken in enumTokens:
splitValue = loopToken.split("=")
if splitValue:
if len(splitValue) > 1:
loopToken = splitValue[0]
value = eval(splitValue[1])
if switchTo == loopToken:
switchToNum = value
break
value += 1
if switchToNum != None:
cmds.setAttr("%s.%s"%(obj, attr), switchToNum)

View File

@ -0,0 +1,189 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
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
========================================================================================================================
'''
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 aToolsMod
import maya.OpenMaya as om
#============================================================================================================
class TempCustomPivot(object):
def __init__(self):
self.STORE_NODE = "tempCustomPivot"
self.CONSTRAINTS = "constraintObjects"
self.LOCATORS = "locatorObjects"
self.CTRLS = "ctrlsObjects"
self.CURRENTFRAME = "currentFrame"
self.sel = []
self.deniedCtx = ["dragAttrContext", "manipMoveContext", "manipRotateContext", "manipScaleContext"]
self.clear()
def popupMenu(self, *args):
cmds.popupMenu()
cmds.menuItem(label="Clear temporary custom pivots", command=self.clear)
def create(self, *args):
img = cmds.iconTextButton("TempCustomPivotBtn", query=True, image=True)
onOff = (img[-10:-4] == "active")
if onOff:
self.clear()
cmds.select(self.sel)
return
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
self.clear()
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
self.sel = cmds.ls(selection=True)
if not self.sel: return
cmds.iconTextButton("TempCustomPivotBtn", edit=True, image= uiMod.getImagePath("specialTools_create_temp_custom_pivot_active"), highlightImage= uiMod.getImagePath("specialTools_create_temp_custom_pivot_active"))
targetObj = self.sel[-1]
aToolsMod.saveInfoWithScene(self.STORE_NODE, self.CTRLS, self.sel)
currentFrame = cmds.currentTime(query=True)
aToolsMod.saveInfoWithScene(self.STORE_NODE, self.CURRENTFRAME, currentFrame)
locators = []
for loopSel in self.sel:
nameSpace = utilMod.getNameSpace([loopSel])
loopSelName = "%s_%s"%(nameSpace[0][0], nameSpace[1][0])
locatorName = "tempCustomPivot_%s"%loopSelName
locator = animMod.createNull(locatorName)
locators.append(locator)
G.aToolsBar.align.align([locator], loopSel)
locatorGroup = "tempCustomPivot_group"
animMod.group(name=locatorGroup)
G.aToolsBar.align.align([locatorGroup], targetObj)
with G.aToolsBar.createAToolsNode: cmds.parent(locators, locatorGroup)
cmds.select(locatorGroup, replace=True)
locators.append(locatorGroup)
aToolsMod.saveInfoWithScene(self.STORE_NODE, self.LOCATORS, locators)
#parent ctrls to locator
constraints = ["%s_tempCustomPivot_constraint"%loopConstraint for loopConstraint in self.sel]
aToolsMod.saveInfoWithScene(self.STORE_NODE, self.CONSTRAINTS, constraints)
for n, loopSel in enumerate(self.sel):
with G.aToolsBar.createAToolsNode: cmds.parentConstraint(locators[n], loopSel, name=constraints[n], maintainOffset=True)
constraintNode = "%s.blendParent1"%loopSel
if not cmds.objExists(constraintNode): continue
cmds.setKeyframe(constraintNode)
if keyTimes:
for loopTime in keyTimes[0]:
cmds.setKeyframe("%s.tx"%locatorGroup, time=(loopTime,loopTime))
if loopTime != currentFrame:
cmds.setKeyframe(constraintNode, time=(loopTime,loopTime), value=0)
#enter edit mode
cmds.setToolTo(cmds.currentCtx())
cmds.ctxEditMode()
#scriptjob
cmds.scriptJob(runOnce = True, killWithScene = True, event =('SelectionChanged', self.scriptJob_SelectionChanged))
def scriptJob_SelectionChanged(self):
self.clear()
cmds.undoInfo(closeChunk=True)
def clear(self, *args):
if cmds.iconTextButton("TempCustomPivotBtn", query=True, exists=True):
cmds.iconTextButton("TempCustomPivotBtn", edit=True, image= uiMod.getImagePath("specialTools_create_temp_custom_pivot"), highlightImage= uiMod.getImagePath("specialTools_create_temp_custom_pivot copy"))
cmds.refresh(suspend=True)
currFrame = cmds.currentTime(query=True)
loadConstraints = aToolsMod.loadInfoWithScene(self.STORE_NODE, self.CONSTRAINTS)
loadLocators = aToolsMod.loadInfoWithScene(self.STORE_NODE, self.LOCATORS)
loadCtrls = aToolsMod.loadInfoWithScene(self.STORE_NODE, self.CTRLS)
currentFrame = aToolsMod.loadInfoWithScene(self.STORE_NODE, self.CURRENTFRAME)
#exit edit mode
if cmds.currentCtx() not in self.deniedCtx: cmds.setToolTo(cmds.currentCtx())
if currentFrame:
cmds.currentTime(eval(currentFrame))
#get values
"""
translation = []
rotation = []
if loadCtrls:
ctrlObjs = eval(loadCtrls)
for loopCtrl in ctrlObjs:
translation.append(cmds.xform(loopCtrl, query=True, ws=True, rotatePivot=True))
rotation.append(cmds.xform(loopCtrl, query=True, ws=True, rotation=True))
"""
if loadConstraints:
constraintObjs = eval(loadConstraints)
for loopConstraint in constraintObjs:
if cmds.objExists(loopConstraint): cmds.delete(loopConstraint)
if loadCtrls and loadLocators:
locatorObjs = eval(loadLocators)
ctrlObjs = eval(loadCtrls)
for n, loopCtrl in enumerate(ctrlObjs):
if cmds.objExists(loopCtrl) and cmds.objExists(locatorObjs[n]):
G.aToolsBar.align.align([loopCtrl], locatorObjs[n])
for loopLocator in locatorObjs:
if cmds.objExists(loopLocator): cmds.delete(loopLocator)
cmds.currentTime(currFrame)
cmds.refresh(suspend=False)

View File

@ -0,0 +1,347 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
from maya import cmds
from maya import mel
from maya import OpenMaya
from maya import OpenMayaAnim
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import uiMod
from aTools.commonMods import utilMod
from aTools.commonMods import animMod
class TransformAll(object):
utilMod.killScriptJobs("G.transformAllScriptJobs")
def __init__(self):
G.deferredManager.removeFromQueue("transformAll")
G.deferredManager.removeFromQueue("TA_blinking")
if G.aToolsBar.transformAll: return
G.aToolsBar.transformAll = self
self.currentValues = {}
self.allValues = {}
self.range = None
self.onOff = False
self.blendRangeMode = False
self.blendImg = ""
G.TA_messages = G.TA_messages or {"anim":[], "node":[], "scene":[]}
self.killJobs()
def blinkingButton(self, onOff):
if onOff: G.aToolsBar.timeoutInterval.setInterval(self.toggleButtonActive, .3, id="TA_blinking")
else: G.aToolsBar.timeoutInterval.stopInterval("TA_blinking")
def toggleButtonActive(self):
onOff = "active" in cmds.iconTextButton("transformAllBtn", query=True, image=True)
self.setButtonImg(not onOff)
def popupMenu(self, *args):
cmds.popupMenu ()
cmds.menuItem ("blendRangeModeMenu", label="Blend Range Mode", checkBox=self.blendRangeMode, command=self.setBlendRangeMode)
def setBlendRangeMode(self, *args):
self.blendRangeMode = args[0]
if self.blendRangeMode: self.blendImg = "_blend"
else: self.blendImg = ""
self.setButtonImg(self.onOff)
self.warn()
def setButtonImg(self, onOff):
if onOff:
cmds.iconTextButton("transformAllBtn", edit=True, image=uiMod.getImagePath("specialTools_transform_all%s_active"%self.blendImg), highlightImage= uiMod.getImagePath("specialTools_transform_all%s_active"%self.blendImg))
else:
cmds.iconTextButton("transformAllBtn", edit=True, image=uiMod.getImagePath("specialTools_transform_all%s"%self.blendImg), highlightImage= uiMod.getImagePath("specialTools_transform_all%s copy"%self.blendImg))
def switch(self):
mod = uiMod.getModKeyPressed()
if mod == "ctrl":
self.setBlendRangeMode(not self.blendRangeMode)
if self.onOff: self.onOff = False
self.onOff = (not self.onOff)
self.setButtonImg(self.onOff)
self.blinkingButton(self.onOff)
self.setMode(self.onOff)
def killJobs(self):
G.deferredManager.removeFromQueue("transformAll")
self.animCurvesToSend = []
self.removeMessages()
utilMod.killScriptJobs("G.transformAllScriptJobs")
def setMode(self, onOff):
self.killJobs()
if onOff:
#self.allAnimCurves = utilMod.getAllAnimCurves()
self.allValues = {}
self.setRange()
self.updateCurrentValues()
utilMod.deselectTimelineRange()
G.transformAllScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.updateCurrentValues )))
G.transformAllScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.updateCurrentValues )))
self.warn()
else:
cmds.warning("Transform All is OFF.")
def addAnimMessages(self):
self.removeMessages()
G.TA_messages["anim"].append(OpenMayaAnim.MAnimMessage.addAnimCurveEditedCallback(self.sendToSetValues))
def removeMessages(self):
try:
for loopId in G.TA_messages["anim"]:
OpenMayaAnim.MAnimMessage.removeCallback(loopId)
except: pass
G.TA_messages["anim"] = []
def sendToSetValues(self, *args):
curveMsg = args[0]
animCurves = [OpenMaya.MFnDependencyNode(curveMsg[n]).name() for n in range(curveMsg.length())]
if OpenMaya.MGlobal.isUndoing() or OpenMaya.MGlobal.isRedoing():
self.updateCurrentValues(animCurves)
return
self.animCurvesToSend.extend(animCurves)
animCurves = list(set(self.animCurvesToSend))
G.deferredManager.removeFromQueue("transformAll")
function = lambda *args:self.setValues(animCurves)
G.deferredManager.sendToQueue(function, 1, "transformAll")
def getRange(self):
animCurves = cmds.keyframe(query=True, name=True, selected=True)
if animCurves:
keysSel = animMod.getTarget("keysSel", animCurves, "graphEditor")
keysSel = utilMod.mergeLists(keysSel)
range = [min(keysSel), max(keysSel)]
else:
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
range = cmds.timeControl(G.playBackSliderPython, query=True, rangeArray=True)
range[1] -= 1
return range
def getCurrentValues(self, animCurves):
if animCurves:
result = {"keyValues":[], "timeValues":[]}
for loopCurve in animCurves:
time = cmds.keyframe(loopCurve, selected=True, query=True, timeChange=True)
if time:
time = [time[0], time[-1]]
result["keyValues"].append(cmds.keyframe(loopCurve, query=True, time=(time[0],time[-1]), valueChange=True))
else:
time = cmds.currentTime(query=True); time = [time, time]
result["keyValues"].append(cmds.keyframe(loopCurve, query=True, eval=True, valueChange=True))
result["timeValues"].append(time)
return result
def updateCurrentValues(self, animCurves=None, *args):
cmds.undoInfo(stateWithoutFlush=False)
self.removeMessages()
if not animCurves: animCurves = utilMod.getAllAnimCurves(selection=True)
if not animCurves: return
for loopCurve in animCurves:
#if loopCurve in self.allAnimCurves:
self.currentValues[loopCurve] = self.getCurrentValues([loopCurve])["keyValues"][0]
self.allValues[loopCurve] = animMod.getTarget("keyValues", [loopCurve])[0]
self.addAnimMessages()
cmds.undoInfo(stateWithoutFlush=True)
def setValues(self, animCurves):
cmds.refresh(suspend=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
cmds.undoInfo(closeChunk=True)
cmds.undoInfo(openChunk=True)
self.removeMessages()
self.warn()
values = self.getCurrentValues(animCurves)
newKeyValues = values["keyValues"]
timeValues = values["timeValues"]
offsetValues = []
offsetPercentsA = []
offsetPercentsB = []
pivotAs = []
pivotBs = []
self.animCurvesToSend = []
for n, loopCurve in enumerate(animCurves):
oldVal = self.currentValues[loopCurve][0]
newVal = newKeyValues[n][0]
if self.blendRangeMode:
pivotA = cmds.keyframe(loopCurve, query=True, eval=True, time=(self.range[0],self.range[0]), valueChange=True)[0]
pivotB = cmds.keyframe(loopCurve, query=True, eval=True, time=(self.range[1],self.range[1]), valueChange=True)[0]
if oldVal == pivotA:
pivotA = newVal
offsetPercentA = 0
else:
offsetPercentA = float((newVal-pivotA)/(oldVal-pivotA))
if oldVal == pivotB:
pivotB = newVal
offsetPercentB = 0
else:
offsetPercentB = float((newVal-pivotB)/(oldVal-pivotB))
offsetPercentsA.append(offsetPercentA)
offsetPercentsB.append(offsetPercentB)
pivotAs.append(pivotA)
pivotBs.append(pivotB)
else:
offsetVal = newVal - oldVal
offsetValues.append(offsetVal)
#reset change
cmds.undoInfo(stateWithoutFlush=False)
for loopCurve in list(self.allValues.keys()):
if loopCurve in animCurves:
valueChange = self.allValues[loopCurve]
for n, loopValue in enumerate(valueChange):
cmds.keyframe(loopCurve, edit=True, index=(n,n), valueChange=loopValue)
#self.allValues[] = {}
cmds.undoInfo(stateWithoutFlush=True)
#set values for all keys
curvesToUpdate = []
if self.blendRangeMode:
for n, loopCurve in enumerate(animCurves):
time = timeValues[n]
timeOffsetA = .01
timeOffsetB = .01
if time[0] == self.range[0]: timeOffsetA = 0
if time[1] == self.range[1]: timeOffsetB = 0
if timeOffsetA != 0 and timeOffsetB != 0 and not self.range[0] < time[0] <= time[1] < self.range[1]:
cmds.warning("Selected keys out of range %s"%self.range)
continue
offsetPercentA = offsetPercentsA[n]
offsetPercentB = offsetPercentsB[n]
#if offsetPercentA != 0 or offsetPercentB != 0:
pivotA = pivotAs[n]
pivotB = pivotBs[n]
curvesToUpdate.append(loopCurve)
cmds.scaleKey(loopCurve, time=(self.range[0]+timeOffsetA, time[1]), valuePivot=pivotA, valueScale=offsetPercentA)
cmds.scaleKey(loopCurve, time=(time[1]+.01, self.range[1]-timeOffsetB), valuePivot=pivotB, valueScale=offsetPercentB)
else:
for n, loopCurve in enumerate(animCurves):
if offsetValues[n] != 0:
curvesToUpdate.append(loopCurve)
if self.range == "All Keys":
#pass
cmds.keyframe(loopCurve, edit=True, valueChange=offsetValues[n], relative=True)
else:
cmds.keyframe(loopCurve, edit=True, time=(self.range[0], self.range[1]), valueChange=offsetValues[n], relative=True)
self.updateCurrentValues(curvesToUpdate)
cmds.undoInfo(closeChunk=True)
cmds.refresh(suspend=False)
def warn(self):
if self.blendRangeMode:
blendTxt = "Blend Range Mode "
else:
blendTxt = ""
cmds.warning("Transform All %sis ON. Please remember to turn it OFF when you are done. Acting on range: %s"%(blendTxt, self.range))
def setRange(self):
self.range = self.getRange()
if self.range[1] - self.range[0] <= 1: #if only one key selected
if self.blendRangeMode: self.range = [cmds.playbackOptions(query=True, minTime=True), cmds.playbackOptions(query=True, maxTime=True)]
else: self.range = "All Keys"