예제 #1
0
    def refresh(self):
        self.list_families.clear()

        has_families = False
        project_name = self.dbcon.Session.get("AVALON_PROJECT")
        if not project_name:
            return

        settings = get_project_settings(project_name)
        sp_settings = settings.get('standalonepublisher', {})

        for key, creator_data in sp_settings.get("create", {}).items():
            creator = type(key, (Creator, ), creator_data)

            label = creator.label or creator.family
            item = QtWidgets.QListWidgetItem(label)
            item.setData(QtCore.Qt.ItemIsEnabled, True)
            item.setData(HelpRole, creator.help or "")
            item.setData(FamilyRole, creator.family)
            item.setData(PluginRole, creator)
            item.setData(PluginKeyRole, key)
            item.setData(ExistsRole, False)
            self.list_families.addItem(item)

            has_families = True

        if not has_families:
            item = QtWidgets.QListWidgetItem("No registered families")
            item.setData(QtCore.Qt.ItemIsEnabled, False)
            self.list_families.addItem(item)

        self.list_families.setCurrentItem(self.list_families.item(0))
    def launch(self, session, entities, event):
        # Get project entity
        project_entity = self.get_project_from_entity(entities[0])
        # Load settings for project
        project_name = project_entity["full_name"]
        project_settings = get_project_settings(project_name)
        project_folder_structure = (
            project_settings["global"]["project_folder_structure"]
        )
        if not project_folder_structure:
            return {
                "success": False,
                "message": "Project structure is not set."
            }

        try:
            # Get paths based on presets
            basic_paths = self.get_path_items(project_folder_structure)
            self.create_folders(basic_paths, project_entity)
            self.create_ftrack_entities(basic_paths, project_entity)

        except Exception as exc:
            self.log.warning("Creating of structure crashed.", exc_info=True)
            session.rollback()
            return {
                "success": False,
                "message": str(exc)
            }

        return True
예제 #3
0
    def load(self, context, name=None, namespace=None, data=None):

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

        # Build namespace
        asset = context["asset"]
        if namespace is None:
            namespace = self.create_namespace(asset["name"])

        # Ensure Yeti is loaded
        if not cmds.pluginInfo("pgYetiMaya", query=True, loaded=True):
            cmds.loadPlugin("pgYetiMaya", quiet=True)

        # Get JSON
        fbase = re.search(r'^(.+)\.(\d+|#+)\.fur', self.fname)
        if not fbase:
            raise RuntimeError('Cannot determine fursettings file path')
        settings_fname = "{}.fursettings".format(fbase.group(1))
        with open(settings_fname, "r") as fp:
            fursettings = json.load(fp)

        # Check if resources map exists
        # Get node name from JSON
        if "nodes" not in fursettings:
            raise RuntimeError("Encountered invalid data, expect 'nodes' in "
                               "fursettings.")

        node_data = fursettings["nodes"]
        nodes = self.create_nodes(namespace, node_data)

        group_name = "{}:{}".format(namespace, name)
        group_node = cmds.group(nodes, name=group_name)

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

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

        nodes.append(group_node)

        self[:] = nodes

        return pipeline.containerise(name=name,
                                     namespace=namespace,
                                     nodes=nodes,
                                     context=context,
                                     loader=self.__class__.__name__)
예제 #4
0
    def load(self, context, name, namespace, data):

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

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

        cmds.loadPlugin("gpuCache", quiet=True)

        # Root group
        label = "{}:{}".format(namespace, name)
        root = cmds.group(name=label, empty=True)

        settings = get_project_settings(os.environ['AVALON_PROJECT'])
        colors = settings['maya']['load']['colors']
        c = colors.get('model')
        if c is not None:
            cmds.setAttr(root + ".useOutlinerColor", 1)
            cmds.setAttr(root + ".outlinerColor",
                         c[0], c[1], c[2])

        # Create transform with shape
        transform_name = label + "_GPU"
        transform = cmds.createNode("transform", name=transform_name,
                                    parent=root)
        cache = cmds.createNode("gpuCache",
                                parent=transform,
                                name="{0}Shape".format(transform_name))

        # Set the cache filepath
        cmds.setAttr(cache + '.cacheFileName', self.fname, type="string")
        cmds.setAttr(cache + '.cacheGeomPath', "|", type="string")    # root

        # Lock parenting of the transform and cache
        cmds.lockNode([transform, cache], lock=True)

        nodes = [root, transform, cache]
        self[:] = nodes

        return containerise(
            name=name,
            namespace=namespace,
            nodes=nodes,
            context=context,
            loader=self.__class__.__name__)
예제 #5
0
    def ftrack_status_change(self, session, entity, project_name):
        project_settings = get_project_settings(project_name)
        status_update = project_settings["ftrack"]["events"]["status_update"]
        if not status_update["enabled"]:
            self.log.debug(
                "Status changes are disabled for project \"{}\"".format(
                    project_name))
            return

        status_mapping = status_update["mapping"]
        if not status_mapping:
            self.log.warning(
                "Project \"{}\" does not have set status changes.".format(
                    project_name))
            return

        actual_status = entity["status"]["name"].lower()
        already_tested = set()
        ent_path = "/".join([ent["name"] for ent in entity["link"]])
        while True:
            next_status_name = None
            for key, value in status_mapping.items():
                if key in already_tested:
                    continue
                if actual_status in value or "__any__" in value:
                    if key != "__ignore__":
                        next_status_name = key
                        already_tested.add(key)
                    break
                already_tested.add(key)

            if next_status_name is None:
                break

            try:
                query = "Status where name is \"{}\"".format(next_status_name)
                status = session.query(query).one()

                entity["status"] = status
                session.commit()
                self.log.debug("Changing status to \"{}\" <{}>".format(
                    next_status_name, ent_path))
                break

            except Exception:
                session.rollback()
                msg = ("Status \"{}\" in presets wasn't found"
                       " on Ftrack entity type \"{}\"").format(
                           next_status_name, entity.entity_type)
                self.log.warning(msg)
예제 #6
0
    def load(self, context, name, namespace, data):

        from avalon.maya.pipeline import containerise
        from pype.hosts.maya.api.lib import namespaced

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

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

        # Ensure V-Ray for Maya is loaded.
        cmds.loadPlugin("vrayformaya", quiet=True)

        with lib.maintained_selection():
            cmds.namespace(addNamespace=namespace)
            with namespaced(namespace, new=False):
                nodes, group_node = self.create_vray_proxy(name,
                                                           filename=self.fname)

        self[:] = nodes
        if not nodes:
            return

        # colour the group node
        settings = get_project_settings(os.environ['AVALON_PROJECT'])
        colors = settings['maya']['load']['colors']
        c = colors.get(family)
        if c is not None:
            cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1)
            cmds.setAttr("{0}.outlinerColor".format(group_node), c[0], c[1],
                         c[2])

        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
예제 #7
0
    def presets_by_hosts(self):
        # Get global filters as base
        presets = get_project_settings(os.environ['AVALON_PROJECT']) or {}
        if not presets:
            return {}

        result = presets.get("global", {}).get("filters", {})
        hosts = pyblish.api.registered_hosts()
        for host in hosts:
            host_presets = presets.get(host, {}).get("filters")
            if not host_presets:
                continue

            for key, value in host_presets.items():
                if value is None:
                    if key in result:
                        result.pop(key)
                    continue

                result[key] = value

        return result
예제 #8
0
파일: lib.py 프로젝트: simonebarbieri/pype
def create_unreal_project(project_name: str,
                          ue_version: str,
                          pr_dir: str,
                          engine_path: str,
                          dev_mode: bool = False) -> None:
    """
    This will create `.uproject` file at specified location. As there is no
    way I know to create project via command line, this is easiest option.
    Unreal project file is basically JSON file. If we find
    `AVALON_UNREAL_PLUGIN` environment variable we assume this is location
    of Avalon Integration Plugin and we copy its content to project folder
    and enable this plugin.

    :param project_name: project name
    :type project_name: str
    :param ue_version: unreal engine version (like 4.23)
    :type ue_version: str
    :param pr_dir: path to directory where project will be created
    :type pr_dir: str
    :param engine_path: Path to Unreal Engine installation
    :type engine_path: str
    :param dev_mode: Flag to trigger C++ style Unreal project needing
                     Visual Studio and other tools to compile plugins from
                     sources. This will trigger automatically if `Binaries`
                     directory is not found in plugin folders as this indicates
                     this is only source distribution of the plugin. Dev mode
                     is also set by preset file `unreal/project_setup.json` in
                     **PYPE_CONFIG**.
    :type dev_mode: bool
    :returns: None
    """
    preset = get_project_settings(project_name)["unreal"]["project_setup"]

    if os.path.isdir(os.environ.get("AVALON_UNREAL_PLUGIN", "")):
        # copy plugin to correct path under project
        plugins_path = os.path.join(pr_dir, "Plugins")
        avalon_plugin_path = os.path.join(plugins_path, "Avalon")
        if not os.path.isdir(avalon_plugin_path):
            os.makedirs(avalon_plugin_path, exist_ok=True)
            dir_util._path_created = {}
            dir_util.copy_tree(os.environ.get("AVALON_UNREAL_PLUGIN"),
                               avalon_plugin_path)

            if (not os.path.isdir(os.path.join(avalon_plugin_path, "Binaries"))
                    or not os.path.join(avalon_plugin_path, "Intermediate")):
                dev_mode = True

    # data for project file
    data = {
        "FileVersion":
        3,
        "EngineAssociation":
        ue_version,
        "Category":
        "",
        "Description":
        "",
        "Plugins": [{
            "Name": "PythonScriptPlugin",
            "Enabled": True
        }, {
            "Name": "EditorScriptingUtilities",
            "Enabled": True
        }, {
            "Name": "Avalon",
            "Enabled": True
        }]
    }

    if preset["install_unreal_python_engine"]:
        # If `PYPE_UNREAL_ENGINE_PYTHON_PLUGIN` is set, copy it from there to
        # support offline installation.
        # Otherwise clone UnrealEnginePython to Plugins directory
        # https://github.com/20tab/UnrealEnginePython.git
        uep_path = os.path.join(plugins_path, "UnrealEnginePython")
        if os.environ.get("PYPE_UNREAL_ENGINE_PYTHON_PLUGIN"):

            os.makedirs(uep_path, exist_ok=True)
            dir_util._path_created = {}
            dir_util.copy_tree(
                os.environ.get("PYPE_UNREAL_ENGINE_PYTHON_PLUGIN"), uep_path)
        else:
            # WARNING: this will trigger dev_mode, because we need to compile
            # this plugin.
            dev_mode = True
            import git
            git.Repo.clone_from(
                "https://github.com/20tab/UnrealEnginePython.git", uep_path)

        data["Plugins"].append({"Name": "UnrealEnginePython", "Enabled": True})

        if (not os.path.isdir(os.path.join(uep_path, "Binaries"))
                or not os.path.join(uep_path, "Intermediate")):
            dev_mode = True

    if dev_mode or preset["dev_mode"]:
        # this will add project module and necessary source file to make it
        # C++ project and to (hopefully) make Unreal Editor to compile all
        # sources at start

        data["Modules"] = [{
            "Name": project_name,
            "Type": "Runtime",
            "LoadingPhase": "Default",
            "AdditionalDependencies": ["Engine"],
        }]

        if preset["install_unreal_python_engine"]:
            # now we need to fix python path in:
            # `UnrealEnginePython.Build.cs`
            # to point to our python
            with open(os.path.join(uep_path, "Source", "UnrealEnginePython",
                                   "UnrealEnginePython.Build.cs"),
                      mode="r") as f:
                build_file = f.read()

            fix = build_file.replace(
                'private string pythonHome = "";',
                'private string pythonHome = "{}";'.format(
                    sys.base_prefix.replace("\\", "/")))

            with open(os.path.join(uep_path, "Source", "UnrealEnginePython",
                                   "UnrealEnginePython.Build.cs"),
                      mode="w") as f:
                f.write(fix)

    # write project file
    project_file = os.path.join(pr_dir, "{}.uproject".format(project_name))
    with open(project_file, mode="w") as pf:
        json.dump(data, pf, indent=4)

    # UE < 4.26 have Python2 by default, so we need PySide
    # but we will not need it in 4.26 and up
    if int(ue_version.split(".")[1]) < 26:
        # ensure we have PySide installed in engine
        # TODO: make it work for other platforms � �
        if platform.system().lower() == "windows":
            python_path = os.path.join(engine_path, "Engine", "Binaries",
                                       "ThirdParty", "Python", "Win64",
                                       "python.exe")

            subprocess.run([python_path, "-m", "pip", "install", "pyside"])

    if dev_mode or preset["dev_mode"]:
        _prepare_cpp_project(project_file, engine_path)
예제 #9
0
    def launch(self, session, entities, event):
        '''Callback method for custom action.'''
        with_childrens = True
        if self.without_interface is False:
            if "values" not in event["data"]:
                return
            with_childrens = event["data"]["values"]["children_included"]

        entity = entities[0]
        if entity.entity_type.lower() == "project":
            proj = entity
        else:
            proj = entity["project"]
        project_name = proj["full_name"]
        project_code = proj["name"]

        if entity.entity_type.lower() == 'project' and with_childrens is False:
            return {'success': True, 'message': 'Nothing was created'}

        all_entities = []
        all_entities.append(entity)
        if with_childrens:
            all_entities = self.get_notask_children(entity)

        anatomy = Anatomy(project_name)
        project_settings = get_project_settings(project_name)

        work_keys = ["work", "folder"]
        work_template = anatomy.templates
        for key in work_keys:
            work_template = work_template[key]
        work_has_apps = "{app" in work_template

        publish_keys = ["publish", "folder"]
        publish_template = anatomy.templates
        for key in publish_keys:
            publish_template = publish_template[key]
        publish_has_apps = "{app" in publish_template

        tools_settings = project_settings["global"]["tools"]
        app_presets = tools_settings["Workfiles"]["sw_folders"]
        app_manager_apps = None
        if app_presets and (work_has_apps or publish_has_apps):
            app_manager_apps = ApplicationManager().applications

        cached_apps = {}
        collected_paths = []
        for entity in all_entities:
            if entity.entity_type.lower() == "project":
                continue
            ent_data = {
                "project": {
                    "name": project_name,
                    "code": project_code
                }
            }

            ent_data["asset"] = entity["name"]

            parents = entity["link"][1:-1]
            hierarchy_names = [p["name"] for p in parents]
            hierarchy = ""
            if hierarchy_names:
                hierarchy = os.path.sep.join(hierarchy_names)
            ent_data["hierarchy"] = hierarchy

            tasks_created = False
            for child in entity["children"]:
                if child["object_type"]["name"].lower() != "task":
                    continue
                tasks_created = True
                task_type_name = child["type"]["name"].lower()
                task_data = ent_data.copy()
                task_data["task"] = child["name"]

                apps = []
                if app_manager_apps:
                    possible_apps = app_presets.get(task_type_name) or []
                    for app_name in possible_apps:

                        if app_name in cached_apps:
                            apps.append(cached_apps[app_name])
                            continue

                        app_def = app_manager_apps.get(app_name)
                        if app_def and app_def.is_host:
                            app_dir = app_def.host_name
                        else:
                            app_dir = app_name
                        cached_apps[app_name] = app_dir
                        apps.append(app_dir)

                # Template wok
                if work_has_apps:
                    app_data = task_data.copy()
                    for app in apps:
                        app_data["app"] = app
                        collected_paths.append(
                            self.compute_template(anatomy, app_data,
                                                  work_keys))
                else:
                    collected_paths.append(
                        self.compute_template(anatomy, task_data, work_keys))

                # Template publish
                if publish_has_apps:
                    app_data = task_data.copy()
                    for app in apps:
                        app_data["app"] = app
                        collected_paths.append(
                            self.compute_template(anatomy, app_data,
                                                  publish_keys))
                else:
                    collected_paths.append(
                        self.compute_template(anatomy, task_data,
                                              publish_keys))

            if not tasks_created:
                # create path for entity
                collected_paths.append(
                    self.compute_template(anatomy, ent_data, work_keys))
                collected_paths.append(
                    self.compute_template(anatomy, ent_data, publish_keys))

        if len(collected_paths) == 0:
            return {
                "success": True,
                "message": "No project folders to create."
            }

        self.log.info("Creating folders:")

        for path in set(collected_paths):
            self.log.info(path)
            if not os.path.exists(path):
                os.makedirs(path)

        return {
            "success": True,
            "message": "Successfully created project folders."
        }
예제 #10
0
    def load(self, context, name, namespace, options):

        import maya.cmds as cmds
        import avalon.maya.lib as lib
        from avalon.maya.pipeline import containerise
        import mtoa.ui.arnoldmenu
        import pymel.core as pm

        version = context['version']
        version_data = version.get("data", {})

        self.log.info("version_data: {}\n".format(version_data))

        frameStart = version_data.get("frameStart", None)

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

        # cmds.loadPlugin("gpuCache", quiet=True)

        # Root group
        label = "{}:{}".format(namespace, name)
        root = pm.group(name=label, empty=True)

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

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

        # Create transform with shape
        transform_name = label + "_ASS"
        # transform = pm.createNode("transform", name=transform_name,
        #                             parent=root)

        standinShape = pm.PyNode(mtoa.ui.arnoldmenu.createStandIn())
        standin = standinShape.getParent()
        standin.rename(transform_name)

        pm.parent(standin, root)

        # Set the standin filepath
        standinShape.dso.set(self.fname)
        if frameStart is not None:
            standinShape.useFrameExtension.set(1)

        nodes = [root, standin]
        self[:] = nodes

        return containerise(
            name=name,
            namespace=namespace,
            nodes=nodes,
            context=context,
            loader=self.__class__.__name__)
예제 #11
0
import os
from pype.api import get_project_settings
import pype.hosts.maya.api.lib as mlib
from maya import cmds

print("starting PYPE usersetup")

# build a shelf
settings = get_project_settings(os.environ['AVALON_PROJECT'])
shelf_preset = settings['maya'].get('project_shelf')

if shelf_preset:
    project = os.environ["AVALON_PROJECT"]

    icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], project,
                             "icons")
    icon_path = os.path.abspath(icon_path)

    for i in shelf_preset['imports']:
        import_string = "from {} import {}".format(project, i)
        print(import_string)
        exec(import_string)

cmds.evalDeferred(
    "mlib.shelf(name=shelf_preset['name'], iconPath=icon_path, preset=shelf_preset)"
)

print("finished PYPE usersetup")
예제 #12
0
    def process_reference(self, context, name, namespace, options):

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

        version = context['version']
        version_data = version.get("data", {})

        self.log.info("version_data: {}\n".format(version_data))

        frameStart = version_data.get("frameStart", None)

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

        with maya.maintained_selection():

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

            if frameStart is not None:
                proxyPath_base = os.path.splitext(proxyPath_base)[0]

                publish_folder = os.path.split(path)[0]
                files_in_folder = os.listdir(publish_folder)
                collections, remainder = clique.assemble(files_in_folder)

                if collections:
                    hashes = collections[0].padding * '#'
                    coll = collections[0].format('{head}[index]{tail}')
                    filename = coll.replace('[index]', hashes)

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

            proxyPath = proxyPath_base + ".ma"
            self.log.info

            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)

            settings = get_project_settings(os.environ['AVALON_PROJECT'])
            colors = settings['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
예제 #13
0
    def load(self, context, name, namespace, data):

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

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

        # Check if viewport drawing engine is Open GL Core (compat)
        render_engine = None
        compatible = "OpenGLCoreProfileCompat"
        if cmds.optionVar(exists="vp2RenderingEngine"):
            render_engine = cmds.optionVar(query="vp2RenderingEngine")

        if not render_engine or render_engine != compatible:
            raise RuntimeError("Current scene's settings are incompatible."
                               "See Preferences > Display > Viewport 2.0 to "
                               "set the render engine to '%s'" % compatible)

        asset = context['asset']
        version = context["version"]

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

        # Root group
        label = "{}:{}".format(namespace, name)
        root = cmds.group(name=label, empty=True)

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

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

        # Create VR
        grid_node = cmds.createNode("VRayVolumeGrid",
                                    name="{}VVGShape".format(label),
                                    parent=root)

        # Set attributes
        cmds.setAttr("{}.inFile".format(grid_node), self.fname, type="string")
        cmds.setAttr("{}.inReadOffset".format(grid_node),
                     version["startFrames"])

        nodes = [root, grid_node]
        self[:] = nodes

        return containerise(
            name=name,
            namespace=namespace,
            nodes=nodes,
            context=context,
            loader=self.__class__.__name__)
예제 #14
0
    def launch(self, session, event):
        if not event.get("data"):
            return

        entities_info = event["data"].get("entities")
        if not entities_info:
            return

        # load shell scripts presets
        tmp_by_project_name = {}
        for entity_info in entities_info:
            if entity_info.get('entity_type') != 'Appointment':
                continue

            task_entity, user_entity = self._get_task_and_user(
                session, entity_info.get('action'), entity_info.get('changes'))

            if not task_entity or not user_entity:
                self.log.error("Task or User was not found.")
                continue

            # format directories to pass to shell script
            project_name = task_entity["project"]["full_name"]
            project_data = tmp_by_project_name.get(project_name) or {}
            if "scripts_by_action" not in project_data:
                project_settings = get_project_settings(project_name)
                _settings = (
                    project_settings["ftrack"]["events"]["user_assignment"])
                project_data["scripts_by_action"] = _settings.get("scripts")
                tmp_by_project_name[project_name] = project_data

            scripts_by_action = project_data["scripts_by_action"]
            if not scripts_by_action:
                continue

            if "anatomy" not in project_data:
                project_data["anatomy"] = Anatomy(project_name)
                tmp_by_project_name[project_name] = project_data

            anatomy = project_data["anatomy"]
            data = self._get_template_data(task_entity)
            anatomy_filled = anatomy.format(data)
            # formatting work dir is easiest part as we can use whole path
            work_dir = anatomy_filled["work"]["folder"]
            # we also need publish but not whole
            anatomy_filled.strict = False
            publish = anatomy_filled["publish"]["folder"]

            # now find path to {asset}
            m = re.search("(^.+?{})".format(data["asset"]), publish)

            if not m:
                msg = 'Cannot get part of publish path {}'.format(publish)
                self.log.error(msg)
                return {'success': False, 'message': msg}
            publish_dir = m.group(1)

            username = user_entity["username"]
            event_entity_action = entity_info["action"]
            for script in scripts_by_action.get(event_entity_action):
                self.log.info(("[{}] : running script for user {}").format(
                    event_entity_action, username))
                self._run_script(script, [username, work_dir, publish_dir])

        return True
예제 #15
0
    def load(self, context, name=None, namespace=None, data=None):

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

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

        # Check if the plugin for redshift is available on the pc
        try:
            cmds.loadPlugin("redshift4maya", quiet=True)
        except Exception as exc:
            self.log.error("Encountered exception:\n%s" % exc)
            return

        # Check if viewport drawing engine is Open GL Core (compat)
        render_engine = None
        compatible = "OpenGL"
        if cmds.optionVar(exists="vp2RenderingEngine"):
            render_engine = cmds.optionVar(query="vp2RenderingEngine")

        if not render_engine or not render_engine.startswith(compatible):
            raise RuntimeError("Current scene's settings are incompatible."
                               "See Preferences > Display > Viewport 2.0 to "
                               "set the render engine to '%s<type>'" %
                               compatible)

        asset = context['asset']

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

        # Root group
        label = "{}:{}".format(namespace, name)
        root = cmds.group(name=label, empty=True)

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

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

        # Create VR
        volume_node = cmds.createNode("RedshiftVolumeShape",
                                      name="{}RVSShape".format(label),
                                      parent=root)

        cmds.setAttr("{}.fileName".format(volume_node),
                     self.fname,
                     type="string")

        nodes = [root, volume_node]
        self[:] = nodes

        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
예제 #16
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
예제 #17
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