Exemple #1
0
 def _transferAnimation(self, srcObj, dstObj, attrs = None, mirrorAxis = None, time = None):
     """
     @param srcObj:
     @param dstObj:
     @param attrs:
     @param mirrorAxis:
     """
     maya.cmds.cutKey(dstObj, time=time or ())
     if maya.cmds.copyKey(srcObj, time=time or ()):
         if not time:
             maya.cmds.pasteKey(dstObj, option='replaceCompletely')
         else:
             maya.cmds.pasteKey(dstObj, time=time, option='replace')
     if attrs is None:
         attrs = maya.cmds.listAttr(srcObj, keyable=True) or []
     for attr in attrs:
         srcAttribute = mutils.Attribute(srcObj, attr)
         dstAttribute = mutils.Attribute(dstObj, attr)
         if dstAttribute.exists():
             if dstAttribute.isConnected():
                 if self.isAttrMirrored(attr, mirrorAxis):
                     maya.cmds.scaleKey(dstAttribute.name(), valueScale=-1, attribute=attr)
             else:
                 value = srcAttribute.value()
                 self.setAttr(dstObj, attr, value, mirrorAxis)
    def _transferAnimation(self, srcObj, dstObj, attrs=None, mirrorAxis=None, time=None):
        """
        :type srcObj: str
        :type dstObj: str
        :type attrs: list[str]
        :type time: list[int]
        :type mirrorAxis: list[int]
        """
        maya.cmds.cutKey(dstObj, time=time or ())  # remove keys
        if maya.cmds.copyKey(srcObj, time=time or ()):
            if not time:
                maya.cmds.pasteKey(dstObj, option="replaceCompletely")
            else:
                maya.cmds.pasteKey(dstObj, time=time, option="replace")

        if attrs is None:
            attrs = maya.cmds.listAttr(srcObj, keyable=True) or []

        for attr in attrs:
            srcAttribute = mutils.Attribute(srcObj, attr)
            dstAttribute = mutils.Attribute(dstObj, attr)

            if dstAttribute.exists():
                if dstAttribute.isConnected():
                    if self.isAttrMirrored(attr, mirrorAxis):
                        maya.cmds.scaleKey(dstAttribute.name(), valueScale=-1, attribute=attr)
                else:
                    value = srcAttribute.value()
                    self.setAttr(dstObj, attr, value, mirrorAxis)
Exemple #3
0
    def cacheNode(self,
                  srcNode,
                  dstNode,
                  dstAttrs=None,
                  ignoreConnected=None,
                  onlyConnected=None,
                  usingNamespaces=None):
        """
        @type srcNode: mutils.Node
        @type dstNode: mutils.Node
        """
        mirrorAxis = None
        mirrorObject = None
        dstNode.stripFirstPipe()
        if self.mirrorTable():
            mirrorObject = self.mirrorTable().mirrorObject(srcNode.name())
            if not mirrorObject:
                mirrorObject = srcNode.name()
                log.debug('Cannot find mirror object in pose for %s' %
                          srcNode.name())
            mirrorAxis = self.mirrorAxis(mirrorObject) or self.mirrorAxis(
                srcNode.name())
            if mirrorObject and not maya.cmds.objExists(mirrorObject):
                log.debug('Mirror object does not exist in the scene %s' %
                          mirrorObject)
        if usingNamespaces:
            try:
                dstNode = dstNode.toShortName()
            except mutils.NoObjectFoundError as msg:
                log.debug(msg)
                return
            except mutils.MoreThanOneObjectFoundError as msg:
                log.debug(msg)
                return

        for attr in self.attrs(srcNode.name()):
            if dstAttrs and attr not in dstAttrs:
                continue
            dstAttribute = mutils.Attribute(dstNode.name(), attr)
            isConnected = dstAttribute.isConnected()
            if ignoreConnected and isConnected or onlyConnected and not isConnected:
                continue
            type_ = self.attrType(srcNode.name(), attr)
            value = self.attrValue(srcNode.name(), attr)
            srcMirrorValue = self.attrMirrorValue(mirrorObject,
                                                  attr,
                                                  mirrorAxis=mirrorAxis)
            srcAttribute = mutils.Attribute(dstNode.name(),
                                            attr,
                                            value=value,
                                            type=type_)
            dstAttribute.update()
            self._cache.append((srcAttribute, dstAttribute, srcMirrorValue))
Exemple #4
0
    def createObjectData(self, name):
        """
        Create the object data for the given object name.
        
        :type name: str
        :rtype: dict
        """
        attrs = []
        # logger.debug(("maya.cmds.ls(name, showType = True) = {0}").format(maya.cmds.ls(name, showType = True)))
        # [u'Face', u'blendShape']
        name_type_list = maya.cmds.ls(name, showType = True)
        if name_type_list[1] == BLEND_SHAPE_TYPE:
            attrs = self.getBlendshapeParamList(name)
        else:
            attrs = maya.cmds.listAttr(name, keyable = True) or []        
            attrs = list(set(attrs))
        attrs = [mutils.Attribute(name, attr) for attr in attrs]

        data = {"attrs": self.attrs(name)}

        for attr in attrs:
            if attr.isValid():
                if attr.value() is None:
                    msg = "Cannot save the attribute %s with value None."
                    logger.warning(msg, attr.fullname())
                else:
                    data["attrs"][attr.attr()] = {
                        "type": attr.type(),
                        "value": attr.value()
                    }

        return data
Exemple #5
0
    def listAttr(self, srcObjects = None, dstObjects = None):
        """
        @rtype: list[mutils.Attribute]
        """
        results = []
        srcObjects = srcObjects or self.srcObjects
        dstObjects = dstObjects or self.dstObjects
        for i, srcObj in enumerate(srcObjects):
            srcObj = srcObjects[i]
            dstObj = dstObjects[i]
            for srcAttr in maya.cmds.listAttr(srcObj, k=True, unlocked=True, scalar=True) or []:
                srcAttribute = mutils.Attribute(srcObj, srcAttr)
                dstAttribute = mutils.Attribute(dstObj, srcAttr)
                results.append((srcAttribute, dstAttribute))

        return results
Exemple #6
0
    def createObjectData(self, name):
        """
        Create the object data for the given object name.
        
        :type name: str
        :rtype: dict
        """
        attrs = maya.cmds.listAttr(name, unlocked=True, keyable=True) or []
        attrs = list(set(attrs))
        attrs = [mutils.Attribute(name, attr) for attr in attrs]

        data = {"attrs": self.attrs(name)}

        for attr in attrs:
            if attr.isValid():
                if attr.value() is None:
                    msg = "Cannot save the attribute %s with value None."
                    logger.warning(msg, attr.fullname())
                else:
                    data["attrs"][attr.attr()] = {
                        "type": attr.type(),
                        "value": attr.value()
                    }

        return data
Exemple #7
0
def listAttr(node, **kwargs):
    """
    :type node: mutils.Node
    :type kwargs: dict
    :rtype: list[mutils.Attribute]
    """
    attrs = maya.cmds.listAttr(node.name(), **kwargs)
    return [mutils.Attribute(node.name(), attr) for attr in attrs or []]
    def test_anim_curve(self):
        """
        Test if get anim curve returns the right value.
        """
        msg = "Incorrect anim curve was returned when using attr.animCurve "

        attr = mutils.Attribute("sphere", "testFloat")
        curve = attr.animCurve()
        assert curve is None, msg + "1"

        attr = mutils.Attribute("sphere", "testConnected")
        curve = attr.animCurve()
        assert curve is None, msg + "2"

        attr = mutils.Attribute("sphere", "testAnimated")
        curve = attr.animCurve()
        assert curve == "sphere_testAnimated", msg + "3"
    def test_set_anim_curve(self):
        """
        Test if set anim curve
        """
        msg = "No anim curve was set"

        attr = mutils.Attribute("sphere", "testAnimated")
        srcCurve = attr.animCurve()

        attr = mutils.Attribute("sphere", "testFloat")
        attr.setAnimCurve(srcCurve, time=(1, 15), option="replace")
        curve = attr.animCurve()
        assert curve is not None, msg

        attr = mutils.Attribute("sphere", "testFloat")
        attr.setAnimCurve(srcCurve, time=(15, 15), option="replaceCompletely")
        curve = attr.animCurve()
        assert curve is not None, msg
    def test_attribute_limit3(self):
        """
        Test the minimum attribute limit when setting a keyframe.
        """
        attr = mutils.Attribute("sphere", "testLimit")
        attr.setKeyframe(-200)

        value = maya.cmds.keyframe("sphere.testLimit", query=True, eval=True)[0]
        assert value == -10, "Minimum attibute limit was ignored when setting animation keyframe"
Exemple #11
0
def animCurve(fullname):
    """
    Return the animation curve name for the give attribute.

    :type fullname: str or None
    :rtype: str or None
    """
    attribute = mutils.Attribute(fullname)
    return attribute.animCurve()
Exemple #12
0
def listAttr(node, **kwargs):
    """
    @type node: mutils.Node
    @type kwargs: {}
    @rtype: list[Attribute]
    """
    return [
        mutils.Attribute(node.name(), attr)
        for attr in maya.cmds.listAttr(node.name(), **kwargs) or []
    ]
Exemple #13
0
def listAttr(name, **kwargs):
    """
    List all the attributes for the given object name.
    
    :type name: str
    :type kwargs: str
    :rtype: list[mutils.Attribute]
    """
    attrs = maya.cmds.listAttr(name, **kwargs) or []
    attrs = list(set(attrs))
    return [mutils.Attribute(name, attr) for attr in attrs]
    def test_attribute_limit(self):
        """
        Test the attribute limit when setting the attribute value.
        """
        range = (-100, 100)
        maya.cmds.cutKey("sphere", cl=True, time=range, f=range, at="testLimit")

        attr = mutils.Attribute("sphere", "testLimit")
        attr.set(200)

        value = maya.cmds.getAttr("sphere.testLimit")
        assert value == 10, "Maximum attibute limit was ignored when setting the attribute value"
    def test_non_keyable(self):
        """
        Test if non-keyable attributes can be keyed.
        """
        range = (-100, 100)
        maya.cmds.cutKey("sphere", cl=True, time=range, f=range, at="testNonKeyable")

        attr = mutils.Attribute("sphere", "testNonKeyable")
        attr.setKeyframe(200)

        value = maya.cmds.keyframe("sphere.testNonKeyable", query=True, eval=True)
        assert value is None, "Non keyable attribute was keyed"
Exemple #16
0
    def listAttr(self, srcObjects=None, dstObjects=None):
        """
        Return the source & destination attributes for the given objects.

        :rtype: list[(mutils.Attribute, mutils.Attribute)]
        """
        attrs = []
        srcObjects = srcObjects or self.srcObjects
        dstObjects = dstObjects or self.dstObjects

        for i, srcObj in enumerate(srcObjects):
            srcObj = srcObjects[i]
            dstObj = dstObjects[i]

            srcAttrs = maya.cmds.listAttr(srcObj, keyable=True, unlocked=True, scalar=True) or []

            for srcAttr in srcAttrs:
                srcAttribute = mutils.Attribute(srcObj, srcAttr)
                dstAttribute = mutils.Attribute(dstObj, srcAttr)
                attrs.append((srcAttribute, dstAttribute))

        return attrs
Exemple #17
0
    def createObjectData(self, name):
        """
        @type name: name
        @rtype: list[Attribute]
        """
        attrs = maya.cmds.listAttr(name, unlocked=True, keyable=True) or []
        attrs = list(set(attrs))
        attrs = [ mutils.Attribute(name, attr) for attr in attrs ]
        result = {'attrs': self.attrs(name)}
        for attr in attrs:
            if attr.isValid():
                result['attrs'][attr.attr()] = {'type': attr.type(),
                 'value': attr.value()}

        return result
    def test_set_static_keyframe(self):
        """
        Test set static keyframes
        """
        msg = "The inserted static keys have different values"

        attr = mutils.Attribute("sphere", "testAnimated", cache=False)
        attr.setStaticKeyframe(value=2, time=(4, 6), option="replace")

        maya.cmds.currentTime(4)
        value1 = attr.value()

        maya.cmds.currentTime(6)
        value2 = attr.value()

        assert value1 == value2, msg
Exemple #19
0
    def createObjectData(self, name):
        """
        :type name: name
        :rtype: list[Attribute]
        """
        attrs = maya.cmds.listAttr(name, unlocked=True, keyable=True) or []
        attrs = list(set(attrs))
        attrs = [mutils.Attribute(name, attr) for attr in attrs]
        result = {"attrs": self.attrs(name)}

        for attr in attrs:
            if attr.isValid():
                if attr.value() is None:
                    logger.warning("Cannot save the attribute %s with value None." % attr.fullname())
                else:
                    result["attrs"][attr.attr()] = {"type": attr.type(), "value": attr.value()}

        return result
Exemple #20
0
    def load(self,
             objects=None,
             namespaces=None,
             attrs=None,
             startFrame=None,
             sourceTime=None,
             option=None,
             connect=False,
             mirrorTable=None,
             currentTime=None):
        """
        Load the animation data to the given objects or namespaces.
        
        :type objects: list[str]
        :type namespaces: list[str]
        :type startFrame: int
        :type sourceTime: (int, int)
        :type attrs: list[str]
        :type option: PasteOption
        :type currentTime: bool
        """
        connect = bool(connect)
        if option is None or option == PasteOption.ReplaceAll:
            option = PasteOption.ReplaceCompletely
        objects = objects or []
        logger.debug(
            'Animation.load(objects=%s, option=%s, namespaces=%s, srcTime=%s, currentTime=%s)'
            % (len(objects), str(option), str(namespaces), str(sourceTime),
               str(currentTime)))
        srcObjects = self.objects().keys()
        if mirrorTable:
            self.setMirrorTable(mirrorTable)
        valid = False
        matches = list(
            mutils.matchNames(srcObjects=srcObjects,
                              dstObjects=objects,
                              dstNamespaces=namespaces))
        for srcNode, dstNode in matches:
            if dstNode.exists():
                valid = True
                break

        if not matches or not valid:
            raise mutils.NoMatchFoundError(
                'No objects match when loading data')
        srcCurves = self.open()
        try:
            maya.cmds.flushUndo()
            maya.cmds.undoInfo(openChunk=True)
            if currentTime and startFrame is None:
                startFrame = int(maya.cmds.currentTime(query=True))
            srcTime = findFirstLastKeyframes(srcCurves, sourceTime)
            dstTime = moveTime(srcTime, startFrame)
            if option != PasteOption.ReplaceCompletely:
                insertKeyframe(srcCurves, srcTime)
            for srcNode, dstNode in matches:
                dstNode.stripFirstPipe()
                for attr in self.attrs(srcNode.name()):
                    if attrs is not None and attr not in attrs:
                        continue
                    dstAttr = mutils.Attribute(dstNode.name(), attr)
                    srcCurve = self.animCurve(srcNode.name(),
                                              attr,
                                              withNamespace=True)
                    if not dstAttr.exists():
                        logger.debug(
                            'Skipping attribute: The destination attribute "%s.%s" does not exist!'
                            % (dstAttr.name(), dstAttr.attr()))
                        continue
                    if srcCurve is None:
                        type_ = self.attrType(srcNode.name(), attr)
                        value = self.attrValue(srcNode.name(), attr)
                        srcAttr = mutils.Attribute(dstNode.name(),
                                                   attr,
                                                   type=type_,
                                                   value=value)
                        self.setStaticKey(srcAttr, dstAttr, dstTime, option)
                    else:
                        self.setAnimationKey(srcCurve,
                                             dstAttr,
                                             time=dstTime,
                                             option=option,
                                             source=srcTime,
                                             connect=connect)

        finally:
            self.close()
            maya.cmds.undoInfo(closeChunk=True)
Exemple #21
0
    def cacheNode(self,
                  srcNode,
                  dstNode,
                  attrs=None,
                  ignoreConnected=None,
                  onlyConnected=None,
                  usingNamespaces=None):
        """
        Cache the given pair of nodes.
        
        :type srcNode: mutils.Node
        :type dstNode: mutils.Node
        :type attrs: list[str] or None 
        :type ignoreConnected: bool or None
        :type onlyConnected: bool or None
        :type usingNamespaces: none or list[str]
        """
        mirrorAxis = None
        mirrorObject = None

        # Remove the first pipe in-case the object has a parent
        dstNode.stripFirstPipe()

        srcName = srcNode.name()

        if self.mirrorTable():
            mirrorObject = self.mirrorTable().mirrorObject(srcName)

            if not mirrorObject:
                mirrorObject = srcName
                msg = "Cannot find mirror object in pose for %s"
                logger.debug(msg, srcName)

            # Check if a mirror axis exists for the mirrorObject otherwise
            # check the srcNode
            mirrorAxis = self.mirrorAxis(mirrorObject) or self.mirrorAxis(
                srcName)

            if mirrorObject and not maya.cmds.objExists(mirrorObject):
                msg = "Mirror object does not exist in the scene %s"
                logger.debug(msg, mirrorObject)

        if usingNamespaces:
            # Try and use the short name.
            # Much faster than the long name when setting attributes.
            try:
                dstNode = dstNode.toShortName()
            except mutils.NoObjectFoundError as msg:
                logger.debug(msg)
                return
            except mutils.MoreThanOneObjectFoundError as msg:
                logger.debug(msg)
                return

        for attr in self.attrs(srcName):

            if attrs and attr not in attrs:
                continue

            dstAttribute = mutils.Attribute(dstNode.name(), attr)
            isConnected = dstAttribute.isConnected()

            if (ignoreConnected and isConnected) or (onlyConnected
                                                     and not isConnected):
                continue

            type_ = self.attrType(srcName, attr)
            value = self.attrValue(srcName, attr)
            srcMirrorValue = self.mirrorValue(mirrorObject,
                                              attr,
                                              mirrorAxis=mirrorAxis)

            srcAttribute = mutils.Attribute(dstNode.name(),
                                            attr,
                                            value=value,
                                            type=type_)
            dstAttribute.update()

            self._cache.append((srcAttribute, dstAttribute, srcMirrorValue))
Exemple #22
0
    def load(self,
             objects=None,
             namespaces=None,
             start=None,
             sourceTime=None,
             attrs=None,
             currentTime=None,
             option=Option.ReplaceCompletely,
             connect=False,
             mirrorTable=None):
        """
        @type objects: list[str]
        @type namespaces: list[str]
        @type start: int
        @type sourceTime: (int, int)
        @type attrs: list[str]
        @type option: Option
        @type currentTime: bool
        """
        if option == Option.ReplaceAll:
            option = Option.ReplaceCompletely
        log.debug(
            'Animation.load(objects=%s, option=%s, namespaces=%s, srcTime=%s, currentTime=%s)'
            % (len(objects), str(option), str(sourceTime), str(namespaces),
               str(currentTime)))
        if currentTime and start is None:
            start = maya.cmds.currentTime(query=True)
        try:
            srcCurves = self.open()
            srcObjects = self.objects().keys()
            srcTime = self.srcTime(sourceTime, srcCurves)
            dstTime = self.dstTime(srcTime, start)
            if mirrorTable:
                self.setMirrorTable(mirrorTable)
            maya.cmds.flushUndo()
            maya.cmds.undoInfo(openChunk=True)
            matches = mutils.matchObjects(srcObjects=srcObjects,
                                          dstObjects=objects,
                                          dstNamespaces=namespaces)
            if not matches:
                raise mutils.NoMatchFoundError(
                    'No objects match when loading data')
            if option != Option.ReplaceCompletely:
                insertSourceKeyframe(srcCurves, srcTime)
            for srcNode, dstNode in matches:
                dstNode.stripFirstPipe()
                for attr in self.attrs(srcNode.name()):
                    if attrs is not None and attr not in attrs:
                        continue
                    dstAttr = mutils.Attribute(dstNode.name(), attr)
                    srcCurve = self.attrCurve(srcNode.name(),
                                              attr,
                                              withNamespace=True)
                    if not dstAttr.exists():
                        log.debug(
                            'Skipping attribute: The destination attribute "%s.%s" does not exist!'
                            % (dstAttr.name(), dstAttr.attr()))
                        continue
                    if srcCurve is None:
                        type_ = self.attrType(srcNode.name(), attr)
                        value = self.attrValue(srcNode.name(), attr)
                        srcAttr = mutils.Attribute(dstNode.name(),
                                                   attr,
                                                   type=type_,
                                                   value=value)
                        self.setStaticKey(srcAttr, dstAttr, dstTime, option)
                    else:
                        self.setAnimationKey(srcCurve,
                                             dstAttr,
                                             time=dstTime,
                                             option=option,
                                             source=srcTime,
                                             connect=connect)

        finally:
            self.close()
            maya.cmds.undoInfo(closeChunk=True)
Exemple #23
0
            # Try to get the short name. Much faster than the long name when setting attributes.
            try:
                dstNode = dstNode.toShortName()
            except mutils.NoObjectFoundError, msg:
                logger.debug(msg)
                return
            except mutils.MoreThanOneObjectFoundError, msg:
                logger.debug(msg)
                return

        for attr in self.attrs(srcNode.name()):

            if dstAttrs and attr not in dstAttrs:
                continue

            dstAttribute = mutils.Attribute(dstNode.name(), attr)
            isConnected = dstAttribute.isConnected()
            if (ignoreConnected and isConnected) or (onlyConnected
                                                     and not isConnected):
                continue

            type_ = self.attrType(srcNode.name(), attr)
            value = self.attrValue(srcNode.name(), attr)
            srcMirrorValue = self.attrMirrorValue(mirrorObject,
                                                  attr,
                                                  mirrorAxis=mirrorAxis)

            srcAttribute = mutils.Attribute(dstNode.name(),
                                            attr,
                                            value=value,
                                            type=type_)
Exemple #24
0
    def save(
        self,
        path,
        time=None,
        sampleBy=1,
        fileType="",
        bakeConnected=True
    ):
        """
        Save all animation data from the objects set on the Anim object.

        :type path: str
        :type time: (int, int) or None
        :type sampleBy: int
        :type fileType: str
        :type bakeConnected: bool
        
        :rtype: None
        """
        objects = list(self.objects().keys())

        fileType = fileType or DEFAULT_FILE_TYPE

        if not time:
            time = mutils.selectedObjectsFrameRange(objects)
        start, end = time

        # Check selected animation layers
        validateAnimLayers()

        # Check frame range
        if start is None or end is None:
            msg = "Please specify a start and end frame!"
            raise AnimationTransferError(msg)

        if start >= end:
            msg = "The start frame cannot be greater than or equal to the end frame!"
            raise AnimationTransferError(msg)

        # Check if animation exists
        if mutils.getDurationFromNodes(objects or []) <= 0:
            msg = "No animation was found on the specified object/s! " \
                  "Please create a pose instead!"
            raise AnimationTransferError(msg)

        self.setMetadata("endFrame", end)
        self.setMetadata("startFrame", start)

        end += 1
        validCurves = []
        deleteObjects = []

        msg = u"Animation.save(path={0}, time={1}, bakeConnections={2}, sampleBy={3})"
        msg = msg.format(path, str(time), str(bakeConnected), str(sampleBy))
        logger.debug(msg)

        try:
            if bakeConnected:
                maya.cmds.undoInfo(openChunk=True)
                mutils.bakeConnected(objects, time=(start, end), sampleBy=sampleBy)

            for name in objects:
                if maya.cmds.copyKey(name, time=(start, end), includeUpperBound=False, option="keys"):

                    # Might return more than one object when duplicating shapes or blendshapes
                    transform, = maya.cmds.duplicate(name, name="CURVE", parentOnly=True)

                    if not FIX_SAVE_ANIM_REFERENCE_LOCKED_ERROR:
                        mutils.disconnectAll(transform)

                    deleteObjects.append(transform)
                    maya.cmds.pasteKey(transform)

                    attrs = maya.cmds.listAttr(transform, unlocked=True, keyable=True) or []
                    attrs = list(set(attrs) - set(['translate', 'rotate', 'scale']))

                    for attr in attrs:
                        dstAttr = mutils.Attribute(transform, attr)
                        dstCurve = dstAttr.animCurve()

                        if dstCurve:

                            dstCurve = maya.cmds.rename(dstCurve, "CURVE")
                            deleteObjects.append(dstCurve)

                            srcAttr = mutils.Attribute(name, attr)
                            srcCurve = srcAttr.animCurve()

                            if srcCurve:
                                preInfinity = maya.cmds.getAttr(srcCurve + ".preInfinity")
                                postInfinity = maya.cmds.getAttr(srcCurve + ".postInfinity")
                                curveColor = maya.cmds.getAttr(srcCurve + ".curveColor")
                                useCurveColor = maya.cmds.getAttr(srcCurve + ".useCurveColor")

                                maya.cmds.setAttr(dstCurve + ".preInfinity", preInfinity)
                                maya.cmds.setAttr(dstCurve + ".postInfinity", postInfinity)
                                maya.cmds.setAttr(dstCurve + ".curveColor", *curveColor[0])
                                maya.cmds.setAttr(dstCurve + ".useCurveColor", useCurveColor)

                            if maya.cmds.keyframe(dstCurve, query=True, time=(start, end), keyframeCount=True):
                                self.setAnimCurve(name, attr, dstCurve)
                                maya.cmds.cutKey(dstCurve, time=(MIN_TIME_LIMIT, start - 1))
                                maya.cmds.cutKey(dstCurve, time=(end + 1, MAX_TIME_LIMIT))
                                validCurves.append(dstCurve)

            fileName = "animation.ma"
            if fileType == "mayaBinary":
                fileName = "animation.mb"

            mayaPath = os.path.join(path, fileName)
            posePath = os.path.join(path, "pose.json")
            mutils.Pose.save(self, posePath)

            if validCurves:
                maya.cmds.select(validCurves)
                logger.info("Saving animation: %s" % mayaPath)
                maya.cmds.file(mayaPath, force=True, options='v=0', type=fileType, uiConfiguration=False, exportSelected=True)
                self.cleanMayaFile(mayaPath)

        finally:
            if bakeConnected:
                # HACK! Undo all baked connections. :)
                maya.cmds.undoInfo(closeChunk=True)
                maya.cmds.undo()
            elif deleteObjects:
                maya.cmds.delete(deleteObjects)

        self.setPath(path)
Exemple #25
0
    def load(self,
             objects=None,
             namespaces=None,
             attrs=None,
             startFrame=None,
             sourceTime=None,
             option=None,
             connect=False,
             mirrorTable=None,
             currentTime=None):
        """
        Load the animation data to the given objects or namespaces.

        :type objects: list[str]
        :type namespaces: list[str]
        :type startFrame: int
        :type sourceTime: (int, int)
        :type attrs: list[str]
        :type option: PasteOption
        :type connect: bool
        :type mirrorTable: mutils.MirrorTable
        :type currentTime: bool or None
        """
        connect = bool(connect)  # Make false if connect is None

        if option is None or option == PasteOption.ReplaceAll:
            option = PasteOption.ReplaceCompletely

        objects = objects or []

        logger.debug(
            "Animation.load(objects=%s, option=%s, namespaces=%s, srcTime=%s, currentTime=%s)"
            % (len(objects), str(option), str(namespaces), str(sourceTime),
               str(currentTime)))

        srcObjects = self.objects().keys()

        if mirrorTable:
            self.setMirrorTable(mirrorTable)

        valid = False
        matches = list(
            mutils.matchNames(srcObjects=srcObjects,
                              dstObjects=objects,
                              dstNamespaces=namespaces))

        for srcNode, dstNode in matches:
            if dstNode.exists():
                valid = True
                break

        if not matches or not valid:

            text = "No objects match when loading data. " \
                   "Turn on debug mode to see more details."

            raise mutils.NoMatchFoundError(text)

        # Load the animation data.
        srcCurves = self.open()

        try:
            maya.cmds.flushUndo()
            maya.cmds.undoInfo(openChunk=True)

            if currentTime and startFrame is None:
                startFrame = int(maya.cmds.currentTime(query=True))

            srcTime = findFirstLastKeyframes(srcCurves, sourceTime)
            dstTime = moveTime(srcTime, startFrame)

            if option != PasteOption.ReplaceCompletely:
                insertKeyframe(srcCurves, srcTime)

            for srcNode, dstNode in matches:

                # Remove the first pipe in-case the object has a parent
                dstNode.stripFirstPipe()

                for attr in self.attrs(srcNode.name()):

                    # Filter any attributes if the parameter has been set
                    if attrs is not None and attr not in attrs:
                        continue

                    dstAttr = mutils.Attribute(dstNode.name(), attr)
                    srcCurve = self.animCurve(srcNode.name(),
                                              attr,
                                              withNamespace=True)

                    # Skip if the destination attribute does not exists.
                    if not dstAttr.exists():
                        logger.debug(
                            'Skipping attribute: The destination attribute "%s.%s" does not exist!'
                            % (dstAttr.name(), dstAttr.attr()))
                        continue

                    if srcCurve:
                        dstAttr.setAnimCurve(srcCurve,
                                             time=dstTime,
                                             option=option,
                                             source=srcTime,
                                             connect=connect)
                    else:
                        value = self.attrValue(srcNode.name(), attr)
                        dstAttr.setStaticKeyframe(value, dstTime, option)

        finally:
            self.close()
            maya.cmds.undoInfo(closeChunk=True)

            # Return the focus to the Maya window
            maya.cmds.setFocus("MayaWindow")
Exemple #26
0
    def save(self,
             path,
             time=None,
             sampleBy=1,
             fileType="",
             bakeConnected=True):
        """
        Save all animation data from the objects set on the Anim object.

        :type path: str
        :type time: (int, int) or None
        :type sampleBy: int
        :type fileType: str
        :type bakeConnected: bool
        
        :rtype: None
        """
        objects = self.objects().keys()
        logger.debug(("objects = {0}").format(objects))

        fileType = fileType or DEFAULT_FILE_TYPE

        if not time:
            time = mutils.selectedObjectsFrameRange(objects)
        start, end = time

        # Check selected animation layers
        validateAnimLayers()

        # Check frame range
        if start is None or end is None:
            msg = "Please specify a start and end frame!"
            raise AnimationTransferError(msg)

        if start >= end:
            msg = "The start frame cannot be greater than or equal to the end frame!"
            raise AnimationTransferError(msg)

        # Check if animation exists
        if mutils.getDurationFromNodes(objects or []) <= 0:
            msg = "No animation was found on the specified object/s! " \
                  "Please create a pose instead!"
            raise AnimationTransferError(msg)

        self.setMetadata("endFrame", end)
        self.setMetadata("startFrame", start)

        end += 1
        validCurves = []
        # deleteObjects = []

        # msg = u"Animation.save(path={0}, time={1}, bakeConnections={2}, sampleBy={3})"
        # msg = msg.format(path, str(time), str(bakeConnected), str(sampleBy))
        # logger.debug(msg)

        try:
            if bakeConnected:
                maya.cmds.undoInfo(openChunk=True)
                mutils.bakeConnected(objects,
                                     time=(start, end),
                                     sampleBy=sampleBy)

            for name in objects:
                if maya.cmds.copyKey(name,
                                     time=(start, end),
                                     includeUpperBound=False,
                                     option="keys"):

                    attrs = maya.cmds.listAttr(
                        name, unlocked=True, keyable=True) or []
                    attrs = list(
                        set(attrs) - set(['translate', 'rotate', 'scale']))

                    self.listAttachedAnimCurves(name)
                    for attr in attrs:
                        dstAttr = mutils.Attribute(name, attr)
                        dstCurve = dstAttr.animCurve()
                        logger.debug(("dstCurve = {0}").format(dstCurve))

                        if dstCurve:

                            srcAttr = mutils.Attribute(name, attr)
                            srcCurve = srcAttr.animCurve()

                            if maya.cmds.keyframe(dstCurve,
                                                  query=True,
                                                  time=(start, end),
                                                  keyframeCount=True):
                                self.setAnimCurve(name, attr, dstCurve)
                                validCurves.append(dstCurve)

            fileName = "animation.ma"
            if fileType == "mayaBinary":
                fileName = "animation.mb"

            mayaPath = os.path.join(path, fileName)
            posePath = os.path.join(path, "pose.json")
            mutils.Pose.save(self, posePath)

            if validCurves:
                maya.cmds.select(validCurves)
                logger.info("Saving animation: %s" % mayaPath)
                maya.cmds.file(mayaPath,
                               force=True,
                               options='v=0',
                               type=fileType,
                               uiConfiguration=False,
                               exportSelected=True)
                self.cleanMayaFile(mayaPath)

        finally:
            if bakeConnected:
                # HACK! Undo all baked connections. :)
                maya.cmds.undoInfo(closeChunk=True)
                maya.cmds.undo()

        self.setPath(path)