mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into bugfix/OP-6591_LoadClip-colorspace-override
This commit is contained in:
commit
9c34d76c7b
5 changed files with 247 additions and 1 deletions
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
from pymxs import runtime as rt
|
||||
from ayon_core.pipeline import (
|
||||
PublishValidationError,
|
||||
OptionalPyblishPluginMixin
|
||||
)
|
||||
from ayon_core.hosts.max.api.action import SelectInvalidAction
|
||||
|
||||
|
||||
def get_invalid_keys(obj):
|
||||
"""function to check on whether there is keyframe in
|
||||
|
||||
Args:
|
||||
obj (str): object needed to check if there is a keyframe
|
||||
|
||||
Returns:
|
||||
bool: whether invalid object(s) exist
|
||||
"""
|
||||
for transform in ["Position", "Rotation", "Scale"]:
|
||||
num_of_key = rt.NumKeys(rt.getPropertyController(
|
||||
obj.controller, transform))
|
||||
if num_of_key > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ValidateNoAnimation(pyblish.api.InstancePlugin,
|
||||
OptionalPyblishPluginMixin):
|
||||
"""Validates No Animation
|
||||
|
||||
Ensure no keyframes on nodes in the Instance
|
||||
"""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
families = ["model"]
|
||||
hosts = ["max"]
|
||||
optional = True
|
||||
label = "Validate No Animation"
|
||||
actions = [SelectInvalidAction]
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError(
|
||||
"Keyframes found on:\n\n{0}".format(invalid)
|
||||
,
|
||||
title="Keyframes on model"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_invalid(instance):
|
||||
"""Get invalid object(s) which have keyframe(s)
|
||||
|
||||
|
||||
Args:
|
||||
instance (pyblish.api.instance): Instance
|
||||
|
||||
Returns:
|
||||
list: list of invalid objects
|
||||
"""
|
||||
invalid = [invalid for invalid in instance.data["members"]
|
||||
if invalid.isAnimated or get_invalid_keys(invalid)]
|
||||
|
||||
return invalid
|
||||
|
|
@ -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")
|
||||
|
|
@ -86,6 +100,10 @@ class PublishersModel(BaseSettingsModel):
|
|||
"the system automatically skips checking it"
|
||||
)
|
||||
)
|
||||
ValidateNoAnimation: BasicValidateModel = SettingsField(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate No Animation"
|
||||
)
|
||||
ValidateLoadedPlugin: ValidateLoadedPluginModel = SettingsField(
|
||||
default_factory=ValidateLoadedPluginModel,
|
||||
title="Validate Loaded Plugin"
|
||||
|
|
@ -94,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",
|
||||
|
|
@ -142,6 +164,12 @@ DEFAULT_PUBLISH_SETTINGS = {
|
|||
"nearclip": 1.0,
|
||||
"farclip": 1000.0
|
||||
},
|
||||
"ValidateModelName": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False,
|
||||
"regex": "(.*)_(?P<subset>.*)_(GEO)"
|
||||
},
|
||||
"ValidateLoadedPlugin": {
|
||||
"enabled": False,
|
||||
"optional": True,
|
||||
|
|
@ -152,6 +180,11 @@ DEFAULT_PUBLISH_SETTINGS = {
|
|||
"optional": True,
|
||||
"active": False
|
||||
},
|
||||
"ValidateNoAnimation": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": False,
|
||||
},
|
||||
"ExtractModelObj": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "0.1.6"
|
||||
__version__ = "0.1.7"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue