diff --git a/client/ayon_core/hosts/max/plugins/publish/help/validate_model_name.xml b/client/ayon_core/hosts/max/plugins/publish/help/validate_model_name.xml
new file mode 100644
index 0000000000..e41146910a
--- /dev/null
+++ b/client/ayon_core/hosts/max/plugins/publish/help/validate_model_name.xml
@@ -0,0 +1,26 @@
+
+
+
+Invalid Model Name
+## Nodes found with Invalid Model Name
+
+Nodes were detected in your scene which have invalid model name which does not
+match the regex you preset in AYON setting.
+### How to repair?
+Make sure the model name aligns with validation regex in your AYON setting.
+
+
+
+### Invalid nodes
+
+{nodes}
+
+
+### How could this happen?
+
+This often happens if you have mesh with the model naming does not match
+with regex in the setting.
+
+
+
+
\ No newline at end of file
diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py
index 87a9132989..a0cad4e454 100644
--- a/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py
+++ b/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py
@@ -3,30 +3,34 @@
import re
import pyblish.api
-from pymxs import runtime as rt
from ayon_core.hosts.max.api.action import SelectInvalidAction
from ayon_core.pipeline.publish import (
OptionalPyblishPluginMixin,
- PublishValidationError,
- ValidateContentsOrder)
-
+ PublishXmlValidationError,
+ ValidateContentsOrder
+)
class ValidateModelName(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
- """Validate Model Name
- Validation regex is (.*)_(?P.*)_(GEO) by default.
- e.g. {SOME_RANDOM_NAME}_{YOUR_SUBSET_NAME}_GEO should be your
- default model name
+ """Validate Model Name.
- The regex of (?P.*) can be replaced by (?P.*)
- and (?P.*).
- e.g.
- - (.*)_(?P.*)_(GEO) check if your model name is
- {SOME_RANDOM_NAME}_{CURRENT_ASSET_NAME}_GEO
- - (.*)_(?P.*)_(GEO) check if your model name is
- {SOME_RANDOM_NAME}_{CURRENT_PROJECT_NAME}_GEO
+ Validation regex is `(.*)_(?P.*)_(GEO)` by default.
+ The setting supports the following regex group name:
+ - project
+ - asset
+ - subset
+
+ Examples:
+ `{SOME_RANDOM_NAME}_{YOUR_SUBSET_NAME}_GEO` should be your
+ default model name.
+ The regex of `(?P.*)` can be replaced by `(?P.*)`
+ and `(?P.*)`.
+ `(.*)_(?P.*)_(GEO)` check if your model name is
+ `{SOME_RANDOM_NAME}_{CURRENT_ASSET_NAME}_GEO`
+ `(.*)_(?P.*)_(GEO)` check if your model name is
+ `{SOME_RANDOM_NAME}_{CURRENT_PROJECT_NAME}_GEO`
"""
optional = True
@@ -35,66 +39,82 @@ class ValidateModelName(pyblish.api.InstancePlugin,
families = ["model"]
label = "Validate Model Name"
actions = [SelectInvalidAction]
- regex = ""
-
- @classmethod
- def get_invalid(cls, instance):
- invalid = []
- model_names = [model.name for model in instance.data.get("members")]
- cls.log.debug(model_names)
- if not model_names:
- cls.log.error("No Model found in the OP Data.")
- invalid.append(model_names)
- for name in model_names:
- invalid_model_name = cls.get_invalid_model_name(instance, name)
- invalid.extend(invalid_model_name)
-
- return invalid
-
- @classmethod
- def get_invalid_model_name(cls, instance, name):
- invalid = []
- regex = cls.regex
- reg = re.compile(regex)
- matched_name = reg.match(name)
- project_name = instance.context.data["projectName"]
- current_asset_name = instance.context.data["folderPath"]
- if matched_name is None:
- cls.log.error("invalid model name on: {}".format(name))
- cls.log.error("name doesn't match regex {}".format(regex))
- invalid.append((rt.getNodeByName(name),
- "Model name doesn't match regex"))
- else:
- if "asset" in reg.groupindex:
- if matched_name.group("asset") != current_asset_name:
- cls.log.error(
- "Invalid asset name of the model {}.".format(name)
- )
- invalid.append((rt.getNodeByName(name),
- "Model with invalid asset name"))
- if "subset" in reg.groupindex:
- if matched_name.group("subset") != instance.name:
- cls.log.error(
- "Invalid subset name of the model {}.".format(name)
- )
- invalid.append((rt.getNodeByName(name),
- "Model with invalid subset name"))
- if "project" in reg.groupindex:
- if matched_name.group("project") != project_name:
- cls.log.error(
- "Invalid project name of the model {}.".format(name)
- )
- invalid.append((rt.getNodeByName(name),
- "Model with invalid project name"))
- return invalid
+ # defined by settings
+ regex = r"(.*)_(?P.*)_(GEO)"
+ # cache
+ regex_compiled = None
def process(self, instance):
if not self.is_active(instance.data):
- self.log.debug("Skipping Validate Model Name...")
return
invalid = self.get_invalid(instance)
+ if invalid:
+ names = "\n".join(
+ "- {}".format(node.name) for node in invalid
+ )
+ raise PublishXmlValidationError(
+ plugin=self,
+ message="Nodes found with invalid model names: {}".format(invalid),
+ formatting_data={"nodes": names}
+ )
+
+ @classmethod
+ def get_invalid(cls, instance):
+ if not cls.regex:
+ cls.log.warning("No regex pattern set. Nothing to validate.")
+ return
+
+ members = instance.data.get("members")
+ if not members:
+ cls.log.error("No members found in the instance.")
+ return
+
+ cls.regex_compiled = re.compile(cls.regex)
+
+ invalid = []
+ for obj in members:
+ if cls.invalid_name(instance, obj):
+ invalid.append(obj)
+ return invalid
+
+ @classmethod
+ def invalid_name(cls, instance, obj):
+ """Function to check the object has invalid name
+ regarding to the validation regex in the AYON setttings
+
+ Args:
+ instance (pyblish.api.instance): Instance
+ obj (str): object name
+
+ Returns:
+ str: invalid object
+ """
+ regex = cls.regex_compiled
+ name = obj.name
+ match = regex.match(name)
+
+ if match is None:
+ cls.log.error("Invalid model name on: %s", name)
+ cls.log.error("Name doesn't match regex {}".format(regex.pattern))
+ return obj
+
+ # Validate regex groups
+ invalid = False
+ compare = {
+ "project": instance.context.data["projectName"],
+ "asset": instance.context.data["folderPath"],
+ "subset": instance.context.data["subset"],
+ }
+ for key, required_value in compare.items():
+ if key in regex.groupindex:
+ if match.group(key) != required_value:
+ cls.log.error(
+ "Invalid %s name for the model %s, "
+ "required name is %s",
+ key, name, required_value
+ )
+ invalid = True
if invalid:
- raise PublishValidationError(
- "Model naming is invalid. See the log.")
+ return obj