From 53dac8b0a8e1893afc9c1720d6c17ca9a65ec911 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 28 Jun 2023 13:12:34 +0800 Subject: [PATCH 01/16] maxscript's conversion of bool to python --- openpype/hosts/max/api/plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 71a0b94e1f..69a495f5ae 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -172,7 +172,7 @@ class MaxCreator(Creator, MaxCreatorBase): # Setting the property rt.setProperty( instance_node.openPypeData, "all_handles", node_list) - + self.log.debug(f"{instance}") self._add_instance_to_context(instance) imprint(instance_node.name, instance.data_to_store()) @@ -184,6 +184,7 @@ class MaxCreator(Creator, MaxCreatorBase): created_instance = CreatedInstance.from_existing( read(rt.GetNodeByName(instance)), self ) + self.log.debug(f"{created_instance}") self._add_instance_to_context(created_instance) def update_instances(self, update_list): From 5a228d4d5192825081225cdaef23d9cbf20397bb Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 28 Jun 2023 13:21:37 +0800 Subject: [PATCH 02/16] maxscript's conversion of bool to python --- openpype/hosts/max/api/lib.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/lib.py b/openpype/hosts/max/api/lib.py index 1d53802ecf..c1e67409a2 100644 --- a/openpype/hosts/max/api/lib.py +++ b/openpype/hosts/max/api/lib.py @@ -78,7 +78,13 @@ def read(container) -> dict: value.startswith(JSON_PREFIX): with contextlib.suppress(json.JSONDecodeError): value = json.loads(value[len(JSON_PREFIX):]) - data[key.strip()] = value + if key.strip() == "active": + if value == "true": + data[key.strip()] = True + else: + data[key.strip()] = False + else: + data[key.strip()] = value data["instance_node"] = container.Name From eb63b4bae1291006071b3689735abe5e4b1d7829 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 28 Jun 2023 13:22:35 +0800 Subject: [PATCH 03/16] remove unnecessary debug check --- openpype/hosts/max/api/plugin.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 69a495f5ae..08e41df554 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -172,7 +172,6 @@ class MaxCreator(Creator, MaxCreatorBase): # Setting the property rt.setProperty( instance_node.openPypeData, "all_handles", node_list) - self.log.debug(f"{instance}") self._add_instance_to_context(instance) imprint(instance_node.name, instance.data_to_store()) @@ -184,7 +183,6 @@ class MaxCreator(Creator, MaxCreatorBase): created_instance = CreatedInstance.from_existing( read(rt.GetNodeByName(instance)), self ) - self.log.debug(f"{created_instance}") self._add_instance_to_context(created_instance) def update_instances(self, update_list): From 3c4c922b4f5e66874ccc886ecddff0d02528afce Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 28 Jun 2023 13:23:22 +0800 Subject: [PATCH 04/16] restore the plugin.py --- openpype/hosts/max/api/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/max/api/plugin.py b/openpype/hosts/max/api/plugin.py index 08e41df554..71a0b94e1f 100644 --- a/openpype/hosts/max/api/plugin.py +++ b/openpype/hosts/max/api/plugin.py @@ -172,6 +172,7 @@ class MaxCreator(Creator, MaxCreatorBase): # Setting the property rt.setProperty( instance_node.openPypeData, "all_handles", node_list) + self._add_instance_to_context(instance) imprint(instance_node.name, instance.data_to_store()) From 04ec40134329694e72d7421e13f60744f824af1a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 28 Jun 2023 15:52:37 +0800 Subject: [PATCH 05/16] roy's comment --- openpype/hosts/max/api/lib.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/max/api/lib.py b/openpype/hosts/max/api/lib.py index c1e67409a2..879f0abfa4 100644 --- a/openpype/hosts/max/api/lib.py +++ b/openpype/hosts/max/api/lib.py @@ -78,13 +78,15 @@ def read(container) -> dict: value.startswith(JSON_PREFIX): with contextlib.suppress(json.JSONDecodeError): value = json.loads(value[len(JSON_PREFIX):]) - if key.strip() == "active": - if value == "true": - data[key.strip()] = True - else: - data[key.strip()] = False - else: - data[key.strip()] = value + + # default value behavior + # convert maxscript boolean values + if value == "true": + value = True + elif value == "false": + value = False + + data[key.strip()] = value data["instance_node"] = container.Name From a0fb1d49cad2da140e3b3ff9a791b37bdabaa199 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Mon, 3 Jul 2023 17:36:48 +0300 Subject: [PATCH 06/16] add select invalid action --- .../publish/validate_sop_output_node.py | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py index ed7f438729..74f45c0925 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py @@ -1,7 +1,13 @@ # -*- coding: utf-8 -*- import pyblish.api from openpype.pipeline import PublishValidationError +from openpype.pipeline.publish import RepairAction +import hou + +class SelectInvalidAction(RepairAction): + label = "Select Invalid ROP" + icon = "mdi.cursor-default-click" class ValidateSopOutputNode(pyblish.api.InstancePlugin): """Validate the instance SOP Output Node. @@ -19,6 +25,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): families = ["pointcache", "vdbcache"] hosts = ["houdini"] label = "Validate Output Node" + actions = [SelectInvalidAction] def process(self, instance): @@ -31,9 +38,6 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): @classmethod def get_invalid(cls, instance): - - import hou - output_node = instance.data.get("output_node") if output_node is None: @@ -81,3 +85,19 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): "Output node `%s` has no geometry data." % output_node.path() ) return [output_node.path()] + + @classmethod + def repair(cls, instance): + """Select Invalid ROP. + + It's used to select invalid ROP which tells the + artist which ROP node need to be fixed! + """ + + rop_node = hou.node(instance.data["instance_node"]) + rop_node.setSelected(True, clear_all_selected=True) + + cls.log.debug( + '%s has been selected' + % rop_node.path() + ) From 6983503468b03490e53089e71a45d86780dfc5a6 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Mon, 3 Jul 2023 18:16:23 +0300 Subject: [PATCH 07/16] fix lint problem --- .../hosts/houdini/plugins/publish/validate_sop_output_node.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py index 74f45c0925..e8fb11a51c 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py @@ -5,6 +5,7 @@ from openpype.pipeline.publish import RepairAction import hou + class SelectInvalidAction(RepairAction): label = "Select Invalid ROP" icon = "mdi.cursor-default-click" From 73ecfe88e8773f5178d72785ac1771b83dde3b7f Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Tue, 4 Jul 2023 13:27:31 +0300 Subject: [PATCH 08/16] change action name to Select ROP --- .../plugins/publish/validate_sop_output_node.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py index e8fb11a51c..0d2aa64df6 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py @@ -6,8 +6,8 @@ from openpype.pipeline.publish import RepairAction import hou -class SelectInvalidAction(RepairAction): - label = "Select Invalid ROP" +class SelectROPAction(RepairAction): + label = "Select ROP" icon = "mdi.cursor-default-click" class ValidateSopOutputNode(pyblish.api.InstancePlugin): @@ -26,7 +26,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): families = ["pointcache", "vdbcache"] hosts = ["houdini"] label = "Validate Output Node" - actions = [SelectInvalidAction] + actions = [SelectROPAction] def process(self, instance): @@ -89,10 +89,10 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): @classmethod def repair(cls, instance): - """Select Invalid ROP. + """Select ROP. - It's used to select invalid ROP which tells the - artist which ROP node need to be fixed! + It's used to select the associated ROP for the selected instance + which tells the artist which ROP node need to be fixed! """ rop_node = hou.node(instance.data["instance_node"]) From 379cf0f76976843d966e4739d1fa6446d0524774 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Tue, 4 Jul 2023 13:29:24 +0300 Subject: [PATCH 09/16] add SelectInvalidAction --- .../plugins/publish/validate_sop_output_node.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py index 0d2aa64df6..834bc39a24 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py @@ -2,6 +2,7 @@ import pyblish.api from openpype.pipeline import PublishValidationError from openpype.pipeline.publish import RepairAction +from openpype.hosts.houdini.api.action import SelectInvalidAction import hou @@ -26,7 +27,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): families = ["pointcache", "vdbcache"] hosts = ["houdini"] label = "Validate Output Node" - actions = [SelectROPAction] + actions = [SelectROPAction, SelectInvalidAction] def process(self, instance): @@ -48,7 +49,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): "Ensure a valid SOP output path is set." % node.path() ) - return [node.path()] + return [node] # Output node must be a Sop node. if not isinstance(output_node, hou.SopNode): @@ -58,7 +59,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): "instead found category type: %s" % (output_node.path(), output_node.type().category().name()) ) - return [output_node.path()] + return [output_node] # For the sake of completeness also assert the category type # is Sop to avoid potential edge case scenarios even though @@ -78,14 +79,14 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): except hou.Error as exc: cls.log.error("Cook failed: %s" % exc) cls.log.error(output_node.errors()[0]) - return [output_node.path()] + return [output_node] # Ensure the output node has at least Geometry data if not output_node.geometry(): cls.log.error( "Output node `%s` has no geometry data." % output_node.path() ) - return [output_node.path()] + return [output_node] @classmethod def repair(cls, instance): From 612b85a703f05a460ecda0285ab441ef72334c39 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Tue, 4 Jul 2023 17:08:14 +0300 Subject: [PATCH 10/16] move SelectRopAction to api.actions --- openpype/hosts/houdini/api/action.py | 43 +++++++++++++++++++ .../publish/validate_sop_output_node.py | 26 ++--------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/houdini/api/action.py b/openpype/hosts/houdini/api/action.py index 27e8ce55bb..b6879bb276 100644 --- a/openpype/hosts/houdini/api/action.py +++ b/openpype/hosts/houdini/api/action.py @@ -44,3 +44,46 @@ class SelectInvalidAction(pyblish.api.Action): node.setCurrent(True) else: self.log.info("No invalid nodes found.") + + +class SelectROPAction(pyblish.api.Action): + """Select ROP. + + It's used to select the associated ROPs with all errored instances + not necessarily the ones that errored on the plugin we're running the action on. + """ + + label = "Select ROP" + on = "failed" # This action is only available on a failed plug-in + icon = "mdi.cursor-default-click" + + def process(self, context, plugin): + errored_instances = get_errored_instances_from_context(context) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(errored_instances, plugin) + + # Get the invalid nodes for the plug-ins + self.log.info("Finding ROP nodes..") + rop_nodes = list() + for instance in instances: + node_path = instance.data.get("instance_node") + if not node_path: + continue + + node = hou.node(node_path) + if not node: + continue + + rop_nodes.append(node) + + hou.clearAllSelected() + if rop_nodes: + self.log.info("Selecting ROP nodes: {}".format( + ", ".join(node.path() for node in rop_nodes) + )) + for node in rop_nodes: + node.setSelected(True) + node.setCurrent(True) + else: + self.log.info("No ROP nodes found.") diff --git a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py index 834bc39a24..d9dee38680 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_sop_output_node.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- import pyblish.api from openpype.pipeline import PublishValidationError -from openpype.pipeline.publish import RepairAction -from openpype.hosts.houdini.api.action import SelectInvalidAction +from openpype.hosts.houdini.api.action import ( + SelectInvalidAction, + SelectROPAction, +) import hou -class SelectROPAction(RepairAction): - label = "Select ROP" - icon = "mdi.cursor-default-click" - class ValidateSopOutputNode(pyblish.api.InstancePlugin): """Validate the instance SOP Output Node. @@ -87,19 +85,3 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin): "Output node `%s` has no geometry data." % output_node.path() ) return [output_node] - - @classmethod - def repair(cls, instance): - """Select ROP. - - It's used to select the associated ROP for the selected instance - which tells the artist which ROP node need to be fixed! - """ - - rop_node = hou.node(instance.data["instance_node"]) - rop_node.setSelected(True, clear_all_selected=True) - - cls.log.debug( - '%s has been selected' - % rop_node.path() - ) From d61bd762049acba4e6fbc0445cb031dde5f452e8 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Tue, 4 Jul 2023 17:11:21 +0300 Subject: [PATCH 11/16] fix lint problems --- openpype/hosts/houdini/api/action.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/api/action.py b/openpype/hosts/houdini/api/action.py index b6879bb276..a9afe38931 100644 --- a/openpype/hosts/houdini/api/action.py +++ b/openpype/hosts/houdini/api/action.py @@ -49,8 +49,7 @@ class SelectInvalidAction(pyblish.api.Action): class SelectROPAction(pyblish.api.Action): """Select ROP. - It's used to select the associated ROPs with all errored instances - not necessarily the ones that errored on the plugin we're running the action on. + It's used to select the associated ROPs with the errored instances. """ label = "Select ROP" From ba877956b94b1663ce6d38168eea48da8dd6bfca Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Wed, 5 Jul 2023 09:17:53 +0100 Subject: [PATCH 12/16] Fix collecting arnold prefix when none --- openpype/hosts/maya/api/lib_renderproducts.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/maya/api/lib_renderproducts.py b/openpype/hosts/maya/api/lib_renderproducts.py index a6bcd003a5..4f52372f06 100644 --- a/openpype/hosts/maya/api/lib_renderproducts.py +++ b/openpype/hosts/maya/api/lib_renderproducts.py @@ -528,6 +528,9 @@ class RenderProductsArnold(ARenderProducts): def get_renderer_prefix(self): prefix = super(RenderProductsArnold, self).get_renderer_prefix() + if prefix is None: + return "" + merge_aovs = self._get_attr("defaultArnoldDriver.mergeAOVs") if not merge_aovs and "" not in prefix.lower(): # When Merge AOVs is disabled and token not present From 9dbba9394b97562025a83cbc5075e17f22dedf73 Mon Sep 17 00:00:00 2001 From: Mustafa-Zarkash Date: Wed, 5 Jul 2023 14:06:58 +0300 Subject: [PATCH 13/16] update action with roy's PR --- openpype/hosts/houdini/api/action.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/houdini/api/action.py b/openpype/hosts/houdini/api/action.py index a9afe38931..eeb9cfda62 100644 --- a/openpype/hosts/houdini/api/action.py +++ b/openpype/hosts/houdini/api/action.py @@ -57,15 +57,12 @@ class SelectROPAction(pyblish.api.Action): icon = "mdi.cursor-default-click" def process(self, context, plugin): - errored_instances = get_errored_instances_from_context(context) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(errored_instances, plugin) + errored_instances = get_errored_instances_from_context(context, plugin) # Get the invalid nodes for the plug-ins self.log.info("Finding ROP nodes..") rop_nodes = list() - for instance in instances: + for instance in errored_instances: node_path = instance.data.get("instance_node") if not node_path: continue From 974d70869300015c9044a1a4b043b50c247ed670 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Wed, 5 Jul 2023 12:41:26 +0100 Subject: [PATCH 14/16] Revert "Fix collecting arnold prefix when none" This reverts commit ba877956b94b1663ce6d38168eea48da8dd6bfca. --- openpype/hosts/maya/api/lib_renderproducts.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib_renderproducts.py b/openpype/hosts/maya/api/lib_renderproducts.py index 4f52372f06..a6bcd003a5 100644 --- a/openpype/hosts/maya/api/lib_renderproducts.py +++ b/openpype/hosts/maya/api/lib_renderproducts.py @@ -528,9 +528,6 @@ class RenderProductsArnold(ARenderProducts): def get_renderer_prefix(self): prefix = super(RenderProductsArnold, self).get_renderer_prefix() - if prefix is None: - return "" - merge_aovs = self._get_attr("defaultArnoldDriver.mergeAOVs") if not merge_aovs and "" not in prefix.lower(): # When Merge AOVs is disabled and token not present From 558cd4fe6818cb708c46d2b3f02f6a4125e8b355 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Wed, 5 Jul 2023 12:42:16 +0100 Subject: [PATCH 15/16] Use BigRoy soluiton --- openpype/hosts/maya/api/lib_renderproducts.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/api/lib_renderproducts.py b/openpype/hosts/maya/api/lib_renderproducts.py index a6bcd003a5..7bfb53d500 100644 --- a/openpype/hosts/maya/api/lib_renderproducts.py +++ b/openpype/hosts/maya/api/lib_renderproducts.py @@ -274,12 +274,14 @@ class ARenderProducts: "Unsupported renderer {}".format(self.renderer) ) + # Note: When this attribute is never set (e.g. on maya launch) then + # this can return None even though it is a string attribute prefix = self._get_attr(prefix_attr) if not prefix: # Fall back to scene name by default - log.debug("Image prefix not set, using ") - file_prefix = "" + log.warning("Image prefix not set, using ") + prefix = "" return prefix From 587b98d65eb9b3f858a519f9760b8fbcf0c92522 Mon Sep 17 00:00:00 2001 From: Kayla Man <64118225+moonyuet@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:14:58 +0800 Subject: [PATCH 16/16] General: add the os library before os.environ.get (#5249) * add the os library before os.environ.get * move os import into the top --- openpype/pipeline/create/creator_plugins.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/pipeline/create/creator_plugins.py b/openpype/pipeline/create/creator_plugins.py index fbb459ab12..947a90ef08 100644 --- a/openpype/pipeline/create/creator_plugins.py +++ b/openpype/pipeline/create/creator_plugins.py @@ -1,3 +1,4 @@ +import os import copy import collections