Maya Python 创建关节层次结构
Maya Python Create joints Hierachy
我正在尝试在 Maya 中为骨架创建关节层次 python。我正在这样做
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')
现在可以正常工作了,因为必须按此顺序创建关节。 (辅助骨架是一个函数,我在其中参考定位器位置创建关节)
考虑到必须保持顺序或创建,我想知道是否有更优化的方法来执行此操作。
谢谢
如果 "optimize" 你的意思是获得更好的性能,我同意@downshift 所说的。
如果您的意思是让您的代码 "cleaner"(更通用或可扩展或只是更 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 的问题):
如果您将 class 保存在一个单独的文件 skeleton_class.py
中,您可以将 class 导入到您的 main.py 中(或任何您想调用的文件),因此:
from skeleton_class import Skeleton
其中小写 skeleton_class
指的是您的模块(读取:文件),而 Skeleton
是 class 本身。
完成后,您可以执行与上述相同的操作:
skeleton = Skeleton()
skeleton.add_joint_group(['root', 'pelvis', 'spine', 'spine01', 'spine02', 'neck', 'head'])
skeleton.add_joint_group(['arm', 'elbow', 'hand'], True)
skeleton.build()
我正在尝试在 Maya 中为骨架创建关节层次 python。我正在这样做
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')
现在可以正常工作了,因为必须按此顺序创建关节。 (辅助骨架是一个函数,我在其中参考定位器位置创建关节)
考虑到必须保持顺序或创建,我想知道是否有更优化的方法来执行此操作。
谢谢
如果 "optimize" 你的意思是获得更好的性能,我同意@downshift 所说的。
如果您的意思是让您的代码 "cleaner"(更通用或可扩展或只是更 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 的问题):
如果您将 class 保存在一个单独的文件 skeleton_class.py
中,您可以将 class 导入到您的 main.py 中(或任何您想调用的文件),因此:
from skeleton_class import Skeleton
其中小写 skeleton_class
指的是您的模块(读取:文件),而 Skeleton
是 class 本身。
完成后,您可以执行与上述相同的操作:
skeleton = Skeleton()
skeleton.add_joint_group(['root', 'pelvis', 'spine', 'spine01', 'spine02', 'neck', 'head'])
skeleton.add_joint_group(['arm', 'elbow', 'hand'], True)
skeleton.build()