Maya python get top most parent transforms
Question:
I have a selection of transforms in maya and I want to get the top parent transforms of all hierarchies within the selection. Is this the best way to achieve that?
import maya.cmds as cmds
def getTopParents(transforms):
'''
Returns a list of the top most parents for the given transforms
'''
parents = []
for t in transforms:
p = cmds.listRelatives(t, parent=True, type='transform')
while p:
p = cmds.listRelatives(p[0], parent=True, type='transform')
if p:
parents.append(p[0])
else:
parents.append(t)
return parents
Answers:
How about something like this? Modify as needed to store the parents instead of just printing them.
import maya.cmds as cmds
targets = ['pCylinder1', 'group4', 'group10']
print('Full hierarchy: {}'.format(cmds.ls(targets[0], long=True)[0]))
for target in targets:
parent = None
stop = False
while not stop:
p = cmds.listRelatives(parent or target, parent=True)
if p is None:
stop = True
else:
parent = p[0]
if parent:
print('{} has top-level parent {}'.format(target, parent))
else:
print('{} is top-level object'.format(target))
Output:
Full hierarchy: |group10|group9|group8|group7|group6|group5|group4|group3|group2|group1|pCylinder1
pCylinder1 has top-level parent group10
group4 has top-level parent group10
group10 is top-level object
Edit: Looks like I didn’t read your question properly. We more or less came up with the same code, so I suppose my answer to your question is Yes, this is probably the best way.
You can also use the full path of an object and split by |
, but it’s not necessarily as precise as it sounds — especially if the objects gets passed to your method by their short names.
You don’t need to go trough listRelatves at all:
if you look at the long name of some transform, for example ‘|group4|group5|group6|pCube4′, you will notice that the top nodes’ long name is already there
def Outliner_TopMost__Get_or_Select(Sel_LongNames=None, Mode='Select'):
if Sel_LongNames is None:
# 'o=1' will return only objects, or rather shapes, if in component mode
Sel_LongNames=cmds.ls(sl=1,fl=1,l=1,o=1)
finalList=[]
for item in Sel_LongNames:
# get the first name after '|', and add it to '|' to create the long name
finalList.append("|"+item.split('|')[1])
if Mode=='Select':
cmds.select(finalList)
else:
return finalList
This function will work on Selection, or if you provide it with a list of object, but with long names (‘l’ flag in cmds.ls). It will also select the meshes, or return the selection, according to the flag ‘Mode’.
Note: will return the top node, even if it is a Mesh, rather then a transform.
I have a selection of transforms in maya and I want to get the top parent transforms of all hierarchies within the selection. Is this the best way to achieve that?
import maya.cmds as cmds
def getTopParents(transforms):
'''
Returns a list of the top most parents for the given transforms
'''
parents = []
for t in transforms:
p = cmds.listRelatives(t, parent=True, type='transform')
while p:
p = cmds.listRelatives(p[0], parent=True, type='transform')
if p:
parents.append(p[0])
else:
parents.append(t)
return parents
How about something like this? Modify as needed to store the parents instead of just printing them.
import maya.cmds as cmds
targets = ['pCylinder1', 'group4', 'group10']
print('Full hierarchy: {}'.format(cmds.ls(targets[0], long=True)[0]))
for target in targets:
parent = None
stop = False
while not stop:
p = cmds.listRelatives(parent or target, parent=True)
if p is None:
stop = True
else:
parent = p[0]
if parent:
print('{} has top-level parent {}'.format(target, parent))
else:
print('{} is top-level object'.format(target))
Output:
Full hierarchy: |group10|group9|group8|group7|group6|group5|group4|group3|group2|group1|pCylinder1
pCylinder1 has top-level parent group10
group4 has top-level parent group10
group10 is top-level object
Edit: Looks like I didn’t read your question properly. We more or less came up with the same code, so I suppose my answer to your question is Yes, this is probably the best way.
You can also use the full path of an object and split by |
, but it’s not necessarily as precise as it sounds — especially if the objects gets passed to your method by their short names.
You don’t need to go trough listRelatves at all:
if you look at the long name of some transform, for example ‘|group4|group5|group6|pCube4′, you will notice that the top nodes’ long name is already there
def Outliner_TopMost__Get_or_Select(Sel_LongNames=None, Mode='Select'):
if Sel_LongNames is None:
# 'o=1' will return only objects, or rather shapes, if in component mode
Sel_LongNames=cmds.ls(sl=1,fl=1,l=1,o=1)
finalList=[]
for item in Sel_LongNames:
# get the first name after '|', and add it to '|' to create the long name
finalList.append("|"+item.split('|')[1])
if Mode=='Select':
cmds.select(finalList)
else:
return finalList
This function will work on Selection, or if you provide it with a list of object, but with long names (‘l’ flag in cmds.ls). It will also select the meshes, or return the selection, according to the flag ‘Mode’.
Note: will return the top node, even if it is a Mesh, rather then a transform.