Merge pull request #329 from BigRoy/enhancement/maya_optimize_get_all_children

Maya: Optimize `get_all_children` logic with ignoring intermediate objects
This commit is contained in:
Toke Jepsen 2024-04-04 10:51:32 +01:00 committed by GitHub
commit 33b3d0591e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 22 deletions

View file

@ -4004,17 +4004,26 @@ def len_flattened(components):
return n
def get_all_children(nodes):
def get_all_children(nodes, ignore_intermediate_objects=False):
"""Return all children of `nodes` including each instanced child.
Using maya.cmds.listRelatives(allDescendents=True) includes only the first
instance. As such, this function acts as an optimal replacement with a
focus on a fast query.
Args:
nodes (iterable): List of nodes to get children for.
ignore_intermediate_objects (bool): Ignore any children that
are intermediate objects.
Returns:
set: Children of input nodes.
"""
sel = OpenMaya.MSelectionList()
traversed = set()
iterator = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst)
fn_dag = OpenMaya.MFnDagNode()
for node in nodes:
if node in traversed:
@ -4031,6 +4040,13 @@ def get_all_children(nodes):
iterator.next() # noqa: B305
while not iterator.isDone():
if ignore_intermediate_objects:
fn_dag.setObject(iterator.currentItem())
if fn_dag.isIntermediateObject:
iterator.prune()
iterator.next() # noqa: B305
continue
path = iterator.fullPathName()
if path in traversed:
@ -4041,7 +4057,7 @@ def get_all_children(nodes):
traversed.add(path)
iterator.next() # noqa: B305
return list(traversed)
return traversed
def get_capture_preset(

View file

@ -46,11 +46,18 @@ class CollectArnoldSceneSource(pyblish.api.InstancePlugin):
self.log.debug("data: {}".format(instance.data))
def get_hierarchy(self, nodes):
"""Return nodes with all their children"""
"""Return nodes with all their children.
Arguments:
nodes (List[str]): List of nodes to collect children hierarchy for
Returns:
list: Input nodes with their children hierarchy
"""
nodes = cmds.ls(nodes, long=True)
if not nodes:
return []
children = get_all_children(nodes)
# Make sure nodes merged with children only
# contains unique entries
return list(set(nodes + children))
children = get_all_children(nodes, ignore_intermediate_objects=True)
return list(children.union(nodes))

View file

@ -48,15 +48,15 @@ class CollectNewInstances(pyblish.api.InstancePlugin):
# Collect members
members = cmds.ls(members, long=True) or []
# Collect full hierarchy
dag_members = cmds.ls(members, type="dagNode", long=True)
children = get_all_children(dag_members)
children = cmds.ls(children, noIntermediate=True, long=True)
parents = (
self.get_all_parents(members)
if creator_attributes.get("includeParentHierarchy", True)
else []
)
members_hierarchy = list(set(members + children + parents))
children = get_all_children(dag_members,
ignore_intermediate_objects=True)
members_hierarchy = set(members)
members_hierarchy.update(children)
if creator_attributes.get("includeParentHierarchy", True):
members_hierarchy.update(self.get_all_parents(dag_members))
instance[:] = members_hierarchy
@ -97,16 +97,16 @@ class CollectNewInstances(pyblish.api.InstancePlugin):
"""Get all parents by using string operations (optimization)
Args:
nodes (list): the nodes which are found in the objectSet
nodes (iterable): the nodes which are found in the objectSet
Returns:
list
set
"""
parents = []
parents = set()
for node in nodes:
splitted = node.split("|")
items = ["|".join(splitted[0:i]) for i in range(2, len(splitted))]
parents.extend(items)
parents.update(items)
return list(set(parents))
return parents

View file

@ -49,8 +49,9 @@ def get_selected_nodes():
"""Get information from current selection"""
selection = cmds.ls(selection=True, long=True)
hierarchy = lib.get_all_children(selection)
return list(set(selection + hierarchy))
hierarchy = lib.get_all_children(selection,
ignore_intermediate_objects=True)
return list(hierarchy.union(selection))
def get_all_asset_nodes():