mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #5595 from BigRoy/bugfix/maya_validate_rig_sets
This commit is contained in:
commit
e331a07589
6 changed files with 108 additions and 31 deletions
39
openpype/hosts/maya/plugins/publish/collect_rig_sets.py
Normal file
39
openpype/hosts/maya/plugins/publish/collect_rig_sets.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import pyblish.api
|
||||
from maya import cmds
|
||||
|
||||
|
||||
class CollectRigSets(pyblish.api.InstancePlugin):
|
||||
"""Ensure rig contains pipeline-critical content
|
||||
|
||||
Every rig must contain at least two object sets:
|
||||
"controls_SET" - Set of all animatable controls
|
||||
"out_SET" - Set of all cacheable meshes
|
||||
|
||||
"""
|
||||
|
||||
order = pyblish.api.CollectorOrder + 0.05
|
||||
label = "Collect Rig Sets"
|
||||
hosts = ["maya"]
|
||||
families = ["rig"]
|
||||
|
||||
accepted_output = ["mesh", "transform"]
|
||||
accepted_controllers = ["transform"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
# Find required sets by suffix
|
||||
searching = {"controls_SET", "out_SET"}
|
||||
found = {}
|
||||
for node in cmds.ls(instance, exactType="objectSet"):
|
||||
for suffix in searching:
|
||||
if node.endswith(suffix):
|
||||
found[suffix] = node
|
||||
searching.remove(suffix)
|
||||
break
|
||||
if not searching:
|
||||
break
|
||||
|
||||
self.log.debug("Found sets: {}".format(found))
|
||||
rig_sets = instance.data.setdefault("rig_sets", {})
|
||||
for name, objset in found.items():
|
||||
rig_sets[name] = objset
|
||||
|
|
@ -2,7 +2,9 @@ import pyblish.api
|
|||
from maya import cmds
|
||||
|
||||
from openpype.pipeline.publish import (
|
||||
PublishValidationError, ValidateContentsOrder)
|
||||
PublishValidationError,
|
||||
ValidateContentsOrder
|
||||
)
|
||||
|
||||
|
||||
class ValidateRigContents(pyblish.api.InstancePlugin):
|
||||
|
|
@ -24,31 +26,45 @@ class ValidateRigContents(pyblish.api.InstancePlugin):
|
|||
|
||||
def process(self, instance):
|
||||
|
||||
objectsets = ("controls_SET", "out_SET")
|
||||
missing = [obj for obj in objectsets if obj not in instance]
|
||||
assert not missing, ("%s is missing %s" % (instance, missing))
|
||||
# Find required sets by suffix
|
||||
required = ["controls_SET", "out_SET"]
|
||||
missing = [
|
||||
key for key in required if key not in instance.data["rig_sets"]
|
||||
]
|
||||
if missing:
|
||||
raise PublishValidationError(
|
||||
"%s is missing sets: %s" % (instance, ", ".join(missing))
|
||||
)
|
||||
|
||||
controls_set = instance.data["rig_sets"]["controls_SET"]
|
||||
out_set = instance.data["rig_sets"]["out_SET"]
|
||||
|
||||
# Ensure there are at least some transforms or dag nodes
|
||||
# in the rig instance
|
||||
set_members = instance.data['setMembers']
|
||||
if not cmds.ls(set_members, type="dagNode", long=True):
|
||||
raise PublishValidationError(
|
||||
("No dag nodes in the pointcache instance. "
|
||||
"(Empty instance?)"))
|
||||
"No dag nodes in the pointcache instance. "
|
||||
"(Empty instance?)"
|
||||
)
|
||||
|
||||
# Ensure contents in sets and retrieve long path for all objects
|
||||
output_content = cmds.sets("out_SET", query=True) or []
|
||||
assert output_content, "Must have members in rig out_SET"
|
||||
output_content = cmds.sets(out_set, query=True) or []
|
||||
if not output_content:
|
||||
raise PublishValidationError("Must have members in rig out_SET")
|
||||
output_content = cmds.ls(output_content, long=True)
|
||||
|
||||
controls_content = cmds.sets("controls_SET", query=True) or []
|
||||
assert controls_content, "Must have members in rig controls_SET"
|
||||
controls_content = cmds.sets(controls_set, query=True) or []
|
||||
if not controls_content:
|
||||
raise PublishValidationError(
|
||||
"Must have members in rig controls_SET"
|
||||
)
|
||||
controls_content = cmds.ls(controls_content, long=True)
|
||||
|
||||
# Validate members are inside the hierarchy from root node
|
||||
root_node = cmds.ls(set_members, assemblies=True)
|
||||
hierarchy = cmds.listRelatives(root_node, allDescendents=True,
|
||||
fullPath=True)
|
||||
root_nodes = cmds.ls(set_members, assemblies=True, long=True)
|
||||
hierarchy = cmds.listRelatives(root_nodes, allDescendents=True,
|
||||
fullPath=True) + root_nodes
|
||||
hierarchy = set(hierarchy)
|
||||
|
||||
invalid_hierarchy = []
|
||||
|
|
|
|||
|
|
@ -52,22 +52,30 @@ class ValidateRigControllers(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError('{} failed, see log '
|
||||
'information'.format(self.label))
|
||||
raise PublishValidationError(
|
||||
'{} failed, see log information'.format(self.label)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
controllers_sets = [i for i in instance if i == "controls_SET"]
|
||||
controls = cmds.sets(controllers_sets, query=True)
|
||||
assert controls, "Must have 'controls_SET' in rig instance"
|
||||
controls_set = instance.data["rig_sets"].get("controls_SET")
|
||||
if not controls_set:
|
||||
cls.log.error(
|
||||
"Must have 'controls_SET' in rig instance"
|
||||
)
|
||||
return [instance.data["instance_node"]]
|
||||
|
||||
controls = cmds.sets(controls_set, query=True)
|
||||
|
||||
# Ensure all controls are within the top group
|
||||
lookup = set(instance[:])
|
||||
assert all(control in lookup for control in cmds.ls(controls,
|
||||
long=True)), (
|
||||
"All controls must be inside the rig's group."
|
||||
)
|
||||
if not all(control in lookup for control in cmds.ls(controls,
|
||||
long=True)):
|
||||
cls.log.error(
|
||||
"All controls must be inside the rig's group."
|
||||
)
|
||||
return [controls_set]
|
||||
|
||||
# Validate all controls
|
||||
has_connections = list()
|
||||
|
|
@ -181,9 +189,17 @@ class ValidateRigControllers(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def repair(cls, instance):
|
||||
|
||||
controls_set = instance.data["rig_sets"].get("controls_SET")
|
||||
if not controls_set:
|
||||
cls.log.error(
|
||||
"Unable to repair because no 'controls_SET' found in rig "
|
||||
"instance: {}".format(instance)
|
||||
)
|
||||
return
|
||||
|
||||
# Use a single undo chunk
|
||||
with undo_chunk():
|
||||
controls = cmds.sets("controls_SET", query=True)
|
||||
controls = cmds.sets(controls_set, query=True)
|
||||
for control in controls:
|
||||
|
||||
# Lock visibility
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ class ValidateRigControllersArnoldAttributes(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
controllers_sets = [i for i in instance if i == "controls_SET"]
|
||||
if not controllers_sets:
|
||||
controls_set = instance.data["rig_sets"].get("controls_SET")
|
||||
if not controls_set:
|
||||
return []
|
||||
|
||||
controls = cmds.sets(controllers_sets, query=True) or []
|
||||
controls = cmds.sets(controls_set, query=True) or []
|
||||
if not controls:
|
||||
return []
|
||||
|
||||
|
|
|
|||
|
|
@ -38,16 +38,19 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
|
|||
# if a deformer has been created on the shape
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError("Nodes found with mismatching "
|
||||
"IDs: {0}".format(invalid))
|
||||
raise PublishValidationError(
|
||||
"Nodes found with mismatching IDs: {0}".format(invalid)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
"""Get all nodes which do not match the criteria"""
|
||||
|
||||
invalid = []
|
||||
out_set = instance.data["rig_sets"].get("out_SET")
|
||||
if not out_set:
|
||||
return []
|
||||
|
||||
out_set = next(x for x in instance if x.endswith("out_SET"))
|
||||
invalid = []
|
||||
members = cmds.sets(out_set, query=True)
|
||||
shapes = cmds.ls(members,
|
||||
dag=True,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ class ValidateRigOutputIds(pyblish.api.InstancePlugin):
|
|||
invalid = {}
|
||||
|
||||
if compute:
|
||||
out_set = next(x for x in instance if "out_SET" in x)
|
||||
out_set = instance.data["rig_sets"].get("out_SET")
|
||||
if not out_set:
|
||||
instance.data["mismatched_output_ids"] = invalid
|
||||
return invalid
|
||||
|
||||
instance_nodes = cmds.sets(out_set, query=True, nodesOnly=True)
|
||||
instance_nodes = cmds.ls(instance_nodes, long=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue