From d9c67a0bd50fb5c8625632d942c6bf4bf85eb908 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 16:43:53 +0200 Subject: [PATCH 01/11] Improve speed of logging for when its validating a node with many prims. --- .../publish/validate_vdb_output_node.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index f9f88b3bf9..e7908ab119 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -2,6 +2,7 @@ import pyblish.api import hou from openpype.pipeline import PublishValidationError +import clique class ValidateVDBOutputNode(pyblish.api.InstancePlugin): @@ -56,12 +57,21 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): nr_of_prims = len(prims) # All primitives must be hou.VDB - invalid_prim = False + invalid_prims = [] for prim in prims: if not isinstance(prim, hou.VDB): - cls.log.error("Found non-VDB primitive: %s" % prim) - invalid_prim = True - if invalid_prim: + invalid_prims.append(prim) + if invalid_prims: + # Log all invalid primitives in a short readable way, like 0-5 + collections, remainder = clique.assemble( + str(prim.number()) for prim in invalid_prims + ) + collection = collections[0] + cls.log.error("Found non-VDB primitives for '{}', " + "primitive indices: {}".format( + node.path(), + collection.format("{ranges}") + )) return [instance] nr_of_points = len(geometry.points()) From e2e03346fa5592c39fdd4cf3904a479f8f029f75 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 17:35:29 +0200 Subject: [PATCH 02/11] Fix VDB validation --- ..._node.xml => validate_vdb_output_node.xml} | 0 .../publish/validate_vdb_input_node.py | 52 ------------------- .../publish/validate_vdb_output_node.py | 27 +++++----- 3 files changed, 13 insertions(+), 66 deletions(-) rename openpype/hosts/houdini/plugins/publish/help/{validate_vdb_input_node.xml => validate_vdb_output_node.xml} (100%) delete mode 100644 openpype/hosts/houdini/plugins/publish/validate_vdb_input_node.py diff --git a/openpype/hosts/houdini/plugins/publish/help/validate_vdb_input_node.xml b/openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml similarity index 100% rename from openpype/hosts/houdini/plugins/publish/help/validate_vdb_input_node.xml rename to openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_input_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_input_node.py deleted file mode 100644 index 1f9ccc9c42..0000000000 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_input_node.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -import pyblish.api -from openpype.pipeline import ( - PublishValidationError -) - - -class ValidateVDBInputNode(pyblish.api.InstancePlugin): - """Validate that the node connected to the output node is of type VDB. - - Regardless of the amount of VDBs create the output will need to have an - equal amount of VDBs, points, primitives and vertices - - A VDB is an inherited type of Prim, holds the following data: - - Primitives: 1 - - Points: 1 - - Vertices: 1 - - VDBs: 1 - - """ - - order = pyblish.api.ValidatorOrder + 0.1 - families = ["vdbcache"] - hosts = ["houdini"] - label = "Validate Input Node (VDB)" - - def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError( - self, - "Node connected to the output node is not of type VDB", - title=self.label - ) - - @classmethod - def get_invalid(cls, instance): - - node = instance.data["output_node"] - - prims = node.geometry().prims() - nr_of_prims = len(prims) - - nr_of_points = len(node.geometry().points()) - if nr_of_points != nr_of_prims: - cls.log.error("The number of primitives and points do not match") - return [instance] - - for prim in prims: - if prim.numVertices() != 1: - cls.log.error("Found primitive with more than 1 vertex!") - return [instance] diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index e7908ab119..ee3b9a0a6a 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import pyblish.api import hou -from openpype.pipeline import PublishValidationError -import clique +from openpype.pipeline import PublishXmlValidationError class ValidateVDBOutputNode(pyblish.api.InstancePlugin): @@ -27,9 +26,9 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): def process(self, instance): invalid = self.get_invalid(instance) if invalid: - raise PublishValidationError( - "Node connected to the output node is not" " of type VDB!", - title=self.label + raise PublishXmlValidationError( + self, + "Node connected to the output node is not" " of type VDB!" ) @classmethod @@ -62,16 +61,16 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): if not isinstance(prim, hou.VDB): invalid_prims.append(prim) if invalid_prims: - # Log all invalid primitives in a short readable way, like 0-5 - collections, remainder = clique.assemble( - str(prim.number()) for prim in invalid_prims + # TODO Log all invalid primitives in a short readable way, like 0-5 + # This logging can be really slow for many primitives, say 20000+ + # which might be fixed by logging only consecutive ranges + cls.log.error( + "Found non-VDB primitives for '{}', " + "primitive indices: {}".format( + node.path(), + ", ".join(prim.number() for prim in invalid_prims) + ) ) - collection = collections[0] - cls.log.error("Found non-VDB primitives for '{}', " - "primitive indices: {}".format( - node.path(), - collection.format("{ranges}") - )) return [instance] nr_of_points = len(geometry.points()) From 3e71ace6b762806d3b4ee097d4bd523d13dbe627 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 17:37:35 +0200 Subject: [PATCH 03/11] Fix logic --- .../hosts/houdini/plugins/publish/validate_vdb_output_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index ee3b9a0a6a..a8fb5007cf 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -68,7 +68,7 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): "Found non-VDB primitives for '{}', " "primitive indices: {}".format( node.path(), - ", ".join(prim.number() for prim in invalid_prims) + ", ".join(str(prim.number()) for prim in invalid_prims) ) ) return [instance] From 3f404002e5abc8eee6778fda6a7363a29273329f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 17:41:41 +0200 Subject: [PATCH 04/11] Cosmetics + less aggresive message (no exclamation point) --- .../hosts/houdini/plugins/publish/validate_vdb_output_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index a8fb5007cf..dd9ffc2a12 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -28,7 +28,7 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): if invalid: raise PublishXmlValidationError( self, - "Node connected to the output node is not" " of type VDB!" + "Node connected to the output node is not of type VDB." ) @classmethod From 13b72fa57ccdb1353d515eac1da797e024175774 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 17:59:36 +0200 Subject: [PATCH 05/11] Improve logging speed + readability for large number of primitives --- .../publish/validate_vdb_output_node.py | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index dd9ffc2a12..98a0796fec 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -4,6 +4,39 @@ import hou from openpype.pipeline import PublishXmlValidationError +def group_consecutive_numbers(nums): + """ + Args: + nums (list): List of sorted integer numbers. + + Yields: + str: Group ranges as {start}-{end} if more than one number in the range + else it yields {end} + + """ + start = None + end = None + + def _result(a, b): + if a == b: + return "{}".format(a) + else: + return "{}-{}".format(a, b) + + for num in nums: + if start is None: + start = num + end = num + elif num == end + 1: + end = num + else: + yield _result(start, end) + start = num + end = num + if start is not None: + yield _result(start, end) + + class ValidateVDBOutputNode(pyblish.api.InstancePlugin): """Validate that the node connected to the output node is of type VDB. @@ -61,14 +94,15 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): if not isinstance(prim, hou.VDB): invalid_prims.append(prim) if invalid_prims: - # TODO Log all invalid primitives in a short readable way, like 0-5 - # This logging can be really slow for many primitives, say 20000+ - # which might be fixed by logging only consecutive ranges + # Log prim numbers as consecutive ranges so logging isn't very + # slow for large number of primitives cls.log.error( "Found non-VDB primitives for '{}', " "primitive indices: {}".format( node.path(), - ", ".join(str(prim.number()) for prim in invalid_prims) + ", ".join(group_consecutive_numbers( + prim.number() for prim in invalid_prims + )) ) ) return [instance] From 97f13a169b421ec8341f6f3c1b02a1cd5d1b4206 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Apr 2023 18:11:35 +0200 Subject: [PATCH 06/11] Allow output node to be not collected, then correctly show error --- .../hosts/houdini/plugins/publish/validate_vdb_output_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index 98a0796fec..b2b5c63799 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -67,7 +67,7 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): @classmethod def get_invalid(cls, instance): - node = instance.data["output_node"] + node = instance.data.get("output_node") if node is None: cls.log.error( "SOP path is not correctly set on " From b3044398fc9181db2d2230f9f0f5cc1de7e9d297 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 19 Apr 2023 23:43:47 +0200 Subject: [PATCH 07/11] Improve validation report + allow to select the invalid node --- openpype/hosts/houdini/api/action.py | 46 +++++++ .../publish/help/validate_vdb_output_node.xml | 25 ++-- .../publish/validate_vdb_output_node.py | 112 ++++++++++++------ 3 files changed, 135 insertions(+), 48 deletions(-) create mode 100644 openpype/hosts/houdini/api/action.py diff --git a/openpype/hosts/houdini/api/action.py b/openpype/hosts/houdini/api/action.py new file mode 100644 index 0000000000..27e8ce55bb --- /dev/null +++ b/openpype/hosts/houdini/api/action.py @@ -0,0 +1,46 @@ +import pyblish.api +import hou + +from openpype.pipeline.publish import get_errored_instances_from_context + + +class SelectInvalidAction(pyblish.api.Action): + """Select invalid nodes in Maya when plug-in failed. + + To retrieve the invalid nodes this assumes a static `get_invalid()` + method is available on the plugin. + + """ + label = "Select invalid" + on = "failed" # This action is only available on a failed plug-in + icon = "search" # Icon from Awesome Icon + + 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 invalid nodes..") + invalid = list() + for instance in instances: + invalid_nodes = plugin.get_invalid(instance) + if invalid_nodes: + if isinstance(invalid_nodes, (list, tuple)): + invalid.extend(invalid_nodes) + else: + self.log.warning("Plug-in returned to be invalid, " + "but has no selectable nodes.") + + hou.clearAllSelected() + if invalid: + self.log.info("Selecting invalid nodes: {}".format( + ", ".join(node.path() for node in invalid) + )) + for node in invalid: + node.setSelected(True) + node.setCurrent(True) + else: + self.log.info("No invalid nodes found.") diff --git a/openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml b/openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml index 0f92560bf7..eb83bfffe3 100644 --- a/openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml +++ b/openpype/hosts/houdini/plugins/publish/help/validate_vdb_output_node.xml @@ -1,21 +1,28 @@ -Scene setting +Invalid VDB -## Invalid input node +## Invalid VDB output + +All primitives of the output geometry must be VDBs, no other primitive +types are allowed. That means that regardless of the amount of VDBs in the +geometry it will have an equal amount of VDBs, points, primitives and +vertices since each VDB primitive is one point, one vertex and one VDB. + +This validation only checks the geometry on the first frame of the export +frame range. + -VDB input must have the same number of VDBs, points, primitives and vertices as output. -### __Detailed Info__ (optional) +### Detailed Info + +ROP node `{rop_path}` is set to export SOP path `{sop_path}`. + +{message} -A VDB is an inherited type of Prim, holds the following data: - - Primitives: 1 - - Points: 1 - - Vertices: 1 - - VDBs: 1 \ No newline at end of file diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index b2b5c63799..3fa75e5822 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- import pyblish.api import hou + from openpype.pipeline import PublishXmlValidationError +from openpype.hosts.houdini.api.action import SelectInvalidAction def group_consecutive_numbers(nums): @@ -40,8 +42,13 @@ def group_consecutive_numbers(nums): class ValidateVDBOutputNode(pyblish.api.InstancePlugin): """Validate that the node connected to the output node is of type VDB. - Regardless of the amount of VDBs create the output will need to have an - equal amount of VDBs, points, primitives and vertices + All primitives of the output geometry must be VDBs, no other primitive + types are allowed. That means that regardless of the amount of VDBs in the + geometry it will have an equal amount of VDBs, points, primitives and + vertices since each VDB primitive is one point, one vertex and one VDB. + + This validation only checks the geometry on the first frame of the export + frame range for optimization purposes. A VDB is an inherited type of Prim, holds the following data: - Primitives: 1 @@ -55,64 +62,91 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): families = ["vdbcache"] hosts = ["houdini"] label = "Validate Output Node (VDB)" + actions = [SelectInvalidAction] def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: + invalid_nodes, message = self.get_invalid_with_message(instance) + if invalid_nodes: raise PublishXmlValidationError( self, - "Node connected to the output node is not of type VDB." + "Node connected to the output node is not of type VDB.", + formatting_data={ + "message": message, + "rop_path": instance.data.get("instance_node"), + "sop_path": instance.data.get("output_node") + } ) @classmethod - def get_invalid(cls, instance): + def get_invalid_with_message(cls, instance): node = instance.data.get("output_node") if node is None: - cls.log.error( + instance_node = instance.data.get("instance_node") + error = ( "SOP path is not correctly set on " - "ROP node '%s'." % instance.data.get("instance_node") + "ROP node `%s`." % instance_node ) - return [instance] + return [instance_node, error] frame = instance.data.get("frameStart", 0) + node.cook(force=True, frame_range=(frame, frame)) geometry = node.geometryAtFrame(frame) if geometry is None: # No geometry data on this node, maybe the node hasn't cooked? - cls.log.error( + error = ( "SOP node has no geometry data. " "Is it cooked? %s" % node.path() ) - return [node] + return [node, error] - prims = geometry.prims() - nr_of_prims = len(prims) - - # All primitives must be hou.VDB - invalid_prims = [] - for prim in prims: - if not isinstance(prim, hou.VDB): - invalid_prims.append(prim) - if invalid_prims: - # Log prim numbers as consecutive ranges so logging isn't very - # slow for large number of primitives - cls.log.error( - "Found non-VDB primitives for '{}', " - "primitive indices: {}".format( - node.path(), - ", ".join(group_consecutive_numbers( - prim.number() for prim in invalid_prims - )) - ) + num_prims = geometry.intrinsicValue("primitivecount") + num_points = geometry.intrinsicValue("pointcount") + if num_prims == 0 and num_points == 0: + # Since we are only checking the first frame it doesn't mean there + # won't be VDB prims in a few frames. As such we'll assume for now + # the user knows what he or she is doing + cls.log.warning( + "SOP node `{}` has no primitives on start frame {}. " + "Validation is skipped and it is assumed elsewhere in the " + "frame range VDB prims and only VDB prims will exist." + "".format(node.path(), int(frame)) ) - return [instance] + return [None, None] - nr_of_points = len(geometry.points()) - if nr_of_points != nr_of_prims: - cls.log.error("The number of primitives and points do not match") - return [instance] + num_vdb_prims = geometry.countPrimType(hou.primType.VDB) + cls.log.debug("Detected {} VDB primitives".format(num_vdb_prims)) + if num_prims != num_vdb_prims: + # There's at least one primitive that is not a VDB. + # Search them and report them to the artist. + prims = geometry.prims() + invalid_prims = [prim for prim in prims + if not isinstance(prim, hou.VDB)] + if invalid_prims: + # Log prim numbers as consecutive ranges so logging isn't very + # slow for large number of primitives + error = ( + "Found non-VDB primitives for `{}`. " + "Primitive indices {} are not VDB primitives.".format( + node.path(), + ", ".join(group_consecutive_numbers( + prim.number() for prim in invalid_prims + )) + ) + ) + return [node, error] - for prim in prims: - if prim.numVertices() != 1: - cls.log.error("Found primitive with more than 1 vertex!") - return [instance] + if num_points != num_vdb_prims: + # We have points unrelated to the VDB primitives. + error = ( + "The number of primitives and points do not match in '{}'. " + "This likely means you have unconnected points, which we do " + "not allow in the VDB output.".format(node.path())) + return [node, error] + + return [None, None] + + @classmethod + def get_invalid(cls, instance): + nodes, _ = cls.get_invalid_with_message(instance) + return nodes From bb24b823649c3cf124fafb9c465a9fd5709d193a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 20 Apr 2023 00:05:07 +0200 Subject: [PATCH 08/11] Fix type bug --- .../houdini/plugins/publish/validate_vdb_output_node.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index 3fa75e5822..def9595e9a 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -67,13 +67,18 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): def process(self, instance): invalid_nodes, message = self.get_invalid_with_message(instance) if invalid_nodes: + + # instance_node is str, but output_node is hou.Node so we convert + output = instance.data.get("output_node") + output_path = output.path() if output else None + raise PublishXmlValidationError( self, "Node connected to the output node is not of type VDB.", formatting_data={ "message": message, "rop_path": instance.data.get("instance_node"), - "sop_path": instance.data.get("output_node") + "sop_path": output_path } ) From 9484bd4a51c465957b49c83c915b0995f1a4de98 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 20 Apr 2023 00:05:47 +0200 Subject: [PATCH 09/11] Force geometry update, otherwise manual update mode will fail to get the geometry correctly --- .../publish/validate_vdb_output_node.py | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index def9595e9a..43da4b0528 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import contextlib + import pyblish.api import hou @@ -39,6 +41,23 @@ def group_consecutive_numbers(nums): yield _result(start, end) +@contextlib.contextmanager +def update_mode_context(mode): + original = hou.updateModeSetting() + try: + hou.setUpdateMode(mode) + yield + finally: + hou.setUpdateMode(original) + + +def get_geometry_at_frame(sop_node, frame, force=True): + """Return geometry at frame but force a cooked value.""" + with update_mode_context(hou.updateMode.AutoUpdate): + sop_node.cook(force=force, frame_range=(frame, frame)) + return sop_node.geometryAtFrame(frame) + + class ValidateVDBOutputNode(pyblish.api.InstancePlugin): """Validate that the node connected to the output node is of type VDB. @@ -95,8 +114,7 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): return [instance_node, error] frame = instance.data.get("frameStart", 0) - node.cook(force=True, frame_range=(frame, frame)) - geometry = node.geometryAtFrame(frame) + geometry = get_geometry_at_frame(node, frame) if geometry is None: # No geometry data on this node, maybe the node hasn't cooked? error = ( From cbd88a616c0420448c3cb3b9028d6e15482a314c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 20 Apr 2023 00:06:10 +0200 Subject: [PATCH 10/11] Tweak formatting, fix type bug for instance node --- .../houdini/plugins/publish/validate_vdb_output_node.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index 43da4b0528..bd1fb0b887 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -109,17 +109,17 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): instance_node = instance.data.get("instance_node") error = ( "SOP path is not correctly set on " - "ROP node `%s`." % instance_node + "ROP node `{}`.".format(instance_node) ) - return [instance_node, error] + return [hou.node(instance_node), error] frame = instance.data.get("frameStart", 0) geometry = get_geometry_at_frame(node, frame) if geometry is None: # No geometry data on this node, maybe the node hasn't cooked? error = ( - "SOP node has no geometry data. " - "Is it cooked? %s" % node.path() + "SOP node `{}` has no geometry data. " + "Was it unable to cook?".format(node.path()) ) return [node, error] From 175db5407403dcb8e0b3a3f7a49b39463b2ceb56 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 20 Apr 2023 00:09:50 +0200 Subject: [PATCH 11/11] Tweak logged message for non-UI report --- .../hosts/houdini/plugins/publish/validate_vdb_output_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py index bd1fb0b887..674782179c 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py +++ b/openpype/hosts/houdini/plugins/publish/validate_vdb_output_node.py @@ -93,7 +93,7 @@ class ValidateVDBOutputNode(pyblish.api.InstancePlugin): raise PublishXmlValidationError( self, - "Node connected to the output node is not of type VDB.", + "Invalid VDB content: {}".format(message), formatting_data={ "message": message, "rop_path": instance.data.get("instance_node"),