From b17df02e418b2061ec6631d028e3039ce55105f5 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 23:04:58 +0100 Subject: [PATCH 1/3] Maya: Validate Model Content improve validation message - Also fix `get_invalid` actually returning the instance node. --- .../plugins/publish/validate_model_content.py | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py index 37c78a72ee..97d602a9ad 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py @@ -28,13 +28,15 @@ class ValidateModelContent(pyblish.api.InstancePlugin, validate_top_group = True optional = False + allowed = ('mesh', 'transform', 'nurbsCurve', 'nurbsSurface', 'locator') + @classmethod def get_invalid(cls, instance): content_instance = instance.data.get("setMembers", None) if not content_instance: cls.log.error("Instance has no nodes!") - return [instance.data["name"]] + return [instance.data["instance_node"]] # All children will be included in the extracted export so we also # validate *all* descendents of the set members and we skip any @@ -46,30 +48,39 @@ def get_invalid(cls, instance): content_instance = list(set(content_instance + descendants)) # Ensure only valid node types - allowed = ('mesh', 'transform', 'nurbsCurve', 'nurbsSurface', 'locator') nodes = cmds.ls(content_instance, long=True) - valid = cmds.ls(content_instance, long=True, type=allowed) + valid = cmds.ls(content_instance, long=True, type=cls.allowed) invalid = set(nodes) - set(valid) if invalid: - cls.log.error("These nodes are not allowed: %s" % invalid) + cls.log.error( + "These nodes are not allowed: {}.\n" + "The valid node types are: {}".format(", ".join(invalid), + ", ".join(cls.allowed)) + ) return list(invalid) if not valid: - cls.log.error("No valid nodes in the instance") - return True + cls.log.error( + "No valid nodes in the model instance.\n" + "The valid node types are: {}".format(", ".join(cls.allowed)) + ) + return [instance.data["instance_node"]] # Ensure it has shapes shapes = cmds.ls(valid, long=True, shapes=True) if not shapes: cls.log.error("No shapes in the model instance") - return True + return [instance.data["instance_node"]] - # Top group - top_parents = set([x.split("|")[1] for x in content_instance]) + # Ensure single top group + top_parents = {x.split("|", 2)[1] for x in content_instance} if cls.validate_top_group and len(top_parents) != 1: - cls.log.error("Must have exactly one top group") - return top_parents + cls.log.error( + "A model instance must have exactly one top group. " + "Found top groups: {}".format(", ".join(top_parents)) + ) + return list(top_parents) def _is_visible(node): """Return whether node is visible""" @@ -101,5 +112,11 @@ def process(self, instance): if invalid: raise PublishValidationError( title="Model content is invalid", - message="See log for more details" + message="Model content is invalid. See log for more details.", + description=( + "## Model content is invalid\n" + "Your model instance does not adhere to the rules of a " + "model.\n\n" + "See log for more details." + ) ) From 1e0c115a5ad52375b63060250e32fd8a95037f82 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 4 Apr 2024 16:38:00 +0200 Subject: [PATCH 2/3] Improve artist-facing report --- .../plugins/publish/validate_model_content.py | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py index 97d602a9ad..015f4c11ed 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py @@ -1,3 +1,5 @@ +import inspect + from maya import cmds import pyblish.api @@ -14,8 +16,7 @@ class ValidateModelContent(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): """Adheres to the content of 'model' product type - - Must have one top group. (configurable) - - Must only contain: transforms, meshes and groups + See `get_description` for more details. """ @@ -35,7 +36,8 @@ def get_invalid(cls, instance): content_instance = instance.data.get("setMembers", None) if not content_instance: - cls.log.error("Instance has no nodes!") + cls.log.error("Model instance has no nodes. " + "It is not allowed to be empty") return [instance.data["instance_node"]] # All children will be included in the extracted export so we also @@ -53,10 +55,13 @@ def get_invalid(cls, instance): invalid = set(nodes) - set(valid) if invalid: + # List as bullet points + invalid_bullets = "\n".join(f"- {node}" for node in invalid) + cls.log.error( - "These nodes are not allowed: {}.\n" - "The valid node types are: {}".format(", ".join(invalid), - ", ".join(cls.allowed)) + "These nodes are not allowed:\n{}\n" + "The valid node types are: {}".format( + invalid_bullets, ", ".join(cls.allowed)) ) return list(invalid) @@ -113,10 +118,20 @@ def process(self, instance): raise PublishValidationError( title="Model content is invalid", message="Model content is invalid. See log for more details.", - description=( - "## Model content is invalid\n" - "Your model instance does not adhere to the rules of a " - "model.\n\n" - "See log for more details." - ) + description=self.get_description() ) + + @classmethod + def get_description(cls): + return inspect.cleandoc(f""" + ### Model content is invalid + + Your model instance does not adhere to the rules of a + model product type: + + - Must have at least one visible shape in it, like a mesh. + - Must have one root node. When exporting multiple meshes they + must be inside a group. + - May only contain the following node types: + {", ".join(cls.allowed)} + """) From fca484dd01cb84f1b14f23d1d50690955eeae57a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 4 Apr 2024 17:11:26 +0200 Subject: [PATCH 3/3] Improve log readability --- .../hosts/maya/plugins/publish/validate_model_content.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py index 015f4c11ed..1001bee91f 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_content.py @@ -59,7 +59,7 @@ def get_invalid(cls, instance): invalid_bullets = "\n".join(f"- {node}" for node in invalid) cls.log.error( - "These nodes are not allowed:\n{}\n" + "These nodes are not allowed:\n{}\n\n" "The valid node types are: {}".format( invalid_bullets, ", ".join(cls.allowed)) )