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

View File

@ -0,0 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from . import *

View File

@ -0,0 +1,317 @@
'''
========================================================================================================================
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 aTools.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,900 @@
'''
========================================================================================================================
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 aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods import uiMod
from aTools.commonMods import utilMod
from aTools.commonMods import animMod
from aTools.commonMods import commandsMod
from aTools.commonMods import aToolsMod
from aTools import setup
from aTools.generalTools import hotkeys; importlib.reload(hotkeys)
from aTools.generalTools import tumbleOnObjects; importlib.reload(tumbleOnObjects)
from aTools.animTools import animationCrashRecovery; importlib.reload(animationCrashRecovery)
from aTools.animTools import framePlaybackRange; importlib.reload(framePlaybackRange)
from aTools.animTools import jumpToSelectedKey; importlib.reload(jumpToSelectedKey)
animationCrashRecovery = animationCrashRecovery.AnimationCrashRecovery()
tumbleOnObjects = tumbleOnObjects.TumbleOnObjects()
versionInfoPath = "%sversion_info.txt"%aToolsMod.getaToolsPath(inScriptsFolder=False)
versionInfoContents = utilMod.readFile(versionInfoPath)
VERSION = versionInfoContents[0].split(" ")[-1].replace("\n", "")
WHATISNEW = "".join(versionInfoContents[1:])
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 aTools.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)
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:
G.deferredManager.sendToQueue(self.atoolsIsRetiring, 50, "warnAnimBot")
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 aTools.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 aTools.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,354 @@
'''
========================================================================================================================
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 aTools.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 aTools.commonMods import commandsMod; commandsMod.setSmartKey()",
"hotkey":"s",
"alt":0,
"ctl":0,
"toolTip":"Set a key without changing the tangents"
},{
"name":"SetSmartKeyOnScrub",
"command":"from aTools.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 aTools.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 aTools.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 aTools.commonMods import commandsMod; commandsMod.eulerFilterSelection()",
"hotkey":"E",
"alt":0,
"ctl":1,
"toolTip":"It is what is says"
},{
"name":"ResetValue",
"command":"from aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.commonMods import commandsMod; commandsMod.toggleRotateMode()",
"hotkey":"e",
"alt":1,
"ctl":0,
"toolTip":"Toggle the rotate tool mode (world, local, gimbal)"
},{
"name":"ToggleMoveMode",
"command":"from aTools.commonMods import commandsMod; commandsMod.toggleMoveMode()",
"hotkey":"w",
"alt":1,
"ctl":0,
"toolTip":"Toggle the move tool mode (world, local, object)"
},{
"name":"OrientMoveManip",
"command":"from aTools.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 aTools.commonMods import commandsMod; commandsMod.cameraOrientMoveManip()",
"hotkey":"W",
"alt":1,
"ctl":1,
"toolTip":"Toggle the move tool mode (world, local, object)"
},{
"name":"ToggleGeometry",
"command":"from aTools.commonMods import commandsMod; commandsMod.toggleObj(['polymeshes', 'nurbsSurfaces'])",
"hotkey":"G",
"alt":0,
"ctl":0,
"toolTip":"Show or hide polygons"
},{
"name":"ToggleNurbCurves",
"command":"from aTools.commonMods import commandsMod; commandsMod.toggleObj(['nurbsCurves'])",
"hotkey":"N",
"alt":0,
"ctl":0,
"toolTip":"Show or hide nurb curves"
},{
"name":"ToggleLocators",
"command":"from aTools.commonMods import commandsMod; commandsMod.toggleObj(['locators'])",
"hotkey":"L",
"alt":0,
"ctl":0,
"toolTip":"Show or hide locators"
},{
"name":"CameraViewMode",
"command":"from aTools.commonMods import utilMod; utilMod.cameraViewMode()",
"hotkey":"C",
"alt":0,
"ctl":1,
"toolTip":"Shows only polygons"
},{
"name":"AnimViewportViewMode",
"command":"from aTools.commonMods import utilMod; utilMod.animViewportViewMode()",
"hotkey":"V",
"alt":0,
"ctl":1,
"toolTip":"Shows only polygons and nurb curves"
}]
gray = [{
"name":"setThreePanelLayout",
"command":"from aTools.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 aTools.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 aTools.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 aTools.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 aTools.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 aTools.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,47 @@
import os
import sys
import shutil
from maya import mel, cmds # type: ignore
def install():
# Get the current path of aTools
current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
aTools_path = os.path.normpath(current_dir).replace('\\', '/')
# Add aTools path to Maya's Python path
if aTools_path not in sys.path:
sys.path.append(aTools_path)
# Create or update userSetup.py file
maya_app_dir = mel.eval('getenv MAYA_APP_DIR')
scripts_dir = os.path.join(maya_app_dir, "scripts")
user_setup_file = os.path.join(scripts_dir, "userSetup.py")
atools_code = f"""
# Start aTools
import sys
atools_path = r"{aTools_path}"
if atools_path not in sys.path:
sys.path.append(atools_path)
from maya import cmds
if not cmds.about(batch=True):
cmds.evalDeferred("from aTools.animTools.animBar import animBarUI; animBarUI.show('launch')", lowestPriority=True)
# End aTools
"""
# If userSetup.py exists, ensure we don't add duplicate aTools code
if os.path.exists(user_setup_file):
with open(user_setup_file, 'r') as f:
content = f.read()
if "# Start aTools" not in content:
with open(user_setup_file, 'a') as f:
f.write(atools_code)
else:
with open(user_setup_file, 'w') as f:
f.write(atools_code)
print("aTools has been successfully installed.")
if __name__ == "__main__":
install()

View File

@ -0,0 +1,111 @@
'''
========================================================================================================================
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 aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.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)