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,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from . import *

View File

@ -0,0 +1,230 @@
'''
========================================================================================================================
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
import os
import shutil
import time
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import utilMod
G.A_NODE = "aTools_StoreNode"
G.USER_FOLDER = G.USER_FOLDER or mel.eval('getenv MAYA_APP_DIR') + os.sep + "aToolsSettings"
G.UM_timerMessage = ""
utilMod.makeDir(G.USER_FOLDER)
def getSceneId(forceCreate=False):
id = loadInfoWithScene("scene", "id") if not forceCreate else False
if not id:
id = time.time()
saveInfoWithScene("scene", "id", id)
return str(id)
def saveInfoWithScene(storeNode, attr, value):
with G.aToolsBar.createAToolsNode:
cmds.undoInfo(stateWithoutFlush=False)
currSel = None
if not cmds.objExists(G.A_NODE) or not cmds.objExists(storeNode): currSel = cmds.ls(selection=True)
if not cmds.objExists(G.A_NODE): cmds.createNode('mute', name=G.A_NODE)
if not cmds.objExists(storeNode): cmds.createNode('mute', name=storeNode)
if currSel: cmds.select(currSel)
if not cmds.isConnected("%s.output"%G.A_NODE, "%s.mute"%storeNode): cmds.connectAttr("%s.output"%G.A_NODE, "%s.mute"%storeNode)
if not cmds.objExists("%s.%s"%(storeNode, attr)): cmds.addAttr(storeNode, longName=attr, dataType="string", keyable=False)
cmds.setAttr("%s.%s"%(storeNode, attr), value, type="string")
cmds.undoInfo(stateWithoutFlush=True)
def loadInfoWithScene(storeNode, attr):
obj = "%s.%s"%(storeNode, attr)
if cmds.objExists(obj):
return cmds.getAttr(obj)
else:
return None
def saveFileWithUser(folder, file, value, ext=None):
filePath = getSaveFilePath("%s%s%s"%(folder, os.sep, file), ext)
folderPath = utilMod.getFolderFromFile(filePath)
if os.path.isfile(filePath): os.remove(filePath)
if not os.path.isdir(folderPath): os.makedirs(folderPath)
newFileContents = "%s"%value
utilMod.writeFile(filePath, newFileContents)
def deleteFileWithUser(folder, file, ext="aTools"):
filePath = getSaveFilePath("%s%s%s"%(folder, os.sep, file), ext)
if os.path.isfile(filePath): os.remove(filePath)
def deleteFolderWithUser(folder):
folderPath = "%s%s%s"%(G.USER_FOLDER, os.sep, folder)
if os.path.isdir(folderPath): shutil.rmtree(folderPath)
def renameFolderWithUser(oldFolder, newFolder):
oldUserFolder = "%s%s%s"%(G.USER_FOLDER, os.sep, oldFolder)
newUserFolder = "%s%s%s"%(G.USER_FOLDER, os.sep, newFolder)
if os.path.isdir(oldUserFolder): os.rename(oldUserFolder, newUserFolder)
def loadFileWithUser(folder, file, ext="aTools"):
filePath = getSaveFilePath("%s%s%s"%(folder, os.sep, file), ext)
readFileContents = utilMod.readFile(filePath)
if readFileContents != None:
return eval(readFileContents[0])
return None
def readFilesWithUser(folder, ext=None):
filePath = getSaveFilePath("%s%s%s"%(folder, os.sep, "dummy"))
folderPath = utilMod.getFolderFromFile(filePath)
if not os.path.isdir(folderPath): return []
filesInFolder = [loopFile for loopFile in os.listdir(folderPath) if ext is None or ext is True or loopFile.endswith(".%s"%ext)]
if ext is None:
for n, loopFile in enumerate(filesInFolder):
filesInFolder[n] = ".".join(loopFile.split(".")[:-1])
return filesInFolder
def readFoldersWithUser(folder):
folderPath = "%s%s%s"%(G.USER_FOLDER, os.sep, folder)
if not os.path.isdir(folderPath): return []
foldersInFolder = [loopFolder for loopFolder in os.listdir(folderPath) if os.path.isdir(folderPath) if loopFolder != ".directory"]
return foldersInFolder
def saveInfoWithUser(file, attr, value, delete=False):
filePath = getSaveFilePath(file)
newFileContents = []
writeNew = True
if isinstance(value, str): value = "\"%s\""%value
readFileContents = utilMod.readFile(filePath)
if readFileContents != None:
for loopLine in readFileContents:
if loopLine.find(attr) == 0:
if not delete:
newFileContents.append("%s = %s\n"%(attr, value))
writeNew = None
else:
if len(loopLine) > 1:
newFileContents.append(loopLine)
if writeNew:
if not delete: newFileContents.append("%s = %s\n"%(attr, value))
utilMod.writeFile(filePath, newFileContents)
def loadInfoWithUser(file, attr):
filePath = getSaveFilePath(file)
readFileContents = utilMod.readFile(filePath)
if readFileContents != None:
for loopLine in readFileContents:
if loopLine.find(attr) == 0:
value = loopLine[(loopLine.find("=")+2):]
return eval(value)
return None
def getUserPref(pref, default):
pref = loadInfoWithUser("userPrefs", pref)
if pref == None: pref = default
return pref
def setUserPref(pref, onOff):
saveInfoWithUser("userPrefs", pref, onOff)
def setPref(pref, preferences, init=False, default=False):
for loopPref in preferences:
name = loopPref["name"]
if pref == name:
if init:
onOff = getPref(pref, preferences)
elif default:
onOff = getDefPref(pref, preferences)
cmds.menuItem("%sMenu"%name, edit=True, checkBox=onOff)
saveInfoWithUser("userPrefs", name, "", True)
else:
onOff = cmds.menuItem("%sMenu"%name, query=True, checkBox=True)
saveInfoWithUser("userPrefs", pref, onOff)
def getPref(pref, preferences):
r = loadInfoWithUser("userPrefs", pref)
if r == None:
default = getDefPref(pref, preferences)
r = default
return r
def getDefPref(pref, preferences):
for loopPref in preferences:
name = loopPref["name"]
if pref == name:
default = loopPref["default"]
return default
def getaToolsPath(level=1, inScriptsFolder=True):
if inScriptsFolder:
mayaAppDir = mel.eval('getenv MAYA_APP_DIR')
scriptsDir = "%s%sscripts%s"%(mayaAppDir, os.sep, os.sep)
aToolsFolder = "%s%saTools%s"%(scriptsDir, os.sep, os.sep)
if level==1: return aToolsFolder
if level==2: return scriptsDir
return utilMod.getFolderFromFile(__file__, level)
def getSaveFilePath(saveFile, ext="aTools"):
saveFilePath = G.USER_FOLDER + os.sep + saveFile
if ext: saveFilePath += ".%s"%ext
return saveFilePath

View File

@ -0,0 +1,941 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
# maya modules
from maya import cmds
from maya import mel
import math
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import utilMod
from aTools.commonMods import aToolsMod
from aTools.animTools import framePlaybackRange
G.lastCurrentFrame = None
G.lastRange = None
G.currNameSpace = None
def getTarget(target, animCurves=None, getFrom=None, rangeAll=None):
# object from curves, object selected, anim curves, attributes, keytimes, keys selected
if target == "keysSel" or target == "keysIndexSel":
if animCurves:
keysSel = []
if getFrom == "graphEditor":
for node in animCurves:
if target == "keysSel": keysSel.append(cmds.keyframe(node, selected=True, query=True, timeChange=True))
if target == "keysIndexSel": keysSel.append(cmds.keyframe(node, selected=True, query=True, indexValue=True))
else:
if rangeAll is None:
timeline_range = getTimelineRange()
allKeys = [cmds.keyframe(node, query=True, timeChange=True) for node in animCurves if cmds.objExists(node)]
allIndexKeys = [cmds.keyframe(node, query=True, indexValue=True) for node in animCurves if cmds.objExists(node)]
keysSel = []
for n, loopKeyArrays in enumerate(allKeys):
keysSel.append([])
if loopKeyArrays:
for nn, loopKey in enumerate(loopKeyArrays):
if rangeAll or timeline_range[0] <= loopKey < timeline_range[1]:
if target == "keysSel": keysSel[n].append(loopKey)
if target == "keysIndexSel": keysSel[n].append(allIndexKeys[n][nn])
return keysSel
elif target == "keyTimes":
if animCurves:
keyTimes = []
for node in animCurves:
keyTimes.append(cmds.keyframe(node, query=True, timeChange=True))
return keyTimes
elif target == "keyIndexTimes":
if animCurves:
keyIndexTimes = []
for node in animCurves:
keyIndexTimes.append(cmds.keyframe(node, query=True, indexValue=True))
return keyIndexTimes
elif target == "keyValues":
if animCurves:
keyValues = []
for node in animCurves:
keyValues.append(cmds.keyframe(node, query=True, valueChange=True))
return keyValues
elif target == "currValues":
if animCurves:
keyValues = []
for node in animCurves:
keyValues.append(cmds.keyframe(node, query=True, eval=True, valueChange=True)[0])
return keyValues
elif target == "keyTangentsAngle":
if animCurves:
keyTangents = []
for n, node in enumerate(animCurves):
indexes = cmds.keyframe(node, query=True, indexValue=True)
keyTangents.append([])
for loopIndex in indexes:
keyTangents[n].append(cmds.keyTangent(node, query=True, index=(loopIndex,loopIndex),inAngle=True, outAngle=True))
return keyTangents
elif target == "keyTangentsY":
if animCurves:
keyTangents = []
for node in animCurves:
keyTangents.append(cmds.keyTangent(node, query=True, iy=True, oy=True))
return keyTangents
elif target == "keyTangentsX":
if animCurves:
keyTangents = []
for node in animCurves:
keyTangents.append(cmds.keyTangent(node, query=True, ix=True, ox=True))
return keyTangents
elif target == "keyTangentsType":
if animCurves:
keyTangents = []
for n, node in enumerate(animCurves):
indexes = cmds.keyframe(node, query=True, indexValue=True)
keyTangents.append([])
for loopIndex in indexes:
keyTangents[n].append(cmds.keyTangent(node, query=True, index=(loopIndex,loopIndex),inTangentType=True, outTangentType=True))
return keyTangents
else: # objFromCurves, attr
if animCurves:
objs = []
attrs = []
for node in animCurves:
if not cmds.objExists(node): continue
for n in range(100): # find transform node (obj) and attribute name
obj = None
attr = None
type = "animBlendNodeEnum"
while type == "animBlendNodeEnum": #skip anim layer nodes
if node is None: break
if cmds.objectType(node) == "animBlendNodeAdditiveRotation":
xyz = node[-1:]
node = cmds.listConnections("%s.output%s"%(node.split(".")[0], xyz), source=False, destination=True, plugs=True, skipConversionNodes=True)
if node is None:
continue
else:
node = node[0]
else:
node = cmds.listConnections("%s.output"%node.split(".")[0], source=False, destination=True, plugs=True, skipConversionNodes=True)
if node is None:
continue
else:
node = node[0]
type = cmds.nodeType(node)
if node is None: break
obj = node.split(".")[0]
attr = node.split(".")[-1]
if type.find("animBlendNodeAdditive") == -1 and type != "animCurveTU": break
objs.append(obj)
attrs.append(attr)
return [objs, attrs]
def getMirrorObjs(selObjs, side="both"):
MIRROR_PATTERN = [["l", "r"], ["lf", "rt"], ["left", "right"]]
SEPARATORS = ["_", "-"]
mirrorObjs = []
mirrorPatern = []
for loopPattern in MIRROR_PATTERN: #add uppercase and title to search
mirrorPatern.append([loopPattern[0], loopPattern[1]])
mirrorPatern.append([loopPattern[0].upper(), loopPattern[1].upper()])
mirrorPatern.append([loopPattern[0].title(), loopPattern[1].title()])
for loopObj in selObjs:
if not loopObj: continue
nameSpaceIndex = loopObj.find(":") + 1
nameSpace = loopObj[:nameSpaceIndex]
objName = loopObj[nameSpaceIndex:]
mirrorObj = objName
sideDetected = None
for loopSeparator in SEPARATORS:
mirrorObj = "%s%s%s"%(loopSeparator, mirrorObj, loopSeparator)
for loopPattern in mirrorPatern:
leftPattern = "%s%s%s"%(loopSeparator, loopPattern[0], loopSeparator)
rightPattern = "%s%s%s"%(loopSeparator, loopPattern[1], loopSeparator)
if side == "both" or side == "left":
if not sideDetected or sideDetected == "left":
doReplace = (mirrorObj.find(leftPattern) != -1)
if doReplace:
sideDetected = "left"
mirrorObj = mirrorObj.replace(leftPattern, rightPattern)
if side == "both" or side == "right":
if not sideDetected or sideDetected == "right":
doReplace = (mirrorObj.find(rightPattern) != -1)
if doReplace:
sideDetected = "right"
mirrorObj = mirrorObj.replace(rightPattern, leftPattern)
mirrorObj = mirrorObj[1:-1]
if mirrorObj == objName:
mirrorObj = None
else:
mirrorObj = "%s%s"%(nameSpace, mirrorObj)
mirrorObjs.append(mirrorObj)
return mirrorObjs
"""
def align(sourceObjs, targetObj, translate=True, rotate=True, suspend=True, onlyCurrFrame=True):
startTime = cmds.timer( startTimer=True)
if not sourceObjs or not targetObj: return
if suspend: cmds.refresh(suspend=True)
currFrame = cmds.currentTime(query=True)
currSel = cmds.ls(selection=True)
tempNull = None
if onlyCurrFrame:
keysSel = [currFrame]
else:
getCurves = getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = getTarget("keysSel", animCurves, getFrom)
keysSel = utilMod.mergeLists(keysSel)
if keysSel == []:
keysSel = [currFrame]
else:
keysSel = [currFrame]
for loopKey in keysSel:
if currFrame != loopKey: cmds.currentTime(loopKey)
if translate:
translation = cmds.xform(targetObj, query=True, ws=True, rotatePivot=True)
if rotate:
rotation = cmds.xform(targetObj, query=True, ws=True, rotation=True)
orderMap = ['xyz', 'yzx', 'zxy', 'xzy', 'yxz', 'zyx']
targetOrder = cmds.getAttr( targetObj+'.ro' )
for loopSourceObj in sourceObjs:
objOrder = cmds.getAttr( loopSourceObj+'.ro' )
if rotate:
if targetOrder != objOrder:
if not tempNull:
tempNull = cmds.group(empty=True, world=True )
if tempNull != None:
cmds.xform(tempNull, ws=True, absolute=False, rotateOrder=orderMap[targetOrder], rotation=rotation)
cmds.xform(tempNull, ws=True, absolute=False, rotateOrder=orderMap[objOrder], p = True)
rotation = cmds.xform(tempNull, query=True, ws=True, rotation=True)
cmds.xform(loopSourceObj, ws=True, rotation=rotation)
cmds.xform(loopSourceObj, ws=True, rotation=rotation)#bug workaround
if translate:
localPivot = cmds.xform(loopSourceObj, query=True, os=True, rotatePivot=True)
cmds.xform(loopSourceObj, ws=True, translation=(localPivot[0]*-1,localPivot[1]*-1,localPivot[2]*-1))
globalPivot = cmds.xform(loopSourceObj, query=True, ws=True, rotatePivot=True)
cmds.move(globalPivot[0]*-1,globalPivot[1]*-1,globalPivot[2]*-1, loopSourceObj, relative=True, worldSpace=True)
cmds.move(translation[0],translation[1],translation[2], loopSourceObj, relative=True, worldSpace=True)
#cmds.xform(loopSourceObj, ws=True, translation=translation)
if tempNull != None and cmds.objExists(tempNull):
cmds.delete(tempNull)
if len(currSel) > 0: cmds.select(currSel, replace=True)
if suspend:
cmds.refresh(suspend=False)
#refresh()
fullTime = cmds.timer( endTimer=True)
print "timer: ", fullTime
"""
def createNull(locatorName="tmp"):
with G.aToolsBar.createAToolsNode: newNull = cmds.spaceLocator(name=locatorName)[0]
cmds.xform(cp=True)
cmds.setAttr(".localScaleX", 0)
cmds.setAttr(".localScaleY", 0)
cmds.setAttr(".localScaleZ", 0)
return newNull
def group(nodes=None, name="aTools_group", empty=True, world=False):
with G.aToolsBar.createAToolsNode:
if nodes: newGroup = cmds.group(nodes, empty=False, name=name, world=world)
else: newGroup = cmds.group(empty=empty, name=name, world=world)
return newGroup
def eulerFilterCurve(animCurves, filter="euler"):
if animCurves:
for loopCurve in animCurves:
#euler filter
if not isNodeRotate(loopCurve): continue
xyzCurves = ["%sX"%loopCurve[:-1], "%sY"%loopCurve[:-1], "%sZ"%loopCurve[:-1]]
apply = True
for loopXyzCurve in xyzCurves:
if not cmds.objExists(loopXyzCurve):
apply = False
break
if apply: cmds.filterCurve(xyzCurves, filter=filter)
def getObjsSel():
return cmds.ls(sl=True)
def getAngle(keyTimeA, keyTimeB, keyValA, keyValB):
relTime = keyTimeB - keyTimeA
relVal = keyValB - keyValA
angle = math.degrees(math.atan(relVal/relTime))
#outOpp = relTimeInA*math.tan(math.radians(outAngleA))
return angle
def getAnimCurves(forceGetFromGraphEditor=False):
# get selected anim curves from graph editor
animCurves = cmds.keyframe(query=True, name=True, selected=True)
#graphEditorFocus = cmds.getPanel(withFocus=True) == "graphEditor1"
visiblePanels = cmds.getPanel(visiblePanels=True)
graphEditor = None
for loopPanel in visiblePanels:
if loopPanel == "graphEditor1":
graphEditor = True
break
getFrom = "graphEditor"
if not animCurves or not graphEditor and not forceGetFromGraphEditor: #get from timeline
getFrom = "timeline"
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
animCurves = cmds.timeControl(G.playBackSliderPython, query=True, animCurveNames=True)
return [animCurves, getFrom]
def getTimelineRange(float=True):
#if G.lastCurrentFrame == cmds.currentTime(query=True): return G.lastRange
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
timeline_range = cmds.timeControl(G.playBackSliderPython, query=True, rangeArray=True)
if float: timeline_range[1] -= .0001
#G.lastRange = timeline_range
#G.lastCurrentFrame = cmds.currentTime(query=True)
return timeline_range
def getTimelineTime():
timelineTime = cmds.currentTime(query=True); timelineTime = (timelineTime, timelineTime)
return timelineTime
def refresh():
cmds.undoInfo(stateWithoutFlush=False)
#cmds.refresh(force=True)
#print "refresh"
cmds.refresh(suspend=False)
cmds.currentTime(cmds.currentTime(query=True), edit=True)
cmds.undoInfo(stateWithoutFlush=True)
def isNodeRotate(node, xyz=None):
isRotate = False
attr = "%s.output"%node.split(".")[0]
type = cmds.getAttr(attr, type=True)
#if type == "double3":
if type == "doubleAngle":
if xyz:
if attr.find("rotate%s"%xyz.upper()) != -1 or (attr.find("Merged_Layer_input") != -1 and attr.find(xyz.upper()) != -1):
isRotate = True
else:
isRotate = True
return isRotate
def isNodeTranslate(node, xyz=None):
isTranslate = False
attr = "%s.output"%node.split(".")[0]
type = cmds.getAttr(attr, type=True)
if type == "doubleLinear":
if xyz:
if attr.find("translate%s"%xyz.upper()) != -1 or (attr.find("Merged_Layer_input") != -1 and attr.find(xyz.upper()) != -1):
isTranslate = True
else:
isTranslate = True
return isTranslate
def isAnimCurveTranslate(aCurve):
isTranslate = False
if aCurve.find("translate") != -1:
isTranslate = True
return isTranslate
def isAnimCurveRotate(aCurve):
isRotate = False
if aCurve.find("rotate") != -1:
isRotate = True
return isRotate
def isAnimCurveScale(aCurve):
isScale = False
if aCurve.find("scale") != -1:
isScale = True
return isScale
def channelBoxSel():
channelsSel = []
mObj = cmds.channelBox('mainChannelBox', query=True, mainObjectList =True)
sObj = cmds.channelBox('mainChannelBox', query=True, shapeObjectList =True)
hObj = cmds.channelBox('mainChannelBox', query=True, historyObjectList =True)
oObj = cmds.channelBox('mainChannelBox', query=True, outputObjectList =True)
mAttr = cmds.channelBox('mainChannelBox', query=True, selectedMainAttributes =True)
sAttr = cmds.channelBox('mainChannelBox', query=True, selectedShapeAttributes =True)
hAttr = cmds.channelBox('mainChannelBox', query=True, selectedHistoryAttributes =True)
oAttr = cmds.channelBox('mainChannelBox', query=True, selectedOutputAttributes =True)
if mObj and mAttr: channelsSel.extend(["%s.%s"%(loopObj, loopAttr) for loopObj in mObj for loopAttr in mAttr if cmds.objExists("%s.%s"%(loopObj, loopAttr))])
if sObj and sAttr: channelsSel.extend(["%s.%s"%(loopObj, loopAttr) for loopObj in sObj for loopAttr in sAttr if cmds.objExists("%s.%s"%(loopObj, loopAttr))])
if hObj and hAttr: channelsSel.extend(["%s.%s"%(loopObj, loopAttr) for loopObj in hObj for loopAttr in hAttr if cmds.objExists("%s.%s"%(loopObj, loopAttr))])
if oObj and oAttr: channelsSel.extend(["%s.%s"%(loopObj, loopAttr) for loopObj in oObj for loopAttr in oAttr if cmds.objExists("%s.%s"%(loopObj, loopAttr))])
return channelsSel
def getAllChannels(objs=None, changed=False, withAnimation=True):
#startTime = cmds.timer( startTimer=True)
allChannels = []
if not objs: objs = getObjsSel()
for loopObj in objs:
if not cmds.objExists(loopObj): continue
isReference = False
if changed: isReference = cmds.referenceQuery(loopObj, isNodeReferenced=True)
#if not withAnimation:
#cmds.listConnections(loopObj, source=True, destination=False, connections=True)
allChannels.append(cmds.listAttr(loopObj, settable=True, keyable=True, locked=False, write=True, read=True, changedSinceFileOpen=isReference))
#allChannels.append([loopAttr for loopAttr in cmds.listAttr(loopObj, settable=True, keyable=True, locked=False, write=True, read=True, changedSinceFileOpen=isReference) if cmds.getAttr("%s.%s"%(loopObj, loopAttr), settable=True)])
shapes = cmds.listRelatives(loopObj, shapes=True, fullPath=True)
if shapes:
for loopShape in shapes:
newChannel = cmds.listAttr(loopShape, userDefined=True, settable=True, keyable=True, locked=False, write=True, read=True)
if newChannel and allChannels[-1]:
allChannels[-1].extend(newChannel)
#fullTime = cmds.timer( endTimer=True)
return allChannels
"""
def getAllChannels(objs=None):
startChrono = cmds.timerX()
total = 0
allChannels = []
if not objs: objs = getObjsSel()
for loopObj in objs:
attrList = cmds.listAttr(loopObj, keyable=True)
allChannels.append([])
if attrList:
total += len(attrList)
for loopAttr in attrList:
if cmds.objExists("%s.%s"%(loopObj, loopAttr)):
if cmds.getAttr("%s.%s"%(loopObj, loopAttr), settable=True):
allChannels[-1].extend(loopAttr)
shapes = cmds.listRelatives(loopObj, shapes=True)
if shapes and allChannels[-1]:
for loopShape in shapes:
attrList = cmds.listAttr(loopShape, userDefined=True, keyable=True)
if attrList:
for loopAttr in attrList:
if cmds.objExists("%s.%s"%(loopObj, loopAttr)):
if cmds.getAttr("%s.%s"%(loopObj, loopAttr), settable=True):
allChannels[-1].extend(loopAttr)
total += len(loopAttr)
endChrono = cmds.timerX(startTime=startChrono)
print "taotal", total, endChrono
return allChannels
"""
def jumpToSelectedKey():
frames = cmds.keyframe(query=True, selected=True)
if frames:
if frames[0] > 0:
size = 0
sum = 0
for loopFrame in frames:
sum += loopFrame
size += 1
average = sum / size
cmds.currentTime(average)
def expandKeySelection(frames = 1):
getCurves = getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = getTarget("keysSel", animCurves, getFrom)
keyTimes = getTarget("keyTimes", animCurves)
# add tail and head keys
for n, loopCurve in enumerate(animCurves):
for key in keysSel[n]:
index = keyTimes[n].index(key)
startIndex = index-frames
endIndex = index+frames
if startIndex < 0: startIndex = 0
cmds.selectKey(loopCurve, addTo=True, index=(startIndex, endIndex))
def getShotCamera():
STORE_NODE = "tUtilities"
CAMERA_ATTR = "cameraSelected"
shotCamera = aToolsMod.loadInfoWithScene(STORE_NODE, CAMERA_ATTR)
if not shotCamera:
cameras = utilMod.getAllCameras()
if cameras:
aToolsMod.saveInfoWithScene(STORE_NODE, CAMERA_ATTR, cameras[0])
return cameras[0]
return shotCamera
def filterNonAnimatedCurves():
curvesShown = cmds.animCurveEditor( 'graphEditor1GraphEd', query=True, curvesShown=True)
if curvesShown:
objsAttrs = getTarget("", curvesShown)
cmds.selectionConnection( 'graphEditor1FromOutliner', e=True, clear=True)
cmds.waitCursor(state=True)
for n, loopCurve in enumerate(curvesShown):
keyValues = cmds.keyframe(loopCurve, query=True, valueChange=True)
if max(keyValues) != min(keyValues):
cmds.selectionConnection('graphEditor1FromOutliner', edit=True, select="%s.%s"%(objsAttrs[0][n], objsAttrs[1][n]))
#framePlaybackRange.framePlaybackRangeFn()
cmds.waitCursor(state=False)
def getAnimData(animCurves=None, showProgress=None):
if animCurves is None:
getCurves = getAnimCurves(True)
animCurves = getCurves[0]
getFrom = getCurves[1]
else:
getFrom = None
if not animCurves: return
if getFrom is None: keysSel = getTarget("keysSel", animCurves, getFrom, rangeAll=True)
else: keysSel = getTarget("keysSel", animCurves, getFrom)
if utilMod.isEmpty(keysSel): return
if showProgress: utilMod.startProgressBar("aTools - Saving animation data...")
objsAttrs = getTarget("", animCurves=animCurves)
objects = objsAttrs[0]
attributes = objsAttrs[1]
animData = {"objects":objects, "animData":[]}
if showProgress:
firstStep = 0
totalSteps = len(animCurves)
estimatedTime = None
status = "aTools - Saving animation data..."
startChrono = None
for thisStep, loopCurve in enumerate(animCurves):
if showProgress: startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
if objects[thisStep] is None: continue
if len(keysSel[thisStep]) == 0: continue
weighted = cmds.keyTangent(loopCurve, query=True, weightedTangents=True)
if weighted is not None: weighted = weighted[0]
objAttr = "%s.%s"%(objects[thisStep], attributes[thisStep])
infinity = cmds.setInfinity(objAttr, query=True, preInfinite=True, postInfinite=True)
animData["animData"].append({"objAttr":objAttr, "curveData":[weighted, infinity], "keyframeData":[], "tangentData":[]})
time = (keysSel[thisStep][0], keysSel[thisStep][-1])
timeChange = cmds.keyframe(loopCurve, query=True, time=time, timeChange=True)
valueChange = cmds.keyframe(loopCurve, query=True, time=time, valueChange=True)
breakdowns = cmds.keyframe(loopCurve, query=True, time=time, breakdown=True)
inTangentType = cmds.keyTangent(loopCurve, query=True, time=time, inTangentType=True)
outTangentType = cmds.keyTangent(loopCurve, query=True, time=time, outTangentType=True)
ix = cmds.keyTangent(loopCurve, query=True, time=time, ix=True)
iy = cmds.keyTangent(loopCurve, query=True, time=time, iy=True)
ox = cmds.keyTangent(loopCurve, query=True, time=time, ox=True)
oy = cmds.keyTangent(loopCurve, query=True, time=time, oy=True)
lock = cmds.keyTangent(loopCurve, query=True, time=time, lock=True)
weightLock = cmds.keyTangent(loopCurve, query=True, time=time, weightLock=True)
for n, loopKey in enumerate(keysSel[thisStep]):
breakdown = (timeChange[n] in breakdowns) if breakdowns else []
keyframe = [timeChange[n], valueChange[n], breakdown]
tangent = [inTangentType[n], outTangentType[n], ix[n], iy[n], ox[n], oy[n], lock[n], weightLock[n]]
animData["animData"][-1]["keyframeData"].append(keyframe)
animData["animData"][-1]["tangentData"].append(tangent)
if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
if showProgress: utilMod.setProgressBar(endProgress=True)
return animData
def applyAnimData(animData, pasteInPlace=True, onlySelectedNodes=False, showProgress=None, status=None):
if animData:
status = "aTools - Applying animation data..." if not status else status
objects = animData["objects"]
if not onlySelectedNodes:
#print "objects1", objects
if len(objects) > 0: objects = [loopObj for loopObj in objects if loopObj is not None and cmds.objExists(loopObj)]
#print "objects2", objects
if len(objects) > 0: cmds.select(objects)
else:
objects = getObjsSel()
if not objects:
cmds.warning("No objects to apply.")
return
cmds.refresh(suspend=True)
if showProgress: utilMod.startProgressBar(status)
if pasteInPlace:
currKey = cmds.currentTime(query=True)
for aData in animData["animData"]:
allKeys = []
keys = aData["keyframeData"]
for n, key in enumerate(keys):
timeChange = aData["keyframeData"][n][0]
allKeys.append(timeChange)
firstKey = 0
if allKeys:
firstKey = min(allKeys)
lastKey = max(allKeys)
cutIn = currKey+firstKey
cuOut = lastKey+firstKey
else:
cutIn = -49999
cuOut = 50000
objsAttrs = [loopItem["objAttr"] for loopItem in animData["animData"]]
existObjsAttrs = [loopObjAttr for loopObjAttr in objsAttrs if cmds.objExists(loopObjAttr)]
createDummyKey(existObjsAttrs)
cmds.cutKey(existObjsAttrs, time=(cutIn, cuOut), clear=True)
if showProgress:
totalSteps = 0
firstStep = 0
thisStep = 0
estimatedTime = None
startChrono = None
for loopObjAttr in existObjsAttrs:
index = objsAttrs.index(loopObjAttr)
aData = animData["animData"][index]
keys = aData["keyframeData"]
totalSteps = totalSteps + len(keys)
for loopObjAttr in existObjsAttrs:
index = objsAttrs.index(loopObjAttr)
aData = animData["animData"][index]
weighted = aData["curveData"][0]
infinity = aData["curveData"][1]
keys = aData["keyframeData"]
for n, key in enumerate(keys):
if showProgress:
if cmds.progressBar(G.progBar, query=True, isCancelled=True ):
refresh()
utilMod.setProgressBar(endProgress=True)
return
startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
#read values
timeChange = aData["keyframeData"][n][0]
valueChange = aData["keyframeData"][n][1]
breakdown = aData["keyframeData"][n][2]
inTangentType = aData["tangentData"][n][0]
outTangentType = aData["tangentData"][n][1]
ix = aData["tangentData"][n][2]
iy = aData["tangentData"][n][3]
ox = aData["tangentData"][n][4]
oy = aData["tangentData"][n][5]
lock = aData["tangentData"][n][6]
weightLock = aData["tangentData"][n][7]
if pasteInPlace: timeChange = timeChange-firstKey+currKey
time = (timeChange,timeChange)
# create key
cmds.setKeyframe(loopObjAttr, time=time, value=valueChange, noResolve=True)
if n == 0:
cmds.keyTangent(loopObjAttr, weightedTangents=weighted)
cmds.setInfinity(loopObjAttr, edit=True, preInfinite=infinity[0], postInfinite=infinity[1])
if breakdown: cmds.keyframe(loopObjAttr, edit=True, time=time, breakdown=True)
cmds.keyTangent(loopObjAttr, time=time, ix=ix, iy=iy, ox=ox, oy=oy, lock=lock)
if weighted: cmds.keyTangent(loopObjAttr, time=time, weightLock=weightLock)
cmds.keyTangent(loopObjAttr, time=time, inTangentType=inTangentType, outTangentType=outTangentType)
if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
thisStep += 1
deleteDummyKey(existObjsAttrs)
if showProgress:
refresh()
utilMod.setProgressBar(endProgress=True)
def selectCtrlGroup(g):
sel = cmds.ls(selection=True)
if not sel and G.currNameSpace == None:
cmds.warning("Please select any controller.")
return
if sel:
nameSpaces = utilMod.getNameSpace(sel)
G.currNameSpace = nameSpaces[0][0]
cmds.select(clear=True)
nameSpaceAndObjs = ["%s%s"%(G.currNameSpace, loopObj) for loopObj in g]
cmds.select(nameSpaceAndObjs)
def setAttribute(obj, attr, value):
sel = cmds.ls(selection=True)
if not sel and G.currNameSpace == None:
cmds.warning("Please select any controller.")
return
if sel:
nameSpaces = utilMod.getNameSpace(sel)
G.currNameSpace = nameSpaces[0][0]
cmds.setAttr("%s%s.%s"%(G.currNameSpace, obj, attr), value)
def filterNoneObjects(objects):
objs = []
if objects:
for loopObj in objects:
if loopObj:
if cmds.objExists(loopObj):
objs.append(loopObj)
return objs
def createDummyKey(objects=None, select=False):
objs = filterNoneObjects(objects)
if len(objs) == 0: objs = getObjsSel()
cmds.setKeyframe(objs, time=(-50000, -50000), insert=False)
if select: cmds.selectKey(objs, replace=True, time=(-50000, -50000))
def deleteDummyKey(objects=None):
objs = filterNoneObjects(objects)
if not objs: objs = getObjsSel()
if len(objs) > 0:
cmds.cutKey(objs, time=(-50000, -50000), clear=True)
def getDefaultValue(node):
type = cmds.nodeType(node)
if "animCurve" in type:
target = getTarget("", [node], "")
object = target[0][0]
attr = target[1][0]
else:
object, attr = node.split(".")
if not object: return 0
isScale = isAnimCurveScale(node)
if isScale:
value = 1
return value
value = cmds.attributeQuery(attr, node=object, listDefault=True)
if len(value) > 0: value = value[0]
else: value = 0
return value
def frameSection(nudge=24):
curvesShown = cmds.animCurveEditor( 'graphEditor1GraphEd', query=True, curvesShown=True)
if not curvesShown: return
firstSelKey = cmds.keyframe(selected=True, query=True, timeChange=True)
#lastKey = max(cmds.keyframe(selected=False, query=True, timeChange=True))
lastKey = cmds.playbackOptions(query=True, maxTime=True)
if firstSelKey: #if key is selected
firstSelKey = min(firstSelKey)
else:
#firstSelKey = min(cmds.keyframe(selected=False, query=True, timeChange=True))
firstSelKey = cmds.playbackOptions(query=True, minTime=True)
try:
if G.AM_lastFrameSection + nudge < lastKey and G.AM_lastCurvesShown == curvesShown:
firstSelKey = G.AM_lastFrameSection + nudge
except:
pass
G.AM_lastFrameSection = firstSelKey
G.AM_lastCurvesShown = curvesShown
framePlaybackRange.framePlaybackRangeFn(rangeStart=(firstSelKey-1), rangeEnd=(firstSelKey+nudge+2))
cmds.currentTime(firstSelKey, edit=True)
def getTokens(obj, att):
objAttr = "%s.%s"%(obj, att)
enumTokens = []
if cmds.objExists(objAttr):
enumFields = None
type = cmds.getAttr(objAttr, type=True)
if type == "enum":
if utilMod.isDynamic(obj, att):
enumFields = cmds.addAttr("%s.%s"%(obj, att), query=True, enumName=True)
if enumFields: enumTokens = enumFields.split(":")
return enumTokens

View File

@ -0,0 +1,383 @@
'''
========================================================================================================================
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
import math
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import animMod
from aTools.commonMods import utilMod
from itertools import cycle
def toggleRotateMode():
rot = cmds.manipRotateContext('Rotate', query=True, mode=True)
# 0 = Local, 1 = Global, 2 = Gimbal
if (rot == 0):
cmds.manipRotateContext('Rotate', edit=True, mode=1)
elif (rot == 1):
cmds.manipRotateContext('Rotate', edit=True, mode=2)
else:
cmds.manipRotateContext('Rotate', edit=True, mode=0)
def toggleMoveMode():
mov = cmds.manipMoveContext('Move', query=True, mode=True)
# 0 = Local, 1 = Global, 2 = Gimbal
if (mov == 0):
cmds.manipMoveContext('Move', edit=True, mode=1)
elif (mov == 1):
cmds.manipMoveContext('Move', edit=True, mode=2)
else:
cmds.manipMoveContext('Move', edit=True, mode=0)
def orientMoveManip():
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]
orient = cmds.xform(targetObj, query=True, ws=True, rotation=True)
orientRad = [math.radians(loopDeg) for loopDeg in orient]
cmds.manipMoveContext('Move', edit=True, mode=6, orientAxes=orientRad)
cmds.select(sourceObjs, replace=True)
cmds.setToolTo("Move")
def cameraOrientMoveManip():
selection = cmds.ls(selection=True)
if len(selection) == 0: return
shotCamera = animMod.getShotCamera()
if not shotCamera or not cmds.objExists(shotCamera):
cmds.warning("No shot camera detected.")
return
cmds.refresh(suspend=True)
sourceObjs = selection[0:-1]
targetObj = selection[-1]
locator = animMod.createNull("tempCameraOrient_locator")
cameraNode = utilMod.getCamFromSelection([shotCamera])[0]
G.aToolsBar.align.align([locator], targetObj, translate=True, rotate=False)
with G.aToolsBar.createAToolsNode: constraint = cmds.aimConstraint(cameraNode, locator, name="tempCameraOrient_constraint", aimVector=[0, 0, 1], worldUpType="objectrotation", worldUpObject=cameraNode, maintainOffset=False)[0]
cmds.select(selection)
cmds.select(locator, add=True)
orientMoveManip()
if cmds.objExists(locator): cmds.delete(locator)
if cmds.objExists(constraint): cmds.delete(constraint)
cmds.refresh(suspend=False)
def toggleObj(type):
panelName = cmds.getPanel(withFocus=True)
value = eval("cmds.modelEditor(panelName, query=True, %s=True)"%type[0])
for loopType in type:
eval("cmds.modelEditor(panelName, edit=True, %s=not value)"%loopType)
def togglePanelLayout():
layouts = ["graphEditor1", "persp"]
currLayout = getCurrentPanelLayout()
licycle = cycle(layouts)
nextItem = next(licycle)
for loopItem in layouts:
nextItem = next(licycle)
if nextItem == currLayout:
nextItem = next(licycle)
break
setPanelLayout(nextItem)
def setPanelLayout(layout):
if layout == "graphEditor1":
mel.eval("setNamedPanelLayout \"Single Perspective View\";"+\
"scriptedPanel -e -rp modelPanel4 graphEditor1;")
else:
mel.eval("setNamedPanelLayout \"Single Perspective View\";"+\
"lookThroughModelPanel persp modelPanel4;")
def getCurrentPanelLayout():
if "graphEditor1" in cmds.getPanel(visiblePanels=True):
return "graphEditor1"
else:
return "persp"
def setSmartKey(time=None, animCurves=None, select=True, insert=True, replace=True, addTo=False):
if not time: time = animMod.getTimelineTime()
getFrom = "timeline"
if not animCurves:
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves and getFrom != "timeline":
cmds.setKeyframe(animCurves, time=time, insert=insert)
if select: cmds.selectKey(animCurves, replace=replace, addTo=addTo, time=time)
else:
objects = animMod.getObjsSel()
if objects:
channelboxSelObjs = animMod.channelBoxSel()
if channelboxSelObjs:
#objsAttrs = ["%s.%s"%(loopObj, loopChannelboxSel) for loopObj in objects for loopChannelboxSel in channelboxSel]
#key selected attributes in the channelbox
for n, loopObjAttr in enumerate(channelboxSelObjs):
prevKey = cmds.findKeyframe(loopObjAttr, time=(time,time), which="previous")
tangentType = cmds.keyTangent(loopObjAttr, query=True, outTangentType=True, time=(prevKey,prevKey))
if not tangentType: #if there is no key
tangentType = cmds.keyTangent(query=True, g=True, outTangentType=True)
inTangentType = tangentType[0].replace("fixed", "auto").replace("step", "auto")
outTangentType = tangentType[0].replace("fixed", "auto")
cmds.setKeyframe(loopObjAttr, time=time, insert=False, shape=False, inTangentType=inTangentType, outTangentType=outTangentType)
continue
inTangentType = tangentType[0].replace("fixed", "auto").replace("step", "auto")
outTangentType = tangentType[0].replace("fixed", "auto")
cmds.setKeyframe(loopObjAttr, time=time, insert=insert, shape=False, inTangentType=inTangentType, outTangentType=outTangentType)
else:
#allChannels = animMod.getAllChannels(objects)
#objAttrs = ["%s.%s"%(objects[n], loopAttr) for n, loopObj in enumerate(allChannels) for loopAttr in loopObj]
prevKeys = [cmds.findKeyframe(obj, time=(time,time), which="previous") for obj in objects]
tangentTypes = [cmds.keyTangent(obj, query=True, outTangentType=True, time=(prevKeys[n],prevKeys[n])) for n, obj in enumerate(objects)]
#prevKeys = [cmds.findKeyframe(obj, time=(time,time), which="previous") for obj in objAttrs]
#tangentTypes = [cmds.keyTangent(obj, query=True, outTangentType=True, time=(prevKeys[n],prevKeys[n])) for n, obj in enumerate(objAttrs)]
#key all atributes
cmds.setKeyframe(objects, time=time, insert=insert, shape=False)
#cmds.setKeyframe(objAttrs, time=time, insert=insert, shape=False)
if insert: #will force create key if there is no key
for n, loopTangent in enumerate(tangentTypes):
if not loopTangent:
cmds.setKeyframe(objects[n], time=time, insert=False, shape=False)
#cmds.setKeyframe(objAttrs[n], time=time, insert=False, shape=False)
def unselectChannelBox():
currList = cmds.channelBox('mainChannelBox', query=True, fixedAttrList=True)
cmds.channelBox('mainChannelBox', edit=True, fixedAttrList=[""])
function = lambda *args:cmds.channelBox('mainChannelBox', edit=True, fixedAttrList=currList)
G.deferredManager.sendToQueue(function, 1, "unselectChannelBox")
def goToKey(which, type="key"):
cmds.undoInfo(stateWithoutFlush=False)
cmds.refresh(suspend=True)
frame = cmds.findKeyframe(timeSlider=True, which=which) if type == "key" else cmds.currentTime(query=True) + (1 if which == "next" else -1)
cmds.currentTime(frame)
G.aToolsBar.timeoutInterval.removeFromQueue("goToKey")
G.aToolsBar.timeoutInterval.setTimeout(animMod.refresh, sec=.05, id="goToKey")
cmds.undoInfo(stateWithoutFlush=True)
def selectOnlyKeyedObjects():
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
if animCurves:
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
objects = animMod.getTarget("", animCurves, getFrom)[0]
selObjs = []
for n, loopObj in enumerate(objects):
if len(keysSel[n]) > 0:
if not loopObj in selObjs:
selObjs.append(loopObj)
if len(selObjs) > 0: cmds.select(selObjs, replace=True)
def cropTimelineAnimation():
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
getFrom = getCurves[1]
range = animMod.getTimelineRange()
if animCurves:
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
for n, aCurve in enumerate(animCurves):
firstKey = keyTimes[n][0]
lastKey = keyTimes[n][-1]
if range[0] >= firstKey:
cmds.cutKey(aCurve, time=(firstKey, range[0]-1), clear=True)
if range[1] <= lastKey:
cmds.cutKey(aCurve, time=(range[1], lastKey), clear=True)
def smartSnapKeys():
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
if not animCurves or len(animCurves) == 0: return
getFrom = getCurves[1]
keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom)
keysSel = animMod.getTarget("keysSel", animCurves, getFrom)
hasDecimalKeys = False
for loopKey in utilMod.mergeLists(keysSel):
if loopKey != round(loopKey) > 0:
hasDecimalKeys = True
break
if not hasDecimalKeys: return
keyTangentsType = animMod.getTarget("keyTangentsType", animCurves, getFrom)
firstStep = 0
totalSteps = len(animCurves)
estimatedTime = None
status = "aTools - Smart Snap Curves..."
startChrono = None
utilMod.startProgressBar(status)
for thisStep, loopCurve in enumerate(animCurves):
startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status)
if None in [keyTimes[thisStep], keysSel[thisStep]]: continue
stepKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "step"]
linearKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "linear"]
decimalKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and loopKey not in stepKeys + linearKeys]
for loopKey in stepKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey))
for loopKey in linearKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey))
if len(decimalKeys) == 0: continue
if not getFrom:
if cmds.keyframe(query=True, selected=True) != None: getFrom = "graphEditor"
#inLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][0] == "linear"]
#outLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][1] == "linear"]
createKeys = list(set([round(loopKey) for loopKey in decimalKeys]))
selectKeys = []
#print "inlinearKeys", inLinearKeys, outLinearKeys
if getFrom == "graphEditor":
selectKeys = list(set([round(loopKey) for loopKey in keysSel[thisStep] if round(loopKey) in createKeys]))
for loopKey in createKeys: cmds.setKeyframe(loopCurve, time=(loopKey, loopKey), insert=True)
for loopKey in selectKeys: cmds.selectKey(loopCurve, addTo=True, time=(loopKey, loopKey))
for loopKey in decimalKeys: cmds.cutKey(loopCurve, time=(loopKey, loopKey))
#for loopKey in outLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), outTangentType="linear")
#for loopKey in inLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), inTangentType="linear")
estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps)
utilMod.setProgressBar(endProgress=True)
def scrubbingUndo(onOff):
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
pc = "from maya import cmds;"
rc = "from maya import cmds;"
if not onOff:
pc += "cmds.undoInfo(stateWithoutFlush=False); "
rc += "cmds.undoInfo(stateWithoutFlush=True); "
pc += "cmds.timeControl('%s',edit=True,beginScrub=True)"%G.playBackSliderPython
rc += "cmds.timeControl('%s',edit=True,endScrub=True)"%G.playBackSliderPython
cmds.timeControl( G.playBackSliderPython, edit=True, pressCommand=pc, releaseCommand=rc)
def topWaveform(onOff):
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
onOff = 'top' if onOff else 'both'
cmds.timeControl(G.playBackSliderPython, edit=True, waveform=onOff)
def eulerFilterSelection():
getCurves = animMod.getAnimCurves()
animCurves = getCurves[0]
animMod.eulerFilterCurve(animCurves)
def setThreePanelLayout():
shotCamera = animMod.getShotCamera()
if not shotCamera: shotCamera = "persp"
mel.eval("toolboxChangeQuickLayoutButton \"Persp/Graph/Hypergraph\" 2;"+\
#"ThreeTopSplitViewArrangement;"+\
"lookThroughModelPanel %s hyperGraphPanel2;"%shotCamera+\
"lookThroughModelPanel persp modelPanel4;")
#"scriptedPanel -e -rp modelPanel2 graphEditor1;")
viewports = [view for view in cmds.getPanel(type='modelPanel') if view in cmds.getPanel(visiblePanels=True)]
defaultCameras = ['front', 'persp', 'side', 'top']
for view in viewports:
camera = utilMod.getCamFromSelection([cmds.modelEditor(view, query=True, camera=True)])
cameraTransform = camera[0]
cameraShape = camera[1]
if cameraTransform in defaultCameras:
utilMod.animViewportViewMode(view)
if cameraTransform == "persp":
cmds.camera(cameraTransform, edit=True, orthographic=False)
cmds.setAttr("%s.nearClipPlane"%cameraShape, 1000)
cmds.setAttr("%s.farClipPlane"%cameraShape, 10000000)
cmds.setAttr("%s.focalLength"%cameraShape, 3500)
else:
utilMod.cameraViewMode(view)
cmds.setAttr("%s.displayFilmGate"%cameraShape, 1)
cmds.setAttr("%s.overscan"%cameraShape, 1)

View File

@ -0,0 +1,71 @@
'''
========================================================================================================================
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
import os
FILE_PATH = __file__
class BaseSubUI(object):
def __init__(self, parent, buttonSizeDict):
self.btnSizeDict = buttonSizeDict
self.parentLayout = parent
#get values
self.ws = self.btnSizeDict["small"][0]
self.hs = self.btnSizeDict["small"][1]
self.wb = self.btnSizeDict["big"][0]
self.hb = self.btnSizeDict["big"][1]
def getImagePath(imageName, ext="png", imageFolder="img"):
imageFile = "%s.%s"%(imageName, ext)
relativePath = os.path.abspath(os.path.join(FILE_PATH, os.pardir, os.pardir))
imgPath = os.path.abspath(os.path.join(relativePath, imageFolder, imageFile))
return imgPath
def getModulePath(filePath, moduleName):
relativePath = os.sep.join(filePath.split(os.sep)[:-1])
return relativePath + os.sep + moduleName
def getModKeyPressed():
mods = cmds.getModifiers()
if mods == 1:
return "shift"
if mods == 4:
return "ctrl"
if mods == 8:
return "alt"
if mods == 5:
return "ctrlShift"
if mods == 9:
return "altShift"
if mods == 12:
return "altCtrl"
if mods == 13:
return "altCtrlShift"
def clearMenuItems(menu):
menuItens = cmds.popupMenu(menu, query=True, itemArray=True)
if menuItens:
for loopMenu in menuItens:
if cmds.menuItem(loopMenu, query=True, exists=True): cmds.deleteUI(loopMenu)

View File

@ -0,0 +1,548 @@
'''
========================================================================================================================
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
import os
import copy
import webbrowser
import urllib.request, urllib.error, urllib.parse
from maya import OpenMaya
from datetime import datetime, timedelta
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
G.UM_timerMessage = ""
def getAllAnimCurves(selection=False):
if selection:
sel = cmds.ls(selection=True)
if len(sel) == 0: return []
return cmds.keyframe(sel, query=True, name=True)
return cmds.ls(type=["animCurveTA","animCurveTL","animCurveTT","animCurveTU"])
def onlyShowObj(types, panelName=None):
allTypes = ["nurbsCurves", "nurbsSurfaces", "polymeshes", "subdivSurfaces", "planes", "lights", "cameras", "controlVertices", "grid", "hulls", "joints", "ikHandles", "deformers", "dynamics", "fluids", "hairSystems", "follicles", "nCloths", "nParticles", "nRigids", "dynamicConstraints", "locators", "manipulators", "dimensions", "handles", "pivots", "textures", "strokes"]
if not panelName: panelName = cmds.getPanel(withFocus=True)
#views = cmds.getPanel(type='modelPanel')
#if panelName in views:
if not cmds.modelEditor(panelName, exists=True): return
cmds.modelEditor(panelName, edit=True, allObjects=True, displayAppearance="smoothShaded", displayTextures=True)
#
for loopType in allTypes:
if not loopType in types:
eval("cmds.modelEditor(panelName, edit=True, %s=False)"%loopType)
else:
eval("cmds.modelEditor(panelName, edit=True, %s=True)"%loopType)
def cameraViewMode(panelName=None):
if not panelName: panelName = cmds.getPanel(withFocus=True)
onlyShowObj(["polymeshes"], panelName)
if (len(cmds.ls(type="light")) > 0): lights = "all"
else : lights = "default"
cmds.modelEditor(panelName, edit=True, displayLights=lights, selectionHiliteDisplay=False)
def animViewportViewMode(panelName=None):
if not panelName: panelName = cmds.getPanel(withFocus=True)
onlyShowObj(["nurbsCurves", "polymeshes", "manipulators"], panelName)
cmds.modelEditor(panelName, edit=True, displayLights="default", selectionHiliteDisplay=True)
def getAllCameras():
defaultCameras = ['frontShape', 'perspShape', 'sideShape', 'topShape']
cameras = [cam for cam in cmds.ls(cameras=True) if cam not in defaultCameras]
return cameras
def download(progBar, downloadUrl, saveFile):
response = None
try:
response = urllib.request.urlopen(downloadUrl, timeout=60)
except:
pass
if response is None: return
fileSize = int(response.info().getheaders("Content-Length")[0])
fileSizeDl = 0
blockSize = 128
output = open(saveFile,'wb')
cmds.progressBar( progBar,
edit=True,
beginProgress=True,
progress=0,
maxValue=100 )
while True:
buffer = response.read(blockSize)
if not buffer:
output.close()
cmds.progressBar(progBar, edit=True, progress=100)
break
fileSizeDl += len(buffer)
output.write(buffer)
p = float(fileSizeDl) / fileSize *100
cmds.progressBar(progBar, edit=True, progress=p)
return output
def dupList(l):
return copy.deepcopy(l)
def timer(mode="l", function=""):
if mode == "s":
try:
startTime = cmds.timer( startTimer=True)
G.UM_timerMessage = "startTime: %s\n"%startTime
G.UM_timerLap = 1
except:
pass
elif mode == "l":
try:
lapTime = cmds.timer( lapTime=True)
G.UM_timerMessage += "lapTime %s: %s\n"%(G.UM_timerLap, lapTime)
G.UM_timerLap += 1
except:
pass
elif mode == "e":
try:
fullTime = cmds.timer( endTimer=True)
G.UM_timerMessage += "Timer: %s took %s sec.\n"%(function, fullTime)
except:
pass
print((G.UM_timerMessage))
#cmds.timer( startTimer=True)
#print (cmds.timer( endTimer=True))
def getRenderResolution():
defaultResolution = "defaultResolution"
width = cmds.getAttr(defaultResolution+".width")
height = cmds.getAttr(defaultResolution+".height")
return [width, height]
def mergeLists(lists):
mergedList = []
if lists:
for loopList in lists:
if not loopList: continue
for loopItem in loopList:
if not loopItem in mergedList:
mergedList.append(loopItem)
return mergedList
def listIntersection(list, sublist):
return list(filter(set(list).__contains__, sublist))
def getNameSpace(objects):
nameSpaces = []
objectNames = []
for loopObj in objects:
nameSpaceIndex = loopObj.find(":") + 1
nameSpace = loopObj[:nameSpaceIndex]
objName = loopObj[nameSpaceIndex:]
nameSpaces.append(nameSpace)
objectNames.append(objName)
return [nameSpaces, objectNames]
def listAllNamespaces():
removeList = ["UI", "shared"]
nameSpaces = list(set(cmds.namespaceInfo(listOnlyNamespaces=True))- set(removeList))
if nameSpaces: nameSpaces.sort()
return nameSpaces
def makeDir(directory):
if not os.path.exists(directory):
try:
os.makedirs(directory)
except:
print(("Was not able to create folder: %s"%directory))
def listReplace(list, search, replace):
newList = []
for loopList in list:
for n, loopSearch in enumerate(search):
loopList = loopList.replace(loopSearch, replace[n])
#if replaced != loopList: break
newList.append(loopList)
return newList
def killScriptJobs(jobVar):
exec("%s = %s or []"%(jobVar, jobVar))
jobs = eval(jobVar)
#kill previous jobs
if jobs:
for job in jobs:
try:
if cmds.scriptJob (exists = job):
cmds.scriptJob (kill = job)
except:
Warning ("Job " + str(job) + " could not be killed!")
jobs = []
exec("%s = %s"%(jobVar, jobs))
def getCurrentCamera():
panel = cmds.getPanel(withFocus=True)
views = cmds.getPanel(type='modelPanel')
if panel in views:
camera = cmds.modelEditor(panel, query=True, camera=True)
return camera
def getFolderFromFile(filePath, level=0):
folderArray = filePath.split(os.sep)[:-1-level]
newFolder = ""
for loopFolder in folderArray:
newFolder += loopFolder + os.sep
return newFolder
def formatPath(path):
path = path.replace("/", os.sep)
path = path.replace("\\", os.sep)
return path
def writeFile(filePath, contents):
contentString = ""
if contents != None:
for loopLine in contents:
contentString += "%s"%loopLine
# write
try:
output = open(filePath, 'w') # Open file for writing
output.write(contentString)
output.close()
except:
print(("aTools - Error writing file: %s"%filePath))
def readFile(filePath):
try:
with open(filePath, 'r'):
input = open(filePath, 'r') # Open file for reading
return input.readlines() # Read entire file into a list of line strings
except IOError:
return None
def toTitle(string):
newString = ""
for n, loopChar in enumerate(string):
if n == 0:
newString += "%s"%loopChar.upper()
elif loopChar.isupper() and not string[n-1].isupper() and not string[n-1] == " ":
newString += " %s"%loopChar
else:
newString += "%s"%loopChar
return newString.replace("_", " ")
def capitalize(string):
spacers = [" ", "_"]
newString = ""
cap = True
for n, loopChar in enumerate(string):
if cap: newString += loopChar.upper()
else: newString += loopChar
cap = False
if loopChar in spacers:
cap = True
return newString
def getUrl(url):
webbrowser.open(url)
def loadDefaultPrefs(preferences, *args):
for loopPref in preferences:
name = loopPref["name"]
setPref(name, preferences, False, True)
def isEmpty(list):
try:
return all(map(isEmpty, list))
except TypeError:
return False
def startProgressBar(status="", isInterruptable=True):
G.progBar = G.progBar or mel.eval('$aTools_gMainProgressBar = $gMainProgressBar')
cmds.progressBar( G.progBar,
edit=True,
beginProgress=True,
status=status,
isInterruptable=isInterruptable,
progress=0,
maxValue=100 )
"""
cmds.progressWindow(title='Doing Nothing',
status=status,
isInterruptable=isInterruptable,
progress=0,
maxValue=100 )
"""
def setProgressBar(status=None, progress=None, endProgress=None):
G.progBar = G.progBar or mel.eval('$aTools_gMainProgressBar = $gMainProgressBar')
if status: cmds.progressBar(G.progBar, edit=True, status=status)
if progress: cmds.progressBar(G.progBar, edit=True, progress=progress)
if endProgress: cmds.progressBar(G.progBar, edit=True, endProgress=True)
def getMayaFileName(path=False):
if path == "path": return cmds.file(query=True, sceneName=True)
fileName = cmds.file(query=True, sceneName=True, shortName=True)
if fileName: shotName = ".".join(fileName.split(".")[:-1])
else: shotName = "Unsaved_shot"
return shotName
def getCamFromSelection(sel):
if len(sel) > 0:
if "camera" in cmds.nodeType(sel[0], inherited=True):
transformNode = cmds.listRelatives(sel[0], parent=True)[0]
shapeNode = sel[0]
elif cmds.nodeType(sel[0]) == "transform":
transformNode = sel[0]
shapeNode = cmds.listRelatives(sel[0], shapes=True)[0]
return [transformNode, shapeNode]
def isAffected(nodeAffected, nodeDriver):
driverFamily = cmds.ls(nodeDriver, dagObjects=True)
if nodeAffected in driverFamily: return True
nodeAffectedConnections = cmds.listHistory(nodeAffected)
if nodeDriver in nodeAffectedConnections: return True
steps1to3=set()
steps1to3.update(steps1and3)
step4=[]
for each in (cmds.ls(list(steps1to3),shapes=True)):
try:
step4.extend(cmds.listConnections(each+'.instObjGroups', t='shadingEngine', et=1))
except TypeError:
pass
steps1to3.update(step4)
steps1to4=set()
steps1to4.update(steps1to3)
steps1to4.update(step4)
step5=set(steps1to4)
step5.update(cmds.listHistory(list(steps1to4)))
print(step5)
def getMObject(objectName):
'''given an object name string, this will return the MDagPath api handle to that object'''
sel = OpenMaya.MSelectionList()
sel.add( str( objectName ) )
obj = OpenMaya.MObject()
sel.getDependNode(0,obj)
return obj
def getMDagPath(nodeName):
"""
Convenience function that returns a MDagPath for a given Maya DAG node.
"""
selList = OpenMaya.MSelectionList()
selList.add(nodeName)
mDagPath = OpenMaya.MDagPath()
selList.getDagPath(0, mDagPath)
return mDagPath
def isDynamic(object, attribute):
MSelectionList = OpenMaya.MSelectionList()
MSelectionList.add(object)
node = OpenMaya.MObject()
MSelectionList.getDependNode(0, node)
fnThisNode = OpenMaya.MFnDependencyNode(node)
try:
attr = fnThisNode.attribute(attribute)
plug = OpenMaya.MPlug(node, attr)
return plug.isDynamic()
except:
pass
def formatTime(sec):
sec = timedelta(seconds=int(sec))
d = datetime(1,1,1) + sec
l = ["day", "hour", "minute", "second"]
for loopL in l:
t = eval("d.%s"%loopL)
if loopL == "day": t -= 1
if t > 0:
if t > 1: loopL+= "s"
return [t, loopL]
return None
def chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status):
if not startChrono and thisStep == firstStep +1: startChrono = cmds.timerX()
if estimatedTime:
estimatedTimeSt = "%s %s"%(estimatedTime[0],estimatedTime[1])
status += " about %s remaining"%estimatedTimeSt
p = float(thisStep) / totalSteps * 100
setProgressBar(status=status, progress=p)
return startChrono
def chronoEnd(startChrono, firstStep, thisStep, totalSteps):
if thisStep >= firstStep +2:
endChrono = cmds.timerX(startTime=startChrono)
estimatedTime = formatTime((((endChrono+1)/(thisStep+1))*totalSteps)-endChrono)
return estimatedTime
def checkScriptJobEvents(onOff=True):
killScriptJobs("G.checkScriptJobEventsJobs")
if onOff:
events = cmds.scriptJob(listEvents=True)
ignore = ["idle", "idleHigh"]
for loopEvent in events:
if loopEvent not in ignore:
G.checkScriptJobEventsJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =(loopEvent, "print('Script Job Event: %s')"%loopEvent )))
def hasInternet(url):
try:
proxy = urllib.request.ProxyHandler({})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
response = urllib.request.urlopen(url, timeout=60)
return True
except: pass
return False
def deselectTimelineRange():
currSel = cmds.ls(selection=True)
if len(currSel) == 0:
cmds.select(G.A_NODE)
cmds.select(None)
else:
cmds.select(currSel)
def transferAttributes(fromNode, toNode):
fromAttrs = {}
for loopAttr in cmds.listAttr(fromNode):
try: fromAttrs[loopAttr] = cmds.getAttr("%s.%s"%(fromNode, loopAttr))
except: pass
for loopAttr in list(fromAttrs.keys()):
value = fromAttrs[loopAttr]
try: cmds.setAttr("%s.%s"%(toNode, loopAttr), value)
except: pass
def getAllViewports():
return [view for view in cmds.getPanel(type='modelPanel') if view in cmds.getPanel(visiblePanels=True) and view != "scriptEditorPanel1"]
def rangeToList(range):
list = []
frame = range[0]
while True:
list.append(frame)
frame += 1
if frame > range[1]: break
return list
def getApiMatrix (matrix):
mat = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList(matrix, mat)
return mat