def getKeyTimes(self, prefKey=None): prefKey = prefKey or self.prefKey getFrom = None keyTimesDict = {} keyTimes = [] if prefKey in ["selection", "selection_list"]: animCurves = cmds.keyframe(query=True, name=True) keyTimes = animMod.getTarget("keyTimes", animCurves) if animCurves else [] keyTimes = sorted(utilMod.mergeLists(keyTimes)) for n, loopMotionTrail in enumerate(self.nodeInfo.keys()): keyTimesDict[loopMotionTrail] = keyTimes else: for loopMotionTrail in self.nodeInfo.keys(): animCurves = cmds.keyframe(loopMotionTrail, query=True, name=True) keyTimes = animMod.getTarget("keyTimes", animCurves) if animCurves else [] keyTimesDict[loopMotionTrail] = utilMod.mergeLists(keyTimes) return keyTimesDict
def alignSelection(self, translate=True, rotate=True, all=False): selection = cmds.ls(selection=True) if len(selection) < 2: cmds.warning("You need to select at least 2 objects.") return sourceObjs = selection[0:-1] targetObj = selection[-1] frames = None currFrame = cmds.currentTime(query=True) getCurves = animMod.getAnimCurves() animCurves = getCurves[0] getFrom = getCurves[1] showProgress = all if animCurves: if all: keysSel = animMod.getTarget("keyTimes", animCurves, getFrom) else: keysSel = animMod.getTarget("keysSel", animCurves, getFrom) frames = utilMod.mergeLists(keysSel) if frames == []: frames = [currFrame] else: frames = [currFrame] self.align(sourceObjs, targetObj, frames, translate, rotate, showProgress, selectSorceObjs=True)
def spaceSwitch(self, args, all=False, mode="token"): cmds.refresh(suspend=True) if mode == "token": switch = self.spaceSwitchToken elif mode == "custom": switch = self.spaceSwitchCustom objects = args[0] attr = args[1] currSel = cmds.ls(selection=True) currFrame = cmds.currentTime(query=True) getCurves = animMod.getAnimCurves() animCurves = getCurves[0] getFrom = getCurves[1] if animCurves: if all: keysSel = animMod.getTarget("keyTimes", animCurves, getFrom) else: keysSel = animMod.getTarget("keysSel", animCurves, getFrom) keysSel = utilMod.mergeLists(keysSel) if keysSel == []: keysSel = [currFrame] else: keysSel = [currFrame] frames = keysSel for loopObj in currSel: if loopObj not in objects: continue if not cmds.objExists("%s.%s"%(loopObj, attr)):continue animMod.createDummyKey([loopObj]) getCurves = animMod.getAnimCurves(True) animCurves = getCurves[0] animMod.deleteDummyKey([loopObj]) for loopFrame in frames: cmds.currentTime(loopFrame) matrix = cmds.xform(loopObj, query=True, ws=True, matrix=True) rotation = cmds.xform(loopObj, query=True, ws=True, rotation=True) switch(loopObj, args) cmds.xform(loopObj, ws=True, matrix=matrix) cmds.xform(loopObj, ws=True, rotation=rotation) animMod.eulerFilterCurve(animCurves) cmds.currentTime(currFrame) cmds.refresh(suspend=False)
def getRange(self): animCurves = cmds.keyframe(query=True, name=True, selected=True) if animCurves: keysSel = animMod.getTarget("keysSel", animCurves, "graphEditor") keysSel = utilMod.mergeLists(keysSel) range = [min(keysSel), max(keysSel)] else: G.playBackSliderPython = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider') range = cmds.timeControl(G.playBackSliderPython, query=True, rangeArray=True) range[1] -= 1 return range
def getRange(self): animCurves = cmds.keyframe(query=True, name=True, selected=True) if animCurves: keysSel = animMod.getTarget("keysSel", animCurves, "graphEditor") keysSel = utilMod.mergeLists(keysSel) range = [min(keysSel), max(keysSel)] else: G.playBackSliderPython = G.playBackSliderPython or mel.eval("$aTools_playBackSliderPython=$gPlayBackSlider") range = cmds.timeControl(G.playBackSliderPython, query=True, rangeArray=True) range[1] -= 1 return range
def populateMenu(self, menu, *args): uiMod.clearMenuItems(menu) tokenCustomDivider = False selObjects = cmds.ls(selection=True) if not selObjects: return channels = animMod.getAllChannels() channelList = {} tokenList = [] for n, loopObjectChannel in enumerate(channels): obj = selObjects[n] if loopObjectChannel: for loopChannel in loopObjectChannel: tokens = animMod.getTokens(obj, loopChannel) if tokens and len(tokens) > 1: if not channelList.has_key(loopChannel): channelList[loopChannel] = {"objects":[], "tokens":[]} channelList[loopChannel]["objects"].append(obj) channelList[loopChannel]["tokens"].append(tokens) for loopChannelList in channelList: newMenu = cmds.menuItem(subMenu=True, label=utilMod.toTitle(loopChannelList), parent=menu) objects = channelList[loopChannelList]["objects"] tokens = channelList[loopChannelList]["tokens"] mergedTokens = utilMod.mergeLists(tokens) tokenDict = [] for loopMergedTokens in mergedTokens: tokenDict.append({"token":loopMergedTokens, "objects":[]}) for n, loopObject in enumerate(objects): t = tokens[n] if loopMergedTokens in t: tokenDict[-1]["objects"].append(loopObject) cmds.radioMenuItemCollection(parent=menu) for n, loopTokenDict in enumerate(tokenDict): tokenCustomDivider = True token = loopTokenDict["token"] objects = loopTokenDict["objects"] selectedList = [cmds.getAttr("%s.%s"%(loopObj, loopChannelList)) for loopObj in objects] radioSelected = False if len(set(selectedList)) == 1: if selectedList[0] == n: radioSelected = True cmds.menuItem(label=utilMod.toTitle(token), radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, channel=loopChannelList, token=token, *args:self.spaceSwitch([objects, channel, token])) #ALL KEYS cmds.menuItem( divider=True, parent=newMenu) newMenu = cmds.menuItem(subMenu=True, label='All Keys', parent=newMenu) cmds.radioMenuItemCollection(parent=newMenu) for n, loopTokenDict in enumerate(tokenDict): token = loopTokenDict["token"] objects = loopTokenDict["objects"] selectedList = [cmds.getAttr("%s.%s"%(loopObj, loopChannelList)) for loopObj in objects] radioSelected = False if len(set(selectedList)) == 1: if selectedList[0] == n: radioSelected = True cmds.menuItem(label=utilMod.toTitle(token), radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, channel=loopChannelList, token=token, *args:self.spaceSwitch([objects, channel, token], all=True)) # CUSTOM SWITCH allCustomSwitch = aToolsMod.loadInfoWithUser("spaceSwitch", "customSwitch") or [] channelboxSelObjs = animMod.channelBoxSel() if channelboxSelObjs: obj = ".".join(channelboxSelObjs[0].split(".")[:-1]) selectedSwitch = [loopAttr.split(".")[-1] for loopAttr in channelboxSelObjs if utilMod.isDynamic(obj, loopAttr.split(".")[-1])] if len(selectedSwitch) > 0 and selectedSwitch not in allCustomSwitch: allCustomSwitch.append(selectedSwitch) aToolsMod.saveInfoWithUser("spaceSwitch", "customSwitch", allCustomSwitch) # populate menu if len(allCustomSwitch) > 0: divider = False customSwitchesAdded = [] customSwitchesMenu = [] for loopObj in selObjects: for loopCustomSwitch in sorted(allCustomSwitch, key=len, reverse=True): if len(loopCustomSwitch) == 0: continue switchName = utilMod.getNameSpace([loopObj])[1][0].split(".")[0] exit = False for loopAttr in loopCustomSwitch: objAttr = "%s.%s"%(loopObj, loopAttr) if not cmds.objExists(objAttr): exit = True break if exit: continue customSwitchesMenu.append({"objects":[loopObj], "switches":loopCustomSwitch}) for loopMenu in customSwitchesMenu[:-1]: if loopObj in loopMenu["objects"] and len(loopCustomSwitch) < len(loopMenu["switches"]) and utilMod.listIntersection(loopMenu["switches"], loopCustomSwitch) == loopCustomSwitch: customSwitchesMenu.pop() break if loopCustomSwitch == loopMenu["switches"]: loopMenu["objects"].append(loopObj) customSwitchesMenu.pop() break for loopSwitchMenu in customSwitchesMenu: objects = loopSwitchMenu["objects"] switches = loopSwitchMenu["switches"] switchName = ", ".join(list(set(utilMod.getNameSpace(objects)[1]))) if not divider and tokenCustomDivider: divider = cmds.menuItem(divider=True, parent=menu) cmds.radioMenuItemCollection(parent=menu) newMenu = cmds.menuItem(subMenu=True, label=switchName, parent=menu) radioSelected = [] for loopCustomSwitchAttr in switches: switchAttr = loopCustomSwitchAttr.split(".")[-1] objAttr = "%s.%s"%(objects[0], switchAttr) minValue = cmds.addAttr(objAttr, query=True, minValue=True) maxValue = cmds.addAttr(objAttr, query=True, maxValue=True) currValue = cmds.getAttr(objAttr) radioSelected.append((currValue == maxValue)) cmds.menuItem(label=switchAttr, radioButton=radioSelected[-1], parent=newMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], mode="custom")) switchAttr = "message" radioSelected = (list(set(radioSelected)) == [False]) cmds.menuItem(label="None", radioButton=radioSelected, parent=newMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], mode="custom")) #ALL KEYS cmds.menuItem( divider=True, parent=newMenu) allMenu = cmds.menuItem(subMenu=True, label='All Keys', parent=newMenu) radioSelected = [] cmds.radioMenuItemCollection(parent=menu) for loopCustomSwitchAttr in switches: switchAttr = loopCustomSwitchAttr.split(".")[-1] objAttr = "%s.%s"%(objects[0], switchAttr) minValue = cmds.addAttr(objAttr, query=True, minValue=True) maxValue = cmds.addAttr(objAttr, query=True, maxValue=True) currValue = cmds.getAttr(objAttr) radioSelected.append((currValue == maxValue)) cmds.menuItem(label=switchAttr, radioButton=radioSelected[-1], parent=allMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], all=True, mode="custom")) switchAttr = "message" radioSelected = (list(set(radioSelected)) == [False]) cmds.menuItem(label="None", radioButton=radioSelected, parent=allMenu, command=lambda x, objects=objects, switchAttr=switchAttr, switches=switches, *args:self.spaceSwitch([objects, switchAttr, switches], all=True, mode="custom")) #DELETE cmds.menuItem(label="Remove", parent=newMenu, command=lambda x, switches=switches, *args:self.removeCustomSwitch(switches))
def smartSnapKeys(): getCurves = animMod.getAnimCurves() animCurves = getCurves[0] if not animCurves or len(animCurves) == 0: return getFrom = getCurves[1] keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom) keysSel = animMod.getTarget("keysSel", animCurves, getFrom) hasDecimalKeys = False for loopKey in utilMod.mergeLists(keysSel): if loopKey != round(loopKey) > 0: hasDecimalKeys = True break if not hasDecimalKeys: return keyTangentsType = animMod.getTarget("keyTangentsType", animCurves, getFrom) firstStep = 0 totalSteps = len(animCurves) estimatedTime = None status = "aTools - Smart Snap Curves..." startChrono = None utilMod.startProgressBar(status) for thisStep, loopCurve in enumerate(animCurves): startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) if None in [keyTimes[thisStep], keysSel[thisStep]]: continue stepKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "step" ] linearKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "linear" ] decimalKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and loopKey not in stepKeys + linearKeys ] for loopKey in stepKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) for loopKey in linearKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) if len(decimalKeys) == 0: continue if not getFrom: if cmds.keyframe(query=True, selected=True) != None: getFrom = "graphEditor" #inLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][0] == "linear"] #outLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][1] == "linear"] createKeys = list(set([round(loopKey) for loopKey in decimalKeys])) selectKeys = [] #print "inlinearKeys", inLinearKeys, outLinearKeys if getFrom == "graphEditor": selectKeys = list( set([ round(loopKey) for loopKey in keysSel[thisStep] if round(loopKey) in createKeys ])) for loopKey in createKeys: cmds.setKeyframe(loopCurve, time=(loopKey, loopKey), insert=True) for loopKey in selectKeys: cmds.selectKey(loopCurve, addTo=True, time=(loopKey, loopKey)) for loopKey in decimalKeys: cmds.cutKey(loopCurve, time=(loopKey, loopKey)) #for loopKey in outLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), outTangentType="linear") #for loopKey in inLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), inTangentType="linear") estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) utilMod.setProgressBar(endProgress=True)
def smartSnapKeys(): getCurves = animMod.getAnimCurves() animCurves = getCurves[0] if not animCurves or len(animCurves) == 0: return getFrom = getCurves[1] keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom) keysSel = animMod.getTarget("keysSel", animCurves, getFrom) hasDecimalKeys = False for loopKey in utilMod.mergeLists(keysSel): if loopKey != round(loopKey) > 0: hasDecimalKeys = True break if not hasDecimalKeys: return keyTangentsType = animMod.getTarget("keyTangentsType", animCurves, getFrom) firstStep = 0 totalSteps = len(animCurves) estimatedTime = None status = "aTools - Smart Snap Curves..." startChrono = None utilMod.startProgressBar(status) for thisStep, loopCurve in enumerate(animCurves): startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) if None in [keyTimes[thisStep], keysSel[thisStep]]: continue stepKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "step"] linearKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "linear"] decimalKeys = [loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and loopKey not in stepKeys + linearKeys] for loopKey in stepKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) for loopKey in linearKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) if len(decimalKeys) == 0: continue if not getFrom: if cmds.keyframe(query=True, selected=True) != None: getFrom = "graphEditor" #inLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][0] == "linear"] #outLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][1] == "linear"] createKeys = list(set([round(loopKey) for loopKey in decimalKeys])) selectKeys = [] #print "inlinearKeys", inLinearKeys, outLinearKeys if getFrom == "graphEditor": selectKeys = list(set([round(loopKey) for loopKey in keysSel[thisStep] if round(loopKey) in createKeys])) for loopKey in createKeys: cmds.setKeyframe(loopCurve, time=(loopKey, loopKey), insert=True) for loopKey in selectKeys: cmds.selectKey(loopCurve, addTo=True, time=(loopKey, loopKey)) for loopKey in decimalKeys: cmds.cutKey(loopCurve, time=(loopKey, loopKey)) #for loopKey in outLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), outTangentType="linear") #for loopKey in inLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), inTangentType="linear") estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) utilMod.setProgressBar(endProgress=True)
def 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 align(self, sourceObjs, targetObj, frames=None, translate=True, rotate=True, showProgress=False, selectSorceObjs=False): if not sourceObjs or not targetObj: return cmds.refresh(suspend=True) currFrame = cmds.currentTime(query=True) constraints = [] setValues = [] modes = [] status = "aTools - Aligning nodes..." if translate: modes.append({"mode":"translate", "constrain":"pointConstraint"}) if rotate: modes.append({"mode":"rotate", "constrain":"orientConstraint"}) if showProgress: utilMod.startProgressBar(status) if not frames: getCurves = animMod.getAnimCurves() animCurves = getCurves[0] getFrom = getCurves[1] if animCurves: keysSel = animMod.getTarget("keysSel", animCurves, getFrom) frames = utilMod.mergeLists(keysSel) if frames == []: frames = [currFrame] else: frames = [currFrame] if showProgress: totalSteps = len(sourceObjs + frames) firstStep = 0 thisStep = 0 estimatedTime = None startChrono = None #get values for thisStep, loopSourceObj in enumerate(sourceObjs): if showProgress: startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) setValues.append({"modes":[], "values":[], "skips":[]}) for loopMode in modes: mode = loopMode["mode"] constrainType = loopMode["constrain"] allAttrs = cmds.listAttr(loopSourceObj, settable=True, keyable=True) skip = [loopXyz for loopXyz in ["x", "y", "z"] if "%s%s"%(mode, loopXyz.upper()) not in allAttrs] contrainFn = eval("cmds.%s"%constrainType) with G.aToolsBar.createAToolsNode: constraints.append(contrainFn(targetObj, loopSourceObj, skip=skip)[0]) setValues[-1]["modes"].append(mode) setValues[-1]["values"].append([cmds.getAttr("%s.%s"%(loopSourceObj, mode), time=loopKey)[0] for loopKey in frames]) setValues[-1]["skips"].append(skip) if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) #del constraints for loopConstrain in constraints: cmds.delete(loopConstrain) for n, loopKey in enumerate(frames): if showProgress: thisStep = thisStep + n + 1 startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) for nn, loopSourceObj in enumerate(sourceObjs): loopSetValue = setValues[nn] values = loopSetValue["values"] skips = loopSetValue["skips"] for nnn, loopMode in enumerate(modes): mode = loopMode["mode"] xyz = [loopXyz for loopXyz in ["x", "y", "z"] if loopXyz not in skips[nnn]] for nnnn, loopXyz in enumerate(xyz): attr = "%s%s"%(mode, loopXyz.upper()) value = values[nnn][n][nnnn] if len(frames) > 1: cmds.setKeyframe(loopSourceObj, attribute=attr, time=(loopKey,loopKey), value=value) if currFrame == loopKey: cmds.setAttr("%s.%s"%(loopSourceObj, attr), value) #euler filter if n == len(frames)-1 and rotate: animCurves = utilMod.mergeLists([cmds.keyframe(loopSourceObj, query=True, name=True) for loopSourceObj in sourceObjs]) animMod.eulerFilterCurve(animCurves) if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) if showProgress: utilMod.setProgressBar(endProgress=True) if selectSorceObjs: cmds.select(sourceObjs) cmds.refresh(suspend=False)
def align(self, sourceObjs, targetObj, frames=None, translate=True, rotate=True, showProgress=False, selectSorceObjs=False): if not sourceObjs or not targetObj: return cmds.refresh(suspend=True) currFrame = cmds.currentTime(query=True) constraints = [] setValues = [] modes = [] status = "aTools - Aligning nodes..." if translate: modes.append({"mode": "translate", "constrain": "pointConstraint"}) if rotate: modes.append({"mode": "rotate", "constrain": "orientConstraint"}) if showProgress: utilMod.startProgressBar(status) if not frames: getCurves = animMod.getAnimCurves() animCurves = getCurves[0] getFrom = getCurves[1] if animCurves: keysSel = animMod.getTarget("keysSel", animCurves, getFrom) frames = utilMod.mergeLists(keysSel) if frames == []: frames = [currFrame] else: frames = [currFrame] if showProgress: totalSteps = len(sourceObjs + frames) firstStep = 0 thisStep = 0 estimatedTime = None startChrono = None #get values for thisStep, loopSourceObj in enumerate(sourceObjs): if showProgress: startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) setValues.append({"modes": [], "values": [], "skips": []}) for loopMode in modes: mode = loopMode["mode"] constrainType = loopMode["constrain"] allAttrs = cmds.listAttr(loopSourceObj, settable=True, keyable=True) skip = [ loopXyz for loopXyz in ["x", "y", "z"] if "%s%s" % (mode, loopXyz.upper()) not in allAttrs ] contrainFn = eval("cmds.%s" % constrainType) with G.aToolsBar.createAToolsNode: constraints.append( contrainFn(targetObj, loopSourceObj, skip=skip)[0]) setValues[-1]["modes"].append(mode) setValues[-1]["values"].append([ cmds.getAttr("%s.%s" % (loopSourceObj, mode), time=loopKey)[0] for loopKey in frames ]) setValues[-1]["skips"].append(skip) if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) #del constraints for loopConstrain in constraints: cmds.delete(loopConstrain) for n, loopKey in enumerate(frames): if showProgress: thisStep = thisStep + n + 1 startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) for nn, loopSourceObj in enumerate(sourceObjs): loopSetValue = setValues[nn] values = loopSetValue["values"] skips = loopSetValue["skips"] for nnn, loopMode in enumerate(modes): mode = loopMode["mode"] xyz = [ loopXyz for loopXyz in ["x", "y", "z"] if loopXyz not in skips[nnn] ] for nnnn, loopXyz in enumerate(xyz): attr = "%s%s" % (mode, loopXyz.upper()) value = values[nnn][n][nnnn] if len(frames) > 1: cmds.setKeyframe(loopSourceObj, attribute=attr, time=(loopKey, loopKey), value=value) if currFrame == loopKey: cmds.setAttr("%s.%s" % (loopSourceObj, attr), value) #euler filter if n == len(frames) - 1 and rotate: animCurves = utilMod.mergeLists([ cmds.keyframe(loopSourceObj, query=True, name=True) for loopSourceObj in sourceObjs ]) animMod.eulerFilterCurve(animCurves) if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) if showProgress: utilMod.setProgressBar(endProgress=True) if selectSorceObjs: cmds.select(sourceObjs) cmds.refresh(suspend=False)