2014-10-09 14 views
0

我試圖在Python中創建while loop以在Autodesk Maya中查找鏈中的下一項。它循環遍歷對象的層次結構,直到找到具有某個特定屬性的對象。目前它首先檢查當前對象是否沒有父對象,然後檢查它是否具有屬性parent,如果它不會進入while loop,並且將打印語句。Effective While循環鏈中的下一個對象

如果對象確實有父對象,只要對象有父對象,它就會運行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)) 
+0

我有點困惑。 listRelative'調用的意義究竟是什麼?他們是否找到元素或其他東西的「父母」?這種父母與「父母」屬性之間的關係是什麼? – Blckknght 2014-10-09 21:11:45

回答

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" 

這裏唯一的問題是它不會支持多父節點(即實例化形狀)。這很棘手,因爲你必須並行地迭代多個鏈(可能重疊)。但它不是一個普遍的問題

+0

謝謝!,工作。另外,你對for循環的變量有什麼看法。只是總是把x放在______中,並在下一個循環中覆蓋它,足夠好了嗎?或者我應該總是喜歡連鎖店的聯合。 – 2014-10-10 02:57:39

+0

使用名稱意味着某些東西總是一個好主意:我喜歡''爲bone_chain中的每個骨骼:'所以很清楚哪個是迭代變量。在循環過程中你不能改變外部變量,所以很清楚什麼是什麼 – theodox 2014-10-10 07:00:19