This commit is contained in:
2025-11-25 02:04:55 +08:00
parent 47a95bc71c
commit 900de70539
207 changed files with 12728 additions and 0 deletions

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,319 @@
'''
========================================================================================================================
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 generalTools.aToolsGlobals import aToolsGlobals as G
from maya import OpenMaya, OpenMayaAnim, OpenMayaUI
class DeferredManager(object):
def __init__(self):
if G.deferredManager: self.queue = G.deferredManager.queue
else: self.queue = {}
#self.queue = {}#temp
G.deferredManager = self
self.running = False
self.nextId = None
#test
"""
self.sendToQueue((lambda *args:self.printe('functionHigh1')), 1)
self.sendToQueue((lambda *args:self.printe('functionLow1')), 100)
self.sendToQueue((lambda *args:self.printe('functionHigh2')), 1)
self.sendToQueue((lambda *args:self.printe('functionMedium1')), 50, "id1")
self.sendToQueue((lambda *args:self.printe('functionMedium2')), 50, "id1")
self.sendToQueue((lambda *args:self.printe('functionMedium3')), 50, "id1")
self.sendToQueue((lambda *args:self.printe('functionLow2')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow3')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow4')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow5')), 100)
self.sendToQueue((lambda *args:self.printe('functionMedium4')), 50, "id2")
self.sendToQueue((lambda *args:self.printe('functionHigh3')), 1)
self.sendToQueue((lambda *args:self.printe('functionLow6')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow7')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow8')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow9')), 100)
self.sendToQueue((lambda *args:self.printe('functionMedium5')), 50, "id2")
self.sendToQueue((lambda *args:self.printe('functionMedium6')), 50, "id2")
self.sendToQueue((lambda *args:self.printe('functionMedium10')), 50)
self.sendToQueue((lambda *args:self.printe('functionMedium11')), 50)
self.sendToQueue((lambda *args:self.printe('functionLow10')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow11')), 100)
self.sendToQueue((lambda *args:self.printe('functionLow12')), 100)
self.sendToQueue((lambda *args:self.printe('functionMedium7')), 50, "id1")
self.sendToQueue((lambda *args:self.printe('functionMedium8')), 50, "id1")
self.sendToQueue((lambda *args:self.printe('functionMedium9')), 50, "id1")
"""
return
self.runQueue()
def printe(self, what):
#pass
print(what)
def sendToQueue(self, function, priority=1, id="default"):
if priority not in self.queue: self.queue[priority] = {}
if id not in self.queue[priority]: self.queue[priority][id] = []
self.queue[priority][id].append(function)
if not self.running:
self.running = True
cmds.evalDeferred(self.runQueue)
def runQueue(self):
if len(self.queue) == 0: return
self.running = True
priority = sorted(self.queue)[0]
if len(self.queue[priority]) > 0:
keys = list(self.queue[priority].keys())
id = self.nextId or keys[0]
if id not in self.queue[priority]: id = keys[0]
function = self.queue[priority][id].pop(0)
try: function()
except: print(("aTools Deferred Manager Error#%s/%s: %s"%(priority, id, function)))
self.nextId = keys[0]
if id in keys:
index = keys.index(id)
if index < len(keys)-1: self.nextId = keys[index+1]
else: self.nextId = keys[0]
if id in self.queue[priority] and len(self.queue[priority][id]) == 0: self.queue[priority].pop(id, None)
if len(self.queue[priority]) == 0: self.queue.pop(priority, None)
if len(self.queue) > 0:
cmds.evalDeferred(self.runQueue)
return
self.running = False
def removeFromQueue(self, id):
for loopChunk in self.queue:
chunk = self.queue[loopChunk]
if id in chunk: chunk.pop(id, None)
def inQueue(self, id):
results = 0
for loopChunk in self.queue:
chunk = self.queue[loopChunk]
if id in chunk: results += len(chunk[id])
return results
DeferredManager()
class TimeoutInterval(object):
def __init__(self):
if not G.aToolsBar: return
G.aToolsBar.timeoutInterval = self
G.deferredManager.removeFromQueue("timeoutInterval")
self.queue = []
def setTimeout(self, function, sec, offset=0, xTimes=1, id=None, interval=None):
timeNow = cmds.timerX()
timeToExec = timeNow + sec + offset
self.queue.append([function, timeToExec, sec, xTimes, id, interval])
self.runQueue()
def runQueue(self):
if len(self.queue) > 0:
timeNow = cmds.timerX()
for loopQueue in self.queue:
timeToExec = loopQueue[1]
if timeToExec <= timeNow:
function = loopQueue[0]
sec = loopQueue[2]
xTimes = loopQueue[3]
id = loopQueue[4]
interval = loopQueue[5]
timeToExec = timeNow + sec
xTimes -= 1
function()
if loopQueue in self.queue: self.queue.remove(loopQueue)
if xTimes > 0 or interval: self.queue.append([function, timeToExec, sec, xTimes, id, interval])
if len(self.queue) > 0:
priority = 1
for loopQueue in self.queue:
interval = loopQueue[5]
id = loopQueue[4]
if interval:
priority = 50
break
G.deferredManager.sendToQueue(self.runQueue, priority, "timeoutInterval")
def setInterval(self, function, sec, offset=0, id="general"):
self.setTimeout(function, sec, offset, id=id, interval=True)
def stopInterval(self, idToStop):
for loopQueue in self.queue:
id = loopQueue[4]
if id == idToStop: self.queue.remove(loopQueue)
def removeFromQueue(self, id):
toRemove = []
for loopQueue in self.queue:
loopId = loopQueue[4]
if id == loopId: toRemove.append(loopQueue)
for loopRemove in toRemove: self.queue.remove(loopRemove)
TimeoutInterval()
class CreateAToolsNode(object):
def __init__(self):
if not G.aToolsBar: return
G.aToolsBar.createAToolsNode = self
def __enter__(self):
#print "enter"
G.animationCrashRecovery.checkNodeCreated = False
def __exit__(self, type, value, traceback):
#print "exit"
G.animationCrashRecovery.checkNodeCreated = True
CreateAToolsNode()
class CallbackManager(object):
def __init__(self):
if G.callbackManager: self.queue = G.callbackManager.queue
else: self.queue = {}
G.callbackManager = self
self.clearQueue()
def __del__(self):
#print "CallbackManager deleted"
self.clearQueue()
def sendToQueue(self, job, type, id):
#print "sendToQueue", job, type, id
newQueue = {"job":job, "type":type}
if id not in self.queue: self.queue[id] = []
self.queue[id].append(newQueue)
def removeFromQueue(self, id):
if id not in self.queue: return
toRemove = []
for loopQueue in self.queue[id]:
loopJob = loopQueue["job"]
loopType = loopQueue["type"]
if loopType == "scriptJob": self.removeScriptJob(loopJob, loopType, id)
else: self.removeApiCallback(loopJob, loopType, id)
toRemove.append(loopQueue)
for loopRemove in toRemove: self.queue[id].remove(loopRemove)
if len(self.queue[id]) == 0: self.queue.pop(id, None)
def removeScriptJob(self, job, type, id):
try:
if cmds.scriptJob(exists=job): cmds.scriptJob(kill=job, force=True)
except: print(("aTools CallbackManager could not remove job %s/%s/%s"%(id, type, job)))
def removeApiCallback(self, job, type, id):
#print "removeApiCallback", job, type, id
function = eval("%s.removeCallback"%type)
try: function(job)
except: cmds.warning("aTools CallbackManager could not remove job %s/%s/%s"%(id, type, job))
def clearQueue(self):
for loopId in list(self.queue.keys()): self.removeFromQueue(loopId)
def inQueue(self, id):
results = 0
for loopId in list(self.queue.keys()):
if loopId == id: results += len(self.queue[id])
return results
CallbackManager()

View File

@@ -0,0 +1,24 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
class AToolsGlobals(object):
def __getattr__(self, attr):
return None
aToolsGlobals = AToolsGlobals()

View File

@@ -0,0 +1,925 @@
'''
========================================================================================================================
Author: Alan Camilo
www.alancamilo.com
Modified: Michael Klimenko
Requirements: aTools Package
------------------------------------------------------------------------------------------------------------------------
To install aTools, please follow the instructions in the file how_to_install.txt
------------------------------------------------------------------------------------------------------------------------
To unistall aTools, go to menu (the last button on the right), Uninstall
========================================================================================================================
'''
import importlib
import sys
import urllib.request, urllib.error, urllib.parse
import shutil
import zipfile
import os
import webbrowser
from maya import cmds
from maya import mel
from maya import OpenMaya
from maya import OpenMayaAnim
from generalTools.aToolsGlobals import aToolsGlobals as G
from commonMods import uiMod
from commonMods import utilMod
from commonMods import animMod
from commonMods import commandsMod
from commonMods import aToolsMod
import setup
from generalTools import hotkeys; importlib.reload(hotkeys)
from generalTools import tumbleOnObjects; importlib.reload(tumbleOnObjects)
from animTools import animationCrashRecovery; importlib.reload(animationCrashRecovery)
from animTools import framePlaybackRange; importlib.reload(framePlaybackRange)
from animTools import jumpToSelectedKey; importlib.reload(jumpToSelectedKey)
animationCrashRecovery = animationCrashRecovery.AnimationCrashRecovery()
tumbleOnObjects = tumbleOnObjects.TumbleOnObjects()
versionInfoPath = "%sversion_info.txt"%aToolsMod.getaToolsPath(inScriptsFolder=False)
versionInfoContents = utilMod.readFile(versionInfoPath)
if versionInfoContents:
VERSION = versionInfoContents[0].split(" ")[-1].replace("\n", "")
WHATISNEW = "".join(versionInfoContents[1:])
else:
VERSION = "2.0.0"
WHATISNEW = "aTools Animation Bar"
KEYSLIST = ["Up", "Down", "Left", "Right", "", "Page_Up", "Page_Down", "Home", "End", "Insert", "", "Return", "Space", "", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]
SITE_URL = "http://camiloalan.wix.com/atoolswebsite"
ATOOLS_FOLDER = "http://www.trickorscript.com/aTools/"
UPDATE_URL = "%slatest_version.txt"%ATOOLS_FOLDER
DOWNLOAD_URL = "%saTools.zip"%ATOOLS_FOLDER
lastUsedVersion = aToolsMod.loadInfoWithUser("userPrefs", "lastUsedVersion")
HELP_URL = "http://camiloalan.wix.com/atoolswebsite#!help/cjg9"
DONATE_URL = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RQLT89A239K6"
PREFS = [{ "name":"tumbleOnObjects",
"command":"tumbleOnObjects.switch(onOff)",
"default":True
},{ "name":"autoFramePlaybackRange",
"command":"framePlaybackRange.toggleframePlaybackRange(onOff)",
"default":False
},{ "name":"autoJumpToSelectedKey",
"command":"jumpToSelectedKey.togglejumpToSelectedKey(onOff)",
"default":False
},{ "name":"autoSmartSnapKeys",
"command":"self.autoSmartSnapKeys.switch(onOff)",
"default":False
},{ "name":"animationCrashRecovery",
"command":"animationCrashRecovery.switch(onOff)",
"default":True
},{ "name":"selectionCounter",
"command":"self.selectionCounter.switch(onOff)",
"default":True
},{ "name":"autoSave",
"command":"cmds.autoSave(enable=onOff)",
"default":cmds.autoSave(query=True, enable=True)
},{ "name":"topWaveform",
"command":"commandsMod.topWaveform(onOff)",
"default":True
},{ "name":"playbackAllViews",
"command":"onOff = 'all' if onOff else 'active'; cmds.playbackOptions(view=onOff)",
"default":True
},{ "name":"displayAffected",
"command":"cmds.displayAffected(onOff)",
"default":False
},{ "name":"undoQueue",
"command":"if onOff: cmds.undoInfo( state=True, infinity=False, length=300)",
"default":True
},{ "name":"scrubbingUndo",
"command":"commandsMod.scrubbingUndo(onOff)",
"default":True
},{ "name":"zoomTowardsCenter",
"command":"cmds.dollyCtx('dollyContext', edit=True, dollyTowardsCenter=onOff)",
"default":cmds.dollyCtx('dollyContext', query=True, dollyTowardsCenter=True)
},{ "name":"cycleCheck",
"command":"cmds.cycleCheck(evaluation=onOff)",
"default":cmds.cycleCheck(query=True, evaluation=True)
}]
class GeneralTools_Gui(uiMod.BaseSubUI):
def createLayout(self):
mainLayout = cmds.rowLayout(numberOfColumns=6, parent=self.parentLayout)
#manipulator orientation
#cmds.iconTextButton("manipOrientButton", style='textOnly', label='-', h=self.hb, annotation="Selected objects", command=updateManipOrient)
#launchManipOrient()
self.autoSmartSnapKeys = AutoSmartSnapKeys()
self.selectionCounter = SelectionCounter()
#selection
cmds.iconTextButton("selectionCounterButton", style='textOnly', font="smallPlainLabelFont", label='0', h=self.hb, annotation="Selected objects")
cmds.popupMenu("selectionCounterButtonMenu", button=1, postMenuCommand=self.selectionCounter.populateMenu)
#animation crash recovery
cmds.image("animationCrashRecoveryLed", w=14, h=14, annotation="Test")
#menu
cmds.iconTextButton(style='iconOnly', w=self.wb, h=self.hb, image= uiMod.getImagePath("aTools"), highlightImage= uiMod.getImagePath("aTools copy"), annotation="aTools Menu")
self.popUpaToolsMenu()
self.update = Update()
self.update.about = self.about
self.update.checkUpdates(self, mainLayout)
# set default config and startup scripts
self.setDefaultConfig()
# end createLayout
def popUpaToolsMenu(self):
cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 1), button=1)
cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 3), button=3)
def populateaToolsMenu(self, menu, button, *args):
#print menu
#print button
#menu = menu[0]
uiMod.clearMenuItems(menu)
subMenu = cmds.menuItem("animBotMenu", subMenu=True, label='animBot - the new aTools' , tearOff=True, parent=menu)
cmds.menuItem("shelfButtonMenu", label="Install animBot", command=installAnimBot, parent=subMenu)
cmds.menuItem( label="Watch Launch Video", command=watchLaunchVideo, parent=subMenu)
cmds.menuItem( label="Join the Community", command=joinTheCommunity, parent=subMenu)
cmds.menuItem(divider=True, parent=menu)
shortPrefs = PREFS[:4]
for loopPref in shortPrefs:
name = loopPref["name"]
cmds.menuItem('%sMenu'%name, label=utilMod.toTitle(name), command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=menu)
#ANIMATION CRASH RECOVERY
animationCrashRecoveryPref = PREFS[4]
cmds.menuItem("animationCrashRecoveryMenu", label='Animation Crash Recovery' , command=lambda *args: self.setPref(animationCrashRecoveryPref["name"]), checkBox=self.getPref(animationCrashRecoveryPref["name"]), parent=menu)
cmds.menuItem(optionBox=True, command=animationCrashRecovery.optionBoxWindow, parent=menu)
cmds.menuItem(divider=True, parent=menu)
subMenu = cmds.menuItem("prefsMenu", subMenu=True, label='Preferences' , tearOff=True, parent=menu)
self.commandsAndHotkeys = CommandsAndHotkeys()
cmds.menuItem(label="Commands and Hotkeys", command=self.commandsAndHotkeys.openGui, parent=subMenu)
cmds.menuItem(divider=True, parent=subMenu)
shortPrefs = PREFS[5:]
for loopPref in shortPrefs:
name = loopPref["name"]
cmds.menuItem('%sMenu'%name, label=utilMod.toTitle(name), command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=subMenu)
cmds.menuItem(divider=True, parent=subMenu)
cmds.menuItem("loadDefaultsMenu", label="Load Defaults", command=self.loadDefaultPrefs, parent=subMenu)
cmds.menuItem("shelfButtonMenu", label="Create Toggle on Shelf", command=shelfButton, parent=menu)
cmds.menuItem( label="Refresh", command=refreshATools, parent=menu)
cmds.menuItem( label="Uninstall", command=self.uninstall, parent=menu)
cmds.menuItem( divider=True )
cmds.menuItem( label="Help", command=self.help, parent=menu)
cmds.menuItem( label="About", command=self.about, parent=menu)
def setPref(self, pref, init=False, default=False):
for loopPref in PREFS:
name = loopPref["name"]
if pref == name:
command = loopPref["command"]
if init:
onOff = self.getPref(pref)
elif default:
onOff = self.getDefPref(pref)
cmds.menuItem("%sMenu"%name, edit=True, checkBox=onOff)
aToolsMod.saveInfoWithUser("userPrefs", name, "", True)
else:
onOff = cmds.menuItem("%sMenu"%name, query=True, checkBox=True)
aToolsMod.saveInfoWithUser("userPrefs", pref, onOff)
exec(command)
def getPref(self, pref):
r = aToolsMod.loadInfoWithUser("userPrefs", pref)
if r == None:
default = self.getDefPref(pref)
r = default
return r
def getDefPref(self, pref):
for loopPref in PREFS:
name = loopPref["name"]
if pref == name:
default = loopPref["default"]
return default
def loadDefaultPrefs(self, *args):
for loopPref in PREFS:
name = loopPref["name"]
self.setPref(name, False, True)
def setDefaultConfig(self):
#STATIC PREFS
# tumble config
#cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0, autoOrthoConstrain=False, orthoLock=False)
cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0)
cmds.dollyCtx( 'dollyContext', edit=True, alternateContext=True, scale=1.0, localDolly=True, centerOfInterestDolly=False)
#timeline ticks display
G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
cmds.timeControl(G.playBackSliderPython, edit=True, showKeys="mainChannelBox", showKeysCombined=True, animLayerFilterOptions="active")
#tickDrawSpecial Color
# seems to fail on maya 2024
# cmds.displayRGBColor('timeSliderTickDrawSpecial',1,1,.4)
#CUSTOMIZABLE PREFS
for loopPref in PREFS:
name = loopPref["name"]
self.setPref(name, True)
def uninstall(self, *args):
message = "Are you sure you want to uninstall aTools?"
confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='No', cancelButton='No', dismissString='No' )
if confirm == 'Yes':
from animTools.animBar import animBarUI; importlib.reload(animBarUI)
#aToolsPath = aToolsMod.getaToolsPath(2)
aToolsFolder = aToolsMod.getaToolsPath()
#if aToolsPath in sys.path: sys.path.remove(aToolsPath)
G.deferredManager.sendToQueue(G.aToolsBar.delWindows, 1, "uninstall_delWindows")
G.deferredManager.sendToQueue(lambda *args:setup.install('', True), 1, "uninstall_install")
#delete files
if os.path.isdir(aToolsFolder): shutil.rmtree(aToolsFolder)
cmds.warning("Uninstall complete! If you want to install aTools in the future, go to %s."%SITE_URL)
def help(self, *args):
webbrowser.open_new_tab(HELP_URL)
def about(self, warnUpdate=None, *args):
winName = "aboutWindow"
title = "About" if not warnUpdate else "aTools has been updated!"
if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
window = cmds.window( winName, title=title)
form = cmds.formLayout(numberOfDivisions=100)
pos = 10
minWidth = 300.0
# Creating Elements
object = cmds.image(image= uiMod.getImagePath("aTools_big"))
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
object = cmds.text( label="aTools - Version %s"%VERSION, font="boldLabelFont")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
#=========================================
pos += 30
object = cmds.text( label="More info:")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
#=========================================
object = cmds.text( label="<a href=\"%s\">aTools website</a>"%SITE_URL, hyperlink=True)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
#=========================================
pos += 15
object = cmds.text( label="Author: Alan Camilo")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
#=========================================
object = cmds.text( label="<a href=\"http://www.alancamilo.com/\">www.alancamilo.com</a>", hyperlink=True)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
#========================================= pos += 15
pos += 15
object = cmds.text( label="Adaped: Michael Klimenko")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
#=========================================
object = cmds.text( label="<a href=\"https://github.com/MKlimenko/\">My GitHub</a>", hyperlink=True)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
#=========================================
minWidth = 550.0
w = 210
object = cmds.text( label="Do you like aTools?", w=w)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-50), ( object, 'right', 10)] )
#=========================================
object = cmds.iconTextButton(label="Buy Me a Beer!", style="iconAndTextVertical", bgc=(.3,.3,.3), h=45, w=w, command=lambda *args: webbrowser.open_new_tab(DONATE_URL), image= uiMod.getImagePath("beer"), highlightImage= uiMod.getImagePath("beer copy"))
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-30), ( object, 'right', 10)] )
object = cmds.text( label="I really appreciate\nthe support!", w=w)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos+20), ( object, 'right', 10)] )
if warnUpdate:
pos += 40
object = cmds.text( label="aTools has been updated to version %s. What is new?"%VERSION, align="left")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos -= 20
# open bit link - next big thing
#webbrowser.open('http://bit.ly/2inAinL', new=0, autoraise=True)
#=========================================
pos += 40
object = cmds.text( label=WHATISNEW, align="left")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
#=========================================
for x in range(WHATISNEW.count("\n")):
pos += 13
pos += 25
cmds.setParent( '..' )
cmds.showWindow( window )
whatsNewWidth = cmds.text(object, query=True, width=True) + 15
wid = whatsNewWidth if whatsNewWidth > minWidth else minWidth
cmds.window( winName, edit=True, widthHeight=(wid, pos))
class Update(object):
def __init__(self):
G.GT_wasUpdated = G.GT_wasUpdated or None
def tryUpdate(self):
return True
def checkUpdates(self, gui, layout, *args):
if self.tryUpdate():
if not G.GT_wasUpdated:
hasUpdate = self.hasUpdate()
if hasUpdate != False:
cmds.iconTextButton(label="Updating...", style='textOnly', h=gui.hb, parent=layout)
cmds.progressBar("aToolsProgressBar", maxValue=100, width=50, parent=layout)
if hasUpdate == "offline_update":
offlinePath = aToolsMod.loadInfoWithUser("userPrefs", "offlinePath")
offlineFolder = offlinePath[0]
offlineFilePath = "%s%saTools.zip"%(offlineFolder, os.sep)
downloadUrl = "file:///%s%saTools.zip"%(offlineFolder, os.sep)
fileModTime = os.path.getmtime(offlineFilePath)
offline = [offlineFilePath, fileModTime]
else:
downloadUrl = DOWNLOAD_URL
offline = None
function = lambda *args:self.updateaTools(downloadUrl, offline)
G.deferredManager.sendToQueue(function, 1, "checkUpdates")
return
self.warnUpdate()
self.warnAnimBot()
def updateaTools(self, downloadUrl, offline=None, *args):
aToolsPath = aToolsMod.getaToolsPath(2)
aToolsFolder = aToolsMod.getaToolsPath()
oldaToolsFolder = "%saTools.old"%aToolsPath
tmpZipFile = "%stmp.zip"%aToolsPath
#delete temp
if os.path.isfile(tmpZipFile): os.remove(tmpZipFile)
if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)
output = utilMod.download("aToolsProgressBar", downloadUrl, tmpZipFile)
if not output:
cmds.warning("Atools - Update failed.")
return
#rename aTools to old
if os.path.isdir(aToolsFolder): os.rename(aToolsFolder, oldaToolsFolder)
#uncompress file
zfobj = zipfile.ZipFile(tmpZipFile)
for name in zfobj.namelist():
uncompressed = zfobj.read(name)
# save uncompressed data to disk
filename = utilMod.formatPath("%s%s"%(aToolsPath, name))
d = os.path.dirname(filename)
if not os.path.exists(d): os.makedirs(d)
if filename.endswith(os.sep): continue
output = open(filename,'wb')
output.write(uncompressed)
output.close()
#delete temp
zfobj.close()
if os.path.isfile(tmpZipFile): os.remove(tmpZipFile)
if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)
setup.install(offline=offline)
#refresh
G.GT_wasUpdated = True
refreshATools()
def hasUpdate(self):
return False
def warnUpdate(self):
if G.GT_wasUpdated:
G.GT_wasUpdated = None
if lastUsedVersion != VERSION:
aToolsMod.saveInfoWithUser("userPrefs", "lastUsedVersion", VERSION)
# Disabled: Don't show update notification window
# G.deferredManager.sendToQueue(lambda *args:self.about(warnUpdate=True), 50, "warnUpdate")
def warnAnimBot(self):
try:
import animBot
except ImportError:
pref = aToolsMod.loadInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain")
if not pref:
# Disabled: Don't show animBot retirement warning
# G.deferredManager.sendToQueue(self.atoolsIsRetiring, 50, "warnAnimBot")
pass
def dontShowAgain(self, onOff):
aToolsMod.saveInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain", onOff)
def atoolsIsRetiring(self):
winName = "atoolsIsRetiringWindow"
title = "aTools is Retiring..."
if cmds.window(winName, query=True, exists=True):
cmds.deleteUI(winName)
window = cmds.window( winName, title=title)
form = cmds.formLayout(numberOfDivisions=100)
pos = 10
minWidth = 300.0
# Creating Elements
object = cmds.text( label="aTools is giving place to animBot, a more robust,\nsmart and intuitive toolset. ", align="left")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 15
object = cmds.image(image=uiMod.getImagePath("atools_animbot"))
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 100
object = cmds.text( label="Three Steps for Full Awesomeness:", fn="boldLabelFont")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 20
object = cmds.button(label="1) Install animBot and have fun!", bgc=(.3,.3,.3), h=45, w=280, command=installAnimBot)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 45
object = cmds.button(label="2) Watch the launch video.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao"))
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 45
object = cmds.button(label="3) Join the community.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439"))
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 65
object = cmds.text(align="left", label="The upgrade will be optional and although aTools\nwon't get feature updates, it will be available forever.\nPlease check the community for information about\nanimBot development progress.")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 80
object = cmds.text( label="Enjoy!")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 20
object = cmds.text( label="-Alan")
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 20
object = cmds.checkBox(label="Don't show this again", value=False, changeCommand=self.dontShowAgain)
cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
pos += 20
pos += 10
cmds.setParent( '..' )
cmds.showWindow( window )
cmds.window( winName, edit=True, widthHeight=(minWidth, pos))
class SelectionCounter(object):
def __init__(self):
self.defaultWidth = 25
def update(self):
selectionCount = len(cmds.ls(selection=True))
cmds.iconTextButton("selectionCounterButton", edit=True, label="%s"%selectionCount)
cmds.iconTextButton("selectionCounterButton", edit=True, w=self.defaultWidth)
def populateMenu(self, parent, *args):
menuItens = cmds.popupMenu(parent, query=True, itemArray=True)
if menuItens:
for loopMenu in menuItens:
if cmds.menuItem(loopMenu, query=True, exists=True): cmds.deleteUI(loopMenu)
selection = cmds.ls(selection=True)
selection.sort()
for loopSel in selection:
cmds.menuItem('%sMenu'%loopSel, label=loopSel, parent=parent, command=lambda x, loopSel=loopSel, *args: self.selectFromMenu(loopSel))
def selectFromMenu(self, selection):
cmds.select(selection)
def switch(self, onOff):
utilMod.killScriptJobs("G.selectionCounterScriptJobs")
cmds.iconTextButton("selectionCounterButton", edit=True, visible=False)
if onOff:
cmds.iconTextButton("selectionCounterButton", edit=True, visible=True)
G.selectionCounterScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.update )))
self.update()
class AutoSmartSnapKeys(object):
def __init__(self):
utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")
def switch(self, onOff):
utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")
if onOff:
G.autoSmartSnapKeysJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.smartSnapKeys )))
def smartSnapKeys(self):
rangeVisible = cmds.timeControl( G.playBackSliderPython, query=True, rangeVisible=True )
if not rangeVisible: return
cmds.undoInfo(stateWithoutFlush=False)
commandsMod.smartSnapKeys()
cmds.undoInfo(stateWithoutFlush=True)
class CommandsAndHotkeys(object):
def __init__(self):
self.allColors = ["yellow", "green", "blue", "purple", "red", "orange", "gray"]
self.colorValues = {"yellow":(1,0.97,0.4),
"green" :(0.44,1,0.53),
"blue" :(0.28,0.6,1),
"purple":(0.640,0.215,0.995),
"red" :(1,0.4,0.4),
"orange":(1,0.6,0.4),
"gray" :(0.5,0.5,0.5)}
self.reassignCommandsAtStartup()
def openGui(self, *args):
winName = "commandsWindow"
height = 26
commands = []
names = []
hotkeysDict = [[]]
allHotkeys = hotkeys.getHotkeys()
totalItems = sum(len(x) for x in allHotkeys)
itemsCount = 0
aB = 0
totalColums = 2
for n, loopHotkey in enumerate(allHotkeys):
if itemsCount > (totalItems/totalColums) * (aB+1):
aB += 1
hotkeysDict.append([])
itemsCount += len(loopHotkey)
for loopItem in loopHotkey:
hotkeysDict[aB].append(loopItem)
hotkeysDict[aB][-1]["colorValue"] = self.colorValues[self.allColors[n]]
if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
window = cmds.window( winName, title = "Commands and Hotkeys")
mainLayout = cmds.columnLayout(adjustableColumn=True)
columnsLayout = cmds.rowColumnLayout(numberOfColumns=totalColums)
for loopColumn in range(totalColums):
parent = cmds.rowColumnLayout(numberOfColumns=7, columnSpacing=([2,5], [3,3], [4,3], [5,1], [6,5], [7,5]), parent=columnsLayout)
cmds.text(label='Command', h=height)
cmds.text(label='Ctl', h=height)
cmds.text(label='Alt', h=height)
cmds.text(label='Key', h=height)
cmds.text(label='', h=height)
cmds.text(label='Set Hotkey', h=height)
cmds.text(label='Assigned to', align="left", h=height)
for loopIndex, loopCommand in enumerate(hotkeysDict[loopColumn]):
command = loopCommand["command"]
name = loopCommand["name"]
key = loopCommand["hotkey"]
alt = loopCommand["alt"]
ctl = loopCommand["ctl"]
toolTip = loopCommand["toolTip"]
color = loopCommand["colorValue"]
hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name)
if hotkeyData != None:
key = hotkeyData[0]
alt = hotkeyData[1]
ctl = hotkeyData[2]
cmds.button("command%s"%name, label=utilMod.toTitle(name), command=command, annotation=toolTip, h=height, bgc=color, parent=parent)
cmds.checkBox('ctl%s'%name, label='', value=ctl, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
cmds.checkBox('alt%s'%name, label='', value=alt, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
cmds.scrollField('key%s'%name, w=80, text=key, keyPressCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
cmds.button(label=" ", h=height, parent=parent)
self.popSpecialHotkeys(name)
cmds.button(label='>', command=lambda x, name=name, command=command, *args: self.setHotkey(self.getHotkeyDict([name], [command])), h=height, parent=parent)
cmds.text("query%s"%name, align="left", label=self.hotkeyCheck(key, ctl, alt), font="plainLabelFont", h=height, parent=parent)
commands.append(command)
names.append(name)
#cmds.button(label="Set Hotkey", command=lambda *args: getHotkeyDict([name], [command], [key], [alt], [ctl], [cmd]))
self.updateHotkeyCheck(name)
#cmds.rowLayout(numberOfColumns=2, columnAttach=([1, 'left', 0],[2, 'right', 0]), adjustableColumn=2)
cmds.button(label="Load Defaults", command=lambda *args: self.loadHotkeys(True), parent=mainLayout)
cmds.button(label="Set All Hotkeys", command=lambda *args: self.setHotkey(self.getHotkeyDict(names, commands)), parent=mainLayout)
cmds.showWindow( window )
def loadHotkeys(self, defaults=False):
allHotkeys = hotkeys.getHotkeys()
hotkeysDict = []
for n, loopHotkey in enumerate(allHotkeys):
for loopItem in loopHotkey:
hotkeysDict.append(loopItem)
for loopIndex, loopCommand in enumerate(hotkeysDict):
command = loopCommand["command"]
name = loopCommand["name"]
key = loopCommand["hotkey"]
alt = loopCommand["alt"]
ctl = loopCommand["ctl"]
toolTip = loopCommand["toolTip"]
if not defaults:
hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name)
if hotkeyData != None:
key = hotkeyData[0]
alt = hotkeyData[1]
ctl = hotkeyData[2]
cmds.checkBox('ctl%s'%name, edit=True, value=ctl)
cmds.checkBox('alt%s'%name, edit=True, value=alt)
cmds.scrollField('key%s'%name, edit=True, text=key)
self.updateHotkeyCheck(name)
def popSpecialHotkeys(self, name):
cmds.popupMenu("popSpecialHotkeysMenu", button=1)
for loopKey in KEYSLIST:
if loopKey == "":
cmds.menuItem( divider=True )
else:
cmds.menuItem ("menu%s"%loopKey, label=str(loopKey), command=lambda x, name=name, loopKey=loopKey, *args: self.typeSpecialKey(name, loopKey))
cmds.setParent( '..', menu=True )
def typeSpecialKey(self, name, text):
cmds.scrollField("key%s"%name, edit=True, text=text)
self.updateHotkeyCheck(name)
def getHotkeyDict(self, names, commands):
hotkeysDict = []
for n, loopName in enumerate(names):
command = commands[n]
name = loopName
key = cmds.scrollField("key%s"%loopName, query=True, text=True)
alt = cmds.checkBox("alt%s"%loopName, query=True, value=True)
ctl = cmds.checkBox("ctl%s"%loopName, query=True, value=True)
if len(key) > 1: key = key[0]
hotkeysDict.append({"name":"%s"%name,
"command":"%s"%command,
"hotkey":"%s"%key,
"alt":alt,
"ctl":ctl
})
return hotkeysDict
def setHotkey(self, hotkeyDict):
message = "Are you sure?\n\n"
#format message
for loopIndex, loopCommand in enumerate(hotkeyDict):
command = loopCommand["command"]
name = loopCommand["name"]
key = loopCommand["hotkey"]
alt = loopCommand["alt"]
ctl = loopCommand["ctl"]
q = cmds.text("query%s"%name, query=True, label=True)
commandKeys = ""
if ctl: commandKeys += "Ctl + "
if alt: commandKeys += "Alt + "
message += "%s (%s%s)"%(name, commandKeys, key)
if q != "": message += " is assigned to: %s"%q
message += "\n"
confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
if confirm == 'Yes':
for loopIndex, loopCommand in enumerate(hotkeyDict):
command = loopCommand["command"]
name = loopCommand["name"]
key = loopCommand["hotkey"]
alt = loopCommand["alt"]
ctl = loopCommand["ctl"]
cmds.nameCommand(name, command='python("%s");'%command, annotation=name)
cmds.hotkey(k=key, alt=alt, ctl=ctl, name=name)
aToolsMod.saveInfoWithUser("hotkeys", name, [key, alt, ctl])
self.updateHotkeyCheck(name)
cmds.savePrefs( hotkeys=True )
def hotkeyCheck(self, key, ctl, alt):
if key != "":
q = cmds.hotkey(key, query=True, alt=alt, ctl=ctl, name=True)
if q != None and "NameCom" in q: q = q[7:]
return q
else:
return ""
def updateHotkeyCheck(self, name):
function = lambda name=name, *args: self.delayedUpdateHotkeyCheck(name)
G.deferredManager.sendToQueue(function, 1, "updateHotkeyCheck")
def delayedUpdateHotkeyCheck(self, name):
command = cmds.button("command%s"%name, query=True, label=True)
key = cmds.scrollField("key%s"%name, query=True, text=True)
ctl = cmds.checkBox("ctl%s"%name, query=True, value=True)
alt = cmds.checkBox("alt%s"%name, query=True, value=True)
if len(key) > 1 and key not in KEYSLIST:
key = key[0]
cmds.scrollField("key%s"%name, edit=True, text=key)
label = self.hotkeyCheck(key, ctl, alt)
if label == None: label = ""
cmds.text("query%s"%name, edit=True, label=label, font="plainLabelFont")
if utilMod.toTitle(label) != command: cmds.text("query%s"%name, edit=True, font="boldLabelFont")
def reassignCommandsAtStartup(self):
allHotkeys = hotkeys.getHotkeys()
hotkeysDict = []
for n, loopHotkey in enumerate(allHotkeys):
for loopItem in loopHotkey:
hotkeysDict.append(loopItem)
for loopCommand in hotkeysDict:
command = loopCommand["command"]
name = loopCommand["name"]
key = loopCommand["hotkey"]
alt = loopCommand["alt"]
ctl = loopCommand["ctl"]
#toolTip = loopCommand["toolTip"]
label = self.hotkeyCheck(key, ctl, alt)
if label == name: cmds.nameCommand(name, command='python("%s");'%command, annotation=name)
#=========================================================
def shelfButton(*args):
topShelf = mel.eval('$nul = $gShelfTopLevel')
currentShelf = cmds.tabLayout(topShelf, q=1, st=1)
command = "from animTools.animBar import animBarUI; animBarUI.show('toggle')"
cmds.shelfButton(parent=currentShelf, annotation='aTools ON/OFF', imageOverlayLabel="aTools", i='commandButton.xpm', command=command)
def refreshATools(*args):
G.deferredManager.sendToQueue(refreshAToolsDef, 1, "refreshATools")
def refreshAToolsDef():
from animTools.animBar import animBarUI; importlib.reload(animBarUI)
animBarUI.show('refresh')
# animBot
def installAnimBot(*args):
installFileFolder = os.path.normpath(os.path.dirname(os.path.dirname(__file__)))
installFilePath = os.path.join(installFileFolder, "animBot Drag'n Drop Install.mel").replace("\\", "/") # fix for windows
mel.eval("source \"%s\";"%installFilePath)
def watchLaunchVideo(*args):
webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao")
def joinTheCommunity(*args):
webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439")

View File

@@ -0,0 +1,355 @@
'''
========================================================================================================================
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
========================================================================================================================
'''
def getHotkeys():
yellow = [{
"name":"RepeatLastTweenMachineCommand",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.tweenMachine.repeatLastCommand()",
"hotkey":"t",
"alt":0,
"ctl":0,
"toolTip":"Repeat the last Tween Machine command"
},{
"name":"SetSmartKey",
"command":"from commonMods import commandsMod; commandsMod.setSmartKey()",
"hotkey":"s",
"alt":0,
"ctl":0,
"toolTip":"Set a key without changing the tangents"
},{
"name":"SetSmartKeyOnScrub",
"command":"from commonMods import commandsMod; commandsMod.setSmartKey(insert=False)",
"hotkey":"s",
"alt":1,
"ctl":0,
"toolTip":"Copy a key dragged with middle mouse"
},{
"name":"smartSnapKeys",
"command":"from commonMods import commandsMod; commandsMod.smartSnapKeys()",
"hotkey":"S",
"alt":0,
"ctl":1,
"toolTip":"Snap decimal frame keys to the closest integer frame and preserve the curves"
},{
"name":"SelectOnlyKeyedObjects",
"command":"from commonMods import commandsMod; commandsMod.selectOnlyKeyedObjects()",
"hotkey":"s",
"alt":1,
"ctl":1,
"toolTip":"Select the objects which the selected keys belong to"
}]
green = [{
"name":"EulerFilterSelection",
"command":"from commonMods import commandsMod; commandsMod.eulerFilterSelection()",
"hotkey":"E",
"alt":0,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"ResetValue",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.keyTransform.resetValue()",
"hotkey":"0",
"alt":0,
"ctl":0,
"toolTip":"The same as the reset value button"
},{
"name":"NudgeKeyLeft",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.nudge.nudgeKey(-1)",
"hotkey":",",
"alt":0,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"NudgeKeyRight",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.nudge.nudgeKey(1)",
"hotkey":".",
"alt":0,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"AddInbetween",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.keyTransform.inbetween(1)",
"hotkey":".",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"RemoveInbetween",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.keyTransform.inbetween(-1)",
"hotkey":",",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"InbetweenUI",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.keyTransform.inbetweenUI()",
"hotkey":"<",
"alt":1,
"ctl":1,
"toolTip":"A GUI to help timing keys"
},{
"name":"CropTimelineAnimation",
"command":"from commonMods import commandsMod; commandsMod.cropTimelineAnimation()",
"hotkey":"X",
"alt":1,
"ctl":1,
"toolTip":"Delete all keys from timeline but the range selected"
}]
blue = [{
"name":"FlowTangent",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.tangents.setTangent('flow')",
"hotkey":"z",
"alt":1,
"ctl":1,
"toolTip":"It is the same command as the one in the aTools bar"
},{
"name":"FlowTangentAround",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.tangents.flowAround(2)",
"hotkey":"Z",
"alt":1,
"ctl":1,
"toolTip":"Will apply Flow Tangent to the selected keys plus two neighbor keys"
},{
"name":"AutoTangent",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.tangents.setTangent('auto')",
"hotkey":"z",
"alt":0,
"ctl":0,
"toolTip":"It is the same command as the one in the aTools bar"
}]
purple = [{
"name":"alignSelection",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.align.alignSelection()",
"hotkey":"a",
"alt":1,
"ctl":0,
"toolTip":"Align selection\nSelect the slaves and a master object"
},{
"name":"toggleMicroTransform",
"command":"from generalTools.aToolsGlobals import aToolsGlobals as G; G.aToolsBar.microTransform.switch()",
"hotkey":"m",
"alt":0,
"ctl":0,
"toolTip":"Toggle Micro Transform mode"
}]
red = [{
"name":"Playblast",
"command":"from maya import mel; mel.eval('performPlayblast false')",
"hotkey":"p",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"FrameSection",
"command":"from commonMods import animMod; animMod.frameSection()",
"hotkey":"f",
"alt":1,
"ctl":0,
"toolTip":"In the Graph Editor, frame/zoom according to the current timeline range"
},{
"name":"FramePlaybackRange",
"command":"from animTools import framePlaybackRange; framePlaybackRange.framePlaybackRangeFn()",
"hotkey":"f",
"alt":1,
"ctl":1,
"toolTip":"In the Graph Editor, frame/zoom according to the current timeline range"
},{
"name":"FilterNonAnimatedCurves",
"command":"from commonMods import animMod; animMod.filterNonAnimatedCurves()",
"hotkey":"f",
"alt":0,
"ctl":1,
"toolTip":"Hide curves in the Graph Editor that have only keys with the same value"
},{
"name":"JumpToSelectedKey",
"command":"from commonMods import animMod; animMod.jumpToSelectedKey()",
"hotkey":"z",
"alt":1,
"ctl":0,
"toolTip":"In the Graph Editor, will go to the selected key"
},{
"name":"CopyKeyframesFromTimeline",
"command":"from maya import mel; mel.eval('timeSliderCopyKey')",
"hotkey":"c",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"CutKeyframesFromTimeline",
"command":"from maya import mel; mel.eval('timeSliderCutKey')",
"hotkey":"x",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"PasteKeyframesFromTimeline",
"command":"from maya import mel; mel.eval('timeSliderPasteKey false')",
"hotkey":"v",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"DeleteKeyframesFromTimeline",
"command":"from maya import mel; mel.eval('timeSliderClearKey')",
"hotkey":"d",
"alt":1,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"TogglePanelLayout",
"command":"from commonMods import commandsMod; commandsMod.togglePanelLayout()",
"hotkey":"`",
"alt":0,
"ctl":0,
"toolTip":"Toggle between graph editor and persp in the main viewport"
}]
orange = [{
"name":"ToggleRotateMode",
"command":"from commonMods import commandsMod; commandsMod.toggleRotateMode()",
"hotkey":"e",
"alt":1,
"ctl":0,
"toolTip":"Toggle the rotate tool mode (world, local, gimbal)"
},{
"name":"ToggleMoveMode",
"command":"from commonMods import commandsMod; commandsMod.toggleMoveMode()",
"hotkey":"w",
"alt":1,
"ctl":0,
"toolTip":"Toggle the move tool mode (world, local, object)"
},{
"name":"OrientMoveManip",
"command":"from commonMods import commandsMod; commandsMod.orientMoveManip()",
"hotkey":"W",
"alt":0,
"ctl":1,
"toolTip":"Orient the move tool axis to the local axis of the last selected object"
},{
"name":"CameraOrientMoveManip",
"command":"from commonMods import commandsMod; commandsMod.cameraOrientMoveManip()",
"hotkey":"W",
"alt":1,
"ctl":1,
"toolTip":"Toggle the move tool mode (world, local, object)"
},{
"name":"ToggleGeometry",
"command":"from commonMods import commandsMod; commandsMod.toggleObj(['polymeshes', 'nurbsSurfaces'])",
"hotkey":"G",
"alt":0,
"ctl":0,
"toolTip":"Show or hide polygons"
},{
"name":"ToggleNurbCurves",
"command":"from commonMods import commandsMod; commandsMod.toggleObj(['nurbsCurves'])",
"hotkey":"N",
"alt":0,
"ctl":0,
"toolTip":"Show or hide nurb curves"
},{
"name":"ToggleLocators",
"command":"from commonMods import commandsMod; commandsMod.toggleObj(['locators'])",
"hotkey":"L",
"alt":0,
"ctl":0,
"toolTip":"Show or hide locators"
},{
"name":"CameraViewMode",
"command":"from commonMods import utilMod; utilMod.cameraViewMode()",
"hotkey":"C",
"alt":0,
"ctl":1,
"toolTip":"Shows only polygons"
},{
"name":"AnimViewportViewMode",
"command":"from commonMods import utilMod; utilMod.animViewportViewMode()",
"hotkey":"V",
"alt":0,
"ctl":1,
"toolTip":"Shows only polygons and nurb curves"
}]
gray = [{
"name":"setThreePanelLayout",
"command":"from commonMods import commandsMod; commandsMod.setThreePanelLayout()",
"hotkey":"3",
"alt":0,
"ctl":1,
"toolTip":"Set layout with 3 panels - camera, perspective and graph editor. Sets a couple of other attributes to the perspective camera."
},{
"name":"UnselectChannelBox",
"command":"from commonMods import commandsMod; commandsMod.unselectChannelBox()",
"hotkey":"C",
"alt":1,
"ctl":1,
"toolTip":"Unselect channels in the channel box\nGood when you want to show all channels keys in the timeline"
},{
"name":"NextFrame",
"command":"from commonMods import commandsMod; commandsMod.goToKey('next', 'frame')",
"hotkey":".",
"alt":1,
"ctl":0,
"toolTip":"Go to next frame without saving the undo state and refreshes in background, \nwhich means you can jump several frames way faster without waiting rigs refresh on every frame"
},{
"name":"NextKeyframe",
"command":"from commonMods import commandsMod; commandsMod.goToKey('next')",
"hotkey":".",
"alt":0,
"ctl":0,
"toolTip":"Go to next keyframe without saving the undo state and refreshes in background, \nwhich means you can jump several frames way faster without waiting rigs refresh on every frame"
},{
"name":"PrevFrame",
"command":"from commonMods import commandsMod; commandsMod.goToKey('previous', 'frame')",
"hotkey":",",
"alt":1,
"ctl":0,
"toolTip":"Go to previous frame without saving the undo state and refreshes in background, \nwhich means you can jump several frames way faster without waiting rigs refresh on every frame"
},{
"name":"PrevKeyframe",
"command":"from commonMods import commandsMod; commandsMod.goToKey('previous')",
"hotkey":",",
"alt":0,
"ctl":0,
"toolTip":"Go to previous keyframe without saving the undo state and refreshes in background, \nwhich means you can jump several frames way faster without waiting rigs refresh on every frame"
},{
"name":"GraphEditor",
"command":"from maya import mel; mel.eval('tearOffPanel \\\"Graph Editor\\\" \\\"graphEditor\\\" true;')",
"hotkey":"`",
"alt":0,
"ctl":1,
"toolTip":"Open the Graph Editor"
},{
"name":"Outliner",
"command":"from maya import mel; mel.eval('tearOffPanel \\\"Outliner\\\" \\\"outlinerPanel\\\" false;')",
"hotkey":"o",
"alt":0,
"ctl":0,
"toolTip":"Open the Outliner"
}]
return [yellow, green, blue, purple, red, orange, gray]

View File

@@ -0,0 +1,102 @@
from maya import cmds, mel
import os, shutil, urllib.request, urllib.error, urllib.parse, shutil, zipfile
import importlib
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 install():
if aToolsZipPath.split(os.sep)[-1] != 'aTools.zip' or not os.path.isfile(aToolsZipPath):
cmds.confirmDialog(message="%sCouldnt find aTools.zip in this location, installation will stop."%os.sep.join(aToolsZipPath.split(os.sep)[:-1]))
return
aToolsOfflineInstall(aToolsZipPath)
def formatPath(path):
path = path.replace('/', os.sep)
path = path.replace('\\\\', os.sep)
return path
def download(downloadUrl, saveFile):
if not hasInternet(downloadUrl):
cmds.warning('Error trying to install.')
return
try: response = urllib.request.urlopen(downloadUrl, timeout=60)
except: pass
if response is None:
cmds.warning('Error trying to install.')
return
fileSize = int(response.info().getheaders('Content-Length')[0])
fileSizeDl = 0
blockSize = 128
output = open(saveFile,'wb')
progBar = mel.eval('$tmp = $gMainProgressBar')
cmds.progressBar( progBar,
edit=True,
beginProgress=True,
status='Downloading aTools...',
progress=0,
maxValue=100 )
while True:
buffer = response.read(blockSize)
if not buffer:
output.close()
cmds.progressBar(progBar, edit=True, progress=100)
cmds.progressBar(progBar, edit=True, endProgress=True)
break
fileSizeDl += len(buffer)
output.write(buffer)
p = float(fileSizeDl) / fileSize *100
cmds.progressBar(progBar, edit=True, progress=p)
return output
def aToolsOfflineInstall(offlineFilePath):
mayaAppDir = mel.eval('getenv MAYA_APP_DIR')
aToolsPath = mayaAppDir + os.sep + 'scripts'
aToolsFolder = aToolsPath + os.sep + 'aTools' + os.sep
tmpZipFile = '%s%stmp.zip'%(aToolsPath, os.sep)
offlineFileUrl = r'file:///%s'%offlineFilePath
if os.path.isfile(tmpZipFile): os.remove(tmpZipFile)
if os.path.isdir(aToolsFolder): shutil.rmtree(aToolsFolder)
output = download(offlineFileUrl, tmpZipFile)
zfobj = zipfile.ZipFile(tmpZipFile)
for name in zfobj.namelist():
uncompressed = zfobj.read(name)
filename = formatPath('%s%s%s'%(aToolsPath, os.sep, name))
d = os.path.dirname(filename)
if not os.path.exists(d): os.makedirs(d)
if filename.endswith(os.sep): continue
output = open(filename,'wb')
output.write(uncompressed)
output.close()
zfobj.close()
if os.path.isfile(tmpZipFile): os.remove(tmpZipFile)
import setup; importlib.reload(setup); setup.install([offlineFilePath, False])
cmds.evalDeferred("from animTools.animBar import animBarUI; importlib.reload(animBarUI); animBarUI.show(\'refresh\')")
install()

View File

@@ -0,0 +1,113 @@
'''
========================================================================================================================
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
========================================================================================================================
Tumble on objects was adapted from:
'''
from maya import cmds
from maya import mel
from generalTools.aToolsGlobals import aToolsGlobals as G
from commonMods import utilMod
import math
class TumbleOnObjects(object):
def __init__(self):
self.currentLocalTumble = cmds.tumbleCtx ("tumbleContext", query=True, localTumble=True)
self.unitMultiplier = {"mm": 0.1,
"cm": 1.0,
"m" : 100.0,
"in": 2.54,
"ft": 30.48,
"yd": 91.44}
def switch(self, onOff):
utilMod.killScriptJobs("G.tumbleOnObjectsScriptJobs")
if onOff:
cmds.tumbleCtx ("tumbleContext", edit=True, localTumble=0)
#scriptJob
G.tumbleOnObjectsScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('DragRelease', self.update )))
G.tumbleOnObjectsScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.update )))
G.tumbleOnObjectsScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.update )))
self.update()
else:
cmds.tumbleCtx ("tumbleContext", edit=True, localTumble=self.currentLocalTumble)
def update(self):
sel = cmds.ls(selection=True)
if len(sel) > 0:
sel = sel[-1]
allowedTypes = ["transform", "joint"]
if cmds.nodeType(sel) in allowedTypes :
currUnit = cmds.currentUnit(query=True, linear=True)
unitMultiplier = self.unitMultiplier[currUnit]
isMesh = cmds.listRelatives(sel, allDescendents=True, noIntermediate=True, type="mesh") != None
if isMesh:
bb = cmds.xform(sel, query=True, boundingBox=True, ws=True)
x = ((bb[0] + bb[3])/2.)
y = ((bb[1] + bb[4])/2.)
z = ((bb[2] + bb[5])/2.)
else:
xyz = cmds.xform(sel, query=True, ws=True, rotatePivot=True)
x = xyz[0]
y = xyz[1]
z = xyz[2]
x = x * unitMultiplier
y = y * unitMultiplier
z = z * unitMultiplier
cams = cmds.ls(dag=True, cameras=True )
"""
for loopCam in cams:
if math.isnan(cmds.getAttr("%s.centerOfInterest"%loopCam)):
print "center is NAN"
if math.isnan(x) or math.isnan(y) or math.isnan(z):
print "tumble returns"
print xyz
for cam in cams:
t = cmds.xform(cam, query=True, ws=True, rotatePivot=True)
print cam, t
return
"""
cmds.undoInfo(stateWithoutFlush=False)
for loopCam in cams:
try: cmds.setAttr("%s.tumblePivot"%loopCam, x, y, z)
except: pass
cmds.undoInfo(stateWithoutFlush=True)