From ca6f2b467ded88c0b0a8ac662f1e75145394f0a3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 24 Apr 2023 11:40:33 +0200 Subject: [PATCH 1/8] Add Fusion USD loader --- .../hosts/fusion/plugins/load/load_usd.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 openpype/hosts/fusion/plugins/load/load_usd.py diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py new file mode 100644 index 0000000000..8c2c69f52f --- /dev/null +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -0,0 +1,73 @@ +from openpype.pipeline import ( + load, + get_representation_path, +) +from openpype.hosts.fusion.api import ( + imprint_container, + get_current_comp, + comp_lock_and_undo_chunk +) + + +class FusionLoadAlembicMesh(load.LoaderPlugin): + """Load USD into Fusion + + Support for USD was added since Fusion 18.5 + """ + + families = ["*"] + representations = ["*"] + extensions = {"usd", "usda", "usdz"} + + label = "Load USD" + order = -10 + icon = "code-fork" + color = "orange" + + tool_type = "uLoader" + + def load(self, context, name, namespace, data): + # Fallback to asset name when namespace is None + if namespace is None: + namespace = context['asset']['name'] + + # Create the Loader with the filename path set + comp = get_current_comp() + with comp_lock_and_undo_chunk(comp, "Create tool"): + + path = self.fname + + args = (-32768, -32768) + tool = comp.AddTool(self.tool_type, *args) + tool["Filename"] = path + + imprint_container(tool, + name=name, + namespace=namespace, + context=context, + loader=self.__class__.__name__) + + def switch(self, container, representation): + self.update(container, representation) + + def update(self, container, representation): + + tool = container["_tool"] + assert tool.ID == self.tool_type, f"Must be {self.tool_type}" + comp = tool.Comp() + + path = get_representation_path(representation) + + with comp_lock_and_undo_chunk(comp, "Update tool"): + tool["Filename"] = path + + # Update the imprinted representation + tool.SetData("avalon.representation", str(representation["_id"])) + + def remove(self, container): + tool = container["_tool"] + assert tool.ID == self.tool_type, f"Must be {self.tool_type}" + comp = tool.Comp() + + with comp_lock_and_undo_chunk(comp, "Remove tool"): + tool.Delete() From bd049da6f93fdffac69d673a66d9387351471576 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 20 Sep 2023 16:11:13 +0200 Subject: [PATCH 2/8] Update openpype/hosts/fusion/plugins/load/load_usd.py --- openpype/hosts/fusion/plugins/load/load_usd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index 8c2c69f52f..f12fbd5ed0 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -9,7 +9,7 @@ from openpype.hosts.fusion.api import ( ) -class FusionLoadAlembicMesh(load.LoaderPlugin): +class FusionLoadUSD(load.LoaderPlugin): """Load USD into Fusion Support for USD was added since Fusion 18.5 From fac33119ec0e7a7087b053b95711b85dd13dc791 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 13:28:57 +0200 Subject: [PATCH 3/8] Enable only in Fusion 18.5+ --- openpype/hosts/fusion/plugins/load/load_usd.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index f12fbd5ed0..beab0c8ecf 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -7,6 +7,7 @@ from openpype.hosts.fusion.api import ( get_current_comp, comp_lock_and_undo_chunk ) +from openpype.hosts.fusion.api.lib import get_fusion_module class FusionLoadUSD(load.LoaderPlugin): @@ -26,6 +27,19 @@ class FusionLoadUSD(load.LoaderPlugin): tool_type = "uLoader" + @classmethod + def apply_settings(cls, project_settings, system_settings): + super(FusionLoadUSD, cls).apply_settings(project_settings, + system_settings) + if cls.enabled: + # Enable only in Fusion 18.5+ + fusion = get_fusion_module() + version = fusion.GetVersion() + major = version[1] + minor = version[2] + is_usd_supported = (major, minor) >= (18, 5) + cls.enabled = is_usd_supported + def load(self, context, name, namespace, data): # Fallback to asset name when namespace is None if namespace is None: From 277a0baa7bbe89b2a58fbe9568271e4d5f72e86b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 13:29:49 +0200 Subject: [PATCH 4/8] Hound --- openpype/hosts/fusion/plugins/load/load_usd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index beab0c8ecf..4f1813a646 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -29,7 +29,7 @@ class FusionLoadUSD(load.LoaderPlugin): @classmethod def apply_settings(cls, project_settings, system_settings): - super(FusionLoadUSD, cls).apply_settings(project_settings, + super(FusionLoadUSD, cls).apply_settings(project_settings, system_settings) if cls.enabled: # Enable only in Fusion 18.5+ From 8a9a1e66f3fe007367d7895fcbcb452a88c4a366 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 19:08:08 +0200 Subject: [PATCH 5/8] comparison of UILabelDef is comparing label value --- openpype/lib/attribute_definitions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index a71d6cc72a..b8faae8f4c 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -240,6 +240,11 @@ class UILabelDef(UIDef): def __init__(self, label): super(UILabelDef, self).__init__(label=label) + def __eq__(self, other): + if not super(UILabelDef, self).__eq__(other): + return False + return self.label == other.label: + # --------------------------------------- # Attribute defintioins should hold value From bbfff158b055b4fcaf520396bdea0d5544321d08 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 19:08:25 +0200 Subject: [PATCH 6/8] it is possible to define key of label to differentiate --- openpype/lib/attribute_definitions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index b8faae8f4c..658a3fe581 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -237,8 +237,8 @@ class UISeparatorDef(UIDef): class UILabelDef(UIDef): type = "label" - def __init__(self, label): - super(UILabelDef, self).__init__(label=label) + def __init__(self, label, key=None): + super(UILabelDef, self).__init__(label=label, key=key) def __eq__(self, other): if not super(UILabelDef, self).__eq__(other): From 576ac94e3168568e1a6e5bc136bc338fac19a8f4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:12:15 +0200 Subject: [PATCH 7/8] Remove semicolon --- openpype/lib/attribute_definitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index 658a3fe581..3dd284b8e4 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -243,7 +243,7 @@ class UILabelDef(UIDef): def __eq__(self, other): if not super(UILabelDef, self).__eq__(other): return False - return self.label == other.label: + return self.label == other.label # --------------------------------------- From 371f9a52755a6c761b87ff1e6a07fe59384acbc1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 31 Oct 2023 11:49:17 +0100 Subject: [PATCH 8/8] Bugfix: Collect Rendered Files only collecting first instance (#5832) * Bugfix: Collect all instances from the metadata file - don't return on first iteration * Fix initial state of variable --- .../plugins/publish/collect_rendered_files.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_rendered_files.py b/openpype/plugins/publish/collect_rendered_files.py index 8a5a5a83f1..a249b3acda 100644 --- a/openpype/plugins/publish/collect_rendered_files.py +++ b/openpype/plugins/publish/collect_rendered_files.py @@ -56,6 +56,17 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): data_object["stagingDir"] = anatomy.fill_root(staging_dir) def _process_path(self, data, anatomy): + """Process data of a single JSON publish metadata file. + + Args: + data: The loaded metadata from the JSON file + anatomy: Anatomy for the current context + + Returns: + bool: Whether any instance of this particular metadata file + has a persistent staging dir. + + """ # validate basic necessary data data_err = "invalid json file - missing data" required = ["asset", "user", "comment", @@ -89,6 +100,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): os.environ["FTRACK_SERVER"] = ftrack["FTRACK_SERVER"] # now we can just add instances from json file and we are done + any_staging_dir_persistent = False for instance_data in data.get("instances"): self.log.debug(" - processing instance for {}".format( @@ -106,6 +118,9 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): staging_dir_persistent = instance.data.get( "stagingDir_persistent", False ) + if staging_dir_persistent: + any_staging_dir_persistent = True + representations = [] for repre_data in instance_data.get("representations") or []: self._fill_staging_dir(repre_data, anatomy) @@ -127,7 +142,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): self.log.debug( f"Adding audio to instance: {instance.data['audio']}") - return staging_dir_persistent + return any_staging_dir_persistent def process(self, context): self._context = context