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