Я уже использовал идею DrWeeny, когда вы пересекаете иерархию по длинному имени объекта.Разница в этом ответе заключается в том, что сценарий не будет аварийно завершать работу, если в сцене присутствуют объекты с повторяющимися именами.Я имею в виду, что у вас есть две ситуации:
group1>>joint1>>joint2>>group2>>joint3
и
group3>>joint1>>joint2>>group2>>joint3
Майяэто легко разрешить, как при дублировании верхнего узла, поэтому в этом случае мы должны предотвратить сбой скрипта.Когда есть несколько объектов с повторяющимися именами, Maya потерпит крах, если вы попытаетесь получить доступ к короткому имени объекта (оно не знает, на какое вы ссылаетесь!), Поэтому вместо этого мы всегда должны использовать его длинное имя:
import maya.cmds as cmds
jnts = cmds.ls(type="joint", l=True) # Collect all joints in the scene by their long names.
output = set() # Use a set to avoid adding the same joint.
for jnt in jnts:
pars = jnt.split("|") # Split long name so we can traverse its hierarchy.
root_jnt = None
while pars:
obj = "|".join(pars)
del pars[-1] # Remove last word to "traverse" up hierarchy on next loop.
# If this is a joint, mark it as the new root joint.
if obj and cmds.nodeType(obj) == "joint":
root_jnt = obj
# If a root joint was found, append it to our final list.
if root_jnt is not None:
output.add(root_jnt)
print(list(output))
Использование этого сценария в иерархиях выше вернет
[u'|group1|joint1', u'|group3|joint1']