Maya Python创建关节层次

时间:2017-08-25 22:33:20

标签: python maya

我试图在maya python中为骨架创建o关节层次结构。我正在做这个

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')

现在这样可以正常工作,因为必须按此顺序创建关节。 (辅助骨架是一个函数,我用关于定位器位置的参考来创建关节)

我想知道是否有更优化的方法来做到这一点,因为必须保留订单或创作。

谢谢

1 个答案:

答案 0 :(得分: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)

这带来了一些好处:

  • 它为你处理对称性
  • 随着关节数量的增加,代码不会增长太多
  • 如果您想要更改定位器和关节的命名约定,可以通过更改单行来实现

或者,您可以使用OOP方法。 这是一个例子:

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&#39的问题):

如果您将课程保存在单独的文件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()