Как получить список корневых родителей, созданных в сцене — Autodesk Maya / Python?

#python #maya

#python #maya

Вопрос:

Я немного новичок в Python и пытаюсь получить список, содержащий всех корневых родительских элементов, существующих в сцене типа joint . например, мой компоновщик сцены выглядит примерно так:

group1>> group2>> joint1>> joint2>> joint3

группа3>> объединение4>> объединение5

joint16>> joint17>> joint18

Мне нужен скрипт, который перемещается по контуру и возвращает список, как в моем примере:

 [joint1, joint4, joint16]
  

Любые советы были бы действительно оценены. большое вам спасибо.

Ответ №1:

Я не уверен, что это можно использовать, решение Haggi Krey работает нормально, но вы также можете использовать флаг: -long from cmds.ls

 # list all the joints from the scene
mjoints = cmds.ls(type='joint', l=True)
# list of the top joints from chain
output = []
# list to optimise the loop counter
exclusion = []
# lets iterate joints
for jnt in mjoints:
    # convert all hierarchy into a list
    pars = jnt.split('|')[1:]
    # lets see if our hierarchy is in the exclusion list
    # we put [1:] because maya root is represented by ''
    if not set(pars) amp; set(exclusion):
        # we parse the hierarchy until we reach the top joint
        # then we add it to the output
        # we add everything else to the exclusion list to avoid 
        for p in pars:
            if cmds.nodeType(p) == 'joint':
                output.append(p)
                exclusion =pars
                break
print(output)
  

Я просто добавляю это, потому что нет единого пути. Я надеюсь, что построение этого кода поможет вашим навыкам работы с python. Это точно то же самое, просто способ поиска родительских узлов отличается!

Комментарии:

1. большое вам спасибо за ваше время и помощь. я тоже попробую и дам вам знать ^^

2. Здравствуйте, Диан Лан Луу, обратите внимание, что пометка вопроса как принятого отличается от получения наилучшего ответа. Теоретически вы должны были предоставить ему ключ Haggi и проголосовать за новые ответы, которые вы считаете более актуальными

3. обратите внимание, что вы, возможно, не сможете проголосовать за повышение, потому что вы новичок, но это своего рода правило stackoverflow ;]

Ответ №2:

Я уже использовал идею DrWeeny, когда вы перемещаетесь по иерархии по длинному имени объекта. Разница в этом ответе заключается в том, что скрипт не завершит работу, если в сцене есть объекты с повторяющимися именами. Под этим я подразумеваю, допустим, у вас ситуация, когда у вас есть 2 иерархии:

group1>>joint1>>joint2>>group2>>joint3

и

group3>>joint1>>joint2>>group2>>joint3

Maya легко допускает это, например, при дублировании верхнего узла, поэтому нам нужно предотвратить сбой скрипта в этом случае. При наличии нескольких объектов с повторяющимися именами 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']

Комментарии:

1. предполагать, что у них будут двойные имена, немного грустно, но всегда есть сумасшедший ученый, пытающийся это сделать…. Мне нравится, когда вы выполняете цикл while, я всегда избегаю их, потому что в конечном итоге я зацикливаю maya: S

2. Я полностью согласен, но это случается чаще, чем мне хотелось бы! Особенно при работе с младшими.

3. Я очень благодарен за ваше время и ценную помощь и прошу прощения за мой поздний ответ, поскольку я не смог протестировать ваши решения в maya. работает как по маслу. миллион раз благодарю вас, Хагги, DrWeeny и Green Cell 🙂

Ответ №3:

Я бы предложил перечислить все соединения, и для каждого соединения вы можете проверить, не является ли это родительское соединение соединением. По вашему определению, эти соединения должны быть вашими корневыми соединениями.

Комментарии:

1. Я попробую и дам вам знать, большое спасибо за ваш совет!!!

2. большое вам спасибо, работает как шарм. импортируйте maya.cmds как cmds allParentsList = [] myItems= cmds.ls (тип=’joint’) для элемента в myItems: theParent = cmds.listRelatives(элемент, родительский элемент= True), если cmds.nodeType(родительский элемент) != «joint»: allParentsList.append(элемент) напечатать allParentsList

3. @DienLanLuu Это не работает. Представьте ситуацию, когда у вас есть другой тип объекта, нарушающий цепочку соединений, например: joint1>>joint2>>group1>>joint3 . Он вернет оба joint1 и joint3 вместо only joint1

4. @GreenCell да, это был быстрый скрипт для тестирования того, что посоветовал мне сделать хагги, но теперь с вашей помощью и всеми остальными я заставил его работать. спасибо миллион раз 🙂

Ответ №4:

Я использую этот метод для получения совместной иерархии. Я отказался от попыток найти более сексуальный способ сделать это.

 myItems = cmds.ls(selection = True, type='joint') 
theParentJnt = cmds.listRelatives(myItems, parent = True)
jntRel = cmds.listRelatives(myItems, allDescendents = True)
allJnt = jntRel   myItems
  

@Green Cell

Ваш метод сработал один раз и больше никогда не работал. Перезапускал maya 2020 более 5 раз и отображает только соединение верхнего узла, больше никогда не возвращает все соединения в одном списке.