Пример #1
0
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)
Пример #2
0
    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
Пример #3
0
    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')
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
    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)
Пример #8
0
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()
Пример #9
0
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])
Пример #11
0
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")
Пример #12
0
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)
Пример #13
0
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))
Пример #14
0
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))
Пример #15
0
 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)
Пример #16
0
 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])
Пример #17
0
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()])
Пример #18
0
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")
Пример #19
0
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
Пример #20
0
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 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)
Пример #22
0
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.')
Пример #23
0
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)
Пример #24
0
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')
Пример #25
0
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
Пример #26
0
 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 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
                )
Пример #28
0
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)
Пример #29
0
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)
Пример #30
0
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()
Пример #31
0
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))
Пример #32
0
    def initializeAnimTab(self, tabHeight, tabWidth):
        columnWidth = 120
        moduleSpecific_scrollHeight = 120
        scrollHeight = tabHeight - moduleSpecific_scrollHeight - 20

        #1. Anim Editing
        self.UIElements["animColumn"] = pm.columnLayout(adj=True, rs=3)

        pm.rowColumnLayout("selsetAddRow",
                           numberOfColumns=3,
                           ro=[(1, "both", 2), (2, "both", 2), (3, "both", 2)],
                           columnAttach=[(1, "both", 3), (2, "both", 3),
                                         (3, "both", 3)],
                           columnWidth=[(1, columnWidth), (2, columnWidth),
                                        (3, columnWidth)])
        pm.textField("setName", parent="selsetAddRow")
        pop = pm.popupMenu(parent='setName')

        #pm.optionMenu(label='Colors', changeCommand=lambda a: self.updateTextfield('setName', 'test'))

        pm.button(label="add",
                  parent="selsetAddRow",
                  command=lambda a: self.addSelectionSetWin())
        pm.button(label="remove",
                  parent="selsetAddRow",
                  command=lambda a: self.removeSelectionSetWin())
        pm.setParent(self.UIElements["animColumn"])
        pm.separator()
        pm.text('selectionSets')
        pm.rowLayout("selsetSelRow",
                     numberOfColumns=2,
                     columnWidth2=[300, 100],
                     columnAlign=[(1, 'right'), (2, 'left')])

        pm.textScrollList("selSetList",
                          parent="selsetSelRow",
                          width=300,
                          height=100,
                          allowMultiSelection=False,
                          selectCommand=lambda: self.selectSelectionSetWin())

        pm.columnLayout("selsetModColumn", parent="selsetSelRow")
        pm.button(label="load",
                  parent="selsetModColumn",
                  height=22,
                  width=50,
                  command=lambda a: self.loadSelectionSetWin())
        pm.button(label="delete",
                  parent="selsetModColumn",
                  height=22,
                  width=50,
                  command=lambda a: self.deleteSelectionSetWin())
        pm.setParent(self.UIElements["animColumn"])

        self.UIElements["1"] = pm.rowColumnLayout(numberOfColumns=3,
                                                  ro=[(1, "both", 2),
                                                      (2, "both", 2),
                                                      (3, "both", 2)],
                                                  columnAttach=[(1, "both", 3),
                                                                (2, "both", 3),
                                                                (3, "both", 3)
                                                                ],
                                                  columnWidth=[
                                                      (1, columnWidth),
                                                      (2, columnWidth),
                                                      (3, columnWidth)
                                                  ])

        pm.button(label="randomizer",
                  command=lambda a: randomizerUI.randomizer_start())
        pm.button(label="set Timesldr Keyrng",
                  command=lambda a: mo_animUtils.setTimesliderToKeyrange())
        pm.button(label="keyEmpty", command=lambda a: mo_animUtils.keyEmpty())

        #2. Rigg Editing
        pm.setParent(self.UIElements["animColumn"])
        pm.separator()
        self.UIElements["2"] = pm.rowColumnLayout(numberOfColumns=3,
                                                  ro=[(1, "both", 2),
                                                      (2, "both", 2),
                                                      (3, "both", 2)],
                                                  columnAttach=[(1, "both", 3),
                                                                (2, "both", 3),
                                                                (3, "both", 3)
                                                                ],
                                                  columnWidth=[
                                                      (1, columnWidth),
                                                      (2, columnWidth),
                                                      (3, columnWidth)
                                                  ])

        pm.button(label="copyKey", command=lambda a: pm.copyKey())
        pm.button(label="pasteKey", command=lambda a: pm.pasteKey())
        pm.button(label="cutKey", command=lambda a: pm.cutKey())

        pm.button(label="copyKeys", command=lambda a: mo_animUtils.copyKeys())
        pm.button(label="infinity", command=lambda a: mo_animUtils.infinity())
        pm.button(label="Save Pose Shelf",
                  command=lambda a: mo_storePoseToShelf.storePoseToShelf())

        pm.button(label="del Constraints",
                  command=lambda a: mo_riggUtils.deleteChildrenConstraints())
        pm.button(label="keyFlash", command=lambda a: mo_animUtils.keyFlash())
        pm.button(label="keyFastinSlowout",
                  command=lambda a: mo_animUtils.keyFastinSlowout())
        pm.text(label="")

        pm.setParent(self.UIElements["animColumn"])
        pm.separator()
        self.UIElements["3"] = pm.rowColumnLayout(numberOfColumns=3,
                                                  ro=[(1, "both", 2),
                                                      (2, "both", 2),
                                                      (3, "both", 2)],
                                                  columnAttach=[(1, "both", 3),
                                                                (2, "both", 3),
                                                                (3, "both", 3)
                                                                ],
                                                  columnWidth=[
                                                      (1, columnWidth),
                                                      (2, columnWidth),
                                                      (3, columnWidth)
                                                  ])

        #3. Ctrl Editing
        pm.button(label="straightMotion",
                  command=lambda a: straightMotion.straightMotion())
        pm.button(label="placeHolderLoc",
                  command=lambda a: libUtil.createPlaceHolder(cnx=0))
        pm.button(label="IkFk Snap UI",
                  command=lambda a: self.mog_ikFkSwitchWin())

        pm.button(label="findIntersectingUI",
                  command=lambda a: findIntersectingWin())

        pm.setParent(self.UIElements["animColumn"])
        return self.UIElements["animColumn"]
Пример #33
0
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 )
Пример #34
0
def SetTranslation(nrOfFrames, source, target):
    for x in range(nrOfFrames):
        pm.copyKey(source, time=(x, x), attribute='translate', option="curve")
        pm.pasteKey(target, time=(x, x), attribute='translate')
Пример #35
0
        r_list.append('x')
    if ry:
        r_list.append('y')
    if rz:
        r_list.append('z')
    if not r_list:
        r_list = "none"
    pm.parentConstraint(src,
                        dst,
                        skipTranslate=t_list,
                        skipRotate=r_list,
                        mo=1)

keyframe_match = {
    "LfArm_Switch": "LfArm_Switch",
    "RtArm_Switch": "RtArm_Switch",
    "LfLeg_Switch": "LfLeg_Switch",
    "RtLeg_Switch": "RtLeg_Switch",
}

start = pm.playbackOptions(q=1, min=1)
end = pm.playbackOptions(q=1, max=1)

for src, dst in keyframe_match.items():
    dst = dst_namespace + dst
    src = src_namespace + src
    src = pm.PyNode(src)
    dst = pm.PyNode(dst)
    pm.copyKey(src, time=(start, end))
    pm.pasteKey(dst)
Пример #36
0
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)