Updated
This commit is contained in:
4
Scripts/Animation/aTools/commonMods/__init__.py
Normal file
4
Scripts/Animation/aTools/commonMods/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import *
|
230
Scripts/Animation/aTools/commonMods/aToolsMod.py
Normal file
230
Scripts/Animation/aTools/commonMods/aToolsMod.py
Normal 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
|
||||
|
941
Scripts/Animation/aTools/commonMods/animMod.py
Normal file
941
Scripts/Animation/aTools/commonMods/animMod.py
Normal 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
|
||||
|
383
Scripts/Animation/aTools/commonMods/commandsMod.py
Normal file
383
Scripts/Animation/aTools/commonMods/commandsMod.py
Normal 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)
|
||||
|
||||
|
71
Scripts/Animation/aTools/commonMods/uiMod.py
Normal file
71
Scripts/Animation/aTools/commonMods/uiMod.py
Normal 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)
|
||||
|
||||
|
548
Scripts/Animation/aTools/commonMods/utilMod.py
Normal file
548
Scripts/Animation/aTools/commonMods/utilMod.py
Normal 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
|
Reference in New Issue
Block a user