Skip to content

Commit

Permalink
Merge pull request #59 from ynput/enhancement/OP-7076_Validate-Model-…
Browse files Browse the repository at this point in the history
…Name

Max: Implementation of the validator for model name
  • Loading branch information
moonyuet authored Mar 7, 2024
2 parents 1b7e22b + d35d719 commit 7dc8505
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<error id="main">
<title>Invalid Model Name</title>
<description>## 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.

</description>
<detail>
### 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.

</detail>
</error>
</root>
120 changes: 120 additions & 0 deletions client/ayon_core/hosts/max/plugins/publish/validate_model_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
"""Validate model nodes names."""
import re

import pyblish.api

from ayon_core.hosts.max.api.action import SelectInvalidAction

from ayon_core.pipeline.publish import (
OptionalPyblishPluginMixin,
PublishXmlValidationError,
ValidateContentsOrder
)

class ValidateModelName(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Validate Model Name.
Validation regex is `(.*)_(?P<subset>.*)_(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<subset>.*)` can be replaced by `(?P<asset>.*)`
and `(?P<project>.*)`.
`(.*)_(?P<asset>.*)_(GEO)` check if your model name is
`{SOME_RANDOM_NAME}_{CURRENT_ASSET_NAME}_GEO`
`(.*)_(?P<project>.*)_(GEO)` check if your model name is
`{SOME_RANDOM_NAME}_{CURRENT_PROJECT_NAME}_GEO`
"""
optional = True
order = ValidateContentsOrder
hosts = ["max"]
families = ["model"]
label = "Validate Model Name"
actions = [SelectInvalidAction]
# defined by settings
regex = r"(.*)_(?P<subset>.*)_(GEO)"
# cache
regex_compiled = None

def process(self, instance):
if not self.is_active(instance.data):
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:
return obj
24 changes: 24 additions & 0 deletions server_addon/max/server/settings/publishers.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ class FamilyMappingItemModel(BaseSettingsModel):
)


class ValidateModelNameModel(BaseSettingsModel):
enabled: bool = SettingsField(title="Enabled")
optional: bool = SettingsField(title="Optional")
active: bool = SettingsField(title="Active")
regex: str = SettingsField(
"(.*)_(?P<subset>.*)_(GEO)",
title="Validation regex",
description=(
"Regex for validating model name. You can use named "
" capturing groups:(?P<asset>.*) for Asset name"
)
)


class ValidateLoadedPluginModel(BaseSettingsModel):
enabled: bool = SettingsField(title="Enabled")
optional: bool = SettingsField(title="Optional")
Expand Down Expand Up @@ -98,6 +112,10 @@ class PublishersModel(BaseSettingsModel):
default_factory=BasicValidateModel,
title="Validate Mesh Has UVs"
)
ValidateModelName: ValidateModelNameModel = SettingsField(
default_factory=ValidateModelNameModel,
title="Validate Model Name"
)
ExtractModelObj: BasicValidateModel = SettingsField(
default_factory=BasicValidateModel,
title="Extract OBJ",
Expand Down Expand Up @@ -146,6 +164,12 @@ class PublishersModel(BaseSettingsModel):
"nearclip": 1.0,
"farclip": 1000.0
},
"ValidateModelName": {
"enabled": True,
"optional": True,
"active": False,
"regex": "(.*)_(?P<subset>.*)_(GEO)"
},
"ValidateLoadedPlugin": {
"enabled": False,
"optional": True,
Expand Down

0 comments on commit 7dc8505

Please sign in to comment.