ayon-core/pype/plugins/maya/publish/validate_attributes.py
2019-08-21 14:35:14 +01:00

100 lines
3.3 KiB
Python

import pymel.core as pm
import pyblish.api
import pype.api
class ValidateAttributes(pyblish.api.ContextPlugin):
"""Ensure attributes are consistent.
Attributes to validate and their values comes from the
"maya/attributes.json" preset, which needs this structure:
{
"family": {
"node_name.attribute_name": attribute_value
}
}
"""
order = pype.api.ValidateContentsOrder
label = "Attributes"
hosts = ["maya"]
actions = [pype.api.RepairContextAction]
optional = True
def process(self, context):
# Check for preset existence.
if not context.data["presets"]["maya"].get("attributes"):
return
invalid = self.get_invalid(context, compute=True)
if invalid:
raise RuntimeError(
"Found attributes with invalid values: {}".format(invalid)
)
@classmethod
def get_invalid(cls, context, compute=False):
invalid = context.data.get("invalid_attributes", [])
if compute:
invalid = cls.get_invalid_attributes(context)
return invalid
@classmethod
def get_invalid_attributes(cls, context):
presets = context.data["presets"]["maya"]["attributes"]
invalid_attributes = []
for instance in context:
# Filter publisable instances.
if not instance.data["publish"]:
continue
# Filter families.
families = [instance.data["family"]]
families += instance.data.get("families", [])
families = list(set(families) & set(presets.keys()))
if not families:
continue
# Get all attributes to validate.
attributes = {}
for family in families:
for preset in presets[family]:
[node_name, attribute_name] = preset.split(".")
attributes.update(
{node_name: {attribute_name: presets[family][preset]}}
)
# Get invalid attributes.
nodes = pm.ls()
for node in nodes:
name = node.name(stripNamespace=True)
if name not in attributes.keys():
continue
presets_to_validate = attributes[name]
for attribute in node.listAttr():
names = [attribute.shortName(), attribute.longName()]
attribute_name = list(
set(names) & set(presets_to_validate.keys())
)
if attribute_name:
expected = presets_to_validate[attribute_name[0]]
if attribute.get() != expected:
invalid_attributes.append(
{
"attribute": attribute,
"expected": expected,
"current": attribute.get()
}
)
context.data["invalid_attributes"] = invalid_attributes
return invalid_attributes
@classmethod
def repair(cls, instance):
invalid = cls.get_invalid(instance)
for data in invalid:
data["attribute"].set(data["expected"])