Merge pull request #2826 from 2-REC-forks/bugfix/rig-deformer-ids

This commit is contained in:
Milan Kolar 2022-03-17 14:23:56 +01:00 committed by GitHub
commit 0d876ccf1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 20 deletions

View file

@ -1937,18 +1937,26 @@ def remove_other_uv_sets(mesh):
cmds.removeMultiInstance(attr, b=True)
def get_id_from_history(node):
def get_id_from_sibling(node, history_only=True):
"""Return first node id in the history chain that matches this node.
The nodes in history must be of the exact same node type and must be
parented under the same parent.
Optionally, if no matching node is found from the history, all the
siblings of the node that are of the same type are checked.
Additionally to having the same parent, the sibling must be marked as
'intermediate object'.
Args:
node (str): node to retrieve the
node (str): node to retrieve the history from
history_only (bool): if True and if nothing found in history,
look for an 'intermediate object' in all the node's siblings
of same type
Returns:
str or None: The id from the node in history or None when no id found
on any valid nodes in the history.
str or None: The id from the sibling node or None when no id found
on any valid nodes in the history or siblings.
"""
@ -1977,6 +1985,45 @@ def get_id_from_history(node):
if _id:
return _id
if not history_only:
# Get siblings of same type
similar_nodes = cmds.listRelatives(parent,
type=node_type,
fullPath=True)
similar_nodes = cmds.ls(similar_nodes, exactType=node_type, long=True)
# Exclude itself
similar_nodes = [x for x in similar_nodes if x != node]
# Get all unique ids from siblings in order since
# we consistently take the first one found
sibling_ids = OrderedDict()
for similar_node in similar_nodes:
# Check if "intermediate object"
if not cmds.getAttr(similar_node + ".intermediateObject"):
continue
_id = get_id(similar_node)
if not _id:
continue
if _id in sibling_ids:
sibling_ids[_id].append(similar_node)
else:
sibling_ids[_id] = [similar_node]
if sibling_ids:
first_id, found_nodes = next(iter(sibling_ids.items()))
# Log a warning if we've found multiple unique ids
if len(sibling_ids) > 1:
log.warning(("Found more than 1 intermediate shape with"
" unique id for '{}'. Using id of first"
" found: '{}'".format(node, found_nodes[0])))
return first_id
# Project settings
def set_scene_fps(fps, update=True):

View file

@ -32,8 +32,8 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Nodes found with non-related "
"asset IDs: {0}".format(invalid))
raise RuntimeError("Nodes found with mismatching "
"IDs: {0}".format(invalid))
@classmethod
def get_invalid(cls, instance):
@ -65,7 +65,7 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
invalid.append(node)
continue
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if history_id is not None and node_id != history_id:
invalid.append(node)
@ -76,7 +76,7 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
continue

View file

@ -48,7 +48,7 @@ class ValidateNodeIdsDeformedShape(pyblish.api.InstancePlugin):
invalid = []
for shape in shapes:
history_id = lib.get_id_from_history(shape)
history_id = lib.get_id_from_sibling(shape)
if history_id:
current_id = lib.get_id(shape)
if current_id != history_id:
@ -61,7 +61,7 @@ class ValidateNodeIdsDeformedShape(pyblish.api.InstancePlugin):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
continue

View file

@ -24,6 +24,7 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
openpype.hosts.maya.api.action.SelectInvalidAction,
openpype.api.RepairAction
]
allow_history_only = False
def process(self, instance):
"""Process all meshes"""
@ -32,8 +33,8 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Nodes found with non-related "
"asset IDs: {0}".format(invalid))
raise RuntimeError("Nodes found with mismatching "
"IDs: {0}".format(invalid))
@classmethod
def get_invalid(cls, instance):
@ -51,10 +52,13 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
noIntermediate=True)
for shape in shapes:
history_id = lib.get_id_from_history(shape)
if history_id:
sibling_id = lib.get_id_from_sibling(
shape,
history_only=cls.allow_history_only
)
if sibling_id:
current_id = lib.get_id(shape)
if current_id != history_id:
if current_id != sibling_id:
invalid.append(shape)
return invalid
@ -63,10 +67,13 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
def repair(cls, instance):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
# Get the original id from sibling
sibling_id = lib.get_id_from_sibling(
node,
history_only=cls.allow_history_only
)
if not sibling_id:
cls.log.error("Could not find ID in siblings for '%s'", node)
continue
lib.set_id(node, history_id, overwrite=True)
lib.set_id(node, sibling_id, overwrite=True)

View file

@ -385,6 +385,10 @@
"optional": true,
"active": true
},
"ValidateRigOutSetNodeIds": {
"enabled": true,
"allow_history_only": false
},
"ValidateCameraAttributes": {
"enabled": false,
"optional": true,

View file

@ -514,6 +514,26 @@
"label": "Validate Rig Controllers"
}
]
},
{
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"key": "ValidateRigOutSetNodeIds",
"label": "Validate Rig Out Set Node Ids",
"is_group": true,
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "boolean",
"key": "allow_history_only",
"label": "Allow history only"
}
]
}
]
},