def apply( self, attrPath, sourceRange, applyStart, additive=False ): ''' used to put the animation data on this instance to an actual attribute sourceRange should be a 2-tuple representing the 0-based time range of the animation data to apply applyStart should be the start time at which to place the animation ''' #if the attrPath isn't settable, bail - maya sometimes crashes if you try to pasteKey on a non-settable attr if not getAttr( attrPath, se=True ): return keyCmdKwargs = {} if sourceRange: keyCmdKwargs[ 't' ] = sourceRange animCurveNode = self.constructNode( applyStart ) if additive: if cmd.keyframe( attrPath, q=True, kc=True ): for t in cmd.keyframe( animCurveNode, q=True ): val = cmd.keyframe( attrPath, t=(t,), q=True, vc=True, eval=True ) or [getAttr( attrPath )] cmd.keyframe( animCurveNode, t=(t,), e=True, vc=val[0], relative=True ) else: cmd.keyframe( animCurveNode, e=True, vc=getAttr( attrPath ), relative=True ) try: cmd.copyKey( animCurveNode, clipboard='api', **keyCmdKwargs ) cmd.pasteKey( attrPath, option='replace', clipboard='api' ) finally: cmd.delete( animCurveNode )
def mirror_animation(self): """ Mirrors the animation based on the selected controls, selected anim layer(if any) and selected selected frames """ controls = animMod.get_controls(selected=True) selected_frames = animMod.get_frames() anim_layers = animMod.get_anim_layers(selected=True) if len(anim_layers) > 0: for anim_layer in anim_layers: for control in controls: opposite_control = animMod.get_opposite_control(node=control) attributes = animMod.get_attributes(node=control, attribute_options=["unlocked", "c", "keyable"]) or [] for attribute in attributes: for frame in selected_frames: if cmds.copyKey(control, time=(frame, frame), at=attribute, option="keys", al=anim_layer) != None: cmds.animLayer(anim_layer, edit=True, at="{0}.{1}".format(opposite_control, attribute)) cmds.setKeyframe(opposite_control, time=(frame,frame), at=attribute, al=anim_layer) cmds.pasteKey(opposite_control, time=(frame, frame), option="replaceCompletely", al=anim_layer) else: for control in controls: opposite_control = animMod.get_opposite_control(node=control) attributes = animMod.get_attributes(node=control, attribute_options=["unlocked", "c", "keyable"]) or [] for attribute in attributes: for frame in selected_frames: current_key = cmds.copyKey(control, time=(frame, frame), at=attribute, option="keys") if current_key > 0: cmds.setKeyframe(opposite_control, time=(frame), at=attribute) cmds.pasteKey(opposite_control, animation="keysOrObjects", option="replace")
def SendAnimation(a, b, optionType): if cmds.selectKey(a) > 0: if optionType == option(option.keys): cmds.cutKey(a, time=(cTime, cTime), option=optionType.__str__()) else: cmds.copyKey(a, option=optionType.__str__()) cmds.pasteKey(b, option='replaceCompletely')
def applyCallback(*pArgs): # print "-------------applyCallback----------------" # print "first mode= %s" %_mode # print "first key= %s" %_key # print "attri key= %s" %_attri # call function to chect array after press "apply" checkList() global index index=0 nowJ=cmds.ls(orderedSelection=True) nowTime=mc.currentTime(q=1) for i in nowJ: # print "now i= %s" %i index += 1 if index >= 2: targetJ=nowJ[index-1] # print "target obj is = %s" %(targetJ) if _key == 2: #all key cmds.copyKey(nowJ,at=_attri) cmds.pasteKey(targetJ,at=_attri,option="replace") if _mode == 2: cmds.scaleKey(targetJ,at=_attri,valueScale=-1) else: # single key cmds.copyKey(nowJ,at=_attri,time=(nowTime,nowTime)) cmds.pasteKey(targetJ) if _mode == 2: cmds.scaleKey(targetJ,at=_attri,valueScale=-1,time=(nowTime,nowTime))
def individualCurveDenoise(self, curveName, faceGroup, TIME_VAL, THRESHOLD_VAL, sampleFace): print "Entered Ind Sample" startTime = self.minSliderTime endTime = self.maxSliderTime nSId = curveName.find(':') if nSId != -1: outTransform = curveName[:nSId] + str( sampleFace) + curveName[nSId:] else: outTransform = self.OTHER_FACE_IDS % sampleFace outTransform = outTransform + curveName cmds.cutKey(outTransform, time=(self.minSliderTime + 1, self.maxSliderTime - 1), option="keys") cmds.copyKey(curveName, time=(self.minSliderTime, self.maxSliderTime), option="keys") # or keys? cmds.pasteKey(outTransform, time=(self.minSliderTime, self.maxSliderTime), option="replace") cmds.filterCurve(outTransform, filter="simplify", timeTolerance=TIME_VAL, tolerance=THRESHOLD_VAL)
def copyToProxy(self, startTime, endTime): animCurves = [] for ac in cmds.ls(type="animCurveTL"): animCurves.append(ac) for ac in cmds.ls(type="animCurveTA"): animCurves.append(ac) for ac in cmds.ls(type="animCurveTU"): animCurves.append(ac) cmds.progressWindow(title=u"导出动画", status=u"导出中...") cmds.progressWindow(e=True, progress=0, max=len(animCurves)) for cv in animCurves: cmds.progressWindow(e=True, step=1) if cmds.referenceQuery(cv, isNodeReferenced=True): continue out = cmds.connectionInfo("%s.output" % cv, destinationFromSource=True) if out and len((':%s' % out[0]).split(self.namespace)) == 2: out = out[0] loc = "%s|%s___Proxy" % (self.grp, out.split(".")[0]) attr = out.split(".")[-1] #print "%s.output"%cv, "-> %s.%s"%(loc, attr) try: cmds.copyKey(cv) cmds.pasteKey(loc, attribute=attr) cmds.setKeyframe(loc, time=[startTime, endTime]) except Exception, e: print u"%s" % e
def setFaceAsElite(self, id, *args): self.lastElite = self.saveFaceCurves() eliteChoice = cmds.optionMenu("controlGroup" + str(id), value=True, query=True) eliteNum = int(eliteChoice[-1]) shapeTree = self.strongestShapesTree for faceGroup, ctlDict in shapeTree.iteritems(): for ctlName, ctlVal in ctlDict.iteritems(): nSId = ctlName.find(':') if nSId != -1: print "in" out1 = ctlName[:nSId] + str(eliteNum) + ctlName[nSId:] else: out1 = (self.OTHER_FACE_IDS + ctlName) % eliteNum cmds.cutKey(ctlName, time=(self.minSliderTime + 1, self.maxSliderTime - 1), option="keys") cmds.copyKey(out1, time=(self.minSliderTime, self.maxSliderTime), option="keys") # or keys? cmds.pasteKey(ctlName, time=(self.minSliderTime, self.maxSliderTime), option="replace") self.EliteGenes = self.saveFaceCurves()
def transferAdd(src, tgt, range=None, tgtTime=None, matchRo=False): ''' this is the core proc for copy/paste animation transfers. like the transfer command, this proc only works with a single source, single target ''' #if there are no keys, quit try: if cmd.keyframe(src, q=True, kc=True): return except RuntimeError: return time = tgtTime if tgtTime is None: time = cmd.currentTime(q=True) #match the rotation orders of the objects. if matchRo: try: cmd.setAttr(tgt + ".ro", cmd.getAttr(src + ".ro")) except RuntimeError: pass #finally, perform the copy - this may fail as we still haven't validated the existence of tgt... try: cmd.copyKey(src, time=range, hierarchy='none', animation='objects', o='curve') cmd.pasteKey(tgt, time=time, option='merge', animation='objects') except RuntimeError: return
def clone(): selected = cmds.ls(sl=True) source = selected.pop(0) cmds.copyKey(source, option="curve") for target in selected: cmds.pasteKey(target, option='replaceCompletely' ) print "Keys copied successfully",
def copyFromProxy(self): animCurves = [] for ac in cmds.ls(type="animCurveTL"): animCurves.append(ac) for ac in cmds.ls(type="animCurveTA"): animCurves.append(ac) for ac in cmds.ls(type="animCurveTU"): animCurves.append(ac) cmds.progressWindow(title=u"导入动画", status=u"导入中...") cmds.progressWindow(e=True, progress=0, max=len(animCurves)) for cv in animCurves: cmds.progressWindow(e=True, step=1) if cmds.referenceQuery(cv, isNodeReferenced=True): continue out = cmds.connectionInfo("%s.output" % cv, destinationFromSource=True) if not out: continue out = out[0] if out.find('___Proxy') == -1: continue if not len((':%s' % out).split(self.namespace)) == 2: continue attr = out.split(".")[-1] target = out.split("___")[0] try: cmds.copyKey(cv) cmds.pasteKey(target, attribute=attr, option=self.configuration['mode']) except Exception, e: print "%s" % e
def copy_keys(source=None, target=None, offset=0, rotateOrder=True): if not cmds.keyframe(source, q=True): om.MGlobal.displayInfo("Source: {} has no animation".format(source)) return if not isinstance(target, (list, tuple)): target = [target] # TODO: animLayer check # if layer: # cmds.select(target) # cmds.animLayer(layer, edit=True, addSelectedObjects=True) # #we want to make sure rotation values are within 360 degrees, so we don't get flipping when blending layers. # utl.minimizeRotationCurves(source) # for each in target: # utl.minimizeRotationCurves(each) if rotateOrder: for each in target: try: if cmds.getAttr(each + ".rotateOrder", keyable=True): cmds.setAttr(each + ".rotateOrder", cmds.getAttr(source + ".rotateOrder")) except: pass cmds.copyKey(source) # if layer: # cmds.animLayer(layer, edit=True, selected=True) for each in target: cmds.pasteKey(each, option="insert", timeOffset=offset)
def copyKeyframes(): objs = cmds.ls(selection=True) if (len(objs) < 2): cmds.error("Please select at least two Objects") sourceObj = objs[0] # First selected object is for copy # Find animated attributes and put on a list animAttributes = cmds.listAnimatable(sourceObj) # Go round the list for attribute in animAttributes: # Get the key frame numbers of animated attributes numKeyframes = cmds.keyframe(attribute, query=True, keyframeCount=True) if (numKeyframes > 0): # Copy keyframes where animated attribute is existed cmds.copyKey(attribute) # Hold keyframes temporarily in memory # No additional flag, grabbing all keyframes for the specified attribute # Paste keyframes to other objects for obj in objs[1:]: cmds.pasteKey(obj, attribute=getAttrName(attribute), option="replace")
def transfer_anim(node, attribute, layer): time_range = get_time_range() can_paste = False try: cmds.copyKey(node, attribute=attribute, time=time_range, animLayer='BaseAnimation') can_paste = True except RuntimeError: try: cmds.copyKey(node, attribute=attribute, time=time_range) can_paste = True except RuntimeError: pass # Fixme: Attributes with no animation connections if can_paste: try: cmds.pasteKey(node, attribute=attribute, option="replace", animLayer=layer) except: pass return
def transferAdd( src, tgt, range=None, tgtTime=None, matchRo=False ): ''' this is the core proc for copy/paste animation transfers. like the transfer command, this proc only works with a single source, single target ''' #if there are no keys, quit try: if cmd.keyframe(src, q=True, kc=True): return except RuntimeError: return time = tgtTime if tgtTime is None: time = cmd.currentTime(q=True) #match the rotation orders of the objects. if matchRo: try: cmd.setAttr(tgt +".ro", cmd.getAttr(src +".ro")) except RuntimeError: pass #finally, perform the copy - this may fail as we still haven't validated the existence of tgt... try: cmd.copyKey(src, time=range, hierarchy='none', animation='objects', o='curve') cmd.pasteKey(tgt, time=time, option='merge', animation='objects') except RuntimeError: return
def copyAnim(filename, objs, *args): #objs = cmds.ls(sl=1) # first: is there even anything here? if len(objs) < 1: return False # check for unknown nodes: this prevents ASCII conversion. unk = cmds.ls(type='unknown') if len(unk) > 0: cmds.error( 'You have unknown nodes in your scene. Run the cleanup utility before exporting animation.' ) if cmds.objExists('animXferTEMP'): cmds.delete('animXferTEMP') cmds.createNode('transform', n='animXferTEMP') for obj in objs: attrs = cmds.listAttr(obj, k=1) startTime = -100000 endTime = 100000 for attr in attrs: numkeys = cmds.keyframe(obj, q=1, at=attr, kc=1) if numkeys > 0: cmds.addAttr('animXferTEMP', at='double', longName=obj.replace(':', '___') + '_ANIM_' + attr) cmds.copyKey(obj, t=(startTime, endTime), at=attr) cmds.pasteKey('animXferTEMP', option='replaceCompletely', at=obj.replace(':', '___') + '_ANIM_' + attr) cmds.select('animXferTEMP') if filename.split('.')[-1] != '.ma': filename = filename + '.ma' f = cmds.file(filename, es=1, chn=1, type='mayaAscii', force=1) print 'wrote animation to file: %s' % (f) cmds.delete('animXferTEMP')
def Activate(): global RandomEnable global SelectedList _Mesh = SelectedList startFrame = int(cmds.textField(TimeTextField_m, q = True, text = True)) endFrame = int(cmds.textField(TimeTextField_M, q = True, text = True)) if RandomEnable: R_m = int(cmds.textField(randomMin, q = True, text = True)) R_M = int(cmds.textField(randomMax, q = True, text = True)) _Interval = randomInt(R_m,R_M) else: _Interval = int(cmds.textField(IntervalTextField, q = True, text = True)) nextFrame = _Interval + 1 cmds.bakeResults(_Mesh, t = (startFrame, endFrame)) for num in range(startFrame, endFrame): if RandomEnable: _Interval = randomInt(R_m,R_M) nextFrame = _Interval + 1 key = IntervalNum(num, nextFrame, startFrame, endFrame) if isValid(key): for index in range(0,len(_Mesh)): cmds.copyKey(_Mesh[index], t = (key,key)) PasteFollowKeys(key,_Interval,_Mesh[index]) #print(nextFrame) else: #print('Error: Out of boundary!') return
def AnimationCopyTool_57(): def keys_as_dictionary(channel): """return a dictionay of times:values for """ keys = mc.keyframe(channel, q=True, tc=True) or [] values = mc.keyframe(channel, q=True, vc=True) or [] return dict(zip(keys, values)) def channels(): """return a dictionary of : for each animated plug selected""" keys = mc.keyframe(sl=True, n=True, q=True) result = {} for k in keys: plugs = mc.listConnections(k, p=True)[0] result[plugs]= keys_as_dictionary(k) return result #store selected object info sel = mc.ls(selection=True) if (len(sel) != 1): mm.eval("warning Must select one animated object;") else: mc.copyKey() win = AnimCopyWindow() win.create() pprint.pprint(channels())
def AnimationCopyTool_57(): def keys_as_dictionary(channel): """return a dictionay of times:values for """ keys = mc.keyframe(channel, q=True, tc=True) or [] values = mc.keyframe(channel, q=True, vc=True) or [] return dict(zip(keys, values)) def channels(): """return a dictionary of : for each animated plug selected""" keys = mc.keyframe(sl=True, n=True, q=True) result = {} for k in keys: plugs = mc.listConnections(k, p=True)[0] result[plugs] = keys_as_dictionary(k) return result #store selected object info sel = mc.ls(selection=True) if (len(sel) != 1): mm.eval("warning Must select one animated object;") else: mc.copyKey() win = AnimCopyWindow() win.create() pprint.pprint(channels())
def copyAnimation(source=None, destination=None, pasteMethod='replace', offset=0, start=None, end=None, layer=None): ''' Actually do the copy and paste from one node to another. If start and end frame is specified, set a temporary key before copying, and delete it afterward. ''' if pasteMethod == 'replaceCompletely' or not start or not end: mc.copyKey(source) mc.pasteKey(destination, option=pasteMethod, timeOffset=offset) else: #need to do this per animation curve, unfortunately, to make sure we're not adding or removing too many keys animCurves = mc.keyframe(source, query=True, name=True) if not animCurves: return #story cut keytimes as 2 separate lists means we only have to run 2 cutkey commands, rather than looping through each cutStart = list() cutEnd = list() for curve in animCurves: #does it have keyframes on the start and end frames? startKey = mc.keyframe(curve, time=(start, ), query=True, timeChange=True) endKey = mc.keyframe(curve, time=(end, ), query=True, timeChange=True) #if it doesn't set a temporary key for start and end #and store the curve name in the appropriate list if not startKey: mc.setKeyframe(curve, time=(start, ), insert=True) cutStart.append(curve) if not endKey: mc.setKeyframe(curve, time=(end, ), insert=True) cutEnd.append(curve) mc.copyKey(source, time=(start, end)) mc.pasteKey(destination, option=pasteMethod, time=(start, end), copies=1, connect=0, timeOffset=offset) #if we set temporary source keys, delete them now if cutStart: mc.cutKey(cutStart, time=(start, )) if cutEnd: mc.cutKey(cutEnd, time=(end, ))
def animCopyPaste(): sel = cmds.ls(sl=True) if len(sel) == 2: frame = frameRange() cmds.copyKey(sel[0], time=(frame[0], frame[1]), option='keys', hierarchy='none', controlPoints=0, shape=1) cmds.pasteKey(sel[1], time=(frame[0], ), f=(frame[0], ), option='merge', copies=1, connect=0, timeOffset=0, floatOffset=0, valueOffset=0) else: cmds.warning('////... Select 2 objects. The first should have keys...////')
def animCopy(): # copy anim sel = animSelList() if len(sel) > 0: frame = frameRange() cmds.copyKey(sel, time=(frame[0], frame[1]), option='keys', hierarchy='none', controlPoints=0, shape=1) mel.eval('print \"' + 'Animation copied form -' + str(frame[0]) + '- to -' + str(frame[1]) + '-\";') else: cmds.warning('////... Select at least one object with animation...////')
def legIkToFk(rigNS,side,start=None,end=None,sampleBy=1): ''' Bake IK leg animation to FK controls @param rigNS: IK/FK toggle attribute @type rigNS: str @param side: Leg side ("lf" or "rt") @type side: str @param start: Transfer animation start frame @type start: int or None @param end: Transfer animation end frame @type end: int or None @param sampleBy: Bake animation by N frames @type sampleBy: int ''' # Get Start/End if start == None: start = mc.playbackOptions(q=True,min=True) if end == None: end = mc.playbackOptions(q=True,max=True) # Set Leg to IK mode mc.setAttr(rigNS+':config.'+side+'LegIkFkBlend',0) # IK # Build IK/FK Joint List ikJntList = [rigNS+':'+side+'_leg_ik'+i+'_jnt' for i in ['A','B']] ikJntList += [rigNS+':'+side+'_foot_ik'+i+'_jnt' for i in ['A','B']] fkJntList = [rigNS+':'+side+'_leg_fk'+i+'_jnt' for i in ['A','B']] fkJntList += [rigNS+':'+side+'_foot_fk'+i+'_jnt' for i in ['A','B']] # Duplicate FK Joints and Constrain to IK fkDupList = [] fkOriList = [] for i in range(len(ikJntList)): fkDupList.append(mc.duplicate(fkJntList[i],po=True)[0]) fkOriList.append(mc.orientConstraint(ikJntList[i],fkDupList[-1])[0]) # Transfer Baked Anim to FK Joints mc.refresh(suspend=True) for i in range(len(fkDupList)): mc.bakeResults( fkDupList[i], t=(start,end), at=['rx','ry','rz'], simulation=True, preserveOutsideKeys=True, sampleBy=sampleBy ) mc.copyKey(fkDupList[i],at=['rx','ry','rz'],t=(start,end)) mc.pasteKey(fkJntList[i],at=['rx','ry','rz'],t=(start,end),option='replace') mc.refresh(suspend=False) # Delete Duplicate Joints and Constraints if fkOriList: try: mc.delete(fkOriList) except Exception, e: print('Error deleting nodes '+str(fkOriList)+'! Exception Msg: '+str(e)) if fkDupList: try: mc.delete(fkDupList) except Exception, e: print('Error deleting nodes '+str(fkDupList)+'! Exception Msg: '+str(e)) # Set to FK mode mc.setAttr(rigNS+':config.'+side+'LegIkFkBlend',1) # FK
def copyAnimation(source=None, destination=None, pasteMethod='replace', offset=0, start=None, end=None, layer=None): ''' Actually do the copy and paste from one node to another. If start and end frame is specified, set a temporary key before copying, and delete it afterward. ''' if layer: mc.select(destination) mc.animLayer(layer, edit=True, addSelectedObjects=True) #we want to make sure rotation values are within 360 degrees, so we don't get flipping when blending layers. utl.minimizeRotationCurves(source) utl.minimizeRotationCurves(destination) if pasteMethod=='replaceCompletely' or not start or not end: mc.copyKey(source) if layer: mc.animLayer(layer, edit=True, selected=True) mc.pasteKey(destination, option=pasteMethod, timeOffset=offset) else: #need to do this per animation curve, unfortunately, to make sure we're not adding or removing too many keys animCurves = mc.keyframe(source, query=True, name=True) if not animCurves: return #story cut keytimes as 2 separate lists means we only have to run 2 cutkey commands, rather than looping through each cutStart = list() cutEnd = list() for curve in animCurves: #does it have keyframes on the start and end frames? startKey = mc.keyframe(curve, time=(start,), query=True, timeChange=True) endKey = mc.keyframe(curve, time=(end,), query=True, timeChange=True) #if it doesn't set a temporary key for start and end #and store the curve name in the appropriate list if not startKey: mc.setKeyframe(curve, time=(start,), insert=True) cutStart.append(curve) if not endKey: mc.setKeyframe(curve, time=(end,), insert=True) cutEnd.append(curve) mc.copyKey(source, time=(start,end)) if layer: for each in mc.ls(type='animLayer'): mc.animLayer(each, edit=True, selected=False, preferred=False) mc.animLayer(layer, edit=True, selected=True, preferred=True) mc.pasteKey(destination, option=pasteMethod, time=(start,end), copies=1, connect=0, timeOffset=offset) #if we set temporary source keys, delete them now if cutStart: mc.cutKey(cutStart, time=(start,)) if cutEnd: mc.cutKey(cutEnd, time=(end,))
def PasteKeys(self): cmds.copyKey('Cube0', attribute='translateY') for i in range(0, self.MC.GroupCubeD): for j in range(0, self.MC.GroupCubeW): if i == 0 and j == 0: continue cmds.pasteKey("Cube" + str(i * self.MC.GroupCubeW + j), attribute='translateY')
def preroll(): amintime = cmds.playbackOptions(query=1, minTime=1) amaxtime = cmds.playbackOptions(query=1, maxTime=1) arolltime = amintime - 21 amidtime = amintime - 11 cmds.playbackOptions(minTime=arolltime) cmds.cutKey(t=(arolltime, amintime - 1)) cmds.copyKey(t=(amintime, amintime)) cmds.pasteKey(t=(amidtime, amidtime)) cmds.pasteKey(t=(arolltime, arolltime)) cmds.currentTime(arolltime, update=1, edit=True)
def copy_animation(source, destination, offset=0): """ Copy animation from source to destination :param str source: Transform node name. :param str destination: Transform node name. :param int offset: Time offset. """ if not cmds.objExists(source) or not cmds.objExists(destination): return cmds.copyKey(source) delete_connected_curves(destination) cmds.pasteKey(destination, option='replaceCompletely', timeOffset=offset)
def CopyAnimation(self): ''' Copies the animations of list one into list two ''' i = 0 while i < len(self.ListOne): cmds.copyKey(self.ListOne[i], time=(cmds.intFieldGrp(self.intGrp, q=True, v1=True), cmds.intFieldGrp(self.intGrp, q=True, v2=True))) cmds.pasteKey(self.ListTwo[i], o='replace') cmds.warning('Animations copied from ' + self.ListOne[i] + ' to ' + self.ListTwo[i]) i += 1
def parentBake(objs, parent=None, bakeOnOnes=False): #check objects can be parented parentReferenced = mc.referenceQuery( parent, isNodeReferenced=True) if parent else False culledObjs = [] for each in objs: eachParent = mc.listRelatives(each, parent=True) if mc.referenceQuery(each, isNodeReferenced=True): if parentReferenced: OpenMaya.MGlobal.displayWarning( "Child and parent are both referenced, skipping: {} > {}". format(each, parent)) continue if eachParent and mc.referenceQuery(eachParent[0], isNodeReferenced=True): OpenMaya.MGlobal.displayWarning( "Node is referenced and can't be reparented, skipping: {}". format(each)) continue if not parent and not eachParent: OpenMaya.MGlobal.displayWarning( "Node is already child of the world, skipping: {}".format( each)) continue culledObjs.append(each) if not culledObjs: OpenMaya.MGlobal.displayWarning("No nodes could be reparented.") return source = [] destination = [] for each in culledObjs: source.append(mc.duplicate(each, parentOnly=True)[0]) mc.copyKey(each) mc.pasteKey(source[-1], option='replaceCompletely') try: if parent: destination.append(mc.parent(each, parent)[0]) else: destination.append(mc.parent(each, world=True)[0]) except RuntimeError as err: mc.delete(source) raise err utl.matchBake(source=source, destination=destination, bakeOnOnes=bakeOnOnes) mc.delete(source)
def _pasteTiming(self, source, target, key): if key.next: cmds.copyKey(source, time=(key.keyIndex, key.keyIndex)) cmds.pasteKey(target, time=(self.currentTime, self.currentTime)) self.currentTime = self.currentTime + ( (key.next.time - key.time) * 25) self._pasteTiming(source, target, key.next) else: return
def _pasteTiming(self, source, target, key): if key.next: cmds.copyKey(source, time=(key.keyIndex, key.keyIndex)) cmds.pasteKey(target, time=(self.currentTime, self.currentTime)) self.currentTime = self.currentTime + ((key.next.time - key.time) * 25) self._pasteTiming(source, target, key.next) else: return
def duplicateFirst(doShaders=False): #1. make an array of all selected objects target = mc.ls(sl=1) #2. if only one selection, just make a new duplicate at the same coordinates... if(len(target)==1): #call through mel because python has no rc option! mel.eval("duplicate -un -ic -rc") else: try: #3. check if the first selection is skinned. mc.select(target[0]) mc.skinCluster(q=True) print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" print "Select the root joint for this to work properly." print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" except: #4. ...otherwise, for each selected object... for i in range(1,len(target)): #5. ...get current selection's position and copy keyframes and shader mc.select(target[i]) pos = mc.xform(target[i], q=True, t=True, ws=True) try: shader = getShader() except: print "Couldn't get shader." try: mc.copyKey() except: print "Couldn't copy keys." #6. duplicate the first selection mc.select(target[0]) #call through mel because python has no rc option! mel.eval("duplicate -un -ic -rc") #7. move first selection to position and paste keyframes and shader mc.move(pos[0],pos[1],pos[2]) if(doShaders==True): setShader(shader) try: mc.pasteKey() except: print "Couldn't paste keys." #8. delete selection mc.delete(target[i])
def duplicateFirst(doShaders=False): #1. make an array of all selected objects target = mc.ls(sl=1) #2. if only one selection, just make a new duplicate at the same coordinates... if (len(target) == 1): #call through mel because python has no rc option! mel.eval("duplicate -un -ic -rc") else: try: #3. check if the first selection is skinned. mc.select(target[0]) mc.skinCluster(q=True) print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" print "Select the root joint for this to work properly." print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" except: #4. ...otherwise, for each selected object... for i in range(1, len(target)): #5. ...get current selection's position and copy keyframes and shader mc.select(target[i]) pos = mc.xform(target[i], q=True, t=True, ws=True) try: shader = getShader() except: print "Couldn't get shader." try: mc.copyKey() except: print "Couldn't copy keys." #6. duplicate the first selection mc.select(target[0]) #call through mel because python has no rc option! mel.eval("duplicate -un -ic -rc") #7. move first selection to position and paste keyframes and shader mc.move(pos[0], pos[1], pos[2]) if (doShaders == True): setShader(shader) try: mc.pasteKey() except: print "Couldn't paste keys." #8. delete selection mc.delete(target[i])
def Keyframe_Match(MotionPathText,LocText): MotionPath = cmds.textField(MotionPathText,q=1,tx=1) Locator = cmds.textField(LocText,q=1,tx=1) Selection = cmds.ls(sl=1)[0] cmds.cutKey("%s.uValue"%MotionPath,clear=True) AnimCurve = cmds.listConnections( "%s.uValue"%Locator, d=False, s=True )[0] StartTime = cmds.findKeyframe(Locator,w="first") EndTime = cmds.findKeyframe(Locator,w="last") cmds.copyKey( "%s.uValue" % Locator, time=(StartTime,EndTime)) cmds.pasteKey("%s.uValue" % MotionPath) cmds.headsUpMessage(u"关键帧匹配完成")
def bakeCameraMeatAnimToClone(camMeta): """Given a camera node which has meta data(MetaCamera), create a temporary meta camera which is a clone of the camera and bake per frame anim data down. The passed in camera will be renamed so that the camera clone has the shot name however we dont not rename the original back to the correct name. The reason for this is so the client can do further operations on the baked cam. :param camMeta: The MetaCamera instance which is attached to the camera :type camMeta: MetaCamera :return: The new Baked camera if the keys were baked. otherwise None :rtype: MetaCamera or None """ # temp rename so that the the baked camera has the original name camMeta.rename("_".join([camMeta.shotName.asString(), "ORIG"])) bakedCam = createCamera(camMeta.shotName.asString(), camMeta.startFrame.asInt(), camMeta.endFrame.asInt()) bakedCam.copyFrom(camMeta) result = cmds.copyKey(camMeta.fullPathName()) if result == 0: bakedCam.delete() camMeta.rename(camMeta.shotName.asString()) return padding = bakedCam.framePadding.asInt() targetName = bakedCam.fullPathName() cmds.pasteKey(targetName, option="replace") cmds.bakeResults(targetName, t=((bakedCam.startFrame.asInt() - padding), (bakedCam.endFrame.asInt() + padding)), sb=1) return bakedCam
def copyKeyframes(self): undoInfo(closeChunk=True) objs = cmds.ls(selection=True) if (len(objs) < 2): cmds.error("Please select at least two objects") sourceObj = objs[0] animAttributes = cmds.listAnimatable(sourceObj); for attribute in animAttributes: numKeyframes = cmds.keyframe(attribute, query=True, keyframeCount=True) if (numKeyframes > 0): cmds.copyKey(attribute) for obj in objs[1:]: cmds.pasteKey(obj, attribute=self.getAttName(attribute), option="replace") undoInfo(closeChunk=True)
def on_slider_pressed(self): sel = cmds.ls(selection=True) #checking selection if sel: #storing animation cmds.copyKey(sel, time=(self.startFrame, self.endFrame)) #start recording keys k = key(time.time(), int(cmds.currentTime(q=True))) self.currentKey = k else: cmds.warning('No nodes selected!')
def Keyframe_Match(text): target = cmds.textField(text,q=1,tx=1) selList = cmds.ls(sl=1) for sel in selList: StartTime = cmds.getAttr("%s.start"%sel) EndTime = cmds.getAttr("%s.end"%sel) if StartTime == EndTime: StartTime = cmds.findKeyframe(sel,w="first") EndTime = cmds.findKeyframe(sel,w="last") cmds.copyKey( sel, time=(StartTime,EndTime), option="curve" ,at="translate") targetEndTime = cmds.findKeyframe(target,w="last") cmds.pasteKey( target, time=(targetEndTime,targetEndTime) ) cmds.headsUpMessage(u"关键帧匹配完成")
def createCleanedCamera() : # Select camera then run the script. # Script will duplicate selected camera. cleanedCam = 'cleanedNuke_cam' if mc.objExists( cleanedCam ) : mc.delete( cleanedCam ) selectedCam = '' selectedCamShp = '' selected = mc.ls( sl=True , l=True )[0] if mc.nodeType( selected ) == 'camera' : selectedCamShp = selected selectedCam = mc.listRelatives( selected , p=True , f=True )[0] else : selectedCam = selected selectedCamShp = mc.listRelatives( selected , type='shape' , f=True )[0] mc.select( selectedCam ) mc.duplicate( selectedCam , rr=True , n=cleanedCam ) mc.parent( w=True ) duppedCamShp = mc.listRelatives( cleanedCam , type='shape' , f=True )[0] for attr in ( 'tx' , 'ty' , 'tz' , 'rx' , 'ry' , 'rz' ) : mc.setAttr( '%s.%s' % ( cleanedCam , attr ) , l=False ) minTime = mc.playbackOptions( q=True , min=True ) maxTime = mc.playbackOptions( q=True , max=True ) animCurves = mc.listConnections( selectedCamShp , s=True , type='animCurve' ) attrs = [] if animCurves : for animCurve in animCurves : attr = mc.listConnections( animCurve , d=True , p=True )[0].split( '.' )[1] mc.copyKey( selectedCamShp , attribute=attr ) mc.pasteKey( duppedCamShp , attribute=attr ) parCons = mc.parentConstraint( selectedCam , cleanedCam ) mc.bakeResults( cleanedCam , simulation=True , t=( minTime , maxTime ) ) mc.delete( parCons )
def apply(self, attrPath, sourceRange, applyStart): ''' used to put the animation data on this instance to an actual attribute sourceRange should be a 2-tuple representing the 0-based time range of the animation data to apply applyStart should be the start time at which to place the animation ''' keyCmdKwargs = {} if sourceRange: keyCmdKwargs['t'] = sourceRange animCurveNode = self.constructNode(applyStart) try: cmd.copyKey(animCurveNode, clipboard='api', **keyCmdKwargs) cmd.pasteKey(attrPath, option='replace', clipboard='api') finally: cmd.delete(animCurveNode)
def apply( self, attrPath, sourceRange, applyStart ): ''' used to put the animation data on this instance to an actual attribute sourceRange should be a 2-tuple representing the 0-based time range of the animation data to apply applyStart should be the start time at which to place the animation ''' keyCmdKwargs = {} if sourceRange: keyCmdKwargs[ 't' ] = sourceRange animCurveNode = self.constructNode( applyStart ) try: cmd.copyKey( animCurveNode, clipboard='api', **keyCmdKwargs ) cmd.pasteKey( attrPath, option='replace', clipboard='api' ) finally: cmd.delete( animCurveNode )
def copyKeyframes(self, obj1, obj2): obj1 = obj1.name() obj2 = obj2.name() objs = [obj1, obj2] if (len(objs) < 2): cmds.error("Please select at least two objects") sourceObj = objs[0] animAttributes = cmds.listAnimatable(sourceObj) for attribute in animAttributes: numKeyframes = cmds.keyframe(attribute, query=True, keyframeCount=True) if (numKeyframes > 0): cmds.copyKey(attribute) for obj in objs[1:]: cmds.pasteKey(obj, attribute=self.getAttName(attribute), option="replace")
def copyAnim(): sels = mc.ls(sl=1) if len(sels) >= 2: source = sels[0] target = sels[1] keyableAttrs = mc.listAttr(source, k=1) for keyableAttr in keyableAttrs: value = mc.getAttr(source+'.'+str(keyableAttr)) # check if target has the attribute if mc.objExists(target + '.' + str(keyableAttr)): # making sure it's either not locked or not having an input if mc.getAttr(target+'.'+str(keyableAttr), l=1) != 1 and mc.connectionInfo(target+'.'+keyableAttr, id=1) != 1: mc.setAttr(target + '.' + str(keyableAttr), value) mc.copyKey(source) try: mc.pasteKey(target) except: pass else: print 'Please select 2 objects to copy from and paste to.'
def copy_original_curves(): # type: () -> tuple """ Copy selected animation curves to clipboard and return their names with start and end frames so we can paste them back later :return: list of anim curve names, start frame, end frame :rtype: list, float, float """ anim_curves = cmds.keyframe(q=True, sl=True, name=True) if anim_curves is None: cmds.headsUpMessage("No animation keys/curve selected! Select keys to filter, please!") cmds.warning("No animation keys/curve selected! Select keys to filter, please!") return None, None, None anim_keys = cmds.keyframe(q=True, sl=True, timeChange=True) start, end = int(anim_keys[0]), int(anim_keys[len(anim_keys) - 1]) cmds.copyKey(anim_curves, t=(start, end)) return anim_curves, start, end
def parentBake(objs, parent=None, bakeOnOnes=False): #check objects can be parented parentReferenced = mc.referenceQuery(parent, isNodeReferenced=True) if parent else False culledObjs = [] for each in objs: eachParent = mc.listRelatives(each, parent=True) if mc.referenceQuery(each, isNodeReferenced=True): if parentReferenced: OpenMaya.MGlobal.displayWarning("Child and parent are both referenced, skipping: {} > {}".format(each, parent)) continue if eachParent and mc.referenceQuery(eachParent[0], isNodeReferenced=True): OpenMaya.MGlobal.displayWarning("Node is referenced and can't be reparented, skipping: {}".format(each)) continue if not parent and not eachParent: OpenMaya.MGlobal.displayWarning("Node is already child of the world, skipping: {}".format(each)) continue culledObjs.append(each) if not culledObjs: OpenMaya.MGlobal.displayWarning("No nodes could be reparented.") return source = [] destination = [] for each in culledObjs: source.append(mc.duplicate(each, parentOnly=True)[0]) mc.copyKey(each) mc.pasteKey(source[-1], option='replaceCompletely') try: if parent: destination.append(mc.parent(each, parent)[0]) else: destination.append(mc.parent(each, world=True)[0]) except RuntimeError as err: mc.delete(source) raise err utl.matchBake(source=source, destination=destination, bakeOnOnes=bakeOnOnes) mc.delete(source)
def paste_animation( self, sTimeRange=tuple(), tTimeRange=tuple(), option="fitInsert", predicate=None, converter=None ): """paste the stored animation to their respective target animation curves, if target does not exist it will be created :param sTimeRange: tuple of timerange passed to copyKey :param tTimeRange: tuple of timerange passed to pasteKey :param option: option on how to paste forwarded to pasteKey (useful: "fitInsert", "fitReplace", "scaleInsert", "scaleReplace") :param predicate and converter: passed to ``iter_assignments``, see documentation there :todo: handle if range is out of curve (error:nothing to paste from) - should paste the pose in this range""" iter_plugs=self.iter_assignments(predicate=predicate, converter=converter) # get animCurves form plugs and copy pate for s_plug, t_plug in iter_plugs: s_animcrv=s_plug.mwn() if apianim.MAnimUtil.isAnimated(t_plug): t_animcrv=t_plug.minput().mwn() else: t_animcrv=nt.Node(apianim.MFnAnimCurve().create(t_plug)) # END get new or existing animCurve cmds.copyKey(s_animcrv, time=sTimeRange, option="curve" ) cmds.pasteKey(t_animcrv, time=tTimeRange, option=option)
def instanceFirst(doShaders=False): #1. make an array of all selected objects target = mc.ls(sl=1) #2. if only one selection, just make a new instance at the same coordinates... if(len(target)==1): mc.instance() else: #3. ...otherwise, for each selected object... for i in range(1,len(target)): #4. ...get current selection's position and copy keyframes and shader mc.select(target[i]) pos = mc.xform(target[i], q=True, t=True, ws=True) try: shader = getShader() except: print "Couldn't get shader." try: mc.copyKey() except: print "Couldn't copy keys." #5. instance the first selection mc.select(target[0]) mc.instance() #6. move first selection to position and paste keyframes and shader mc.move(pos[0],pos[1],pos[2]) if(doShaders==True): setShader(shader) try: mc.pasteKey() except: print "Couldn't paste keys." #7. delete selection mc.delete(target[i])
def _transfer_keys(self, from_controls, to_controls): """ Responsible for the transfer of keys, given a provided frame range. @param: from_controls: Controls with keys you want to transfer. to_controls: Controls you want to transfer keys too. """ start = self.start_frame end = self.end_frame for count, control in enumerate(from_controls): copy = cmds.copyKey(control, time=(start, end), at=TR_ATTRS) try: paste = cmds.pasteKey(to_controls[count], at=TR_ATTRS) except RuntimeError: continue
def limbsIkToFkOLD(rigNS,start=None,end=None,sampleBy=1): ''' Bake IK limb animation to FK controls @param rigNS: IK/FK toggle attribute @type rigNS: str @param start: Transfer animation start frame @type start: int or None @param end: Transfer animation end frame @type end: int or None @param sampleBy: Bake animation by N frames @type sampleBy: int ''' # ========== # - Checks - # ========== # Get Start/End if start == None: start = mc.playbackOptions(q=True,min=True) if end == None: end = mc.playbackOptions(q=True,max=True) # ========================== # - Build IK/FK Joint List - # ========================== ikJntList = [] fkJntList = [] index = ['A','B'] sides = ['lf','rt'] for side in sides: if not mc.getAttr(rigNS+':config.'+side+'ArmIkFkBlend'): #ikJntList += [rigNS+':'+side+'_arm_ik'+i+'_jnt' for i in index] #fkJntList += [rigNS+':'+side+'_arm_fk'+i+'_jnt' for i in index] armIkToFk(rigNS,side,True,start,end,sampleBy) if not mc.getAttr(rigNS+':config.'+side+'LegIkFkBlend'): #ikJntList += [rigNS+':'+side+'_leg_ik'+i+'_jnt' for i in index] #fkJntList += [rigNS+':'+side+'_leg_fk'+i+'_jnt' for i in index] #ikJntList += [rigNS+':'+side+'_foot_ik'+i+'_jnt' for i in index] #fkJntList += [rigNS+':'+side+'_foot_fk'+i+'_jnt' for i in index] legIkToFk(rigNS,side,start,end,sampleBy) # Check IK/FK State if not fkJntList: print('Limbs already in FK mode! Nothing to do...') return fkJntList # ==================================== # - Bake Wrist Animation to Locators - # ==================================== # Build Wrist Duplicates for Baking wristJnts = [rigNS+':'+side+'_handA_jnt' for side in sides] wristDups = [mc.duplicate(jnt,po=True)[0] for jnt in wristJnts] keys = mc.copyKey(wristJnts,at=['rx','ry','rz'],t=(start,end)) if keys: mc.pasteKey(wristDups,at=['rx','ry','rz'],t=(start,end),option='replace') # Bake Wrists to Locators wristLocs = glTools.anim.utils.bakeAnimToLocators( objList = wristJnts, start = start, end = end, sampleBy = sampleBy, simulation = True, attrList = ['rx','ry','rz'] ) # ======================= # - Bake Limb Animation - # ======================= # Duplicate FK Joints and Constrain to IK fkDupList = [] fkOriList = [] for i in range(len(ikJntList)): fkDupList.append(mc.duplicate(fkJntList[i],po=True)[0]) fkOriList.append(mc.orientConstraint(ikJntList[i],fkDupList[-1])[0]) # Transfer Baked Anim to FK Joints mc.refresh(suspend=True) for i in range(len(fkDupList)): mc.bakeResults( fkDupList[i], t=(start,end), at=['rx','ry','rz'], simulation=True, preserveOutsideKeys=True, sampleBy=sampleBy ) # Transfer Keys for i in range(len(fkDupList)): keys = mc.copyKey(fkDupList[i],at=['rx','ry','rz'],t=(start,end)) if keys: mc.pasteKey(fkJntList[i],at=['rx','ry','rz'],t=(start,end),option='replace') mc.refresh(suspend=False) # Delete Duplicate Joints and Constraints if fkOriList: try: mc.delete(fkOriList) except Exception, e: print('Error deleting nodes '+str(fkOriList)+'! Exception Msg: '+str(e)) if fkDupList: try: mc.delete(fkDupList) except Exception, e: print('Error deleting nodes '+str(fkDupList)+'! Exception Msg: '+str(e)) # ====================================== # - Bake Wrist Animation from Locators - # ====================================== # Set to FK Mode for side in sides: mc.setAttr(rigNS+':config.'+side+'ArmIkFkBlend',1) mc.setAttr(rigNS+':config.'+side+'LegIkFkBlend',1) # Bake Wrists from Locators glTools.anim.utils.bakeAnimFromLocators( locList = wristLocs, start = start, end = end, sampleBy = sampleBy, simulation = True, attrList = ['rx','ry','rz'] ) # Transfer Baked Keys keys = mc.copyKey(wristDups,at=['rx','ry','rz'],t=(start,end)) if keys: mc.pasteKey(wristJnts,at=['rx','ry','rz'],t=(start,end),option='replace') # Cleanup if wristLocs: try: mc.delete(wristLocs) except: pass if wristDups: try: mc.delete(wristDups) except: pass # ================= # - Return Result - # ================= return fkJntList
def copyAnimation(fromNode, toNode): mc.copyKey(fromNode) mc.pasteKey(toNode, option='replaceCompletely') for axis in getMirrorAxis(toNode): mc.scaleKey(toNode, attribute=axis, valueScale=-1)
def armFkToIk(rigNS,side,bakeWrist=True,start=None,end=None,sampleBy=1): ''' Bake FK arm animation to IK controls @param rigNS: IK/FK toggle attribute @type rigNS: str @param side: Arm side ("lf" or "rt") @type side: str @param bakeWrist: Bake wrist animation @type bakeWrist: bool @param start: Transfer animation start frame @type start: int or None @param end: Transfer animation end frame @type end: int or None @param sampleBy: Bake animation by N frames @type sampleBy: int ''' # ========== # - Checks - # ========== # Get Start/End if start == None: start = mc.playbackOptions(q=True,min=True) if end == None: end = mc.playbackOptions(q=True,max=True) # Get FK Joints fkShoulder = rigNS+':'+side+'_arm_fkA_jnt' fkElbow = rigNS+':'+side+'_arm_fkB_jnt' fkWrist = rigNS+':'+side+'_handA_jnt' # Get IK Controls ikWrist = rigNS+':'+side+'_arm_ik_ctrl' ikElbow = rigNS+':'+side+'_arm_pv_ctrl' # ===================== # - Transfer FK to IK - # ===================== # Set Arm to FK mode mc.setAttr(rigNS+':config.'+side+'ArmIkFkBlend',1) # FK # Bake Wrist to Locator wristLoc = None if bakeWrist: wristLoc = glTools.anim.utils.bakeAnimToLocator( obj = fkWrist, start = start, end = end, sampleBy = sampleBy, simulation = True, attrList = ['rx','ry','rz'] ) # Duplicate IK Controls ikWristLoc = mc.duplicate(ikWrist,po=True)[0] ikElbowLoc = mc.duplicate(ikElbow,po=True)[0] # Constrain IK to FK joints ikWristCon = mc.pointConstraint(fkWrist,ikWristLoc)[0] pvWristCon = mc.pointConstraint(fkElbow,ikElbowLoc)[0] # Bake Constraint Keys mc.refresh(suspend=True) mc.bakeResults( [ikWristLoc,ikElbowLoc], t=(start,end), at=['tx','ty','tz'], simulation=True, preserveOutsideKeys=True, sampleBy=sampleBy ) mc.refresh(suspend=False) # Transfer Keys to IK Controls mc.copyKey(ikWristLoc,at=['tx','ty','tz'],t=(start,end)) mc.pasteKey(ikWrist,at=['tx','ty','tz'],t=(start,end),option='replace') mc.copyKey(ikElbowLoc,at=['tx','ty','tz'],t=(start,end)) mc.pasteKey(ikElbow,at=['tx','ty','tz'],t=(start,end),option='replace') # Delete Duplicate Joints and Constraints for item in [ikWristLoc,ikElbowLoc]: if mc.objExists(item): try: mc.delete(item) except Exception, e: print('Error deleting node "'+str(item)+'"!') print(str(e))
# Set to FK Mode for side in sides: cmds.setAttr(rigNS + ':config.' + side + 'ArmIkFkBlend', 1) cmds.setAttr(rigNS + ':config.' + side + 'LegIkFkBlend', 1) # Bake Wrists from Locators glTools.anim.utils.bakeAnimFromLocators(locList=wristLocs, start=start, end=end, sampleBy=sampleBy, simulation=True, attrList=['rx', 'ry', 'rz']) # Transfer Baked Keys keys = cmds.copyKey(wristDups, at=['rx', 'ry', 'rz'], t=(start, end)) if keys: cmds.pasteKey(wristJnts, at=['rx', 'ry', 'rz'], t=(start, end), option='replace') # Cleanup if wristLocs: try: cmds.delete(wristLocs) except: pass if wristDups: try: cmds.delete(wristDups) except: pass # =================
def transferAttrs(self, *args): #get selected checkboxes cmds.select(self.character + ":*_space_switcher_follow") nodes = cmds.ls(sl = True) spaceSwitchers = [] for node in nodes: if node.find("invis") == -1: spaceSwitchers.append(node) selectNodes = [] for node in spaceSwitchers: control = node.partition("_space")[0] spaceSwitchNode = node.partition("_follow")[0] value = cmds.symbolCheckBox(control + "_checkboxWidget", q = True, value = True) if value: selectNodes.append(spaceSwitchNode) node = "" for node in selectNodes: control = node.partition("_space")[0] #need to add attr that is on spaceSwitchNode to control attrs = [] try: attrs.extend((cmds.listAttr(node, string = "space_*"))) except: pass #get the target list from the constraint constraint = cmds.listConnections(node, type = "parentConstraint") if constraint != None: targets = cmds.parentConstraint(constraint[0], q = True, weightAliasList = True) #we now have a list of attrs and targets that should match if attrs != None: for attr in reversed(attrs): cmds.addAttr(control, ln = attr, dv = 0, min = 0, max = 1, keyable = True) #setup the new constraint connection targetAttr = None for target in targets: try: cmds.disconnectAttr(node + "." + attr, constraint[0] + "." + target) targetAttr = target except: pass try: cmds.connectAttr(control + "." + attr, constraint[0] + "." + targetAttr) except: cmds.warning("Could not setup connections on " + control) #copy keys from original attr to new attr start = cmds.findKeyframe(node, at = attr, which = "first") end = cmds.findKeyframe(node, at = attr, which = "last") keys = cmds.copyKey(node, time=(start, end), attribute = attr, option = "curve") try: cmds.pasteKey(control, attribute = attr) except: pass #delete spaceSwitchNode attr cmds.deleteAttr(node, at = attr)
import maya.cmds as cmds
def create(target, slaveList, slaveAimUp=None, weightList=None, bakeAnim=False, bakeStartEnd=[None, None], offsetAnim=None, offset=(0, 0, 0), cleanup=False): """ Create a lookAt constraint setup based in the input arguments @param target: LookAt target transform. @type target: str @param slaveList: LookAt slave transform list. @type slaveList: list @param slaveAimUp: List of slave lookAt aim and up vectors. [(aim,up),('z',x),...] @type slaveAimUp: list @param weightList: LookAt weight list. If None, use default weight list (evenly distributed). @type weightList: list @param bakeAnim: Bake lookAt animation to controls. @type bakeAnim: bool @param bakeStartEnd: Tuple containing start and end frame value. @type bakeStartEnd: tuple @param offsetAnim: Offset baked lookAt animation. @type offsetAnim: float or None @param offset: Constraint offset. @type offset: tuple """ # ========== # - Checks - # ========== # Target if not glTools.utils.transform.isTransform(target): raise Exception('LookAt target "' + target + '" is not a valid transform! Unable to create lookAt setup...') # Slave List if not slaveList: raise Exception('Invalid lookAt slave list! Unable to create lookAt setup...') # Weight List if not weightList: print('Invalid lookAt weight list! Generating default lookAt weight list...') weightList = range(0, 101, 100.0 / len(slaveList))[1:] if len(weightList) != len(slaveList): print('Invalid lookAt weight list! Generating default lookAt weight list...') weightList = range(0, 101, 100.0 / len(slaveList))[1:] # Slave Aim/Up Vectors if not slaveAimUp: print('Invalid lookAt slave aim/up vector values! Using default lookAt vectors (aim="z",up="y")...') slaveAimUp = [('z', 'y') for slave in slaveList] if len(slaveAimUp) != len(slaveList): print('Invalid lookAt slave aim/up vector values! Using default lookAt vectors (aim="z",up="y")...') slaveAimUp = [('z', 'y') for slave in slaveList] # =========== # - Look At - # =========== slaveReferenceList = [] slaveLookAtList = [] slaveLookAt_aimList = [] slaveLookAt_orientList = [] slaveBakeList = [] for i in range(len(slaveList)): # Check Slave Object if not cmds.objExists(slaveList[i]): print('Slave object "' + slaveList[i] + '" not found! Skipping...') continue # Get Slave Short Name slaveSN = slaveList[i].split(':')[0] # Duplicate Slave to get Reference and LookAt Targets slaveReference = cmds.duplicate(slaveList[i], po=True, n=slaveSN + '_reference')[0] slaveLookAt = cmds.duplicate(slaveList[i], po=True, n=slaveSN + '_lookAt')[0] # Transfer Anim to Reference slaveKeys = cmds.copyKey(slaveList[i]) if slaveKeys: cmds.pasteKey(slaveReference) # Delete Slave Rotation Anim cmds.cutKey(slaveList[i], at=['rx', 'ry', 'rz']) # Create Slave LookAt slaveLookAt_aim = glTools.tools.constraint.aicmdsonstraint(target=target, slave=slaveLookAt, aim=slaveAimUp[i][0], up=slaveAimUp[i][1], worldUpType='scene', offset=offset, mo=False)[0] # Weighted Orient Constraint slaveLookAt_orient = cmds.orientConstraint([slaveReference, slaveLookAt], slaveList[i], mo=False)[0] slaveLookAt_targets = glTools.utils.constraint.targetAliasList(slaveLookAt_orient) # Set Constraint Target Weights cmds.setAttr(slaveLookAt_orient + '.' + slaveLookAt_targets[0], 1.0 - (weightList[i] * 0.01)) cmds.setAttr(slaveLookAt_orient + '.' + slaveLookAt_targets[1], weightList[i] * 0.01) cmds.setAttr(slaveLookAt_orient + '.interpType', 2) # Shortest # Add Message Connections cmds.addAttr(slaveList[i], ln='lookAtTarget', at='message') cmds.addAttr(slaveList[i], ln='lookAtAnmSrc', at='message') cmds.connectAttr(slaveLookAt + '.message', slaveList[i] + '.lookAtTarget', f=True) cmds.connectAttr(slaveReference + '.message', slaveList[i] + '.lookAtAnmSrc', f=True) # Append Lists slaveReferenceList.append(slaveReference) slaveLookAtList.append(slaveLookAt) slaveLookAt_aimList.append(slaveLookAt_aim) slaveLookAt_orientList.append(slaveLookAt_orient) slaveBakeList.append(slaveList[i]) # ============= # - Bake Anim - # ============= if bakeAnim: # Get Bake Range start = bakeStartEnd[0] end = bakeStartEnd[1] if start == None: start = cmds.playbackOptions(q=True, min=True) if end == None: end = cmds.playbackOptions(q=True, max=True) # Bake Results cmds.refresh(suspend=True) # for slave in slaveBakeList: cmds.bakeResults(slaveBakeList, t=(start, end), at=['rx', 'ry', 'rz'], simulation=True) cmds.refresh(suspend=False) # Post Bake Cleanup if cleanup: try: cmds.delete(slaveLookAt_orientList) except: pass try: cmds.delete(slaveLookAt_aimList) except: pass try: cmds.delete(slaveReferenceList) except: pass try: cmds.delete(slaveLookAtList) except: pass # ==================== # - Bake Anim Offset - # ==================== if offsetAnim != None: # For Each Slave Object for slave in slaveList: # Check Slave Object if not cmds.objExists(slave): print('Slave object "' + slave + '" not found! Skipping...') continue # Offset Rotate Channels for r in ['rx', 'ry', 'rz']: cmds.keyframe(slave + '.' + r, e=True, relative=True, timeChange=offsetAnim) # ================= # - Return Result - # ================= return slaveList
def btnRetarget(*arg): currentTime = cmds.currentTime(query=True) sourceItem = maya.textScrollList(srcBox, q=True, si=True) pasteindex=maya.radioButtonGrp(pasteKeyOptions,q=True,sl=True) if sourceItem == None: return # copyKeyOptions index = maya.radioButtonGrp(copyKeyOptions, q=True, sl=True) if(index == 1): starttime = firstKey(sourceItem[0]) endtime = endKey(sourceItem[0]) else: starttime = maya.floatFieldGrp(timeStart, q=True, value1=True) endtime = maya.floatFieldGrp(timeEnd, q=True, value1=True) maya.copyKey(sourceItem[0], t=(starttime, endtime)) dtnItem = maya.textScrollList(dtnBox, q=True, si=True) if dtnItem == None: return index = maya.radioButtonGrp(timeRange, q=True, sl=True) print index if index == 1: for dtnObj in dtnItem: # Paste animation global pasteOptions #paste animation from current time qt=maya.currentTime(q=True) #get offsettime #use fixed offsettime or random offset from range if(maya.radioButtonGrp(timeOffsetMehod,q=True,sl=True)==1): offsettime = maya.intFieldGrp(fixedtimeOffset, q=True, value1=True) else: startint=maya.intFieldGrp(RandomtimeOffset,q=True,value1=True) endint=maya.intFieldGrp(RandomtimeOffset,q=True,value2=True) offsettime=random.randint(startint,endint) nt=qt+offsettime print offsettime #paste animation recursively if(maya.radioButtonGrp(timeOffsetOptions,q=True,sl=True)==2): maya.currentTime(nt,e=True) maya.pasteKey(dtnObj, t=(nt,),o=pasteOptions[pasteindex-1]) else: #paste animation from specified time st=maya.floatFieldGrp(pastetimeStart,q=True,value1=True) print st et=maya.floatFieldGrp(pastetimeEnd,q=True,value1=True) for dtnObj in dtnItem: if(maya.radioButtonGrp(timeOffsetMehod,q=True,sl=True)==1): offsettime = maya.intFieldGrp(fixedtimeOffset, q=True, value1=True) else: startint=maya.intFieldGrp(RandomtimeOffset,q=True,value1=True) endint=maya.intFieldGrp(RandomtimeOffset,q=True,value2=True) offsettime=random.randint(startint,endint) nst=st+offsettime net=et+offsettime #paste animation recursively if(maya.radioButtonGrp(timeOffsetOptions,q=True,sl=True)==2): maya.currentTime(st,e=True) maya.pasteKey(dtnObj, t=(nst,net),o=pasteOptions[pasteindex-1]) print st print et