Merge pull request #266 from BigRoy/enhancement/maya_validate_animation_out_set_id_report

Maya: Validate Animation Out Set Related Node Ids improve report
This commit is contained in:
Libor Batek 2024-03-29 10:11:39 +01:00 committed by GitHub
commit cc8ebdd5a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 19 deletions

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<error id="main">
<title>Shape IDs mismatch original shape</title>
<description>## Shapes mismatch IDs with original shape
Meshes are detected where the (deformed) mesh has a different `cbId` than
the same mesh in its deformation history.
Theses should normally be the same.
### How to repair?
By using the repair action the IDs from the shape in history will be
copied to the deformed shape. For **animation** instances using the
repair action usually is usually the correct fix.
</description>
<detail>
### How does this happen?
When a deformer is applied in the scene on a referenced mesh that had no
deformers then Maya will create a new shape node for the mesh that
does not have the original id. Then on scene save new ids get created for the
meshes lacking a `cbId` and thus the mesh then has a different `cbId` than
the mesh in the deformation history.
</detail>
</error>
</root>

View file

@ -6,7 +6,7 @@ from ayon_core.hosts.maya.api import lib
from ayon_core.pipeline.publish import (
RepairAction,
ValidateContentsOrder,
PublishValidationError,
PublishXmlValidationError,
OptionalPyblishPluginMixin,
get_plugin_settings,
apply_plugin_settings_automatically
@ -56,40 +56,39 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin,
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
if invalid:
# TODO: Message formatting can be improved
raise PublishValidationError("Nodes found with mismatching "
"IDs: {0}".format(invalid),
title="Invalid node ids")
# Use the short names
invalid = cmds.ls(invalid)
invalid.sort()
# Construct a human-readable list
invalid = "\n".join("- {}".format(node) for node in invalid)
raise PublishXmlValidationError(
plugin=self,
message=(
"Nodes have different IDs than their input "
"history: \n{0}".format(invalid)
)
)
@classmethod
def get_invalid(cls, instance):
"""Get all nodes which do not match the criteria"""
invalid = []
types_to_skip = ["locator"]
types = ["mesh", "nurbsCurve", "nurbsSurface"]
# get asset id
nodes = instance.data.get("out_hierarchy", instance[:])
for node in nodes:
for node in cmds.ls(nodes, type=types, long=True):
# We only check when the node is *not* referenced
if cmds.referenceQuery(node, isNodeReferenced=True):
continue
# Check if node is a shape as deformers only work on shapes
obj_type = cmds.objectType(node, isAType="shape")
if not obj_type:
continue
# Skip specific types
if cmds.objectType(node) in types_to_skip:
continue
# Get the current id of the node
node_id = lib.get_id(node)
if not node_id:
invalid.append(node)
continue
history_id = lib.get_id_from_sibling(node)
if history_id is not None and node_id != history_id: