supports families check before the validation of loaded plugins

This commit is contained in:
Kayla Man 2023-11-02 12:27:22 +08:00
parent 1ecd96acf6
commit 881340b60a
6 changed files with 74 additions and 25 deletions

View file

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
"""Validator for Loaded Plugin."""
from pyblish.api import ContextPlugin, ValidatorOrder
import os
from pyblish.api import InstancePlugin, ValidatorOrder
from pymxs import runtime as rt
from openpype.pipeline.publish import (
RepairContextAction,
RepairAction,
OptionalPyblishPluginMixin,
PublishValidationError
)
@ -12,7 +13,7 @@ from openpype.hosts.max.api.lib import get_plugins
class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
ContextPlugin):
InstancePlugin):
"""Validates if the specific plugin is loaded in 3ds max.
Studio Admin(s) can add the plugins they want to check in validation
via studio defined project settings"""
@ -21,17 +22,17 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
hosts = ["max"]
label = "Validate Loaded Plugins"
optional = True
actions = [RepairContextAction]
actions = [RepairAction]
def get_invalid(self, context):
def get_invalid(self, instance):
"""Plugin entry point."""
if not self.is_active(context.data):
if not self.is_active(instance.data):
self.log.debug("Skipping Validate Loaded Plugin...")
return
required_plugins = (
context.data["project_settings"]["max"]["publish"]
["ValidateLoadedPlugin"]["plugins_for_check"]
instance.context.data["project_settings"]["max"]["publish"]
["ValidateLoadedPlugin"]["family_plugins_mapping"]
)
if not required_plugins:
@ -45,9 +46,21 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
get_plugins())
}
for plugin in required_plugins:
plugin_name = plugin.lower()
for families, plugin in required_plugins.items():
families_list = families.split(",")
excluded_families = [family for family in families_list
if instance.data["family"]!=family
and family!="_"]
if excluded_families:
self.log.debug("The {} instance is not part of {}.".format(
instance.data["family"], excluded_families
))
return
if not plugin:
return
plugin_name = plugin.format(**os.environ).lower()
plugin_index = available_plugins.get(plugin_name)
if plugin_index is None:
@ -61,8 +74,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
return invalid
def process(self, context):
invalid_plugins = self.get_invalid(context)
def process(self, instance):
invalid_plugins = self.get_invalid(instance)
if invalid_plugins:
bullet_point_invalid_statement = "\n".join(
"- {}".format(invalid) for invalid in invalid_plugins
@ -76,18 +89,30 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin,
report, title="Required Plugins unloaded")
@classmethod
def repair(cls, context):
def repair(cls, instance):
# get all DLL loaded plugins in Max and their plugin index
available_plugins = {
plugin_name.lower(): index for index, plugin_name in enumerate(
get_plugins())
}
required_plugins = (
context.data["project_settings"]["max"]["publish"]
["ValidateLoadedPlugin"]["plugins_for_check"]
instance.context.data["project_settings"]["max"]["publish"]
["ValidateLoadedPlugin"]["family_plugins_mapping"]
)
for plugin in required_plugins:
plugin_name = plugin.lower()
for families, plugin in required_plugins.items():
families_list = families.split(",")
excluded_families = [family for family in families_list
if instance.data["family"]!=family
and family!="_"]
if excluded_families:
cls.log.debug("The {} instance is not part of {}.".format(
instance.data["family"], excluded_families
))
continue
if not plugin:
continue
plugin_name = plugin.format(**os.environ).lower()
plugin_index = available_plugins.get(plugin_name)
if plugin_index is None:

View file

@ -24,6 +24,7 @@ class CollectSceneVersion(pyblish.api.ContextPlugin):
"hiero",
"houdini",
"maya",
"max",
"nuke",
"photoshop",
"resolve",

View file

@ -640,6 +640,19 @@ def _convert_3dsmax_project_settings(ayon_settings, output):
}
ayon_max["PointCloud"]["attribute"] = new_point_cloud_attribute
ayon_publish = ayon_max["publish"]
if "ValidateLoadedPlugin" in ayon_publish:
family_plugin_mapping = (
ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"]
)
new_family_plugin_mapping = {
item["families"]: item["plugins"]
for item in family_plugin_mapping
}
ayon_max["ValidateLoadedPlugin"]["family_plugins_mapping"] = (
new_family_plugin_mapping
)
output["max"] = ayon_max

View file

@ -40,7 +40,7 @@
"ValidateLoadedPlugin": {
"enabled": false,
"optional": true,
"plugins_for_check": []
"family_plugins_mapping": {}
}
}
}

View file

@ -47,10 +47,14 @@
"label": "Optional"
},
{
"type": "list",
"key": "plugins_for_check",
"label": "Plugins Needed For Check",
"object_type": "text"
"type": "dict-modifiable",
"collapsible": true,
"key": "family_plugins_mapping",
"label": "Family Plugins Mapping",
"use_label_wrap": true,
"object_type": {
"type": "text"
}
}
]
}

View file

@ -3,11 +3,17 @@ from pydantic import Field
from ayon_server.settings import BaseSettingsModel
class FamilyPluginsMappingModel(BaseSettingsModel):
_layout = "compact"
families: str = Field(title="Families")
plugins: str = Field(title="Plugins")
class ValidateLoadedPluginModel(BaseSettingsModel):
enabled: bool = Field(title="ValidateLoadedPlugin")
optional: bool = Field(title="Optional")
plugins_for_check: list[str] = Field(
default_factory=list, title="Plugins Needed For Check"
family_plugins_mapping: list[FamilyPluginsMappingModel] = Field(
default_factory=list, title="Family Plugins Mapping"
)
@ -37,6 +43,6 @@ DEFAULT_PUBLISH_SETTINGS = {
"ValidateLoadedPlugin": {
"enabled": False,
"optional": True,
"plugins_for_check": []
"family_plugins_mapping": {}
}
}