2017-08-25 43 views
0

我正在嘗試爲maya python中的骨架創建o層次結構。我正在這樣做Maya Python創建關節Hierachy

def makeSkelet(args): 

    helperSkelet('Root_Locator', 'root_Joint') 
    helperSkelet('Pelvis_Locator', 'pelvis_Joint') 
    helperSkelet('Spine_Locator', 'spine_Joint') 
    helperSkelet('Spine01_Locator', 'spine01_Joint') 
    helperSkelet('Spine02_Locator', 'spine02_Joint') 
    helperSkelet('Neck_Locator', 'neck_Joint') 
    helperSkelet('Head_Locator', 'head_Joint') 
    mc.select(cl=True) 
    helperSkelet('ArmL_Locator', 'armL_joint') 
    helperSkelet('ElbowL_Locator', 'elbowL_Joint') 
    helperSkelet('HandL_Locator', 'handL_Joint') 
    mc.select(cl=True) 
    helperSkelet('ArmR_Locator', 'armR_joint') 
    helperSkelet('ElbowR_Locator', 'elbowR_Joint') 
    helperSkelet('HandR_Locator', 'handR_Joint') 
    mc.select(cl=True) 
    helperSkelet('HipL_Locator', 'hipL_joint') 
    helperSkelet('KneeL_Locator', 'kneeL_Joint') 
    helperSkelet('AnkleL_Locator', 'ankleL_Joint') 
    helperSkelet('FootL_Locator', 'footL_Joint') 
    mc.select(cl=True) 
    helperSkelet('HipR_Locator', 'hipR_joint') 
    helperSkelet('KneeR_Locator', 'kneeR_Joint') 
    helperSkelet('AnkleR_Locator', 'ankleR_Joint') 
    helperSkelet('FootR_Locator', 'footR_Joint') 

現在這工作正常,因爲關節必須按此順序創建。 (助手骨骼是一個函數,我創建關於一個定位器位置的關節)

我想知道是否有一個更優化的方式來做到這一點考慮到訂單或創建必須保持。

謝謝

+0

如果一切正常,我不能想辦法把「優化」它比它已經是了。當然,你可以將它壓縮到一個關節的「列表」中,並循環遍歷列表,但仍然不會優化它。 – davedwards

回答

2

如果「優化」你的意思是越來越好服務表現,我同意@downshift說。

如果你的意思是讓你的代碼變得更「乾淨」(更一般或可擴展或更簡單的pythonic),下面是另一種方法,你可以做同樣的事情,它更緊湊一些(並將邏輯與輸入分開):

def helperSkeletGroup(group, symmetric=False): 
    # quick workaround to capitalize a word, leaving the following letters unchanged 
    capitalize = lambda s: s[:1].upper() + s[1:] 

    symmetric_group = [] 
    for elem in group: 
     if symmetric: 
      symmetric_group.append('{0}R'.format(elem)) 
      elem = '{0}L'.format(elem) 
     # format locators and joints 
     loc, joint = '{0}_Locator'.format(capitalize(elem)), '{0}_Joint'.format(elem) 
     helperSkelet(loc, joint) 
    cmds.select(cl=True) 
    if symmetric_group: 
     helperSkeletGroup(symmetric_group) 

helperSkeletGroup(['root', 'pelvis', 'spine', 'spine01', 'spine02', 'neck', 'head']) 
helperSkeletGroup(['arm', 'elbow', 'hand'], True) 
helperSkeletGroup(['hip', 'knee', 'ankle', 'foot'], True) 

這帶有一些優點:

  • 它處理對稱性您
  • 代碼不會增長太多,因爲關節數量增加
  • 如果在某些時候,你要更改定位器和關節的命名規則,你可以通過改變單行

或者做到這一點,你可以用一個面向對象的方法去。 下面是一個例子:

class Skeleton: 

    def __init__(self): 
     self.joint_groups = [] 

    def add_joint_group(self, group, symmetric=False): 
     # quick workaround to capitalize a word, leaving the following letters unchanged 
     capitalize = lambda s: s[:1].upper() + s[1:] 

     processed, processed_symmetric = [], [] 
     for elem in group: 
      if symmetric: 
       processed_symmetric.append('{0}R'.format(elem)) 
       elem = '{0}L'.format(elem) 
      processed.append(('{0}_Locator'.format(capitalize(elem)), '{0}_Joint'.format(elem))) 
     self.joint_groups.append(processed) 
     if processed_symmetric: 
      self.add_joint_group(processed_symmetric) 

    def helper_skelet(self, loc, joint): 
     # your helper logic goes here 
     print loc, joint 

    def build(self): 
     for group in self.joint_groups: 
      for loc, joint in group: 
       self.helper_skelet(loc, joint) 
      cmds.select(cl=True) 

skeleton = Skeleton() 
skeleton.add_joint_group(['root', 'pelvis', 'spine', 'spine01', 'spine02', 'neck', 'head']) 
skeleton.add_joint_group(['arm', 'elbow', 'hand'], True) 
skeleton.add_joint_group(['hip', 'knee', 'ankle', 'foot'], True) 

from pprint import pformat 
print pformat(skeleton.joint_groups) 

skeleton.build() 

下面的代碼是有點長,但都包含在一個單一的對象,在那裏你可以存儲更多的數據,這些數據在施工時只得到,哪些是你可能需要以後。

編輯(應答@ Giakaama在評論問題):

如果您保存類在一個單獨的文件skeleton_class.py,您可以在main.py導入類(或任何你想調用它),因爲這樣的:

from skeleton_class import Skeleton

其中小寫skeleton_class指的是你的模塊(讀:文件),並Skeleton是類本身。 一旦你做到了這一點,你可以做上面一樣:

skeleton = Skeleton() 
skeleton.add_joint_group(['root', 'pelvis', 'spine', 'spine01', 'spine02', 'neck', 'head']) 
skeleton.add_joint_group(['arm', 'elbow', 'hand'], True) 
skeleton.build() 
+0

不錯,是的,我指的是讓代碼更「清潔」:)。感謝您的答案。 – Giakaama

+0

如果我使用Class Skeleton,並將該類放入另一個文件(如Skeleton.py),如何將其導入到我的主文件中?我已經嘗試了空的__init__.py,它不工作:(。 – Giakaama

+0

剛剛編輯了一個提示的答案,讓我知道這是否解決了你的問題。另外,如果'Skeleton'類存在於你的'main .py'位置,確保你命名'__init__。py'文件正確;) – mapofemergence