예제 #1
0
    def load(self, context, name=None, namespace=None, data=None):
        import maya.cmds as cmds

        from avalon import maya
        from avalon.maya import lib

        choice = self.display_warning()
        if choice is False:
            return

        asset = context['asset']

        namespace = namespace or lib.unique_namespace(
            asset["name"] + "_",
            prefix="_" if asset["name"][0].isdigit() else "",
            suffix="_",
        )

        with maya.maintained_selection():
            cmds.file(self.fname,
                      i=True,
                      namespace=namespace,
                      returnNewNodes=True,
                      groupReference=True,
                      groupName="{}:{}".format(namespace, name))

        # We do not containerize imported content, it remains unmanaged
        return
예제 #2
0
    def _post_process(self, name, namespace, context, data):

        # TODO(marcus): We are hardcoding the name "out_SET" here.
        #   Better register this keyword, so that it can be used
        #   elsewhere, such as in the Integrator plug-in,
        #   without duplication.

        output = next((node for node in self if node.endswith("out_SET")),
                      None)
        controls = next(
            (node for node in self if node.endswith("controls_SET")), None)

        assert output, "No out_SET in rig, this is a bug."
        assert controls, "No controls_SET in rig, this is a bug."

        # Find the roots amongst the loaded nodes
        roots = cmds.ls(self[:], assemblies=True, long=True)
        assert roots, "No root nodes in rig, this is a bug."

        asset = api.Session["AVALON_ASSET"]
        dependency = str(context["representation"]["_id"])

        # Create the animation instance
        with maya.maintained_selection():
            cmds.select([output, controls] + roots, noExpand=True)
            api.create(name=namespace,
                       asset=asset,
                       family="animation",
                       options={"useSelection": True},
                       data={"dependencies": dependency})
예제 #3
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya
        import pymel.core as pm

        with maya.maintained_selection():

            groupName = "{}:{}".format(namespace, name)
            path = self.fname
            proxyPath = os.path.splitext(path)[0] + ".ma"

            nodes = cmds.file(proxyPath,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName=groupName)

            cmds.makeIdentity(groupName,
                              apply=False,
                              rotate=True,
                              translate=True,
                              scale=True)

            # Set attributes
            proxyShape = pm.ls(nodes, type="mesh")[0]

            proxyShape.aiTranslator.set('procedural')
            proxyShape.dso.set(path)
            proxyShape.aiOverrideShaders.set(0)

        self[:] = nodes

        return nodes
예제 #4
0
    def process(self, instance):
        import os
        from maya import cmds
        from avalon import maya

        dirname = tempfile.mkdtemp()
        filename = "{name}.ma".format(**instance.data)
        path = os.path.join(dirname, filename)

        # Perform extraction
        self.log.info("Performing extraction..")
        with maya.maintained_selection(), maya.without_extension():
            self.log.info("Extracting %s" % str(list(instance)))
            cmds.select(instance, noExpand=True)
            cmds.file(path,
                      force=True,
                      typ="mayaAscii",
                      exportSelected=True,
                      preserveReferences=False)

        # Store reference for integration
        if "files" not in instance.data:
            instance.data["files"] = list()

        instance.data["files"].append(filename)
        instance.data["stagingDir"] = dirname

        self.log.info("Extracted {instance} to {path}".format(**locals()))
예제 #5
0
    def process(self, instance):
        from maya import cmds
        from avalon import maya
        from reveries import utils

        staging_dir = utils.stage_dir()
        filename = "%s.ma" % instance.data["subset"]
        outpath = "%s/%s" % (staging_dir, filename)

        instance.data["repr.mayaAscii._stage"] = staging_dir
        instance.data["repr.mayaAscii._files"] = [filename]
        instance.data["repr.mayaAscii.entryFileName"] = filename

        # Perform extraction
        self.log.info("Performing extraction..")
        with maya.maintained_selection():
            # Set flag `noExpand` to True for sharing containers,
            # which will be ignored if the selection expanded since
            # they are objectSets.
            cmds.select(instance, noExpand=True)
            cmds.file(outpath,
                      force=True,
                      typ="mayaAscii",
                      exportSelected=True,
                      preserveReferences=True,
                      channels=True,
                      constraints=True,
                      expressions=True,
                      shader=True,
                      constructionHistory=True)
예제 #6
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "fbx"

        # Ensure FBX plug-in is loaded
        cmds.loadPlugin("fbxmaya", quiet=True)

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        groupName = "{}:{}".format(namespace, name)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']

        c = colors.get(family)
        if c is not None:
            cmds.setAttr(groupName + ".useOutlinerColor", 1)
            cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2])

        self[:] = nodes

        return nodes
예제 #7
0
def polyConstraint(components, *args, **kwargs):
    """Return the list of *components* with the constraints applied.

    A wrapper around Maya's `polySelectConstraint` to retrieve its results as
    a list without altering selections. For a list of possible constraints
    see `maya.cmds.polySelectConstraint` documentation.

    Arguments:
        components (list): List of components of polygon meshes

    Returns:
        list: The list of components filtered by the given constraints.

    """

    kwargs.pop('mode', None)

    with no_undo(flush=False):
        with maya.maintained_selection():
            # Apply constraint using mode=2 (current and next) so
            # it applies to the selection made before it; because just
            # a `maya.cmds.select()` call will not trigger the constraint.
            with reset_polySelectConstraint():
                cmds.select(components, r=1, noExpand=True)
                cmds.polySelectConstraint(*args, mode=2, **kwargs)
                result = cmds.ls(selection=True)
                cmds.select(clear=True)

    return result
예제 #8
0
    def _post_process_rig(self, name, namespace, context, options):

        output = next((node for node in self if node.endswith("out_SET")),
                      None)
        controls = next(
            (node for node in self if node.endswith("controls_SET")), None)

        assert output, "No out_SET in rig, this is a bug."
        assert controls, "No controls_SET in rig, this is a bug."

        # Find the roots amongst the loaded nodes
        roots = cmds.ls(self[:], assemblies=True, long=True)
        assert roots, "No root nodes in rig, this is a bug."

        asset = api.Session["AVALON_ASSET"]
        dependency = str(context["representation"]["_id"])

        self.log.info("Creating subset: {}".format(namespace))

        # Create the animation instance
        creator_plugin = get_creator_by_name(self.animation_creator_name)
        with maya.maintained_selection():
            cmds.select([output, controls] + roots, noExpand=True)
            api.create(creator_plugin,
                       name=namespace,
                       asset=asset,
                       options={"useSelection": True},
                       data={"dependencies": dependency})
    def extract_mayaAscii(self, packager):
        # Define extract output file path
        entry_file = packager.file_name("ma")
        package_path = packager.create_package()
        entry_path = os.path.join(package_path, entry_file)

        # Perform extraction
        self.log.info("Performing extraction..")
        with maya.maintained_selection():
            # Set flag `noExpand` to True for sharing containers,
            # which will be ignored if the selection expanded since
            # they are objectSets.
            cmds.select(self.member, noExpand=True)
            cmds.file(entry_path,
                      force=True,
                      typ="mayaAscii",
                      exportSelected=True,
                      preserveReferences=True,
                      channels=True,
                      constraints=True,
                      expressions=True,
                      shader=True,
                      constructionHistory=True)

        packager.add_data({
            "entryFileName": entry_file,
        })

        self.log.info("Extracted {name} to {path}".format(
            name=self.data["subset"],
            path=entry_path)
        )
예제 #10
0
    def load(self, context, name=None, namespace=None, data=None):
        import maya.cmds as cmds

        from avalon import maya
        from avalon.maya import lib
        from avalon.maya.pipeline import containerise

        asset = context['asset']
        namespace = namespace or lib.unique_namespace(
            asset["name"] + "_",
            prefix="_" if asset["name"][0].isdigit() else "",
            suffix="_",
        )
        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              i=True,
                              namespace=namespace,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))
        # Only containerize if any nodes were loaded by the Loader
        if not nodes:
            return
        self[:] = nodes
        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
예제 #11
0
def assign_look_by_version(nodes, version_id):
    """Assign nodes a specific published look version by id.

    This assumes the nodes correspond with the asset.

    Args:
        nodes(list): nodes to assign look to
        version_id (bson.ObjectId): database id of the version

    Returns:
        None
    """

    # Get representations of shader file and relationships
    look_representation = io.find_one({
        "type": "representation",
        "parent": version_id,
        "name": "ma"
    })

    json_representation = io.find_one({
        "type": "representation",
        "parent": version_id,
        "name": "json"
    })

    # See if representation is already loaded, if so reuse it.
    host = api.registered_host()
    representation_id = str(look_representation['_id'])
    for container in host.ls():
        if (container['loader'] == "LookLoader"
                and container['representation'] == representation_id):
            log.info("Reusing loaded look ..")
            container_node = container['objectName']
            break
    else:
        log.info("Using look for the first time ..")

        # Load file
        loaders = api.loaders_from_representation(api.discover(api.Loader),
                                                  representation_id)
        Loader = next((i for i in loaders if i.__name__ == "LookLoader"), None)
        if Loader is None:
            raise RuntimeError("Could not find LookLoader, this is a bug")

        # Reference the look file
        with maya.maintained_selection():
            container_node = pipeline.load(Loader, look_representation)

    # Get container members
    shader_nodes = cmds.sets(container_node, query=True)

    # Load relationships
    shader_relation = api.get_representation_path(json_representation)
    with open(shader_relation, "r") as f:
        relationships = json.load(f)

    # Assign relationships
    apply_shaders(relationships, shader_nodes, nodes)
예제 #12
0
    def process(self, instance):
        import os
        import ava
        from maya import cmds
        from avalon import maya

        self.log.debug("Loading plug-in..")
        cmds.loadPlugin("atomImportExport.mll", quiet=True)

        self.log.info("Extracting curves..")
        dirname = ava.format_staging_dir(
            root=instance.context.data["workspaceDir"],
            time=instance.context.data["time"],
            name=instance.data["name"])

        try:
            os.makedirs(dirname)
        except OSError:
            pass

        filename = "{name}.curves".format(**instance.data)

        options = ";".join([
            "precision=8", "statics=1", "baked=1", "sdk=0", "constraint=0",
            "animLayers=0", "selected=selectedOnly", "whichRange=1",
            "range=1:10", "hierarchy=none", "controlPoints=0",
            "useChannelBox=1", "options=keys",
            ("copyKeyCmd="
             "-animation objects "
             "-option keys "
             "-hierarchy none "
             "-controlPoints 0 ")
        ])

        controls = next(
            (node for node in instance if node.endswith("controls_SET")), None)

        if controls is None:
            # Backwards compatibility
            self.log.warning("%s is missing a controls_SET" % instance.name)
            return

        with maya.maintained_selection(), maya.without_extension():
            cmds.select(controls, noExpand=False)
            cmds.file(os.path.join(dirname, filename).replace("\\", "/"),
                      force=True,
                      options=options,
                      typ="atomExport",
                      exportSelected=True)

        # Store reference for integration
        if "files" not in instance.data:
            instance.data["files"] = list()

        instance.data["files"].append(filename)
        instance.data["stagingDir"] = dirname

        self.log.info("Extracted {instance} to {dirname}".format(**locals()))
예제 #13
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True)

        self[:] = nodes
예제 #14
0
    def process(self, instance):
        import os
        import ava
        from maya import cmds
        from avalon import maya

        self.log.info("Extracting history..")

        dirname = ava.format_staging_dir(
            root=instance.context.data["workspaceDir"],
            time=instance.context.data["time"],
            name=instance.data["name"])

        try:
            os.makedirs(dirname)
        except OSError:
            pass

        filename = "{name}.history".format(**instance.data)

        options = ";".join([
            "precision=8", "statics=1", "baked=1", "sdk=0", "constraint=0",
            "animLayers=0", "selected=selectedOnly", "whichRange=1",
            "range=1:10", "hierarchy=none", "controlPoints=0",
            "useChannelBox=1", "options=keys",
            ("copyKeyCmd="
             "-animation objects "
             "-option keys "
             "-hierarchy none "
             "-controlPoints 0 ")
        ])

        with maya.maintained_selection(), maya.without_extension():
            cmds.select(instance, noExpand=True)
            cmds.exportEdits(
                os.path.join(dirname, filename).replace("\\", "/"),
                force=True,
                type="editMA",
                selected=True,
                includeNetwork=True,
                includeAnimation=True,
                includeSetAttrs=True,
            )

        # Store reference for integration
        if "files" not in instance.data:
            instance.data["files"] = list()

        instance.data["files"].append(filename)
        instance.data["stagingDir"] = dirname

        self.log.info("Extracted {instance} to {dirname}".format(**locals()))
예제 #15
0
    def repair(cls, instance):
        with maya.maintained_selection():
            with pc.UndoChunk():
                temp_transform = pc.polyCube()[0]

                attributes = cls.get_invalid_attributes(instance,
                                                        compute=False)
                for attr in attributes:
                    source = pc.PyNode("{}.{}".format(
                        temp_transform.getShape(), attr.attrName()))
                    attr.set(source.get())

                pc.delete(temp_transform)
예제 #16
0
    def process(self, instance):
        import os
        import polly
        from maya import cmds
        from avalon import maya

        dirname = polly.format_staging_dir(
            root=instance.context.data["workspaceDir"],
            time=instance.context.data["time"],
            name=instance.data["name"])

        try:
            os.makedirs(dirname)
        except OSError:
            pass

        filename = "{name}.ma".format(**instance.data)

        path = os.path.join(dirname, filename)

        # Perform extraction
        self.log.info("Performing extraction..")
        with maya.maintained_selection(), maya.without_extension():
            self.log.info("Extracting %s" % str(list(instance)))
            cmds.select(instance, noExpand=True)
            cmds.file(
                path,
                force=True,
                typ="mayaAscii",
                exportSelected=True,
                preserveReferences=False,

                # Shader assignment is the responsibility of
                # riggers, for animators, and lookdev, for rendering.
                shader=False,

                # Construction history inherited from collection
                # This enables a selective export of nodes relevant
                # to this particular plug-in.
                constructionHistory=False)

        # Store reference for integration
        if "files" not in instance.data:
            instance.data["files"] = list()

        instance.data["files"].append(filename)
        instance.data["stagingDir"] = dirname

        self.log.info("Extracted {instance} to {path}".format(**locals()))
    def extract_LightSet(self, packager):

        from maya import cmds
        from avalon import maya
        from reveries.maya import capsule

        entry_file = packager.file_name("ma")
        package_path = packager.create_package()

        # Extract lights
        #
        entry_path = os.path.join(package_path, entry_file)

        self.log.info("Extracting lights..")

        # From texture extractor
        try:
            texture = next(chd for chd in self.data.get("childInstances", [])
                           if chd.data["family"] == "reveries.texture")
        except StopIteration:
            file_node_attrs = dict()
        else:
            file_node_attrs = texture.data.get("fileNodeAttrs", dict())

        with contextlib.nested(
            maya.maintained_selection(),
            capsule.attribute_values(file_node_attrs),
            capsule.no_refresh(),
        ):
            cmds.select(self.member,
                        replace=True,
                        noExpand=True)

            cmds.file(entry_path,
                      options="v=0;",
                      type="mayaAscii",
                      force=True,
                      exportSelected=True,
                      preserveReferences=False,
                      constructionHistory=False,
                      channels=True,  # allow animation
                      constraints=False,
                      shader=False,
                      expressions=True)

        packager.add_data({
            "entryFileName": entry_file,
        })
예제 #18
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya
        import pymel.core as pm

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "ass"

        with maya.maintained_selection():

            groupName = "{}:{}".format(namespace, name)
            path = self.fname
            proxyPath = os.path.splitext(path)[0] + ".ma"

            nodes = cmds.file(proxyPath,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName=groupName)

            cmds.makeIdentity(groupName,
                              apply=False,
                              rotate=True,
                              translate=True,
                              scale=True)

            # Set attributes
            proxyShape = pm.ls(nodes, type="mesh")[0]

            proxyShape.aiTranslator.set('procedural')
            proxyShape.dso.set(path)
            proxyShape.aiOverrideShaders.set(0)

            presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
            colors = presets['plugins']['maya']['load']['colors']

            c = colors.get(family)
            if c is not None:
                cmds.setAttr(groupName + ".useOutlinerColor", 1)
                cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2])

        self[:] = nodes

        return nodes
예제 #19
0
    def process(self, instance):
        from maya import cmds
        from avalon import maya
        from reveries import utils
        from reveries.maya import capsule

        staging_dir = utils.stage_dir()
        filename = "%s.ma" % instance.data["subset"]
        outpath = "%s/%s" % (staging_dir, filename)

        instance.data["repr.LightSet._stage"] = staging_dir
        instance.data["repr.LightSet._files"] = [filename]
        instance.data["repr.LightSet.entryFileName"] = filename

        # Extract lights
        #
        self.log.info("Extracting lights..")

        # From texture extractor
        child_instances = instance.data.get("childInstances", [])
        try:
            texture = next(chd for chd in child_instances
                           if chd.data["family"] == "reveries.texture")
        except StopIteration:
            file_node_attrs = dict()
        else:
            file_node_attrs = texture.data.get("fileNodeAttrs", dict())

        with contextlib.nested(
                maya.maintained_selection(),
                capsule.attribute_values(file_node_attrs),
                capsule.no_refresh(),
        ):
            cmds.select(instance, replace=True, noExpand=True)

            cmds.file(
                outpath,
                options="v=0;",
                type="mayaAscii",
                force=True,
                exportSelected=True,
                preserveReferences=False,
                constructionHistory=False,
                channels=True,  # allow animation
                constraints=False,
                shader=False,
                expressions=True)
예제 #20
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "model"

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        self[:] = nodes
        groupName = "{}:{}".format(namespace, name)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']

        c = colors.get(family)
        if c is not None:
            cmds.setAttr(groupName + ".useOutlinerColor", 1)
            cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2])
            cmds.setAttr(groupName + ".displayHandle", 1)
            # get bounding box
            bbox = cmds.exactWorldBoundingBox(groupName)
            # get pivot position on world space
            pivot = cmds.xform(groupName, q=True, sp=True, ws=True)
            # center of bounding box
            cx = (bbox[0] + bbox[3]) / 2
            cy = (bbox[1] + bbox[4]) / 2
            cz = (bbox[2] + bbox[5]) / 2
            # add pivot position to calculate offset
            cx = cx + pivot[0]
            cy = cy + pivot[1]
            cz = cz + pivot[2]
            # set selection handle offset to center of bounding box
            cmds.setAttr(groupName + ".selectHandleX", cx)
            cmds.setAttr(groupName + ".selectHandleY", cy)
            cmds.setAttr(groupName + ".selectHandleZ", cz)
        return nodes
예제 #21
0
    def process_reference(self, context, name, namespace, group, options):

        import maya.cmds as cmds
        from avalon import maya

        representation = context["representation"]

        entry_path = self.file_path(representation)

        with maya.maintained_selection():
            nodes = cmds.file(entry_path,
                              namespace=namespace,
                              ignoreVersion=True,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName=group)
        self[:] = nodes
예제 #22
0
    def process_reference(self, context, name=None, namespace=None, data=None):

        import maya.cmds as cmds
        from avalon import maya

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        self[:] = nodes

        self.log.info("Yeti Rig Connection Manager will be available soon")

        return nodes
예제 #23
0
    def process_reference(self, context, name, namespace, data):

        import maya.cmds as cmds
        from avalon import maya

        # Ensure FBX plug-in is loaded
        cmds.loadPlugin("fbxmaya", quiet=True)

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        self[:] = nodes

        return nodes
예제 #24
0
    def _post_process(self, name, namespace, context, data):
        import os
        from maya import cmds
        from avalon import maya, io

        # Task-dependent post-process
        if os.getenv("AVALON_TASK") != "animate":
            return self.log.info(
                "No animation instance created due to task != animate")

        # Find associated rig to these curves
        try:
            dependency = context["representation"]["dependencies"][0]
        except (KeyError, IndexError):
            return self.log.warning("No dependencies found for %s" % name)

        dependency = io.find_one({"_id": io.ObjectId(dependency)})
        _, _, dependency, _ = io.parenthood(dependency)

        # TODO(marcus): We are hardcoding the name "out_SET" here.
        #   Better register this keyword, so that it can be used
        #   elsewhere, such as in the Integrator plug-in,
        #   without duplication.
        output = next((node for node in self if node.endswith("out_SET")),
                      None)
        controls = next(
            (node for node in self if node.endswith("controls_SET")), None)

        assert output, "No out_SET in rig, this is a bug."
        assert controls, "No controls_SET in rig, this is a bug."

        with maya.maintained_selection():
            cmds.select([output, controls], noExpand=True)

            dependencies = [context["representation"]["_id"]]
            name = "anim" + dependency["name"].title() + "_"

            # TODO(marcus): Hardcoding the family here, better separate this.
            maya.create(
                name=maya.unique_name(name, suffix="_SET"),
                family="ava.animation",
                options={"useSelection": True},
                data={"dependencies": " ".join(str(d) for d in dependencies)})
예제 #25
0
    def process(self, instance):
        from maya import cmds
        from avalon import maya

        with maya.maintained_selection():
            cmds.select(instance, replace=True)
            nodes = cmds.file(
                constructionHistory=True,
                exportSelected=True,
                preview=True,
                force=True,
            )

        self.assemblies[:] = cmds.ls(nodes, assemblies=True)

        if not self.assemblies:
            raise Exception("No assembly found.")

        if len(self.assemblies) != 1:
            self.assemblies = '"%s"' % '", "'.join(self.assemblies)
            raise Exception("Multiple assemblies found: %s" % self.assemblies)
예제 #26
0
    def process(self, instance):
        import os
        import polly
        from maya import cmds
        from avalon import maya

        dirname = polly.format_staging_dir(
            root=instance.context.data["workspaceDir"],
            time=instance.context.data["time"],
            name=instance.data["name"])

        try:
            os.makedirs(dirname)
        except OSError:
            pass

        filename = "{name}.ma".format(**instance.data)

        path = os.path.join(dirname, filename)

        # Perform extraction
        self.log.info("Performing extraction..")
        with maya.maintained_selection(), maya.without_extension():
            cmds.select(instance, noExpand=True)
            cmds.file(path,
                      force=True,
                      typ="mayaAscii",
                      exportSelected=True,
                      preserveReferences=False,
                      constructionHistory=True)

        # Store reference for integration
        if "files" not in instance.data:
            instance.data["files"] = list()

        instance.data["files"].append(filename)
        instance.data["stagingDir"] = dirname

        self.log.info("Extracted {instance} to {path}".format(**locals()))
예제 #27
0
    def process_reference(self, context, name, namespace, options):
        """
        Load and try to assign Lookdev to nodes based on relationship data.

        Args:
            name:
            namespace:
            context:
            options:

        Returns:

        """
        import maya.cmds as cmds
        from avalon import maya

        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True)

        self[:] = nodes
예제 #28
0
    def extract_mayaBinary(self, packager):
        # Define extract output file path
        entry_file = packager.file_name("mb")
        package_path = packager.create_package()
        entry_path = os.path.join(package_path, entry_file)

        # Perform extraction
        self.log.info("Performing extraction..")
        with contextlib.nested(
                capsule.no_undo(),
                capsule.no_display_layers(self.member),
                maya.maintained_selection(),
        ):
            with capsule.undo_chunk_when_no_undo():
                """(DEPRECATED, keeping namespaces)
                # - Remove referenced subset's namespace before exporting
                #   (Not keeping model namespace)
                referenced_namespace = self.context.data["referencedNamespace"]
                for namespace in reversed(sorted(list(referenced_namespace))):
                    if not cmds.namespace(exists=namespace):
                        continue

                    try:
                        cmds.namespace(removeNamespace=namespace,
                                       mergeNamespaceWithRoot=True)
                    except Exception:
                        # Reload reference and try again.
                        # The namespace of the reference will be able to
                        # removed after reload.
                        # (TODO) This publish workflow might not be a good
                        #        approach...
                        ref_node = lib.reference_node_by_namespace(namespace)
                        # There must be a reference node, since that's the
                        # main reason why namespace can not be removed.
                        cmds.file(loadReference=ref_node)
                        cmds.namespace(removeNamespace=namespace,
                                       mergeNamespaceWithRoot=True)
                """

                # - Remove loaded container member
                #   If the mesh of the loaded model has been copied and edited
                #   (mesh face detach and separation), the model container
                #   might end up with a lots of facet member, which means there
                #   are dag connections that would make the model container be
                #   exported as well, and we don't want that happens.
                #   So we just remove them all for good.
                for container in self.context.data["RootContainers"]:
                    cmds.delete(container)

                mesh_nodes = cmds.ls(self.member,
                                     type="mesh",
                                     noIntermediate=True,
                                     long=True)
                geo_id_and_hash = self.hash(set(mesh_nodes))
                packager.add_data({"modelProfile": geo_id_and_hash})

                cmds.select(cmds.ls(self.member), noExpand=True)

                cmds.file(entry_path,
                          force=True,
                          typ="mayaBinary",
                          exportSelected=True,
                          preserveReferences=False,
                          channels=True,
                          constraints=True,
                          expressions=True,
                          constructionHistory=True,
                          shader=True)

        packager.add_data({
            "entryFileName": entry_file,
        })

        self.log.info("Extracted {name} to {path}".format(
            name=self.data["subset"], path=entry_path))
예제 #29
0
    def process_reference(self, context, name, namespace, options):
        import maya.cmds as cmds
        from avalon import maya
        import pymel.core as pm

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "model"

        with maya.maintained_selection():

            groupName = "{}:{}".format(namespace, name)
            cmds.loadPlugin("AbcImport.mll", quiet=True)
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              sharedReferenceFile=False,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name),
                              reference=True,
                              returnNewNodes=True)

            # namespace = cmds.referenceQuery(nodes[0], namespace=True)

            shapes = cmds.ls(nodes, shapes=True, long=True)

            newNodes = (list(set(nodes) - set(shapes)))

            current_namespace = pm.namespaceInfo(currentNamespace=True)

            if current_namespace != ":":
                groupName = current_namespace + ":" + groupName

            groupNode = pm.PyNode(groupName)
            roots = set()

            for node in newNodes:
                try:
                    roots.add(pm.PyNode(node).getAllParents()[-2])
                except:  # noqa: E722
                    pass

            if family not in ["layout", "setdress", "mayaAscii"]:
                for root in roots:
                    root.setParent(world=True)

            groupNode.zeroTransformPivots()
            for root in roots:
                root.setParent(groupNode)

            cmds.setAttr(groupName + ".displayHandle", 1)

            settings = get_project_settings(os.environ['AVALON_PROJECT'])
            colors = settings['maya']['load']['colors']
            c = colors.get(family)
            if c is not None:
                groupNode.useOutlinerColor.set(1)
                groupNode.outlinerColor.set(c[0], c[1], c[2])

            self[:] = newNodes

            cmds.setAttr(groupName + ".displayHandle", 1)
            # get bounding box
            bbox = cmds.exactWorldBoundingBox(groupName)
            # get pivot position on world space
            pivot = cmds.xform(groupName, q=True, sp=True, ws=True)
            # center of bounding box
            cx = (bbox[0] + bbox[3]) / 2
            cy = (bbox[1] + bbox[4]) / 2
            cz = (bbox[2] + bbox[5]) / 2
            # add pivot position to calculate offset
            cx = cx + pivot[0]
            cy = cy + pivot[1]
            cz = cz + pivot[2]
            # set selection handle offset to center of bounding box
            cmds.setAttr(groupName + ".selectHandleX", cx)
            cmds.setAttr(groupName + ".selectHandleY", cy)
            cmds.setAttr(groupName + ".selectHandleZ", cz)

            if family == "rig":
                self._post_process_rig(name, namespace, context, options)
            else:
                if "translate" in options:
                    cmds.setAttr(groupName + ".t", *options["translate"])

            return newNodes
예제 #30
0
    def process_reference(self,
                          context,
                          name=None,
                          namespace=None,
                          options=None):

        import maya.cmds as cmds
        from avalon import maya

        # get roots of selected hierarchies
        selected_roots = []
        for sel in cmds.ls(sl=True, long=True):
            selected_roots.append(sel.split("|")[1])

        # get all objects under those roots
        selected_hierarchy = []
        for root in selected_roots:
            selected_hierarchy.append(
                cmds.listRelatives(root, allDescendents=True) or [])

        # flatten the list and filter only shapes
        shapes_flat = []
        for root in selected_hierarchy:
            shapes = cmds.ls(root, long=True, type="mesh") or []
            for shape in shapes:
                shapes_flat.append(shape)

        # create dictionary of cbId and shape nodes
        scene_lookup = defaultdict(list)
        for node in shapes_flat:
            cb_id = lib.get_id(node)
            scene_lookup[cb_id] = node

        # load rig
        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        # for every shape node we've just loaded find matching shape by its
        # cbId in selection. If found outMesh of scene shape will connect to
        # inMesh of loaded shape.
        for destination_node in nodes:
            source_node = scene_lookup[lib.get_id(destination_node)]
            if source_node:
                self.log.info("found: {}".format(source_node))
                self.log.info(
                    "creating connection to {}".format(destination_node))

                cmds.connectAttr("{}.outMesh".format(source_node),
                                 "{}.inMesh".format(destination_node),
                                 force=True)

        groupName = "{}:{}".format(namespace, name)

        settings = get_project_settings(os.environ['AVALON_PROJECT'])
        colors = settings['maya']['load']['colors']

        c = colors.get('yetiRig')
        if c is not None:
            cmds.setAttr(groupName + ".useOutlinerColor", 1)
            cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2])
        self[:] = nodes

        return nodes