2017-08-25 44 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