How to isolate group nodes in maya with python
Question:
I have a selection that can reasonably contain most any node type. In python I need to filter out everything except the group nodes. The problem is that group nodes are read by maya as just transform nodes so its proving difficult to filter them out from all of the other transform nodes in the scene. Is there a way to do this? Possibly in the API?
Thanks!
Answers:
As you alluded to, “group” nodes really are just transform
nodes, with no real distinction.
The clearest distinction I can think of however would be that its children must be comprised entirely of other transform
nodes. Parenting a shape node under a “group” will no longer be considered a “group”
First, your selection of transform
nodes. I assume you already have something along these lines:
selection = pymel.core.ls(selection=True, transforms=True)
Next, a function to check if a given transform is itself a “group”.
Iterate over all the children of a given node, returning False
if any of them aren’t transform
. Otherwise return True
.
def is_group(node):
children = node.getChildren()
for child in children:
if type(child) is not pymel.core.nodetypes.Transform:
return False
return True
Now you just need to filter the selection, in one of the following two ways, depending on which style you find most clear:
selection = filter(is_group, selection)
or
selection = [node for node in selection if is_group(node)]
I know this is old, the method described here will not work properly when used with maya.cmds commands only. Here is my solution:
import maya.cmds as cmds
def is_group(groupName):
try:
children = cmds.listRelatives(groupName , children=True)
for child in children:
if not cmds.ls(child, transforms=True):
return False
return True
except:
return False
for item in cmds.ls():
if is_group(item):
print(item)
else:
pass
This answer will return true for joints since they also fit that definition. It also fails to account for empty groups.
def isGroup(node):
if mc.objectType(node, isType = 'joint'):
return False
kids = mc.listRelatives(node, c=1)
if kids:
for kid in kids:
if not mc.objectType(kid, isType = 'transform'):
return False
return True
print isGroup(mc.ls(sl=1))
I have a selection that can reasonably contain most any node type. In python I need to filter out everything except the group nodes. The problem is that group nodes are read by maya as just transform nodes so its proving difficult to filter them out from all of the other transform nodes in the scene. Is there a way to do this? Possibly in the API?
Thanks!
As you alluded to, “group” nodes really are just transform
nodes, with no real distinction.
The clearest distinction I can think of however would be that its children must be comprised entirely of other transform
nodes. Parenting a shape node under a “group” will no longer be considered a “group”
First, your selection of transform
nodes. I assume you already have something along these lines:
selection = pymel.core.ls(selection=True, transforms=True)
Next, a function to check if a given transform is itself a “group”.
Iterate over all the children of a given node, returning False
if any of them aren’t transform
. Otherwise return True
.
def is_group(node):
children = node.getChildren()
for child in children:
if type(child) is not pymel.core.nodetypes.Transform:
return False
return True
Now you just need to filter the selection, in one of the following two ways, depending on which style you find most clear:
selection = filter(is_group, selection)
or
selection = [node for node in selection if is_group(node)]
I know this is old, the method described here will not work properly when used with maya.cmds commands only. Here is my solution:
import maya.cmds as cmds
def is_group(groupName):
try:
children = cmds.listRelatives(groupName , children=True)
for child in children:
if not cmds.ls(child, transforms=True):
return False
return True
except:
return False
for item in cmds.ls():
if is_group(item):
print(item)
else:
pass
This answer will return true for joints since they also fit that definition. It also fails to account for empty groups.
def isGroup(node):
if mc.objectType(node, isType = 'joint'):
return False
kids = mc.listRelatives(node, c=1)
if kids:
for kid in kids:
if not mc.objectType(kid, isType = 'transform'):
return False
return True
print isGroup(mc.ls(sl=1))