Skip to content

Commit

Permalink
Merge pull request #329 from BigRoy/enhancement/maya_optimize_get_all…
Browse files Browse the repository at this point in the history
…_children

Maya: Optimize `get_all_children` logic with ignoring intermediate objects
  • Loading branch information
tokejepsen authored Apr 4, 2024
2 parents aa3f048 + 32b325b commit 33b3d05
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 22 deletions.
20 changes: 18 additions & 2 deletions client/ayon_core/hosts/maya/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,18 @@ def process(self, instance):
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))
26 changes: 13 additions & 13 deletions client/ayon_core/hosts/maya/plugins/publish/collect_instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ def process(self, instance):
# 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

Expand Down Expand Up @@ -97,16 +97,16 @@ def get_all_parents(self, nodes):
"""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
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down

0 comments on commit 33b3d05

Please sign in to comment.