Ejemplo n.º 1
0
def saveAnim(path,
             objects=None,
             time=None,
             sampleBy=1,
             metadata=None,
             bakeConnected=False):
    """
    Save the anim data for the given objects.

    Example:
        anim = "C:/example.anim"
        anim = saveAnim(path, metadata={'description': 'Example anim'})
        print anim.metadata()
        # {'description': 'test', 'user': '******', 'mayaVersion': u'2016'}

    :type path: str
    :type objects: None or list[str]
    :type time: None or int
    :type sampleBy: int
    :type metadata: dict or None
    :type bakeConnected: bool
    :rtype: mutils.Animation
    """
    step = 1
    objects = objects or maya.cmds.ls(selection=True) or []

    if not objects:
        raise Exception(
            "No objects selected. Please select at least one object.")

    if not time:
        time = mutils.selectedObjectsFrameRange(objects)

    start, end = time

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

    iconPath = path + "/thumbnail.jpg"
    sequencePath = path + "/sequence/thumbnail.jpg"

    sequencePath = mutils.createSnapshot(
        path=sequencePath,
        start=start,
        end=end,
        step=step,
    )

    if iconPath:
        shutil.copyfile(sequencePath, iconPath)

    anim = mutils.Animation.fromObjects(objects)

    if metadata:
        anim.updateMetadata(metadata)

    anim.save(path, time=time, bakeConnected=bakeConnected, sampleBy=sampleBy)
    return anim
    def __init__(self, parent=None):
        super(FrameRangeMenu, self).__init__(parent)

        action = FrameRangeAction("From Timeline", self)
        action.setFrameRange(mutils.playbackFrameRange())
        self.addAction(action)

        action = FrameRangeAction("From Selected Timeline", self)
        action.setFrameRange(mutils.selectedFrameRange())
        self.addAction(action)

        action = FrameRangeAction("From Selected Objects", self)
        action.setFrameRange(mutils.selectedObjectsFrameRange())
        self.addAction(action)
Ejemplo n.º 3
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()

        fileType = fileType or DEFAULT_FILE_TYPE

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

        # Check selected animation layers
        gSelectedAnimLayers = maya.mel.eval(
            '$gSelectedAnimLayers=$gSelectedAnimLayers')
        if len(gSelectedAnimLayers) > 1:
            msg = "More than one animation layer is selected! Please select only one animation layer for export!"
            raise AnimationTransferError(msg)

        # 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(nodes=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
        dstCurves = []
        validAnimCurves = []

        msg = "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)

                    dstCurves.append(transform)
                    mutils.disconnectAll(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:
                        fullname = ("%s.%s" % (transform, attr))
                        dstCurve, = maya.cmds.listConnections(
                            fullname, destination=False) or [None]

                        if dstCurve:
                            # Filter to only animCurves since you can have proxy attributes
                            if not maya.cmds.nodeType(dstCurve).startswith(
                                    "animCurve"):
                                continue

                            dstCurve = maya.cmds.rename(dstCurve, "CURVE")
                            srcCurve = mutils.animCurve("%s.%s" % (name, attr))
                            if srcCurve and "animCurve" in maya.cmds.nodeType(
                                    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)

                            dstCurves.append(dstCurve)

                            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))
                                validAnimCurves.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 validAnimCurves:
                maya.cmds.select(validAnimCurves)
                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 dstCurves:
                maya.cmds.delete(dstCurves)

        self.setPath(path)
Ejemplo n.º 4
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"):

                    logger.debug(name)
                    # 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[0])

                    # deleteObjects.append(transform[0])
                    # maya.cmds.pasteKey(transform[0])

                    attrs = []
                    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, unlocked=True, keyable=True) or []
                    attrs = list(set(attrs) - set(['translate', 'rotate', 'scale']))

                    logger.debug(("attrs = {0}").format(attrs))
                    for attr in attrs:
                        logger.debug(("transform name = {0}, attr name = {1}").format(name, attr))
                        dstAttr = mutils.Attribute(name, 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)
Ejemplo n.º 5
0
def saveAnim(
    path,
    objects=None,
    time=None,
    sampleBy=1,
    metadata=None,
    bakeConnected=False
):
    """
    Save the anim data for the given objects.

    Example:
        import mutils
        mutils.saveAnim(
            path="c:/example.anim", 
            time=(1, 20),
            metadata={'description': 'Example anim'}
            )
            
    :type path: str
    :type objects: None or list[str]
    :type time: None or int
    :type sampleBy: int
    :type metadata: dict or None
    :type bakeConnected: bool
    
    :rtype: mutils.Animation
    """
    step = 1
    objects = objects or maya.cmds.ls(selection=True) or []

    if os.path.exists(path):
        raise Exception("Cannot override an existing path. " + path)

    if not objects:
        raise Exception(
            "No objects selected. Please select at least one object."
        )

    if not time:
        time = mutils.selectedObjectsFrameRange(objects)

    start, end = time

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

    tmpPath = mutils.TempDir("anim", clean=True).path()

    os.makedirs(tmpPath + '/sequence')

    iconPath = tmpPath + "/thumbnail.jpg"
    sequencePath = tmpPath + "/sequence/thumbnail.jpg"

    window = mutils.gui.thumbnailCapture(
        path=sequencePath,
        startFrame=start,
        endFrame=end,
        step=step,
        modifier=False,
    )

    if iconPath:
        shutil.copyfile(window.capturedPath(), iconPath)

    anim = mutils.Animation.fromObjects(objects)

    if metadata:
        anim.updateMetadata(metadata)

    anim.save(tmpPath, time=time, bakeConnected=bakeConnected, sampleBy=sampleBy)

    shutil.copytree(tmpPath, path)

    return mutils.Animation.fromPath(path)
Ejemplo n.º 6
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()

        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 = "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)
Ejemplo n.º 7
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)