Эффективный цикл цикла для следующего объекта в цепочке

Я пытаюсь сделать while loop в Python, чтобы найти следующий элемент в цепочке в Autodesk Maya. Он проходит по иерархии объектов, пока не найдет объект с определенным атрибутом. В настоящее время он сначала проверяет, не имеет ли текущий объект родительский элемент, а затем проверяет, имеет ли он атрибут parent на это, если это произойдет, это не войдет в while loopи распечатает заявление.

Если у объекта есть родитель, он запустит while loop до тех пор, пока объект имеет родителя. Приведенный ниже код перечисляет родителя этого выбранного объекта:

while pm.listRelatives( pm.ls( sl = True ), p = True ):

Затем он проверит, имеет ли текущий объект атрибут, если он этого не сделает, он выберет следующий объект вверх по иерархии, пока не получит, если он достигнет следующего за концом, он выйдет из цикла. Что мне интересно, есть ли более эффективный способ сделать это? Предпочтительно способ иметь один while loop с условием, которое будет работать, даже если он не может найти следующий объект в цепочке.

import pymel.core as pm

if not pm.listRelatives( pm.ls( sl = True )[ 0 ], p = True ):

    if pm.attributeQuery( 'parent', n = pm.ls( sl = True, tl = True )[ 0 ], ex = True ) == 1:
        print 'found parent on no parent ' + pm.ls( sl = True, tl = True )[ 0 ]

    else:
        while pm.listRelatives( pm.ls( sl = True ), p = True ):

            if pm.attributeQuery( 'parent', n = pm.ls( sl = True, tl = True )[ 0 ], ex = True ) == 1:
                print 'found parent on selected ' + pm.ls( sl = True, tl = True )[ 0 ]
                break
            else:
                print 'parent not found'
                pm.select( pm.listRelatives( pm.ls( sl = True, tl = True ), p = True ) )

1 ответ

Решение

Для зацикливания цепи:

def loop_up(item):
    current = [item]
    while current:
        yield current[0]
        current = cmds.listRelatives(current[0], p=True)

это вернет все элементы в цепочке, начиная с первого элемента, который вы передали. Так как это генератор (благодаря yield) вы можете вырваться в любое время:

for each_bone in loop_up(startbone):
    if is_what_youre_looking_for(each_bone):
       # do something
       break
# if you get here you didn't find what you're looking for
print "parent attribute not found"

Единственная проблема здесь заключается в том, что он не будет поддерживать нескольких родителей (например, фигурные формы). Это сложнее, потому что вам придется проходить несколько цепочек (которые могут перекрываться) параллельно. Однако это не общая проблема

Другие вопросы по тегам