コード例 #1
0
    def extract_XGenLegacy(self, packager):

        packager.skip_stage()
        package_dir = packager.create_package()

        xgen_files = list()
        descriptions_data = dict()

        for desc in self.data["xgenDescriptions"]:
            palette = xgen.get_palette_by_description(desc)

            # Save UUID and bounding
            descriptions_data[desc] = {
                "id": utils.get_id(desc),
                "bound": xgen.list_bound_geometry(desc),
            }

            # Transfer maps
            maps = xgen.maps_to_transfer(desc)
            data_paths = xgen.current_data_paths(palette, expand=True)

            for src in maps:
                for root in data_paths:
                    if src.startswith(root):
                        # At least one root will be matched, since all
                        # map path has been validated that must exists
                        # under ${DESC} dir.
                        tail = src[len(root):]
                        if tail.startswith("/") or tail.startswith("\\"):
                            tail = tail[1:]
                        break
                else:
                    self.log.critical("Searched data path:")
                    for root in data_paths:
                        self.log.critical(root)
                    raise Exception("Could not find root path for %s , "
                                    "this is a bug." % src)

                dst = os.path.join(package_dir, "maps", palette, tail)
                packager.add_file(src, dst)

            # Export guides
            guides = xgen.list_guides(desc)
            if guides:
                guide_file = os.path.join(package_dir,
                                          "guides",
                                          palette,
                                          desc + ".abc")
                io.export_xgen_LGC_guides(guides, guide_file)

            # Export grooming
            groom = xgen.get_groom(desc)
            if groom and cmds.objExists(groom):
                groom_dir = os.path.join(package_dir,
                                         "groom",
                                         palette,
                                         desc)
                xgen.export_grooming(desc, groom, groom_dir)

        # Extract palette
        for palette in self.data["xgenPalettes"]:
            xgen_file = palette + ".xgen"
            xgen_path = os.path.join(package_dir, xgen_file)
            io.export_xgen_LGC_palette(palette, xgen_path)
            xgen_files.append(xgen_file)

            # Culled
            xgd_file = palette + "_culled.xgd"
            xgd_path = os.path.join(package_dir, "deltas", palette, xgd_file)
            if xgen.save_culled_as_delta(palette, xgd_path):
                self.log.info("Culled primitives saved.")

        packager.add_data({
            "entryFileName": None,  # Yes, no entry file for XGen Legacy.
            "descriptionsData": descriptions_data,
            "palettes": xgen_files,
            "step": self.data["step"],
        })
コード例 #2
0
    def load(self, context, name=None, namespace=None, options=None):

        # (NOTE) AnimWire modifier has a bug that not able to find wires if
        #        namespace is applied.
        #        The hairSystem is okay to work with, but not able to update
        #        XGen preview. So you either simulate without the update, or
        #        build the simulation without namespace and save with .xgen
        #        file exported, then reference it with namespace.
        #
        #        https://forums.autodesk.com/t5/maya-dynamics/anim-wire-
        #        errors-when-using-namespaces/m-p/7329883#M5642
        #

        if not cmds.pluginInfo("xgenToolkit", query=True, loaded=True):
            cmds.loadPlugin("xgenToolkit", quiet=True)

        representation = context["representation"]

        asset = context["asset"]
        asset_name = asset["data"].get("shortName", asset["name"])
        family_name = context["version"]["data"]["families"][0].split(".")[-1]
        namespace = namespace or unique_root_namespace(asset_name, family_name)

        descriptions_data = representation["data"]["descriptionsData"]
        baked = representation["data"]["step"] != xgen.SHAPING
        bound_meshes = list()

        # Varify selection
        selected = cmds.ls(sl=True, long=True)

        all_bound_geos = set()
        for data in descriptions_data.values():
            for geo in data["bound"]:
                all_bound_geos.add("|" + geo)

        msg = ("Require bound geos: {0}\n"
               "Selected: {1}".format(all_bound_geos, selected))
        assert set(selected) == all_bound_geos, msg

        # Rename bound geos to namespace
        for node in selected:
            bound_meshes.append(node)

        # Copy maps
        local_map_dir = os.path.join(avalon.api.Session["AVALON_WORKDIR"],
                                     "xgen",
                                     "published",
                                     # Add username to ease out file lock issue
                                     getpass.getuser())
        map_dir = os.path.join(self.package_path, "maps")
        for palette in os.listdir(map_dir):
            palette_dir = os.path.join(map_dir, palette)
            local_palette_dir = os.path.join(local_map_dir, palette)

            # Copy
            copy_tree(palette_dir, local_palette_dir)

        # Import palette
        palette_nodes = list()
        xgen.preview_clear()

        for file in representation["data"]["palettes"]:

            xgen_path = os.path.join(self.package_path, file)
            xgen_path = xgen_path.replace("\\", "/")
            palette_node = xgen.import_palette(xgen_path,
                                               wrapPatches=True)
            palette_nodes.append(palette_node)

            # Set xgDataPath
            palette = os.path.splitext(file)[0]
            data_path = os.path.join(local_map_dir, palette).replace("\\", "/")
            xgen.set_data_path(palette_node, data_path)

            if not baked:
                # Bind grooming descriptions to geometry
                for desc in xgen.list_descriptions(palette_node):
                    groom = xgen.get_groom(desc)
                    if groom:
                        groom_dir = os.path.join(self.package_path,
                                                 "groom",
                                                 palette_node,
                                                 desc)
                        xgen.import_grooming(desc, groom, groom_dir)

            # Apply ID
            asset_id = str(asset["_id"])
            with utils.id_namespace(asset_id):
                for desc in xgen.list_descriptions(palette_node):
                    _desc = desc.rsplit(":", 1)[-1]
                    id = descriptions_data[_desc]["id"]
                    utils.upsert_id(desc, id)

            # Ensure tube shade disabled
            xgen.disable_tube_shade(palette_node)

        group_name = self.group_name(namespace, name)
        # Cannot be grouped
        # cmds.group(palette_nodes, name=group_name, world=True)
        # palette_nodes = cmds.ls(palette_nodes, long=True)

        # Containerising..
        nodes = palette_nodes[:]
        nodes += bound_meshes
        nodes += cmds.listRelatives(palette_nodes,
                                    allDescendents=True,
                                    fullPath=True)
        nodes += apply_namespace_wrapper(namespace, nodes)

        container_id = options.get("containerId",
                                   utils.generate_container_id())
        container = subset_containerising(name=name,
                                          namespace=namespace,
                                          container_id=container_id,
                                          nodes=nodes,
                                          context=context,
                                          cls_name=self.__class__.__name__,
                                          group_name=group_name)
        return container
コード例 #3
0
    def process(self, instance):
        from maya import cmds
        from reveries import utils
        from reveries.maya import io, utils as maya_utils
        from reveries.maya.xgen import legacy as xgen

        staging_dir = utils.stage_dir()

        files = list()
        xgen_files = list()
        descriptions_data = dict()

        for desc in instance.data["xgenDescriptions"]:
            palette = xgen.get_palette_by_description(desc)

            # Save UUID and bounding
            descriptions_data[desc] = {
                "id": maya_utils.get_id(desc),
                "bound": xgen.list_bound_geometry(desc),
            }

            # Stage maps
            map_stage = staging_dir + "/maps/%s" % palette

            for head, src in xgen.maps_to_transfer(desc):
                relative = os.path.relpath(src, head)
                if os.path.isfile(src):
                    relative = os.path.dirname(relative)
                    ship = shutil.copy2
                elif os.path.isdir(src):
                    ship = shutil.copytree
                else:
                    continue

                dst_dir = map_stage + "/" + relative
                if not os.path.isdir(dst_dir):
                    os.makedirs(dst_dir)

                try:
                    ship(src, dst_dir)
                except OSError:
                    msg = "An unexpected error occurred."
                    self.log.critical(msg)
                    raise OSError(msg)

            for root, _, fnames in os.walk(map_stage):
                relative = os.path.relpath(root, staging_dir)
                relative = "" if relative == "." else (relative + "/")
                relative = relative.replace("\\", "/")
                for file in fnames:
                    map_file = relative + file
                    files.append(map_file)

            # Export guides
            guides = xgen.list_guides(desc)
            if guides:
                guide_file = "guides/%s/%s.abc" % (palette, desc)
                guide_path = "%s/%s" % (staging_dir, guide_file)
                io.export_xgen_LGC_guides(guides, guide_path)

                files.append(guide_file)

            # Export grooming
            groom = xgen.get_groom(desc)
            if groom and cmds.objExists(groom):
                groom_dir = "groom/%s/%s" % (palette, desc)
                groom_path = "%s/%s" % (staging_dir, groom_dir)
                xgen.export_grooming(desc, groom, groom_path)

                # Walk groom_path and add into files
                for root, _, fnames in os.walk(groom_path):
                    relative = os.path.relpath(root, staging_dir)
                    relative = "" if relative == "." else (relative + "/")
                    for file in fnames:
                        groom_file = relative + file
                        files.append(groom_file)

        # Extract palette
        for palette in instance.data["xgenPalettes"]:
            xgen_file = palette + ".xgen"
            xgen_path = "%s/%s" % (staging_dir, xgen_file)
            io.export_xgen_LGC_palette(palette, xgen_path)

            xgen_files.append(xgen_file)
            files.append(xgen_file)

            # Culled
            xgd_file = "deltas/%s/%s_culled.xgd" % (palette, palette)
            xgd_path = "%s/%s" % (staging_dir, xgd_file)
            if xgen.save_culled_as_delta(palette, xgd_path):
                self.log.info("Culled primitives saved.")

                files.append(xgd_file)

        instance.data["repr.XGenLegacy._stage"] = staging_dir
        instance.data["repr.XGenLegacy._files"] = files
        instance.data["repr.XGenLegacy.entryFileName"] = None  # no entry file
        instance.data["repr.XGenLegacy.descriptionsData"] = descriptions_data
        instance.data["repr.XGenLegacy.palettes"] = xgen_files
        instance.data["repr.XGenLegacy.step"] = instance.data["step"]