def copyAnim(self, args): ''' Copy all animation on transform nodes from one namespace to another ''' srcNS = pm.optionMenu(self.srcFld, q=1, v=1) tgtNS = pm.optionMenu(self.tgtFld, q=1, v=1) sourceControls = pm.ls('%s:*' % srcNS, type='transform') sourceControls += pm.ls('%s:CRIG:*' % srcNS, type='transform') msgs = [] for src in sourceControls: try: if not src.getShape().type() == 'nurbsCurve': continue except: continue print "Trying: ", src cnt = src.split(':')[1:] cnt = ":".join(cnt) tgtCnt = '%s:%s' % (tgtNS, cnt) try: pm.copyKey(src) pm.pasteKey(tgtCnt) except Exception, e: # try: # pm.delete(pm.pointConstraint(src, tgtCnt, mo=0)) # pm.delete(pm.orientConstraint(src, tgtCnt, mo=0)) # except Exception, e: print '\nFailed' print 'Source: ', src print 'Error:', e
def aw_copyKeys(source, targets, randomShift=0, increment=0, mo=False): '''This script will copy the keyframes from source to targets from selected channel box attributes Args: source (mayaObject): Source object with animation targets (list[mayaObject]): Copy To Targets randomShift (int): Randomly shift by x, 0 is no shift increment (int): Increment value through selection by x, 0 is no increment mo (Boolean): Maintain the Offset or not Returns (void): no return Example: aw_copyKeys(pm.PyNode('pSphere1'), pm.ls(sl=True), randomShift=0, increment=1, mo=True) ''' args=targets animSrc=source #Determine Selected attributes from channelbox pm.language.melGlobals.initVar( 'string', 'gChannelBoxName' ) attrs = pm.channelBox(pm.language.melGlobals['gChannelBoxName'],q=True,sma=True) #Copy Keys from the Graph Editor for main object (deselect other objects before copying) if not attrs: print 'Nothing selected in channel box, setting copy attributes to default all' attrs=['tx','ty','tz','rx','ry','rz','sx','sy','sz','v'] for arg,i in zip(args, range(len(args))): if arg != animSrc: for attr in attrs: pm.copyKey(animSrc, time = (pm.playbackOptions(q=True,ast=True), pm.playbackOptions(q=True,aet=True)), at=attr,option="curve", hierarchy='none') #Paste keys to all objects depending on attributes selected from the channelBox offsetCheck = attr in ['tx','ty','tz','rx','ry','rz'] offsetSeed = ((i+1) * increment) + int(math.floor( random.random() * randomShift)) pm.pasteKey(arg, option='insert', valueOffset=((offsetCheck * mo) * (arg.attr(attr).get() - animSrc.attr(attr).get())), copies=True, connect=True, at=attr, timeOffset=offsetSeed)
def scaleChara(self, mayaFalse): #this part does the importing and admin stuff try: pm.createReference( '//p.sv/Prism/project/Parallel/element/character_Roll/scenes/' + pm.optionMenu(self.charalist, q=True, value=True)[-4:-1] + '001_SP01.mb', namespace=':') except: pm.confirmDialog(title=u'Parallel scaling', message=u'Parallel フォルダーの許可がないです。') #this part does the scaling pm.optionMenu('listofchara', q=True, value=True) inverseScale = 1 / self.nameScale[pm.optionMenu( self.charalist, q=True, value=True)] pm.scale('Reference|Root', inverseScale, inverseScale, inverseScale) for i in pm.listRelatives('Reference', ad=True, type='joint'): try: pm.copyKey(i) pm.pasteKey(i.replace('Reference', 'Reference1')) except: print 'no keys to copypasta' pm.scaleKey('Reference1|Root|Hips', valueScale=inverseScale, valuePivot=0, attribute='translate') #this part cleans up the file pm.delete('Reference') pm.listReferences()[0].importContents(removeNamespace=False) pm.rename('Reference1', 'Reference')
def smart_loop(): with pm.UndoChunk(): for obj in pm.ls(sl=True): for curve in pm.keyframe(obj, q=True, name=True): first = pm.findKeyframe(curve, which='first') last = pm.findKeyframe(curve, which='last') t = (first, last) pm.copyKey(curve) pm.pasteKey(curve, time=last, option='insert', connect=True)
def copy_animation(source_object, target_objects, attr_name_list=None, relative=False): """Copy animation from single source to multiple target. :arg source_object: PyNode object copy animation source. :type source_object: pm.PyNode :arg target_objects: PyNodes object copy animation destination. :type target_objects: list of pm.PyNode :key attr_name_list: Attributes name need to copy the animation. Default is using all visible attributes in channelbox. :type attr_name_list: list of str :key relative: If True, target object will keep the initial attribute value. :type relative: bool """ if attr_name_list is None: attr_name_list = [] if len(attr_name_list) > 0: attr_name_list = [ attr_name for attr_name in attr_name_list if source_object.hasAttr(attr_name) ] else: attr_name_list = [ attr_node.attrName() for attr_node in general.get_channelbox_attributes(source_object) ] for attr_name in attr_name_list: # If attribute doesnt have anim key, skip it keyframe_count = pm.keyframe(source_object, attribute=attr_name, q=True, keyframeCount=True) if not keyframe_count: continue pm.copyKey(source_object, attribute=attr_name) paste_key_data = { 'attribute': attr_name, 'clipboard': 'anim', 'option': 'replaceCompletely' } if relative: # calculate offset value before paste the key src_val = source_object.attr(attr_name).get() for tgt_obj in target_objects: tgt_val = tgt_obj.attr(attr_name).get() offset_value = tgt_val - src_val paste_key_data['valueOffset'] = offset_value pm.pasteKey(tgt_obj, **paste_key_data) else: pm.pasteKey(target_objects, **paste_key_data)
def moveKeys(self, src, dest, attr, axis): areThereKeys = pm.keyframe(src, attribute=attr + axis, query=True, valueChange=True) if len(areThereKeys) > 0: pm.cutKey(src, attribute=attr + axis) pm.pasteKey(dest, attribute=attr + axis)
def copyPasteKeyWithOffset(rctrls, rsuffix='R_', lsuffix='L_'): pm.select(rctrls) for rctrl in rctrls: lctrl = rctrl.replace(rsuffix, lsuffix) print 'lctrl is %s' % lctrl rc = pm.copyKey(rctrl, t=(0, 31)) pm.pasteKey(lctrl, t=31, o="merge") try: pm.cutKey(lctrl, t=(32, 66)) except: pass pm.pasteKey(lctrl, t=32, o="merge")
def mirror(self): """ Copy the animation curves from first to second selection item, """ sel = pm.selected() if len(sel) == 2: pm.copyKey(sel[0]) pm.pasteKey( sel[1], timeOffset=float(self.offset.text()), option='replace', )
def transferAnimationAttrs(self, src, dest): """ When duplicating a standin, transfer across keyed attributes to the new standin """ # get animation cache animationKeys = self.getCoreData( src, self.animationAttrName ) # iterate through cache # and copy and paste over keys for newName, attr in animationKeys.iteritems(): pm.copyKey(src, at=newName) pm.pasteKey(dest, at=newName)
def bdCopyPasteChunli(): #copy animation from the softimage fbx to the chunli mocap rig fbxJnt = pm.ls('RM_Cnl_Middle:*',type='joint') skeleton = [] for jnt in fbxJnt: skeletonJnt = '' skeletonJnt = pm.ls(jnt.stripNamespace()) if skeletonJnt : if (skeletonJnt[0].find('cloth') < 0) and (skeletonJnt[0].find('ribbon') < 0): print jnt pm.select(jnt) pm.copyKey() pm.select(skeletonJnt[0]) pm.pasteKey()
def bdCopyPasteChunli(): #copy animation from the softimage fbx to the chunli mocap rig fbxJnt = pm.ls('RM_Cnl_Middle:*', type='joint') skeleton = [] for jnt in fbxJnt: skeletonJnt = '' skeletonJnt = pm.ls(jnt.stripNamespace()) if skeletonJnt: if (skeletonJnt[0].find('cloth') < 0) and (skeletonJnt[0].find('ribbon') < 0): print jnt pm.select(jnt) pm.copyKey() pm.select(skeletonJnt[0]) pm.pasteKey()
def loadStoredKeys(self, node): """ Takes all the stored animation keys on a standIn node and transfers them to the source mesh controls """ # get animation cache animationKeys = self.getCoreData( node, self.animationAttrName ) for newName, attr in animationKeys.iteritems(): pm.copyKey(node, at=newName) elms = attr.split(".") pm.pasteKey(elms[0], at=elms[1])
def camBakeAim(): cam = pm.ls(sl=True)[0] # print cam.nodeName() # print type(cam) if (cam): # focalLen = cam.getFocalLength() try: camloa = pm.spaceLocator() # print camloa # print type(camloa) pm.parent(camloa, cam) camloa.setTranslation([0, 0, 0]) camloa.setRotation([0, 0, 0]) newCam = pm.createNode('camera').getParent() newCam.setDisplayResolution(True) newCam.setDisplayGateMask(True) mel.eval('setAttr "{}.displayGateMaskOpacity" 1;'.format( cam.getShape().longName())) newCam.setOverscan(1) pm.rename(newCam, cam.nodeName()) pointCon = pm.pointConstraint(camloa, newCam) orientCon = pm.orientConstraint(camloa, newCam) start = pm.playbackOptions(query=True, min=True) end = pm.playbackOptions(query=True, max=True) pm.copyKey(cam, attribute='focalLength', option='curve') try: pm.copyKey(cam, attribute='focalLength', option='curve') except: focalLen = cam.getFocalLength() else: try: pm.pasteKey(newCam, attribute='focalLength') except: focalLen = cam.getFocalLength() newCam.setFocalLength(focalLen) pm.bakeResults(newCam, sm=True, t=(start, end)) pm.delete(pointCon, orientCon, camloa) except: print("shi_Bai") else: print("cheng_Gong")
def dubplicate_reference(copy_attrs=DEFAULT_ATTR, select_node=False, copy_anim=False): """ 選択しているリファレンスノードを複製する """ sel_node = pm.ls(sl=True) load_reference = [] for i in sel_node: ref_node = i.referenceFile() if i.referenceFile() not in load_reference: load_reference.append(ref_node) for ref in load_reference: path = ref.path bn = os.path.splitext(os.path.basename(path))[0] to_ref = pm.createReference(path, ns=bn) to_ns = to_ref.namespace for n in ref.nodes(): # if n.type() == "transform": if select_node: if n not in sel_node: continue to_pynode = pm.PyNode(n.name().replace(ref.namespace + ":", to_ns + ":")) for attr in n.listAttr(): # コピーするアトリビュートかチェックする # Keyを指定できて、かつLockがかかっていないアトリビュートをコピーする if attr.isKeyable() and attr.isLocked() is False: attr_name = attr.plugAttr() # copy_attrsで指定したアトリビュートのみコピーする if attr_name not in copy_attrs and '<other_attr>' not in copy_attrs: continue # constraintがあったらなにもしない if len(attr.connections(scn=True, type="constraint")) != 0: continue to_pynode.attr(attr_name).set(attr.get()) # AnimationNodeが刺さってたらKeyをコピーする if copy_anim: if len(attr.connections(scn=True, type="animCurve")) != 0: pm.copyKey(n, attribute=attr.plugAttr()) pm.pasteKey(to_pynode, attribute=attr_name)
def camConstraint(self): #making no-aim camera self.cameraShapeRename() newCamGrp = pm.camera() #creating camera newCamShape = newCamGrp[1] #declaring camera shape pm.xform(newCamGrp[0], rotateOrder = 'zxy')#changing rotation order so I can add the camera roll later pm.camera(newCamShape, edit = True, fl = pm.camera('cameraShape1', q = True, fl = True), coi = pm.camera('cameraShape1', q = True, coi = True) ) #adjusting attributes of camera shape pm.setAttr(newCamShape.filmFit, 2) pm.copyKey('cameraShape1', time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value()), option = 'curve')#copying of camera shape keys try: pm.pasteKey(newCamShape) #pasting except: print('camShape has no keys') pm.parentConstraint('camera1', newCamGrp[0], mo = False) #constraining camera pm.bakeResults(newCamGrp[0], simulation = True, time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value()) )#baking the movement into the camera pm.keyframe(newCamGrp[0].rotateZ, edit = True, animation = 'objects', relative = True, valueChange = pm.camera('cameraShape1', q = True, filmRollValue = True) ) #adding the roll to the camera rotateZ pm.select(newCamGrp)
def keyAllChildren(op="set", jointsOnly=False): #set, cut, copy, paste selectedObjects = mc.ls(sl=True) targetObjects = mc.listRelatives( selectedObjects, ad=True ) + selectedObjects if(jointsOnly): targetObjects = mc.ls(targetObjects, type='joint') if(op=="set"): py.setKeyframe( targetObjects ) elif(op=="cut"): py.cutKey( targetObjects ) elif(op=="copy"): py.copyKey( targetObjects ) elif(op=="paste"): py.pasteKey( targetObjects ) elif(op=="bake"): inTime=mc.playbackOptions(q=1,ast=1) outTime=mc.playbackOptions(q=1,aet=1) mc.bakeResults(targetObjects,simulation=1,sampleBy=1,time=(inTime,outTime))
def copyAnim(self, args): ''' Copy all animation on transform nodes from one namespace to another ''' srcNS = pm.optionMenu(self.srcFld, q=1, v=1) tgtNS = pm.optionMenu(self.tgtFld, q=1, v=1) sourceControls = pm.ls('%s:*' % srcNS, type='transform') sourceControls.sort() for src in sourceControls: try: pm.copyKey(src) pm.pasteKey('%s:%s' % (tgtNS, src.split(':')[-1])) except Exception, e: print src print '%s:%s' % (tgtNS, src.split(':')[-1])
def restore_anim(from_file, to_file): fbx_rig = 'c:\\repo\\StarIsland_content\\06_TimoBoll\\07_Rig\\00_TimoBoll\\01_Release\\timoboll_fbxOn_rig.ma' pm.openFile(from_file, force=1) anim_layers_data = get_anim_layer() anim_layers = [item[0] for item in anim_layers_data] start_frame = pm.playbackOptions(q=1, min=1) end_frame = pm.playbackOptions(q=1, max=1) ###### Copy mocap pm.select('root_jnt') lr.bdSelectHierarchyJnt() pm.copyKey() pm.openFile(fbx_rig, force=1) start_frame = pm.playbackOptions(min=start_frame) end_frame = pm.playbackOptions(max=end_frame) pm.currentTime(0) pm.select('root_jnt') lr.bdSelectHierarchyJnt() pm.pasteKey() pm.saveAs(to_file) select_all() pm.copyKey() ##Copy Base Anim pm.openFile(from_file, force=1) set_active_layer('BaseAnimation') select_all() pm.copyKey() pm.openFile(to_file, force=1) start_frame = pm.playbackOptions(min=start_frame) end_frame = pm.playbackOptions(max=end_frame) pm.currentTime(start_frame) select_all() pm.setKeyframe() pm.pasteKey() pm.saveFile()
def copyTagAttribiutes(srcRoot, dstRoot): """ Copies animation tag attributes from the source root to the destination root. Args: source(Joint): A source root joint. destination(Joint): A destination root joint. """ for srcAttr in srcRoot.listAttr(userDefined=True): if not dstRoot.hasAttr(srcAttr.attrName()): cmd = srcAttr.__apimattr__().getAddAttrCmd(True) cmd = cmd.replace(';', ' %s;' % dstRoot) pmc.mel.eval(cmd) pmc.copyAttr(srcRoot, dstRoot, at=[srcAttr.attrName()], v=True) # Copy Animation if pmc.keyframe(srcRoot, at=[srcAttr.attrName()], q=True): pmc.copyKey(srcRoot, at=[srcAttr.attrName()]) pmc.pasteKey(dstRoot, at=[srcAttr.attrName()])
def copyKeys(source=None, target=None, channel=None, offset=0): if source == None or target == None: if len(pm.ls(sl=1)) < 2: return False target = pm.ls(sl=1) source = pm.ls(sl=1)[0] if channel == None: pm.copyKey(source) else: pm.copyKey(source, attribute=channel) i = 0 for each in target: print each if i > 0: if channel == None: pm.pasteKey(each, timeOffset=offset * i) else: pm.pasteKey(each, attribute=channel, timeOffset=offset * i) i = i + 1
def buttonPressed(*args): startFrame = minFld.getValue() endFrame = maxFld.getValue() difference = endFrame - startFrame if bakeBox.getValue(): bakeJoints(root, startFrame, endFrame) if loopBox.getValue(): startInterp = endFrame - int(difference * 0.2) pm.playbackOptions(min=0, max=difference) for jnt in sourceJoints: if (startFrame > 1): pm.cutKey(jnt, time=(0, startFrame - 1), option='keys') pm.cutKey(jnt, time=(startInterp, keyCount), option='keys') pm.copyKey(jnt, time=startFrame) pm.pasteKey(jnt, time=endFrame) for i in range(endFrame - int(difference * 0.2), endFrame): pm.currentTime(i) pm.setKeyframe(jnt) animCrvs = pm.ls( type=['animCurveTA', 'animCurveTL', 'animCurveTT', 'animCurveTU']) for item in animCrvs: pm.keyframe(item, edit=True, relative=True, timeChange=-startFrame) for jnt in sourceJoints: pm.cutKey(jnt, time=(-keyCount, 0), option='keys') pm.cutKey(jnt, time=(difference + 1, keyCount), option='keys') pm.copyKey(jnt, time=difference) pm.pasteKey(jnt, time=0) if interpBox.getValue(): for i in range(startFrame, endFrame): for jnt in sourceJoints: pm.currentTime(i + 1) qt1 = jnt.getRotation().asQuaternion() pm.currentTime(i) qt2 = jnt.getRotation().asQuaternion() newqt1 = slerp(qt1, qt2, 0.5) jnt.setRotation(newqt1) pm.setKeyframe(jnt)
def keys_copy(source, targets, rand_shift=0, incr=0, mo=False, rand_abs=False, from_time=False): """ This script will copy the keyframes from source to targets from selected channel box attributes Args: source (pm.nt.Transform): source object with animation targets (pm.nt.Transform): copy To Targets rand_shift (float): randomly shift by x, 0 is no shift incr (int): Increment value through selection by x, 0 is no increment mo (Boolean): Maintain the Offset or not (will offset if you're not at the anim keys start) rand_abs (bool): Random range will be absolute and not include negatives from_time (bool): if true, pastes from given time forward Returns [pm.nt.Transform]: list of keyed transforms Example: keys_copy(pm.ls(sl=True)[0], pm.ls(sl=True)[1:], rand_shift=0.0, incr=1.5, mo=True) """ #Determine Selected attributes from channelbox attrs = get_cb_sel_attrs() x_shift = 0 for target in targets: rand_val = 0.0 if rand_shift: rand_val = random.randrange(-rand_shift*(1-rand_abs), rand_shift) x_shift += incr + rand_val for attr in attrs: y_shift = mo * (target.attr(attr).get() - source.attr(attr).get()) if pm.keyframe(source, at = attr, q = True): # Copy + Paste the offset values pm.copyKey(source, at = attr, option = "curve", hierarchy = 'none') pm.pasteKey(target, option = 'replace', valueOffset = y_shift, copies = True, connect = True, at = attr, timeOffset = x_shift) x_shift += incr return targets
def key_attr(attr, new_value=None, copy_previous=None): """ Key given attr on previous and current frame. :param attr: Attribute to be keyed of type Attribute(). :param new_value: Explicitly set key value on current frame. :param copy_previous: Explicitly copy previous key or value onto previous frame for a single-frame switch. """ log.debug("Keying attr...") cur_time = pmc.currentTime(q=True) log.debug("Attr: {}".format(attr)) log.debug("New value: {}".format(new_value)) log.debug("Copy previous: {}".format(copy_previous)) log.debug("Current time: {}".format(cur_time)) if copy_previous: prev_key_time = pmc.findKeyframe(attr, which="previous") prev_key_value = attr.get(t=prev_key_time) prev_key = pmc.copyKey(attr, t=prev_key_time) log.debug("Previous key time: {}".format(prev_key_time)) log.debug("Previous key value: {}".format(prev_key_value)) # If a key did not exist if prev_key == 0: pmc.setKeyframe(attr, t=(cur_time - 1)) # If a key exists elif prev_key == 1: pmc.pasteKey(attr, t=(cur_time - 1)) else: pmc.setKeyframe(attr, t=(cur_time - 1)) if new_value: pmc.setKeyframe(attr, t=cur_time, v=new_value) attr.set(new_value) else: pmc.setKeyframe(attr, t=cur_time)
def animationAttrs(self, keyedAttrs, node): """ Clears existing animation attrs (on Standin) then writes keys currently on souce mesh controls to standIn """ self.clearAnimationAttrs(node) animationAttrs = {} for attr in keyedAttrs: try: # santize the name newName = self.processAttrName(attr) # get the attribute type # from the original attrType = str(pm.getAttr(attr, typ=1)) attrVal = pm.getAttr(attr) # create new attribute if dt.isAt(str(attrType)): node.addAttr(newName, at=attrType, k=1) else: node.addAttr(newName, dt=attrType, k=1) # add to data map animationAttrs[newName] = attr # copy keys from original to new attribute elms = attr.split(".") copyRes = pm.copyKey(elms[0], at=elms[1]) pm.pasteKey(node,at=newName) except: print("Failed to store animation attribute " + str(attr)) # write the dict to object self.storeCoreData( node, animationAttrs, self.animationAttrName )
def swap_two_curves(): """Hotkey to swap two selected animation curves""" curves = pm.keyframe(q=True, selected=True, name=True) if len(curves) == 2: swap_a, swap_b = curves[0], curves[1] pm.copyKey(swap_a) # snapshot of swap_b before copying over pm.bufferCurve(swap_b, overwrite=True) pm.pasteKey(swap_b, option='replaceCompletely') # swap temporarily to previous buffer curve on swap_b pm.bufferCurve(swap_b, swap=True) pm.copyKey(swap_b) # swap back pm.bufferCurve(swap_b, swap=True) pm.pasteKey(swap_a, option='replaceCompletely') else: pm.warning('[swap_curves] Select 2 curves.')
def fix_solo_keyframe_layers(): ''' Find all animation layers with a single keyframe and place a second keyframe 1 frame after the first for all objects in the layer. ''' for anim_layer in pm.ls(type='animLayer'): anim_curve_list = pm.animLayer(anim_layer, query=True, animCurves=True) # Ignore anim layers with no animation single_keyframe = True if anim_curve_list else False keyed_frame = None for anim_curve in anim_curve_list: if anim_curve.numKeyframes() > 1: single_keyframe = False break else: keyed_frame = anim_curve.getTime(0) if single_keyframe: layer_obj_list = list( set(anim_layer.dagSetMembers.listConnections())) if layer_obj_list: pm.copyKey(layer_obj_list, animLayer=anim_layer, t=keyed_frame) pm.pasteKey(layer_obj_list, animLayer=anim_layer, t=keyed_frame + 1)
def copy_paste_offset(): offset = pm.promptDialog(button=['OK', 'Cancel'], defaultButton='OK', dismissString='Cancel', cancelButton='Cancel', title='Copy Offset', message='Copy and paste offset:') if offset == 'Cancel': return try: offset = float(pm.promptDialog(q=True, text=True)) except ValueError: return # get time slider range aTimeSlider = mel.eval('$tmpVar=$gPlayBackSlider') timeRange = [] if cmds.timeControl(aTimeSlider, q=True, rangeVisible=True): timeRange = cmds.timeControl(aTimeSlider, q=True, rangeArray=True) else: timeRange += 2 * [cmds.currentTime(q=True)] timeRange = tuple(timeRange) with pm.UndoChunk(): for o in pm.ls(sl=True): for k in sorted( list( set( pm.keyframe(o, q=True, timeChange=True, time=timeRange)))): pm.copyKey(o, time=(k, k)) pm.pasteKey(o, time=(k, k), timeOffset=offset, option='merge')
def transferAnimation( targetFile="", prefix=False, prefixName='ref:' ): """ Set the Target Scene and selected the controls to transfer. """ pm.select( pm.ls( sl=1 ), replace=True ) control_list = map( str, pm.ls( sl=1 ) ) if not control_list: mel.error( "No Controls Selected for Transfer!" ) startTime = pm.playbackOptions( query=True, animationStartTime=True ) minTime = pm.playbackOptions( query=True, minTime=True ) maxTime = pm.playbackOptions( query=True, maxTime=True ) endTime = pm.playbackOptions( query=True, animationEndTime=True ) tempPose = Pose() tempPose.capture() pm.copyKey( control_list, hierarchy=False ) pm.openFile( targetFile, force=False ) if _checkControls( control_list ): if prefix: tempPose.apply( alterNamespace=True, namespace=prefixName ) else: tempPose.apply() pm.pasteKey( control_list, option='replaceCompletely', copies=1, connect=1, timeOffset=0, floatOffset=0, valueOffset=0 ) pm.playbackOptions( minTime=minTime, ast=startTime, maxTime=maxTime, aet=endTime ) else: raise
def aimCamMake(self): #will be deprecated self.cameraShapeRename() aimCam = pm.camera(coi = 5, fl = 35, lsr = 1, cs = 1, hfa = 1.41732, hfo = 0, vfa = 0.94488, vfo = 0, ff = 'Fill', ovr = 1, mb = 0, sa = 144, ncp = 0.1, ow = 30, pze = False, hpn = 0, zoom = 1) pm.rename(aimCam[0], 'camera1') mel.eval('cameraMakeNode 2 "";')#creates camera with aim constr = pm.parentConstraint('camera2', 'camera1_group', mo = False) #constraining the aimCam group to old camera camLoc = pm.spaceLocator() pm.xform(camLoc, ws = True, translation = pm.xform('camera1', ws = True, q = True, translation = True)) pm.parentConstraint('camera2', camLoc, mo = True) aimLoc = pm.spaceLocator() pm.xform(aimLoc, ws = True, translation = pm.xform('camera1_aim', ws = True, q = True, translation = True)) pm.parentConstraint('camera2', aimLoc, mo = True) pm.bakeResults(camLoc, aimLoc, simulation = True, time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value()) )#baking the movement into the camera pm.copyKey(camLoc, time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value())) pm.pasteKey('camera1') #pasting pm.copyKey(aimLoc, time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value())) pm.pasteKey('camera1_aim') #pasting pm.copyKey('cameraShape2', time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value()), option = 'curve') #copying all camera focal length and stuff try: pm.pasteKey('cameraShape1') #pasting except: print('camShape has no keys') pm.setAttr('cameraShape1.filmFit', 2) pm.copyKey('camera2', time = (animAPI.MAnimControl.minTime().value(), animAPI.MAnimControl.maxTime().value()), option = 'curve', at = 'rz') #copying rotate/roll data pm.pasteKey('cameraShape1', attribute = 'filmRollValue') #pasting into roll pm.delete(constr) pm.setAttr('camera1_group.tx', 0) pm.setAttr('camera1_group.ty', 0) pm.setAttr('camera1_group.tz', 0) pm.setAttr('camera1_group.rx', 0) pm.setAttr('camera1_group.ry', 0) pm.setAttr('camera1_group.rz', 0) pm.setKeyframe('camera1_group', time = 0) print('keyed camera1_group') pm.select('camera2')
def paste_keys_merge(): """paste keys merge at current frame""" current_frame = pm.getCurrentTime() pm.pasteKey(option='merge', time=(current_frame,))
def paste_keys_connect(): """paste keys replace connect (replace but at the starting value of the pasted over curve)""" pm.pasteKey(option='replace', connect=True)
def paste_keys_replace(): """paste keys replace completely""" pm.pasteKey(option='replaceCompletely')
def paste_keys_insert(): """paste keys insert at current frame""" current_frame = pm.getCurrentTime() pm.pasteKey(option='insert', connect=True, time=(current_frame,))
def load(filename, insertTime=None, alterPlug=None, bufferKeys=True, targetPool=None): ''' Loads a file containing animCurves (made with `save`) and hooks them up. :param func alterPlug: If the input needs some sort of transformation, provide a function that takes the plug string, ex "someSphere.tx" and returns a plug string of how it maps back, ex "zCube.tx" or "zCube.ty" and a function to alter the curve (or None) def alterPlug( 'inputNode.attr' ): return 'transformed' :param bool bufferKeys: If True (default), will add keys a frame before and after the range. ''' global TAGGING_ATTR global _loadAlterPlug existingSelection = selected() # Hook for easily providing an alterPlug via the GUI if _loadAlterPlug and not alterPlug: alterPlug = _loadAlterPlug # Using cmds for speed getAttr = cmds.getAttr objExists = cmds.objExists ls = cmds.ls # --- if insertTime is None: insertTime = currentTime(q=True) missingObj = set() missingAttr = [] pasteError = [] newNodes = cmds.file(filename, i=True, rnn=True) curves = cmds.ls(newNodes, type='animCurve') info = ls(newNodes, type='network')[0] start = getAttr(info + '.start') end = getAttr(info + '.end') length = end - start attr = '.' + TAGGING_ATTR singleObj = '' if len(existingSelection) == 1: targetObj = getAttr(curves[0] + attr).split('.')[0] for c in curves: loadedTarget = getAttr(c + attr).split('.')[0] # FKIK_SWITCH is a hack to deal with the switching attr if a single # obj is selected if loadedTarget != targetObj and not loadedTarget.endswith( 'FKIK_SWITCH'): break else: singleObj = targetObj if singleObj: targetObj = existingSelection[0].longName() def alter(plug): return targetObj + '.' + plug.split('.')[-1], None else: # Determine if there is a namespace mismatch if alterPlug: targets = [ alterPlug(cmds.getAttr(crv + attr))[0].split('.')[0] for crv in curves ] else: targets = [ cmds.getAttr(crv + attr).split('.')[0] for crv in curves ] changeNamespace = None newTargets = core.names.findAlternates(targets, targetPool) global JUNK JUNK = targets if newTargets.alteration: print('NS change', '--' * 20, newTargets.alteration) if newTargets.alteration[0] == 'add': def changeNamespace(plug): return newTargets.alteration[1] + plug elif newTargets.alteration[0] == 'sub': def changeNamespace(plug): return plug.replace(newTargets.alteration[1], newTargets.alteration[2]) elif newTargets.alteration[0] == 'rem': def changeNamespace(plug): return plug.replace(newTargets.alteration[1], '') # Build an alteration function if needed alter = None if alterPlug and changeNamespace: def alter(plug): newPlug, curveEditFunc = alterPlug(changeNamespace(plug)) return newPlug, curveEditFunc elif alterPlug: alter = alterPlug elif changeNamespace: def alter(plug): return changeNamespace(plug), None if hasAttr(PyNode(info), 'staticValues'): keys = json.loads( core.text.asciiDecompress(getAttr(info + '.staticValues'))) for plug, value in keys.items(): try: if alter: setAttr(alter(plug), value) else: setAttr(plug, value) except Exception: pass # Finally, actually copy over the animation for node in curves: alterCurve = None if objExists(node + '.' + TAGGING_ATTR): dest = getAttr(node + '.' + TAGGING_ATTR) if alter: dest, alterCurve = alter(dest) if alterCurve: alterCurve(node) if objExists(dest): # If we aren't going to be able to paste, just punt. if not getAttr(dest, k=True): pasteError.append(dest) continue if bufferKeys or getAttr(node, s=1) <= 1: setKeyframe(node, time=(insertTime - 1), insert=True) setKeyframe(node, time=(insertTime + length + 1), insert=True) copyKey(node, time=(start, end), iub=True, option='curve') try: pasteKey(dest, time=(insertTime, insertTime + length), option='replace') except Exception: pasteError.append(dest) else: obj, attr = dest.split('.') if objExists(obj): missingAttr.append(dest) else: missingObj.add(obj) if missingObj: print( core.text.writeInBox("These objects don't exist:\n\n" + '\n'.join(missingObj))) if missingAttr: print( core.text.writeInBox("These attribute couldn't be found:\n\n" + '\n'.join(missingAttr))) if pasteError: print( core.text.writeInBox( "Errors occurred when pasting animation onto:\n\n" + '\n'.join(pasteError))) if missingObj or missingAttr or pasteError: warning('Completed but with errors. See script editor for details.') delete(newNodes) return SavedCurveInfo(insertTime, insertTime + length, length)
def mirrorAnimation( defaultAxis='XZ' ): tempGroups = [] st2 = pm.timerX() pm.waitCursor( state=True ) autoKeyState = pm.autoKeyframe( query=True, state=True ) pm.autoKeyframe( state=False ) pm.select( pm.ls( selection=True ), replace=True ) objects = pm.ls( selection=True, type='transform' ) if len( objects ) == 0: mel.warning( 'No Transform objects selected for mirroring.' ) else: for obj in objects: if obj.mirrorAxis.exists(): axis = ( 'XY', 'YZ', 'XZ' )[ obj.mirrorAxis.get() ] else: axis = defaultAxis split = obj.split( ':' ) if len( split ) > 1: a = split[1] else: a = obj if a.startswith( prefix[0] ) or a.startswith( prefix[1] ): if a.startswith( prefix[1] ): prefix.reverse() opposite = pm.PyNode( obj.replace( prefix[0], prefix[1] ) ) else: opposite = None if opposite is not None and opposite.exists(): # -- make holder group -- g = pm.group( name='%s_holder' % obj, empty=True ) tempGroups.append( g ) ud_attrs = map( pm.Attribute, obj.listAttr( keyable=True ) ) for attr in ud_attrs: newAttr = pm.Attribute( '%s.%s' % ( g, attr.longName() ) ) if not newAttr.exists(): newAttr.add( attributeType=attr.type(), keyable=True ) if attr.longName() in mirrAttrs[axis] or attr.longName() in extrasList: newAttr.set( -attr.get() ) else: newAttr.set( attr.get() ) copy_result = pm.copyKey( obj, hierarchy='none', controlPoints=0, shape=1 ) if copy_result > 0: pm.pasteKey( g, option='replaceCompletely', copies=1, connect=1, timeOffset=0, floatOffset=0, valueOffset=0 ) # -- get opposite's values/keys -- og = '%s_holder' % opposite print 'tempGroups:', tempGroups print 'og:', og print len( tempGroups ) if og in tempGroups: obj2 = og else: obj2 = opposite copy_result = pm.copyKey( obj2, hierarchy=None, controlPoints=0, shape=1 ) if copy_result > 0: pm.pasteKey( obj, option='replaceCompletely', copies=1, connect=1, timeOffset=0, floatOffset=0, valueOffset=0 ) for attr in ud_attrs: srcAttr = pm.Attribute( '%s.%s' % ( obj2, attr.longName() ) ) if srcAttr.exists(): if attr.longName() in mirrAttrs[axis] or attr.longName() in extrasList: attr.set( -srcAttr.get() ) mirrorCurve( curves=attr.listConnections() ) else: attr.set( srcAttr.get() ) else: for attr in map( pm.Attribute, obj.listAttr( keyable=True ) ): if attr.longName() in mirrAttrs[axis] or attr.longName() in extrasList: attr.set( -attr.get() ) mirrorCurve( curves=attr.listConnections() ) # -- Finalize -- try: pm.delete( tempGroups ) except: pass pm.select( objects, replace=True ) pm.autoKeyframe( state=autoKeyState ) print '// Results: Mirrored animation for %i objects in %f seconds' % ( len( objects ), pm.timerX( st=st2 ) ) pm.waitCursor( state=False )
def transferAttrs(sourceObj, targetObjs, attributes=[]): """Copies the value(s) of the attribute from sourceObj to targetObj. Handles multi-attributes.""" sourceObj = pm.PyNode(sourceObj) if attributes == []: attributes=pm.listAttr(sourceObj, k=1, l=0) for targetObj in targetObjs: targetObj = pm.PyNode(targetObj) for attribute in attributes: sourceAttrNode = pm.PyNode('%s.%s'%(sourceObj, attribute)) print 'sourceAttr is %s'%sourceAttrNode if pm.attributeQuery(attribute, node = targetObj.name(), exists=True): # Execute only if the entered attribute exists multiAttr = pm.attributeQuery(attribute, node=targetObj.name(), listChildren=1) # Get list of multi-attribute children, if any if multiAttr: # If the attribute is a multi-attribute extraInst = set(sourceObj.getAttr(attribute, mi=1)).symmetric_difference( set(targetObj.getAttr(attribute, mi=1)) ) # Get the set of extra instances in multi-attribute for ins in extraInst: # Remove these extra instances pm.removeMultiInstance('{0}.{1}[{2}]'.format(targetObj.name(), attribute, ins) ) for attrChild in multiAttr: for ind in sourceObj.getAttr(attribute, mi=1): attrString = '{attr}[{index}].{child}'.format( attr = attribute, index = ind, child = attrChild ) attrVal = sourceObj.getAttr( attrString ) targetObj.setAttr( attrString, attrVal ) print( '// {objName}.{attr} was set to {val} //'.format(objName = targetObj.name(), attr = attrString, val = attrVal) ) else: trgtAttrNode = pm.PyNode('%s.%s'%(targetObj, attribute)) # clear target Attr if trgtAttrNode.isConnected(): trgtConn = trgtAttrNode.listConnections(scn=1) if trgtConn[0].type() in ['expression', 'animCurveTU']: # If animCurve or Expression connected, delete it pm.delete(trgtConn) else: pm.disconnectAttr(trgtAttrNode) if sourceAttrNode.isConnected(): conn = sourceAttrNode.listConnections(scn=1) if conn[0].type() == 'expression': # If the attribute has an expression dupconn = pm.duplicate(conn[0]) expressionstring = conn[0].getExpression().replace(sourceObj.name(), targetObj.name()) dupconn[0].setExpression(expressionstring) elif conn[0].type() == 'animCurveTU': # If the attribute is keyed pm.copyKey(sourceObj, at=attribute) pm.pasteKey(targetObj, at=attribute, o='replace') else: # Otherwise simple copy paste attr attrVal = sourceObj.getAttr(attribute) try: targetObj.setAttr(attribute, attrVal) except Exception as e: print 'Error occurred : ' + str(e) continue print('// {0}.{1} was set to {2} //\n'.format(targetObj.name(), attribute, attrVal) ) else: print('!! {0} does not exist !!\n'.format(attribute))