From 27cb6512cf708c8187465e52c66f84e837b3f521 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Dec 2022 12:19:30 +0100 Subject: [PATCH 01/27] added more collectors of plugin types and use them on openpype plugin installation --- openpype/modules/base.py | 61 ++++++++++++++++++++----- openpype/modules/interfaces.py | 73 +++++++++++++++++++++--------- openpype/pipeline/context_tools.py | 23 ++++++---- 3 files changed, 117 insertions(+), 40 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 4761462df0..0fd21492e8 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -786,23 +786,15 @@ class ModulesManager: ).format(expected_keys, " | ".join(msg_items))) return output - def collect_creator_plugin_paths(self, host_name): - """Helper to collect creator plugin paths from modules. - - Args: - host_name (str): For which host are creators meants. - - Returns: - list: List of creator plugin paths. - """ - # Output structure + def _collect_plugin_paths(self, method_name, *args, **kwargs): output = [] for module in self.get_enabled_modules(): # Skip module that do not inherit from `IPluginPaths` if not isinstance(module, IPluginPaths): continue - paths = module.get_creator_plugin_paths(host_name) + method = getattr(module, method_name) + paths = method(*args, **kwargs) if paths: # Convert to list if value is not list if not isinstance(paths, (list, tuple, set)): @@ -810,6 +802,53 @@ class ModulesManager: output.extend(paths) return output + def collect_create_plugin_paths(self, host_name): + """Helper to collect creator plugin paths from modules. + + Args: + host_name (str): For which host are creators meant. + + Returns: + list: List of creator plugin paths. + """ + + return self._collect_plugin_paths( + "get_create_plugin_paths", + host_name + ) + + collect_creator_plugin_paths = collect_create_plugin_paths + + def collect_load_plugin_paths(self, host_name): + """Helper to collect load plugin paths from modules. + + Args: + host_name (str): For which host are load plugins meant. + + Returns: + list: List of load plugin paths. + """ + + return self._collect_plugin_paths( + "get_load_plugin_paths", + host_name + ) + + def collect_publish_plugin_paths(self, host_name): + """Helper to collect load plugin paths from modules. + + Args: + host_name (str): For which host are load plugins meant. + + Returns: + list: List of pyblish plugin paths. + """ + + return self._collect_plugin_paths( + "get_publish_plugin_paths", + host_name + ) + def get_host_module(self, host_name): """Find host module by host name. diff --git a/openpype/modules/interfaces.py b/openpype/modules/interfaces.py index f92ec6bf2d..d2c0dd5582 100644 --- a/openpype/modules/interfaces.py +++ b/openpype/modules/interfaces.py @@ -24,7 +24,7 @@ class OpenPypeInterface: Child classes of OpenPypeInterface may be used as mixin in different OpenPype modules which means they have to have implemented methods defined - in the interface. By default interface does not have any abstract parts. + in the interface. By default, interface does not have any abstract parts. """ pass @@ -44,40 +44,71 @@ class IPluginPaths(OpenPypeInterface): def get_plugin_paths(self): pass - def get_creator_plugin_paths(self, host_name): - """Retreive creator plugin paths. + def _get_plugin_paths_by_type(self, plugin_type): + paths = self.get_plugin_paths() + if not paths or plugin_type not in paths: + return [] - Give addons ability to add creator plugin paths based on host name. + paths = paths[plugin_type] + if not paths: + return [] - NOTES: - - Default implementation uses 'get_plugin_paths' and always return - all creator plugins. - - Host name may help to organize plugins by host, but each creator - alsomay have host filtering. + if not isinstance(paths, (list, tuple, set)): + paths = [paths] + return paths + + def get_create_plugin_paths(self, host_name): + """Receive create plugin paths. + + Give addons ability to add create plugin paths based on host name. + + Notes: + Default implementation uses 'get_plugin_paths' and always return + all create plugin paths. Args: host_name (str): For which host are the plugins meant. """ - paths = self.get_plugin_paths() - if not paths or "create" not in paths: - return [] + return self._get_plugin_paths_by_type("create") - create_paths = paths["create"] - if not create_paths: - return [] + def get_load_plugin_paths(self, host_name): + """Receive load plugin paths. - if not isinstance(create_paths, (list, tuple, set)): - create_paths = [create_paths] - return create_paths + Give addons ability to add load plugin paths based on host name. + + Notes: + Default implementation uses 'get_plugin_paths' and always return + all load plugin paths. + + Args: + host_name (str): For which host are the plugins meant. + """ + + return self._get_plugin_paths_by_type("load") + + def get_publish_plugin_paths(self, host_name): + """Receive publish plugin paths. + + Give addons ability to add publish plugin paths based on host name. + + Notes: + Default implementation uses 'get_plugin_paths' and always return + all publish plugin paths. + + Args: + host_name (str): For which host are the plugins meant. + """ + + return self._get_plugin_paths_by_type("publish") class ILaunchHookPaths(OpenPypeInterface): """Module has launch hook paths to return. - Modules does not have to inherit from this interface (changed 8.11.2022). - Module just have to have implemented 'get_launch_hook_paths' to be able use - the advantage. + Modules don't have to inherit from this interface (changed 8.11.2022). + Module just have to have implemented 'get_launch_hook_paths' to be able to + use the advantage. Expected result is list of paths. ["path/to/launch_hooks_dir"] diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 0ec19d50fe..da0ce8ecf4 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -158,17 +158,24 @@ def install_openpype_plugins(project_name=None, host_name=None): pyblish.api.register_discovery_filter(filter_pyblish_plugins) register_loader_plugin_path(LOAD_PATH) - modules_manager = _get_modules_manager() - publish_plugin_dirs = modules_manager.collect_plugin_paths()["publish"] - for path in publish_plugin_dirs: - pyblish.api.register_plugin_path(path) - if host_name is None: host_name = os.environ.get("AVALON_APP") - creator_paths = modules_manager.collect_creator_plugin_paths(host_name) - for creator_path in creator_paths: - register_creator_plugin_path(creator_path) + modules_manager = _get_modules_manager() + publish_plugin_dirs = modules_manager.collect_publish_plugin_paths( + host_name) + for path in publish_plugin_dirs: + pyblish.api.register_plugin_path(path) + + create_plugin_paths = modules_manager.collect_create_plugin_paths( + host_name) + for path in create_plugin_paths: + register_creator_plugin_path(path) + + load_plugin_paths = modules_manager.collect_load_plugin_paths( + host_name) + for path in load_plugin_paths: + register_loader_plugin_path(path) if project_name is None: project_name = os.environ.get("AVALON_PROJECT") From 853bc962179713a195c7630423a59e050306917c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 11:25:43 +0100 Subject: [PATCH 02/27] nuke: fix subset name search in imageio override nodes --- openpype/hosts/nuke/api/lib.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index bde06e4fd7..cc5e0a94a1 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -611,7 +611,7 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset): if ( onode["subsets"] - and not any(re.search(s, subset) for s in onode["subsets"]) + and not any(re.search(s, subset.lower()) for s in onode["subsets"]) ): continue @@ -694,7 +694,8 @@ def get_imageio_node_override_setting( # find matching override node override_imageio_node = None for onode in override_nodes: - log.info(onode) + log.debug("__ onode: {}".format(onode)) + log.debug("__ subset: {}".format(subset)) if node_class not in onode["nukeNodeClass"]: continue @@ -703,7 +704,7 @@ def get_imageio_node_override_setting( if ( onode["subsets"] - and not any(re.search(s, subset) for s in onode["subsets"]) + and not any(re.search(s, subset.lower()) for s in onode["subsets"]) ): continue From a7a2731f05a00a8436ea9153e1ce03c560346148 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 12:35:41 +0100 Subject: [PATCH 03/27] nuke: subset with mixed letter sizes --- openpype/hosts/nuke/api/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index cc5e0a94a1..1e5e7fc54b 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -611,7 +611,7 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset): if ( onode["subsets"] - and not any(re.search(s, subset.lower()) for s in onode["subsets"]) + and not any(re.search(s.lower(), subset.lower()) for s in onode["subsets"]) ): continue @@ -704,7 +704,7 @@ def get_imageio_node_override_setting( if ( onode["subsets"] - and not any(re.search(s, subset.lower()) for s in onode["subsets"]) + and not any(re.search(s.lower(), subset.lower()) for s in onode["subsets"]) ): continue From a9d5beecfaf17610aa9249ff88132cd768b15f5e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 12:46:27 +0100 Subject: [PATCH 04/27] flake8 --- openpype/hosts/nuke/api/lib.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 1e5e7fc54b..7ee30bf273 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -611,7 +611,10 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset): if ( onode["subsets"] - and not any(re.search(s.lower(), subset.lower()) for s in onode["subsets"]) + and not any( + re.search(s.lower(), subset.lower()) + for s in onode["subsets"] + ) ): continue @@ -704,7 +707,10 @@ def get_imageio_node_override_setting( if ( onode["subsets"] - and not any(re.search(s.lower(), subset.lower()) for s in onode["subsets"]) + and not any( + re.search(s.lower(), subset.lower()) + for s in onode["subsets"] + ) ): continue From 1a75a6a041d83a2619b280af10b8c172338c9687 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 16:19:28 +0100 Subject: [PATCH 05/27] flame: settings for layer renaming --- .../settings/defaults/project_settings/flame.json | 6 +++++- .../schemas/projects_schema/schema_project_flame.json | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json index 34baf9ba06..9966fdbd33 100644 --- a/openpype/settings/defaults/project_settings/flame.json +++ b/openpype/settings/defaults/project_settings/flame.json @@ -142,7 +142,11 @@ "exr16fpdwaa" ], "reel_name": "OP_LoadedReel", - "clip_name_template": "{batch}_{asset}_{subset}<_{output}>" + "clip_name_template": "{batch}_{asset}_{subset}<_{output}>", + "layer_rename_template": "{asset}_{subset}<_{output}>", + "layer_rename_patterns": [ + "rgba" + ] } } } \ No newline at end of file diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json index 73664300aa..26a2dce2f5 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json @@ -554,6 +554,17 @@ "type": "text", "key": "clip_name_template", "label": "Clip name template" + }, + { + "type": "text", + "key": "layer_rename_template", + "label": "Layer name template" + }, + { + "type": "list", + "key": "layer_rename_patterns", + "label": "Layer rename patters", + "object_type": "text" } ] } From 42764559330b63c91f6b3e1678bd9f79f0aa88fb Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 16:20:08 +0100 Subject: [PATCH 06/27] flame: added layer renaming to batch loader --- openpype/hosts/flame/api/plugin.py | 56 +++++++++++++++++-- .../flame/plugins/load/load_clip_batch.py | 11 ++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index ca113fd98a..6aaf0c6d80 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -8,7 +8,7 @@ import qargparse from Qt import QtCore, QtWidgets from openpype import style -from openpype.lib import Logger +from openpype.lib import Logger, StringTemplate from openpype.pipeline import LegacyCreator, LoaderPlugin from openpype.settings import get_current_project_settings @@ -775,6 +775,11 @@ class OpenClipSolver(flib.MediaInfoFile): self.feed_colorspace = feed_data.get("colorspace") self.log.debug("feed_version_name: {}".format(self.feed_version_name)) + # layer rename variables + self.layer_rename_template = feed_data["layer_rename_template"] + self.layer_rename_patterns = feed_data["layer_rename_patterns"] + self.context_data = feed_data["context_data"] + # derivate other feed variables self.feed_basename = os.path.basename(feed_path) self.feed_dir = os.path.dirname(feed_path) @@ -813,9 +818,11 @@ class OpenClipSolver(flib.MediaInfoFile): def _create_new_open_clip(self): self.log.info("Building new openClip") - self.log.debug(">> self.clip_data: {}".format(self.clip_data)) for tmp_xml_track in self.clip_data.iter("track"): + # solve track (layer) name + self._rename_track_name(tmp_xml_track) + tmp_xml_feeds = tmp_xml_track.find('feeds') tmp_xml_feeds.set('currentVersion', self.feed_version_name) @@ -850,6 +857,46 @@ class OpenClipSolver(flib.MediaInfoFile): if uid == track_uid: return xml_track + def _rename_track_name(self, xml_track_data): + name_obj = xml_track_data.find("name") + layer_name = name_obj.text + + if ( + self.layer_rename_patterns + and not any( + re.search(lp_.lower(), layer_name.lower()) + for lp_ in self.layer_rename_patterns + ) + ): + return + + formating_data = self._update_formating_data( + layer=layer_name + ) + name_obj.text = StringTemplate( + self.layer_rename_template + ).format(formating_data) + + def _update_formating_data(self, **kwargs): + """ Updating formating data for layer rename + + Attributes: + key=value (optional): will be included to formating data + as {key: value} + Returns: + dict: anatomy context data for formating + """ + self.log.debug(">> self.clip_data: {}".format(self.clip_data)) + clip_name_obj = self.clip_data.find("name") + data = { + "originalBasename": clip_name_obj.text + } + # include version context data + data.update(self.context_data) + # include input kwargs data + data.update(kwargs) + return data + def _update_open_clip(self): self.log.info("Updating openClip ..") @@ -857,11 +904,12 @@ class OpenClipSolver(flib.MediaInfoFile): out_xml = out_xml.getroot() self.log.debug(">> out_xml: {}".format(out_xml)) - self.log.debug(">> self.clip_data: {}".format(self.clip_data)) - # loop tmp tracks updated_any = False for tmp_xml_track in self.clip_data.iter("track"): + # solve track (layer) name + self._rename_track_name(tmp_xml_track) + # get tmp track uid tmp_track_uid = tmp_xml_track.get("uid") self.log.debug(">> tmp_track_uid: {}".format(tmp_track_uid)) diff --git a/openpype/hosts/flame/plugins/load/load_clip_batch.py b/openpype/hosts/flame/plugins/load/load_clip_batch.py index 048ac19431..96db04f6e3 100644 --- a/openpype/hosts/flame/plugins/load/load_clip_batch.py +++ b/openpype/hosts/flame/plugins/load/load_clip_batch.py @@ -25,6 +25,13 @@ class LoadClipBatch(opfapi.ClipLoader): reel_name = "OP_LoadedReel" clip_name_template = "{batch}_{asset}_{subset}<_{output}>" + """ Anatomy keys from version context data and dynamically added: + - {layer} - original layer name token + - {originalBasename} - original clip name taken from file + """ + layer_rename_template = "{asset}_{subset}<_{output}>" + layer_rename_patterns = [] + def load(self, context, name, namespace, options): # get flame objects @@ -40,6 +47,7 @@ class LoadClipBatch(opfapi.ClipLoader): # in case output is not in context replace key to representation if not context["representation"]["context"].get("output"): self.clip_name_template.replace("output", "representation") + self.layer_rename_template.replace("output", "representation") formating_data = deepcopy(context["representation"]["context"]) formating_data["batch"] = self.batch.name.get_value() @@ -69,6 +77,9 @@ class LoadClipBatch(opfapi.ClipLoader): "path": self.fname.replace("\\", "/"), "colorspace": colorspace, "version": "v{:0>3}".format(version_name), + "layer_rename_template": self.layer_rename_template, + "layer_rename_patterns": self.layer_rename_patterns, + "context_data": formating_data } self.log.debug(pformat( loading_context From 99e1c91a7531b0085f34192b50ef179afe22c76b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 9 Dec 2022 16:57:12 +0100 Subject: [PATCH 07/27] flame: enhancing formatting data --- openpype/hosts/flame/api/plugin.py | 4 +++- openpype/hosts/flame/plugins/load/load_clip_batch.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index 6aaf0c6d80..c682d294c5 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -858,6 +858,7 @@ class OpenClipSolver(flib.MediaInfoFile): return xml_track def _rename_track_name(self, xml_track_data): + layer_uid = xml_track_data.get("uid") name_obj = xml_track_data.find("name") layer_name = name_obj.text @@ -871,7 +872,8 @@ class OpenClipSolver(flib.MediaInfoFile): return formating_data = self._update_formating_data( - layer=layer_name + layerName=layer_name, + layerUID=layer_uid ) name_obj.text = StringTemplate( self.layer_rename_template diff --git a/openpype/hosts/flame/plugins/load/load_clip_batch.py b/openpype/hosts/flame/plugins/load/load_clip_batch.py index 96db04f6e3..47d7da2a76 100644 --- a/openpype/hosts/flame/plugins/load/load_clip_batch.py +++ b/openpype/hosts/flame/plugins/load/load_clip_batch.py @@ -26,7 +26,8 @@ class LoadClipBatch(opfapi.ClipLoader): clip_name_template = "{batch}_{asset}_{subset}<_{output}>" """ Anatomy keys from version context data and dynamically added: - - {layer} - original layer name token + - {layerName} - original layer name token + - {layerUID} - original layer UID token - {originalBasename} - original clip name taken from file """ layer_rename_template = "{asset}_{subset}<_{output}>" From d6b384f019e02b341e4c43d938daaa184c3ff4b2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Dec 2022 17:18:28 +0100 Subject: [PATCH 08/27] added deprecation warning for 'get_creator_plugin_paths' --- openpype/modules/interfaces.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openpype/modules/interfaces.py b/openpype/modules/interfaces.py index d2c0dd5582..e3f54f1694 100644 --- a/openpype/modules/interfaces.py +++ b/openpype/modules/interfaces.py @@ -70,6 +70,13 @@ class IPluginPaths(OpenPypeInterface): host_name (str): For which host are the plugins meant. """ + if hasattr(self, "get_creator_plugin_paths"): + # TODO remove in 3.16 + self.log.warning(( + "DEPRECATION WARNING: Using method 'get_creator_plugin_paths'" + " which was renamed to 'get_create_plugin_paths'." + )) + return self.get_creator_plugin_paths(host_name) return self._get_plugin_paths_by_type("create") def get_load_plugin_paths(self, host_name): From 7d2229df4ab5164c98a1b811a06eae818bd04243 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 13 Dec 2022 15:30:59 +0100 Subject: [PATCH 09/27] flame: replicating multilayer rename to reel clip loader --- .../hosts/flame/plugins/load/load_clip.py | 20 ++++++++++++++++++- .../defaults/project_settings/flame.json | 6 +++++- .../projects_schema/schema_project_flame.json | 11 ++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index f8cb7b3e11..2c107de2b4 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -1,3 +1,4 @@ +from copy import deepcopy import os import flame from pprint import pformat @@ -25,6 +26,14 @@ class LoadClip(opfapi.ClipLoader): reel_name = "Loaded" clip_name_template = "{asset}_{subset}<_{output}>" + """ Anatomy keys from version context data and dynamically added: + - {layerName} - original layer name token + - {layerUID} - original layer UID token + - {originalBasename} - original clip name taken from file + """ + layer_rename_template = "{asset}_{subset}<_{output}>" + layer_rename_patterns = [] + def load(self, context, name, namespace, options): # get flame objects @@ -38,8 +47,14 @@ class LoadClip(opfapi.ClipLoader): version_name = version.get("name", None) colorspace = self.get_colorspace(context) + # in case output is not in context replace key to representation + if not context["representation"]["context"].get("output"): + self.clip_name_template.replace("output", "representation") + self.layer_rename_template.replace("output", "representation") + + formating_data = deepcopy(context["representation"]["context"]) clip_name = StringTemplate(self.clip_name_template).format( - context["representation"]["context"]) + formating_data) # convert colorspace with ocio to flame mapping # in imageio flame section @@ -62,6 +77,9 @@ class LoadClip(opfapi.ClipLoader): "path": self.fname.replace("\\", "/"), "colorspace": colorspace, "version": "v{:0>3}".format(version_name), + "layer_rename_template": self.layer_rename_template, + "layer_rename_patterns": self.layer_rename_patterns, + "context_data": formating_data } self.log.debug(pformat( loading_context diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json index 9966fdbd33..337e58ac62 100644 --- a/openpype/settings/defaults/project_settings/flame.json +++ b/openpype/settings/defaults/project_settings/flame.json @@ -119,7 +119,11 @@ ], "reel_group_name": "OpenPype_Reels", "reel_name": "Loaded", - "clip_name_template": "{asset}_{subset}<_{output}>" + "clip_name_template": "{asset}_{subset}<_{output}>", + "layer_rename_template": "{asset}_{subset}<_{output}>", + "layer_rename_patterns": [ + "rgba" + ] }, "LoadClipBatch": { "enabled": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json index 26a2dce2f5..24726f2d07 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_flame.json @@ -512,6 +512,17 @@ "type": "text", "key": "clip_name_template", "label": "Clip name template" + }, + { + "type": "text", + "key": "layer_rename_template", + "label": "Layer name template" + }, + { + "type": "list", + "key": "layer_rename_patterns", + "label": "Layer rename patters", + "object_type": "text" } ] }, From a97f92760086eb34b1d07b4e68b6d850355d49eb Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 13 Dec 2022 21:35:01 +0100 Subject: [PATCH 10/27] fixing logic --- openpype/hosts/flame/plugins/load/load_clip.py | 6 ++++-- openpype/hosts/flame/plugins/load/load_clip_batch.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/flame/plugins/load/load_clip.py b/openpype/hosts/flame/plugins/load/load_clip.py index 2c107de2b4..6f47c23d57 100644 --- a/openpype/hosts/flame/plugins/load/load_clip.py +++ b/openpype/hosts/flame/plugins/load/load_clip.py @@ -49,8 +49,10 @@ class LoadClip(opfapi.ClipLoader): # in case output is not in context replace key to representation if not context["representation"]["context"].get("output"): - self.clip_name_template.replace("output", "representation") - self.layer_rename_template.replace("output", "representation") + self.clip_name_template = self.clip_name_template.replace( + "output", "representation") + self.layer_rename_template = self.layer_rename_template.replace( + "output", "representation") formating_data = deepcopy(context["representation"]["context"]) clip_name = StringTemplate(self.clip_name_template).format( diff --git a/openpype/hosts/flame/plugins/load/load_clip_batch.py b/openpype/hosts/flame/plugins/load/load_clip_batch.py index 47d7da2a76..5975c6e42f 100644 --- a/openpype/hosts/flame/plugins/load/load_clip_batch.py +++ b/openpype/hosts/flame/plugins/load/load_clip_batch.py @@ -47,8 +47,10 @@ class LoadClipBatch(opfapi.ClipLoader): # in case output is not in context replace key to representation if not context["representation"]["context"].get("output"): - self.clip_name_template.replace("output", "representation") - self.layer_rename_template.replace("output", "representation") + self.clip_name_template = self.clip_name_template.replace( + "output", "representation") + self.layer_rename_template = self.layer_rename_template.replace( + "output", "representation") formating_data = deepcopy(context["representation"]["context"]) formating_data["batch"] = self.batch.name.get_value() From 9d76f9d50c52e0208c2bdf3be797c38eeab14dda Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 15 Dec 2022 16:53:03 +0000 Subject: [PATCH 11/27] Implemented workfile importer --- .../blender/plugins/load/import_workfile.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 openpype/hosts/blender/plugins/load/import_workfile.py diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py new file mode 100644 index 0000000000..3b9edbc8c7 --- /dev/null +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -0,0 +1,38 @@ +from pathlib import Path + +import bpy + +from openpype.hosts.blender.api import plugin + + +class ImportBlendLoader(plugin.AssetLoader): + """Import action for Blender (unmanaged) + + Warning: + The loaded content will be unmanaged and is *not* visible in the + scene inventory. It's purely intended to merge content into your scene + so you could also use it as a new base. + + """ + + representations = ["blend"] + families = ["*"] + + label = "Import" + order = 10 + icon = "arrow-circle-down" + color = "#775555" + + def load(self, context, name=None, namespace=None, data=None): + scene = bpy.context.scene + + with bpy.data.libraries.load(self.fname) as (data_from, data_to): + for attr in dir(data_to): + setattr(data_to, attr, getattr(data_from, attr)) + + # Add objects to current scene + # for obj in data_to.objects: + # scene.collection.objects.link(obj) + + # We do not containerize imported content, it remains unmanaged + return From d935b9b689ddff657056cf92cabb5be9a5b0be3f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 15 Dec 2022 16:57:59 +0000 Subject: [PATCH 12/27] Hound fixes --- openpype/hosts/blender/plugins/load/import_workfile.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index 3b9edbc8c7..14c970c8d9 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -1,5 +1,3 @@ -from pathlib import Path - import bpy from openpype.hosts.blender.api import plugin @@ -24,13 +22,12 @@ class ImportBlendLoader(plugin.AssetLoader): color = "#775555" def load(self, context, name=None, namespace=None, data=None): - scene = bpy.context.scene - with bpy.data.libraries.load(self.fname) as (data_from, data_to): for attr in dir(data_to): setattr(data_to, attr, getattr(data_from, attr)) # Add objects to current scene + # scene = bpy.context.scene # for obj in data_to.objects: # scene.collection.objects.link(obj) From 2a49265ba7c23c965754d5ed1c5ee59bfd7e058f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 16 Dec 2022 10:59:51 +0000 Subject: [PATCH 13/27] Renamed to "Append workfile" --- openpype/hosts/blender/plugins/load/import_workfile.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index 14c970c8d9..244eefe936 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -3,20 +3,19 @@ import bpy from openpype.hosts.blender.api import plugin -class ImportBlendLoader(plugin.AssetLoader): - """Import action for Blender (unmanaged) +class AppendBlendLoader(plugin.AssetLoader): + """Append workfile in Blender (unmanaged) Warning: The loaded content will be unmanaged and is *not* visible in the scene inventory. It's purely intended to merge content into your scene so you could also use it as a new base. - """ representations = ["blend"] families = ["*"] - label = "Import" + label = "Append Workfile" order = 10 icon = "arrow-circle-down" color = "#775555" From c053762fedc29289d0e1d03fd0f0a012d2923c81 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 16 Dec 2022 11:17:34 +0000 Subject: [PATCH 14/27] Differentiate Append and Import loaders --- .../blender/plugins/load/import_workfile.py | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index 244eefe936..2849031f7e 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -16,7 +16,7 @@ class AppendBlendLoader(plugin.AssetLoader): families = ["*"] label = "Append Workfile" - order = 10 + order = 9 icon = "arrow-circle-down" color = "#775555" @@ -25,10 +25,37 @@ class AppendBlendLoader(plugin.AssetLoader): for attr in dir(data_to): setattr(data_to, attr, getattr(data_from, attr)) + # We do not containerize imported content, it remains unmanaged + return + +class ImportBlendLoader(plugin.AssetLoader): + """Import workfile in the current Blender scene (unmanaged) + + Warning: + The loaded content will be unmanaged and is *not* visible in the + scene inventory. It's purely intended to merge content into your scene + so you could also use it as a new base. + """ + + representations = ["blend"] + families = ["*"] + + label = "Import Workfile" + order = 9 + icon = "arrow-circle-down" + color = "#775555" + + def load(self, context, name=None, namespace=None, data=None): + with bpy.data.libraries.load(self.fname) as (data_from, data_to): + for attr in dir(data_to): + if attr == "scenes": + continue + setattr(data_to, attr, getattr(data_from, attr)) + # Add objects to current scene - # scene = bpy.context.scene - # for obj in data_to.objects: - # scene.collection.objects.link(obj) + scene = bpy.context.scene + for obj in data_to.objects: + scene.collection.objects.link(obj) # We do not containerize imported content, it remains unmanaged return From 38ec7d49debc81b8b4b1536448b7fbcaad44fa18 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 16 Dec 2022 13:34:58 +0100 Subject: [PATCH 15/27] changelog update --- CHANGELOG.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++- HISTORY.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cca692b68..f9820dec45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,73 @@ # Changelog +## [3.14.9](https://github.com/pypeclub/OpenPype/tree/3.14.9) + +[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.8...3.14.9) + +### 📖 Documentation + +- Documentation: Testing on Deadline [\#4185](https://github.com/pypeclub/OpenPype/pull/4185) +- Consistent Python version [\#4160](https://github.com/pypeclub/OpenPype/pull/4160) + +**🆕 New features** + +- Feature/op 4397 gl tf extractor for maya [\#4192](https://github.com/pypeclub/OpenPype/pull/4192) +- Maya: Extractor for Unreal SkeletalMesh [\#4174](https://github.com/pypeclub/OpenPype/pull/4174) +- 3dsmax: integration [\#4168](https://github.com/pypeclub/OpenPype/pull/4168) +- Blender: Extract Alembic Animations [\#4128](https://github.com/pypeclub/OpenPype/pull/4128) +- Unreal: Load Alembic Animations [\#4127](https://github.com/pypeclub/OpenPype/pull/4127) + +**🚀 Enhancements** + +- Houdini: Use new interface class name for publish host [\#4220](https://github.com/pypeclub/OpenPype/pull/4220) +- General: Default command for headless mode is interactive [\#4203](https://github.com/pypeclub/OpenPype/pull/4203) +- Maya: Enhanced ASS publishing [\#4196](https://github.com/pypeclub/OpenPype/pull/4196) +- Feature/op 3924 implement ass extractor [\#4188](https://github.com/pypeclub/OpenPype/pull/4188) +- File transactions: Source path is destination path [\#4184](https://github.com/pypeclub/OpenPype/pull/4184) +- Deadline: improve environment processing [\#4182](https://github.com/pypeclub/OpenPype/pull/4182) +- General: Comment per instance in Publisher [\#4178](https://github.com/pypeclub/OpenPype/pull/4178) +- Ensure Mongo database directory exists in Windows. [\#4166](https://github.com/pypeclub/OpenPype/pull/4166) +- Note about unrestricted execution on Windows. [\#4161](https://github.com/pypeclub/OpenPype/pull/4161) +- Maya: Enable thumbnail transparency on extraction. [\#4147](https://github.com/pypeclub/OpenPype/pull/4147) +- Maya: Disable viewport Pan/Zoom on playblast extraction. [\#4146](https://github.com/pypeclub/OpenPype/pull/4146) +- Maya: Optional viewport refresh on pointcache extraction [\#4144](https://github.com/pypeclub/OpenPype/pull/4144) +- CelAction: refactory integration to current openpype [\#4140](https://github.com/pypeclub/OpenPype/pull/4140) +- Maya: create and publish bounding box geometry [\#4131](https://github.com/pypeclub/OpenPype/pull/4131) +- Changed the UOpenPypePublishInstance to use the UDataAsset class [\#4124](https://github.com/pypeclub/OpenPype/pull/4124) +- General: Collection Audio speed up [\#4110](https://github.com/pypeclub/OpenPype/pull/4110) +- Maya: keep existing AOVs when creating render instance [\#4087](https://github.com/pypeclub/OpenPype/pull/4087) +- General: Oiio conversion multipart fix [\#4060](https://github.com/pypeclub/OpenPype/pull/4060) + +**🐛 Bug fixes** + +- Publisher: Signal type issues in Python 2 DCCs [\#4230](https://github.com/pypeclub/OpenPype/pull/4230) +- Blender: Fix Layout Family Versioning [\#4228](https://github.com/pypeclub/OpenPype/pull/4228) +- Blender: Fix Create Camera "Use selection" [\#4226](https://github.com/pypeclub/OpenPype/pull/4226) +- TrayPublisher - join needs list [\#4224](https://github.com/pypeclub/OpenPype/pull/4224) +- General: Event callbacks pass event to callbacks as expected [\#4210](https://github.com/pypeclub/OpenPype/pull/4210) +- Build:Revert .toml update of Gazu [\#4207](https://github.com/pypeclub/OpenPype/pull/4207) +- Nuke: fixed imageio node overrides subset filter [\#4202](https://github.com/pypeclub/OpenPype/pull/4202) +- Maya: pointcache [\#4201](https://github.com/pypeclub/OpenPype/pull/4201) +- Unreal: Support for Unreal Engine 5.1 [\#4199](https://github.com/pypeclub/OpenPype/pull/4199) +- General: Integrate thumbnail looks for thumbnail to multiple places [\#4181](https://github.com/pypeclub/OpenPype/pull/4181) +- Various minor bugfixes [\#4172](https://github.com/pypeclub/OpenPype/pull/4172) +- Nuke/Hiero: Remove tkinter library paths before launch [\#4171](https://github.com/pypeclub/OpenPype/pull/4171) +- Flame: vertical alignment of layers [\#4169](https://github.com/pypeclub/OpenPype/pull/4169) +- Nuke: correct detection of viewer and display [\#4165](https://github.com/pypeclub/OpenPype/pull/4165) +- Settings UI: Don't create QApplication if already exists [\#4156](https://github.com/pypeclub/OpenPype/pull/4156) +- General: Extract review handle start offset of sequences [\#4152](https://github.com/pypeclub/OpenPype/pull/4152) +- Maya: Maintain time connections on Alembic update. [\#4143](https://github.com/pypeclub/OpenPype/pull/4143) + +**🔀 Refactored code** + +- General: Use qtpy in modules and hosts UIs which are running in OpenPype process [\#4225](https://github.com/pypeclub/OpenPype/pull/4225) +- Tools: Use qtpy instead of Qt in standalone tools [\#4223](https://github.com/pypeclub/OpenPype/pull/4223) +- General: Use qtpy in settings UI [\#4215](https://github.com/pypeclub/OpenPype/pull/4215) + +**Merged pull requests:** + +- layout publish more than one container issue [\#4098](https://github.com/pypeclub/OpenPype/pull/4098) + ## [3.14.8](https://github.com/pypeclub/OpenPype/tree/3.14.8) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.7...3.14.8) @@ -21,7 +89,6 @@ - Maya: Looks - add all connections [\#4135](https://github.com/pypeclub/OpenPype/pull/4135) - General: Fix variable check in collect anatomy instance data [\#4117](https://github.com/pypeclub/OpenPype/pull/4117) - ## [3.14.7](https://github.com/pypeclub/OpenPype/tree/3.14.7) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.6...3.14.7) diff --git a/HISTORY.md b/HISTORY.md index f4e132488b..f24e95b2e1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,74 @@ # Changelog + +## [3.14.9](https://github.com/pypeclub/OpenPype/tree/3.14.9) + +[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.8...3.14.9) + +### 📖 Documentation + +- Documentation: Testing on Deadline [\#4185](https://github.com/pypeclub/OpenPype/pull/4185) +- Consistent Python version [\#4160](https://github.com/pypeclub/OpenPype/pull/4160) + +**🆕 New features** + +- Feature/op 4397 gl tf extractor for maya [\#4192](https://github.com/pypeclub/OpenPype/pull/4192) +- Maya: Extractor for Unreal SkeletalMesh [\#4174](https://github.com/pypeclub/OpenPype/pull/4174) +- 3dsmax: integration [\#4168](https://github.com/pypeclub/OpenPype/pull/4168) +- Blender: Extract Alembic Animations [\#4128](https://github.com/pypeclub/OpenPype/pull/4128) +- Unreal: Load Alembic Animations [\#4127](https://github.com/pypeclub/OpenPype/pull/4127) + +**🚀 Enhancements** + +- Houdini: Use new interface class name for publish host [\#4220](https://github.com/pypeclub/OpenPype/pull/4220) +- General: Default command for headless mode is interactive [\#4203](https://github.com/pypeclub/OpenPype/pull/4203) +- Maya: Enhanced ASS publishing [\#4196](https://github.com/pypeclub/OpenPype/pull/4196) +- Feature/op 3924 implement ass extractor [\#4188](https://github.com/pypeclub/OpenPype/pull/4188) +- File transactions: Source path is destination path [\#4184](https://github.com/pypeclub/OpenPype/pull/4184) +- Deadline: improve environment processing [\#4182](https://github.com/pypeclub/OpenPype/pull/4182) +- General: Comment per instance in Publisher [\#4178](https://github.com/pypeclub/OpenPype/pull/4178) +- Ensure Mongo database directory exists in Windows. [\#4166](https://github.com/pypeclub/OpenPype/pull/4166) +- Note about unrestricted execution on Windows. [\#4161](https://github.com/pypeclub/OpenPype/pull/4161) +- Maya: Enable thumbnail transparency on extraction. [\#4147](https://github.com/pypeclub/OpenPype/pull/4147) +- Maya: Disable viewport Pan/Zoom on playblast extraction. [\#4146](https://github.com/pypeclub/OpenPype/pull/4146) +- Maya: Optional viewport refresh on pointcache extraction [\#4144](https://github.com/pypeclub/OpenPype/pull/4144) +- CelAction: refactory integration to current openpype [\#4140](https://github.com/pypeclub/OpenPype/pull/4140) +- Maya: create and publish bounding box geometry [\#4131](https://github.com/pypeclub/OpenPype/pull/4131) +- Changed the UOpenPypePublishInstance to use the UDataAsset class [\#4124](https://github.com/pypeclub/OpenPype/pull/4124) +- General: Collection Audio speed up [\#4110](https://github.com/pypeclub/OpenPype/pull/4110) +- Maya: keep existing AOVs when creating render instance [\#4087](https://github.com/pypeclub/OpenPype/pull/4087) +- General: Oiio conversion multipart fix [\#4060](https://github.com/pypeclub/OpenPype/pull/4060) + +**🐛 Bug fixes** + +- Publisher: Signal type issues in Python 2 DCCs [\#4230](https://github.com/pypeclub/OpenPype/pull/4230) +- Blender: Fix Layout Family Versioning [\#4228](https://github.com/pypeclub/OpenPype/pull/4228) +- Blender: Fix Create Camera "Use selection" [\#4226](https://github.com/pypeclub/OpenPype/pull/4226) +- TrayPublisher - join needs list [\#4224](https://github.com/pypeclub/OpenPype/pull/4224) +- General: Event callbacks pass event to callbacks as expected [\#4210](https://github.com/pypeclub/OpenPype/pull/4210) +- Build:Revert .toml update of Gazu [\#4207](https://github.com/pypeclub/OpenPype/pull/4207) +- Nuke: fixed imageio node overrides subset filter [\#4202](https://github.com/pypeclub/OpenPype/pull/4202) +- Maya: pointcache [\#4201](https://github.com/pypeclub/OpenPype/pull/4201) +- Unreal: Support for Unreal Engine 5.1 [\#4199](https://github.com/pypeclub/OpenPype/pull/4199) +- General: Integrate thumbnail looks for thumbnail to multiple places [\#4181](https://github.com/pypeclub/OpenPype/pull/4181) +- Various minor bugfixes [\#4172](https://github.com/pypeclub/OpenPype/pull/4172) +- Nuke/Hiero: Remove tkinter library paths before launch [\#4171](https://github.com/pypeclub/OpenPype/pull/4171) +- Flame: vertical alignment of layers [\#4169](https://github.com/pypeclub/OpenPype/pull/4169) +- Nuke: correct detection of viewer and display [\#4165](https://github.com/pypeclub/OpenPype/pull/4165) +- Settings UI: Don't create QApplication if already exists [\#4156](https://github.com/pypeclub/OpenPype/pull/4156) +- General: Extract review handle start offset of sequences [\#4152](https://github.com/pypeclub/OpenPype/pull/4152) +- Maya: Maintain time connections on Alembic update. [\#4143](https://github.com/pypeclub/OpenPype/pull/4143) + +**🔀 Refactored code** + +- General: Use qtpy in modules and hosts UIs which are running in OpenPype process [\#4225](https://github.com/pypeclub/OpenPype/pull/4225) +- Tools: Use qtpy instead of Qt in standalone tools [\#4223](https://github.com/pypeclub/OpenPype/pull/4223) +- General: Use qtpy in settings UI [\#4215](https://github.com/pypeclub/OpenPype/pull/4215) + +**Merged pull requests:** + +- layout publish more than one container issue [\#4098](https://github.com/pypeclub/OpenPype/pull/4098) + ## [3.14.8](https://github.com/pypeclub/OpenPype/tree/3.14.8) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.7...3.14.8) From 86d3636004e37554e3cfc505425cf0868e98a4bb Mon Sep 17 00:00:00 2001 From: OpenPype Date: Fri, 16 Dec 2022 12:45:18 +0000 Subject: [PATCH 16/27] [Automated] Bump version --- openpype/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/version.py b/openpype/version.py index 8d82df563d..021b816b8f 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.14.9-nightly.4" +__version__ = "3.14.9-nightly.5" From a1fe5359cc7f88b80142128d09bbcd38215f3e45 Mon Sep 17 00:00:00 2001 From: OpenPype Date: Fri, 16 Dec 2022 12:51:43 +0000 Subject: [PATCH 17/27] [Automated] Release --- openpype/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/version.py b/openpype/version.py index 021b816b8f..5b5b1475c0 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.14.9-nightly.5" +__version__ = "3.14.9" From 8ceafdbc367130e2bfb26e44f7f68e4d5a84acf1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 16 Dec 2022 15:42:48 +0100 Subject: [PATCH 18/27] flame: adding also `rgb` layer to default rename --- openpype/settings/defaults/project_settings/flame.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/settings/defaults/project_settings/flame.json b/openpype/settings/defaults/project_settings/flame.json index 337e58ac62..1422a76af3 100644 --- a/openpype/settings/defaults/project_settings/flame.json +++ b/openpype/settings/defaults/project_settings/flame.json @@ -122,6 +122,7 @@ "clip_name_template": "{asset}_{subset}<_{output}>", "layer_rename_template": "{asset}_{subset}<_{output}>", "layer_rename_patterns": [ + "rgb", "rgba" ] }, @@ -149,6 +150,7 @@ "clip_name_template": "{batch}_{asset}_{subset}<_{output}>", "layer_rename_template": "{asset}_{subset}<_{output}>", "layer_rename_patterns": [ + "rgb", "rgba" ] } From a0c60afb286bb615b67aa3e0fa156767f3c167e5 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 16 Dec 2022 14:46:29 +0000 Subject: [PATCH 19/27] Objects imported are stored in collections for each scene --- .../blender/plugins/load/import_workfile.py | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index 2849031f7e..ed24140a59 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -1,8 +1,20 @@ +from pathlib import Path + import bpy from openpype.hosts.blender.api import plugin +def get_unique_number(asset, subset): + count = 1 + name = f"{asset}_{count:0>2}_{subset}" + collection_names = [coll.name for coll in bpy.data.collections] + while name in collection_names: + count += 1 + name = f"{asset}_{count:0>2}_{subset}" + return f"{count:0>2}" + + class AppendBlendLoader(plugin.AssetLoader): """Append workfile in Blender (unmanaged) @@ -28,6 +40,7 @@ class AppendBlendLoader(plugin.AssetLoader): # We do not containerize imported content, it remains unmanaged return + class ImportBlendLoader(plugin.AssetLoader): """Import workfile in the current Blender scene (unmanaged) @@ -46,16 +59,26 @@ class ImportBlendLoader(plugin.AssetLoader): color = "#775555" def load(self, context, name=None, namespace=None, data=None): + asset = context['asset']['name'] + subset = context['subset']['name'] + + unique_number = get_unique_number(asset, subset) + group_name = plugin.asset_name(asset, subset, unique_number) + with bpy.data.libraries.load(self.fname) as (data_from, data_to): for attr in dir(data_to): - if attr == "scenes": - continue setattr(data_to, attr, getattr(data_from, attr)) - # Add objects to current scene - scene = bpy.context.scene - for obj in data_to.objects: - scene.collection.objects.link(obj) + current_scene = bpy.context.scene + + for scene in data_to.scenes: + # scene.name = group_name + collection = bpy.data.collections.new(name=group_name) + for obj in scene.objects: + collection.objects.link(obj) + current_scene.collection.children.link(collection) + for coll in scene.collection.children: + collection.children.link(coll) # We do not containerize imported content, it remains unmanaged return From f94a4195eb63662cdd70f17796c4c31f1265922b Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 16 Dec 2022 14:47:28 +0000 Subject: [PATCH 20/27] The original names of the scenes are now preserved --- .../hosts/blender/plugins/load/import_workfile.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index ed24140a59..92f5ba168c 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -65,15 +65,22 @@ class ImportBlendLoader(plugin.AssetLoader): unique_number = get_unique_number(asset, subset) group_name = plugin.asset_name(asset, subset, unique_number) + # We need to preserve the original names of the scenes, otherwise, + # if there are duplicate names in the current workfile, the imported + # scenes will be renamed by Blender to avoid conflicts. + original_scene_names = [] + with bpy.data.libraries.load(self.fname) as (data_from, data_to): for attr in dir(data_to): + if attr == "scenes": + for scene in data_from.scenes: + original_scene_names.append(scene) setattr(data_to, attr, getattr(data_from, attr)) current_scene = bpy.context.scene - for scene in data_to.scenes: - # scene.name = group_name - collection = bpy.data.collections.new(name=group_name) + for scene, s_name in zip(data_to.scenes, original_scene_names): + collection = bpy.data.collections.new(f"{group_name}_{s_name}") for obj in scene.objects: collection.objects.link(obj) current_scene.collection.children.link(collection) From 9d57af05615ccf93943600f5af6fc1e8dfaad983 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 16 Dec 2022 14:59:39 +0000 Subject: [PATCH 21/27] Scenes are renamed to identify from where they have been loaded --- .../blender/plugins/load/import_workfile.py | 71 ++++++++----------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/import_workfile.py b/openpype/hosts/blender/plugins/load/import_workfile.py index 92f5ba168c..618fb83e31 100644 --- a/openpype/hosts/blender/plugins/load/import_workfile.py +++ b/openpype/hosts/blender/plugins/load/import_workfile.py @@ -1,18 +1,37 @@ -from pathlib import Path - import bpy from openpype.hosts.blender.api import plugin -def get_unique_number(asset, subset): - count = 1 - name = f"{asset}_{count:0>2}_{subset}" - collection_names = [coll.name for coll in bpy.data.collections] - while name in collection_names: - count += 1 - name = f"{asset}_{count:0>2}_{subset}" - return f"{count:0>2}" +def append_workfile(context, fname, do_import): + asset = context['asset']['name'] + subset = context['subset']['name'] + + group_name = plugin.asset_name(asset, subset) + + # We need to preserve the original names of the scenes, otherwise, + # if there are duplicate names in the current workfile, the imported + # scenes will be renamed by Blender to avoid conflicts. + original_scene_names = [] + + with bpy.data.libraries.load(fname) as (data_from, data_to): + for attr in dir(data_to): + if attr == "scenes": + for scene in data_from.scenes: + original_scene_names.append(scene) + setattr(data_to, attr, getattr(data_from, attr)) + + current_scene = bpy.context.scene + + for scene, s_name in zip(data_to.scenes, original_scene_names): + scene.name = f"{group_name}_{s_name}" + if do_import: + collection = bpy.data.collections.new(f"{group_name}_{s_name}") + for obj in scene.objects: + collection.objects.link(obj) + current_scene.collection.children.link(collection) + for coll in scene.collection.children: + collection.children.link(coll) class AppendBlendLoader(plugin.AssetLoader): @@ -33,9 +52,7 @@ class AppendBlendLoader(plugin.AssetLoader): color = "#775555" def load(self, context, name=None, namespace=None, data=None): - with bpy.data.libraries.load(self.fname) as (data_from, data_to): - for attr in dir(data_to): - setattr(data_to, attr, getattr(data_from, attr)) + append_workfile(context, self.fname, False) # We do not containerize imported content, it remains unmanaged return @@ -59,33 +76,7 @@ class ImportBlendLoader(plugin.AssetLoader): color = "#775555" def load(self, context, name=None, namespace=None, data=None): - asset = context['asset']['name'] - subset = context['subset']['name'] - - unique_number = get_unique_number(asset, subset) - group_name = plugin.asset_name(asset, subset, unique_number) - - # We need to preserve the original names of the scenes, otherwise, - # if there are duplicate names in the current workfile, the imported - # scenes will be renamed by Blender to avoid conflicts. - original_scene_names = [] - - with bpy.data.libraries.load(self.fname) as (data_from, data_to): - for attr in dir(data_to): - if attr == "scenes": - for scene in data_from.scenes: - original_scene_names.append(scene) - setattr(data_to, attr, getattr(data_from, attr)) - - current_scene = bpy.context.scene - - for scene, s_name in zip(data_to.scenes, original_scene_names): - collection = bpy.data.collections.new(f"{group_name}_{s_name}") - for obj in scene.objects: - collection.objects.link(obj) - current_scene.collection.children.link(collection) - for coll in scene.collection.children: - collection.children.link(coll) + append_workfile(context, self.fname, True) # We do not containerize imported content, it remains unmanaged return From c58cd1fb792fc27187fc58fb93b9eebe368c99d3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Dec 2022 17:35:15 +0100 Subject: [PATCH 22/27] use qtpy in flame host --- openpype/hosts/flame/api/menu.py | 2 +- openpype/hosts/flame/api/plugin.py | 2 +- .../flame/startup/openpype_babypublisher/modules/panel_app.py | 2 +- .../flame/startup/openpype_babypublisher/modules/uiwidgets.py | 2 +- openpype/hosts/flame/startup/openpype_in_flame.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/flame/api/menu.py b/openpype/hosts/flame/api/menu.py index 319ed7afb6..5f9dc57a61 100644 --- a/openpype/hosts/flame/api/menu.py +++ b/openpype/hosts/flame/api/menu.py @@ -1,5 +1,5 @@ import os -from Qt import QtWidgets +from qtpy import QtWidgets from copy import deepcopy from pprint import pformat from openpype.tools.utils.host_tools import HostToolsHelper diff --git a/openpype/hosts/flame/api/plugin.py b/openpype/hosts/flame/api/plugin.py index ca113fd98a..b53ce758f9 100644 --- a/openpype/hosts/flame/api/plugin.py +++ b/openpype/hosts/flame/api/plugin.py @@ -5,7 +5,7 @@ from copy import deepcopy from xml.etree import ElementTree as ET import qargparse -from Qt import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets from openpype import style from openpype.lib import Logger diff --git a/openpype/hosts/flame/startup/openpype_babypublisher/modules/panel_app.py b/openpype/hosts/flame/startup/openpype_babypublisher/modules/panel_app.py index 1e8011efaa..5c5bb0b4a1 100644 --- a/openpype/hosts/flame/startup/openpype_babypublisher/modules/panel_app.py +++ b/openpype/hosts/flame/startup/openpype_babypublisher/modules/panel_app.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import uiwidgets import app_utils diff --git a/openpype/hosts/flame/startup/openpype_babypublisher/modules/uiwidgets.py b/openpype/hosts/flame/startup/openpype_babypublisher/modules/uiwidgets.py index c6db875df0..5498a49197 100644 --- a/openpype/hosts/flame/startup/openpype_babypublisher/modules/uiwidgets.py +++ b/openpype/hosts/flame/startup/openpype_babypublisher/modules/uiwidgets.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore class FlameLabel(QtWidgets.QLabel): diff --git a/openpype/hosts/flame/startup/openpype_in_flame.py b/openpype/hosts/flame/startup/openpype_in_flame.py index d07aaa6b7d..39869333aa 100644 --- a/openpype/hosts/flame/startup/openpype_in_flame.py +++ b/openpype/hosts/flame/startup/openpype_in_flame.py @@ -1,6 +1,6 @@ from __future__ import print_function import sys -from Qt import QtWidgets +from qtpy import QtWidgets from pprint import pformat import atexit From b60ccfaf01dd1bb2ebf964afe33c435016956650 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Dec 2022 17:44:39 +0100 Subject: [PATCH 23/27] use qtpy in nuke host --- openpype/hosts/nuke/api/lib.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 7ee30bf273..a066bbcdcf 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -10,7 +10,7 @@ from collections import OrderedDict import clique import nuke -from Qt import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets from openpype.client import ( get_project, @@ -81,7 +81,6 @@ class Context: def get_main_window(): """Acquire Nuke's main window""" if Context.main_window is None: - from Qt import QtWidgets top_widgets = QtWidgets.QApplication.topLevelWidgets() name = "Foundry::UI::DockMainWindow" From 18c0a7fb3300d4e95651941b15eb4965b43e48f5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Dec 2022 17:49:28 +0100 Subject: [PATCH 24/27] use qtpy in hiero host implementation --- openpype/hosts/hiero/api/launchforhiero.py | 2 +- openpype/hosts/hiero/api/lib.py | 2 +- openpype/hosts/hiero/api/menu.py | 2 +- openpype/hosts/hiero/api/plugin.py | 2 +- openpype/hosts/hiero/plugins/publish/precollect_workfile.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/hiero/api/launchforhiero.py b/openpype/hosts/hiero/api/launchforhiero.py index 5f7dbe23c9..c2186e1d2a 100644 --- a/openpype/hosts/hiero/api/launchforhiero.py +++ b/openpype/hosts/hiero/api/launchforhiero.py @@ -1,7 +1,7 @@ import logging from scriptsmenu import scriptsmenu -from Qt import QtWidgets +from qtpy import QtWidgets log = logging.getLogger(__name__) diff --git a/openpype/hosts/hiero/api/lib.py b/openpype/hosts/hiero/api/lib.py index 7f0cf8149a..c344b35718 100644 --- a/openpype/hosts/hiero/api/lib.py +++ b/openpype/hosts/hiero/api/lib.py @@ -15,7 +15,7 @@ import secrets import shutil import hiero -from Qt import QtWidgets, QtCore, QtXml +from qtpy import QtWidgets, QtCore, QtXml from openpype.client import get_project from openpype.settings import get_project_settings diff --git a/openpype/hosts/hiero/api/menu.py b/openpype/hosts/hiero/api/menu.py index 2a7560c6ba..6baeb38cc0 100644 --- a/openpype/hosts/hiero/api/menu.py +++ b/openpype/hosts/hiero/api/menu.py @@ -43,7 +43,7 @@ def menu_install(): """ - from Qt import QtGui + from qtpy import QtGui from . import ( publish, launch_workfiles_app, reload_config, apply_colorspace_project, apply_colorspace_clips diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index 5ec1c78aaa..38933a1e30 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -5,7 +5,7 @@ from copy import deepcopy import hiero -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qargparse from openpype.settings import get_current_project_settings diff --git a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py index c9bfb86810..08963f98fd 100644 --- a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py @@ -3,7 +3,7 @@ import tempfile from pprint import pformat import pyblish.api -from Qt.QtGui import QPixmap +from qtpy.QtGui import QPixmap import hiero.ui From 48d4f611f7cd60e0115e77329b464285e325431b Mon Sep 17 00:00:00 2001 From: OpenPype Date: Sat, 17 Dec 2022 03:27:33 +0000 Subject: [PATCH 25/27] [Automated] Bump version --- openpype/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/version.py b/openpype/version.py index 5b5b1475c0..454d56a5b7 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.14.9" +__version__ = "3.14.10-nightly.1" From b22d22a65ecb7c8e750427ef4ac00fa1eaa80f6d Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Mon, 19 Dec 2022 00:03:05 +0100 Subject: [PATCH 26/27] :bug: fix dependencies --- .../modules/deadline/plugins/publish/submit_maya_deadline.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py index 3398e1725e..a92b996327 100644 --- a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -183,7 +183,6 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): # Adding file dependencies. if self.asset_dependencies: dependencies = instance.context.data["fileDependencies"] - dependencies.append(context.data["currentFile"]) for dependency in dependencies: job_info.AssetDependency += dependency @@ -294,7 +293,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): # Add export job as dependency -------------------------------------- if export_job: job_info, _ = payload - job_info.JobDependency = export_job + job_info.JobDependencies = export_job if instance.data.get("tileRendering"): # Prepare tiles data @@ -431,7 +430,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): frame_assembly_job_info.ExtraInfo[0] = file_hash frame_assembly_job_info.ExtraInfo[1] = file - frame_assembly_job_info.JobDependency = tile_job_id + frame_assembly_job_info.JobDependencies = tile_job_id # write assembly job config files now = datetime.now() From 4c214cabe4890dcc2a9fd5f1f8fd4d4e5822cb4e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 19 Dec 2022 21:47:21 +0100 Subject: [PATCH 27/27] fix import of QtXml --- openpype/hosts/hiero/api/lib.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/hiero/api/lib.py b/openpype/hosts/hiero/api/lib.py index c344b35718..bbd1edc14a 100644 --- a/openpype/hosts/hiero/api/lib.py +++ b/openpype/hosts/hiero/api/lib.py @@ -15,7 +15,11 @@ import secrets import shutil import hiero -from qtpy import QtWidgets, QtCore, QtXml +from qtpy import QtWidgets, QtCore +try: + from PySide import QtXml +except ImportError: + from PySide2 import QtXml from openpype.client import get_project from openpype.settings import get_project_settings