def refresh(self): has_families = False presets = config.get_presets().get('standalone_publish', {}) for key, creator in presets.get('families', {}).items(): creator = namedtuple("Creator", creator.keys())(*creator.values()) 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 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) presets = config.get_presets(project=os.environ['AVALON_PROJECT']) colors = presets['plugins']['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__)
def get_build_presets(self, task_name): """ Returns presets to build workfile for task name. Presets are loaded for current project set in io.Session["AVALON_PROJECT"], filtered by registered host and entered task name. :param task_name: Task name used for filtering build presets. :type task_name: str :return: preset per eneter task :rtype: dict | None """ host_name = avalon.api.registered_host().__name__.rsplit(".", 1)[-1] presets = config.get_presets(io.Session["AVALON_PROJECT"]) # Get presets for host build_presets = (presets["plugins"].get(host_name, {}).get("workfile_build")) if not build_presets: return task_name_low = task_name.lower() per_task_preset = None for preset in build_presets: preset_tasks = preset.get("tasks") or [] preset_tasks_low = [task.lower() for task in preset_tasks] if task_name_low in preset_tasks_low: per_task_preset = preset break return per_task_preset
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
def custom_attributes_from_file(self, session, event): presets = config.get_presets()['ftrack']['ftrack_custom_attributes'] for cust_attr_data in presets: cust_attr_name = cust_attr_data.get('label', cust_attr_data.get('key')) try: data = {} # Get key, label, type data.update(self.get_required(cust_attr_data)) # Get hierachical/ entity_type/ object_id data.update(self.get_entity_type(cust_attr_data)) # Get group, default, security roles data.update(self.get_optional(cust_attr_data)) # Process data self.process_attribute(data) except CustAttrException as cae: if cust_attr_name: msg = 'Custom attribute error "{}" - {}'.format( cust_attr_name, str(cae)) else: msg = 'Custom attribute error - {}'.format(str(cae)) self.log.warning(msg, exc_info=True) self.show_message(event, msg) return True
def get_families(): families = [] paths = config.get_presets().get("djv_view", {}).get("config", {}).get("djv_paths", []) for path in paths: if os.path.exists(path): families.append("*") break return families
def add_review_presets_config(): returning = {"families": list(), "representations": list()} review_presets = config.get_presets()["plugins"]["global"]["publish"].get( "ExtractReview", {}) outputs = review_presets.get("outputs", {}) # for output, properities in outputs.items(): returning["representations"].append(output) returning["families"] += properities.get("families", []) return returning
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) 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(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__)
def __init__(self, session, plugins_presets): '''Expects a ftrack_api.Session instance''' super().__init__(session, plugins_presets) self.djv_path = None self.config_data = config.get_presets()['djv_view']['config'] self.set_djv_path() if self.djv_path is None: return self.allowed_types = self.config_data.get('file_ext', ["img", "mov", "exr"])
def __init__(self): super(StaticsServer, self).__init__() self.qaction = None self.failed_icon = None self._is_running = False self.log = Logger().get_logger(self.__class__.__name__) try: self.presets = config.get_presets().get('services', {}).get('statics_server') except Exception: self.presets = {'default_port': 8010, 'exclude_ports': []} self.port = self.find_port()
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) presets = config.get_presets(project=os.environ['AVALON_PROJECT']) colors = presets['plugins']['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__)
def __init__(self, session, plugins_presets): """ Constructor :param session: ftrack Session :type session: :class:`ftrack_api.Session` """ super().__init__(session, plugins_presets) self.rv_path = None self.config_data = None # RV_HOME should be set if properly installed if os.environ.get('RV_HOME'): self.rv_path = os.path.join(os.environ.get('RV_HOME'), 'bin', 'rv') else: # if not, fallback to config file location if "rv" in config.get_presets(): self.config_data = config.get_presets()['rv']['config'] self.set_rv_path() if self.rv_path is None: return self.allowed_types = self.config_data.get('file_ext', ["img", "mov", "exr"])
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
def refresh(self): listing = self.data["Listing"] asset = self.data["Asset"] asset.setText(api.Session["AVALON_ASSET"]) listing.clear() has_families = False creators = api.discover(api.Creator) for creator in creators: label = creator.label or creator.family item = QtWidgets.QListWidgetItem(label) item.setData(QtCore.Qt.ItemIsEnabled, True) item.setData(HelpRole, creator.__doc__) item.setData(FamilyRole, creator.family) item.setData(PluginRole, creator) item.setData(ExistsRole, False) listing.addItem(item) has_families = True if not has_families: item = QtWidgets.QListWidgetItem("No registered families") item.setData(QtCore.Qt.ItemIsEnabled, False) listing.addItem(item) config_data = config.get_presets()["tools"]["creator"] item = None family_type = None task_name = io.Session.get('AVALON_TASK', None) if task_name: for key, value in config_data.items(): for t_name in value: if t_name in task_name.lower(): family_type = key break if family_type: break if family_type: items = listing.findItems(family_type, QtCore.Qt.MatchExactly) if len(items) > 0: item = items[0] listing.setCurrentItem(item) if not item: listing.setCurrentItem(listing.item(0))
def filter_pyblish_plugins(plugins): """ This servers as plugin filter / modifier for pyblish. It will load plugin definitions from presets and filter those needed to be excluded. :param plugins: Dictionary of plugins produced by :mod:`pyblish-base` `discover()` method. :type plugins: Dict """ from pypeapp import config from pyblish import api host = api.current_host() presets = config.get_presets().get('plugins', {}) # iterate over plugins for plugin in plugins[:]: # skip if there are no presets to process if not presets: continue file = os.path.normpath(inspect.getsourcefile(plugin)) file = os.path.normpath(file) # host determined from path host_from_file = file.split(os.path.sep)[-3:-2][0] plugin_kind = file.split(os.path.sep)[-2:-1][0] try: config_data = presets[host]["publish"][plugin.__name__] except KeyError: try: config_data = presets[host_from_file][plugin_kind][ plugin.__name__] # noqa: E501 except KeyError: continue for option, value in config_data.items(): if option == "enabled" and value is False: log.info('removing plugin {}'.format(plugin.__name__)) plugins.remove(plugin) else: log.info('setting {}:{} on plugin {}'.format( option, value, plugin.__name__)) setattr(plugin, option, value)
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
def launch(self, session, event): # load shell scripts presets presets = config.get_presets()['ftrack'].get("user_assigment_event") if not presets: return for entity in event.get('data', {}).get('entities', []): if entity.get('entity_type') != 'Appointment': continue task, user = self._get_task_and_user(session, entity.get('action'), entity.get('changes')) if not task or not user: self.log.error( 'Task or User was not found.') continue data = self._get_template_data(task) # format directories to pass to shell script anatomy = Anatomy(data["project"]["name"]) # formatting work dir is easiest part as we can use whole path work_dir = anatomy.format(data)['avalon']['work'] # we also need publish but not whole publish = anatomy.format_all(data)['partial']['avalon']['publish'] # 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) for script in presets.get(entity.get('action')): self.log.info( '[{}] : running script for user {}'.format( entity.get('action'), user["username"])) self._run_script(script, [user["username"], work_dir, publish_dir]) return True
def load(self, context, name, namespace, data): from avalon.maya.pipeline import containerise from pype.maya.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 = self.create_vray_proxy(name, filename=self.fname) self[:] = nodes if not nodes: return 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("{0}_{1}.useOutlinerColor".format(name, "GRP"), 1) cmds.setAttr("{0}_{1}.outlinerColor".format(name, "GRP"), c[0], c[1], c[2]) return containerise( name=name, namespace=namespace, nodes=nodes, context=context, loader=self.__class__.__name__)
def launch(self, session, entities, event): entity = entities[0] if entity.entity_type.lower() == 'project': project = entity else: project = entity['project'] presets = config.get_presets()['tools']['project_folder_structure'] try: # Get paths based on presets basic_paths = self.get_path_items(presets) self.create_folders(basic_paths, entity) self.create_ftrack_entities(basic_paths, project) except Exception as e: session.rollback() return {'success': False, 'message': str(e)} return True
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds # Get family type from the context try: family = context["representation"]["context"]["family"] except ValueError: family = "camera" cmds.loadPlugin("AbcImport.mll", quiet=True) groupName = "{}:{}".format(namespace, name) nodes = cmds.file(self.fname, namespace=namespace, sharedReferenceFile=False, groupReference=True, groupName="{}:{}".format(namespace, name), reference=True, returnNewNodes=True) cameras = cmds.ls(nodes, type="camera") 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]) # Check the Maya version, lockTransform has been introduced since # Maya 2016.5 Ext 2 version = int(cmds.about(version=True)) if version >= 2016: for camera in cameras: cmds.camera(camera, edit=True, lockTransform=True) else: self.log.warning("This version of Maya does not support locking of" " transforms of cameras.") self[:] = nodes return nodes
def __init__(self): self.qaction = None self.failed_icon = None self._is_running = False try: self.presets = config.get_presets()["services"]["rest_api"] except Exception: self.presets = {"default_port": 8011, "exclude_ports": []} log.debug(("There are not set presets for RestApiModule." " Using defaults \"{}\"").format(str(self.presets))) port = self.find_port() self.rest_api_thread = RestApiThread(self, port) statics_dir = os.path.sep.join([os.environ["PYPE_MODULE_ROOT"], "res"]) self.register_statics("/res", statics_dir) os.environ["PYPE_STATICS_SERVER"] = "{}/res".format( os.environ["PYPE_REST_API_URL"])
def on_start(self): project_name = io.Session['AVALON_PROJECT'] project_query = 'Project where full_name is "{}"'.format(project_name) if self.session is None: session = ftrack_api.Session() self.session = session else: session = self.session ft_project = session.query(project_query).one() schema_name = ft_project['project_schema']['name'] # Load config schemas_items = config.get_presets().get('ftrack', {}).get( 'project_schemas', {}) # Get info if it is silo project self.silos = io.distinct("silo") if self.silos and None in self.silos: self.silos = None key = "default" if schema_name in schemas_items: key = schema_name self.config_data = schemas_items[key] # set outlink input_outlink = self.data['inputs']['outlink'] checkbox_outlink = self.data['inputs']['outlink_cb'] outlink_text = io.Session.get('AVALON_ASSET', '') checkbox_outlink.setChecked(True) if outlink_text == '': outlink_text = '< No context >' checkbox_outlink.setChecked(False) checkbox_outlink.hide() input_outlink.setText(outlink_text) # load asset build types self.load_assetbuild_types() # Load task templates self.load_task_templates() self.data["model"]["assets"].refresh() self.on_asset_changed()
def _get_template_id(renderer): """ Return muster template ID based on renderer name. :param renderer: renderer name :type renderer: str :returns: muster template id :rtype: int """ templates = config.get_presets()["muster"]["templates_mapping"] if not templates: raise RuntimeError(("Muster template mapping missing in pype-config " "`presets/muster/templates_mapping.json`")) try: template_id = templates[renderer] except KeyError: raise RuntimeError("Unmapped renderer - missing template id") return template_id
def process(self, context): presets = config.get_presets() try: # try if it is not in projects custom directory # `{PYPE_PROJECT_CONFIGS}/[PROJECT_NAME]/init.json` # init.json define preset names to be used p_init = presets["init"] presets["colorspace"] = presets["colorspace"][p_init["colorspace"]] presets["dataflow"] = presets["dataflow"][p_init["dataflow"]] except KeyError: self.log.warning("No projects custom preset available...") presets["colorspace"] = presets["colorspace"]["default"] presets["dataflow"] = presets["dataflow"]["default"] self.log.info( "Presets `colorspace` and `dataflow` loaded from `default`...") context.data["presets"] = presets # self.log.info(context.data["presets"]) return
def presets_by_hosts(self): # Get global filters as base presets = config.get_presets().get("plugins", {}) result = presets.get("global", {}).get("filter", {}) hosts = pyblish.api.registered_hosts() for host in hosts: host_presets = presets.get(host, {}).get("filter") 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
def get_default_project(self): # looks into presets if any default library is set # - returns name of library from presets if exists in db # - if was not found or not set then returns first existing project # - returns `None` if any project was found in db name = None presets = config.get_presets().get("tools", {}).get("library_loader", {}) if self.show_projects: name = presets.get("default_project") if self.show_libraries and not name: name = presets.get("default_library") projects = self.get_filtered_projects() if name and name in projects: return name elif len(projects) > 0: return projects[0] return None
def __init__(self): super(RestApiServer, self).__init__() self.registered_callbacks = { RestMethods.GET: collections.defaultdict(list), RestMethods.POST: collections.defaultdict(list), RestMethods.PUT: collections.defaultdict(list), RestMethods.PATCH: collections.defaultdict(list), RestMethods.DELETE: collections.defaultdict(list) } self.qaction = None self.failed_icon = None self._is_running = False try: self.presets = config.get_presets().get("services", {}).get("rest_api", {}) except Exception: self.presets = {"default_port": 8011, "exclude_ports": []} self.port = self.find_port()
def patched_discover(superclass): """ Monkey patched version of :func:`avalon.api.discover()`. It allows us to load presets on plugins being discovered. """ # run original discover and get plugins plugins = _original_discover(superclass) # determine host application to use for finding presets if avalon.registered_host() is None: return plugins host = avalon.registered_host().__name__.split(".")[-1] # map plugin superclass to preset json. Currenly suppoted is load and # create (avalon.api.Loader and avalon.api.Creator) plugin_type = "undefined" if superclass.__name__.split(".")[-1] == "Loader": plugin_type = "load" elif superclass.__name__.split(".")[-1] == "Creator": plugin_type = "create" print(">>> trying to find presets for {}:{} ...".format(host, plugin_type)) try: config_data = config.get_presets()['plugins'][host][plugin_type] except KeyError: print("*** no presets found.") else: for plugin in plugins: if plugin.__name__ in config_data: print(">>> We have preset for {}".format(plugin.__name__)) for option, value in config_data[plugin.__name__].items(): if option == "enabled" and value is False: setattr(plugin, "active", False) print(" - is disabled by preset") else: setattr(plugin, option, value) print(" - setting `{}`: `{}`".format(option, value)) return plugins
def launch(self, session, entities, event): entity = entities[0] project = self.get_project_from_entity(entity) project_folder_presets = (config.get_presets().get( "tools", {}).get("project_folder_structure")) if not project_folder_presets: return { "success": False, "message": "Project structure presets are not set." } try: # Get paths based on presets basic_paths = self.get_path_items(project_folder_presets) anatomy = Anatomy(project["full_name"]) self.create_folders(basic_paths, entity, project, anatomy) self.create_ftrack_entities(basic_paths, project) except Exception as exc: session.rollback() return {"success": False, "message": str(exc)} return True
def __init__(self, parent): super().__init__() self.parent_widget = parent self.presets = config.get_presets()['standalone_publish'] self.setAcceptDrops(True) layout = QtWidgets.QVBoxLayout(self) self.components_list = ComponentsList(self) layout.addWidget(self.components_list) self.drop_widget = DropEmpty(self) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.drop_widget.sizePolicy().hasHeightForWidth()) self.drop_widget.setSizePolicy(sizePolicy) layout.addWidget(self.drop_widget) self._refresh_view()