后缀if语句
我在寻找一种方法,想给Maya里的关节链添加后缀。这个关节链有特定的命名规则,所以我创建了一个需要的名称列表。第一个链的后缀是“_1”,结果是:
R_Clavicle_1|R_UpperArm_1|R_UnderArm_1|R_Wrist_1
当我创建第二个链时,结果是:
R_Clavicle_2|R_UpperArm_1|R_UnderArm_1|R_Wrist_1
代码如下:
DRClavPos = cmds.xform ('DRClavicle', q=True, ws=True, t=True)
DRUpArmPos = cmds.xform ('DRUpperArm', q=True, ws=True, t=True)
DRUnArmPos = cmds.xform ('DRUnderArm', q=True, ws=True, t=True)
DRWristPos = cmds.xform ('DRWrist', q=True, ws=True, t=True), cmds.xform('DRWrist', q=True, os=True, ro=True)
suffix = 1
jntsA = cmds.ls(type="joint", long=True)
while True:
jntname = ["R_Clavicle_"+str(suffix),"R_UpperArm_"+str(suffix),"R_UnderArm_"+str(suffix),"R_Wrist_"+str(suffix)]
if jntname not in jntsA:
cmds.select (d=True)
cmds.joint ( p=(DRClavPos))
cmds.joint ( p=(DRUpArmPos))
cmds.joint ( 'joint1', e=True, zso=True, oj='xyz', radius=0.5, n=jntname[0])
cmds.joint ( p=(DRUnArmPos))
cmds.joint ( 'joint2', e=True, zso=True, oj='xyz', radius=0.5, n=jntname[1])
cmds.joint ( p=(DRWristPos[0]))
cmds.joint ( 'joint3', e=True, zso=True, oj='xyz', radius=0.5, n=jntname[2])
cmds.rename ('joint4', jntname[3])
cmds.select ( cl=True)
break
else:
suffix + 1
我尝试在jntname中加1,这样得到了一个不错的第二个链,但第三个链的R_Clavicle_3后面却出现了“_2”。
在我看来,这段代码应该是可以工作的。有没有人能给我指个正确的方向呢 :)
2 个回答
你从来没有在重新绑定 suffix:
else:
suffix + 1
这其实是没什么作用的。这个表达式返回 2
,但这个值完全被忽略了。这里 suffix
本身所指向的值并没有受到影响。
你想在这里重新给 suffix
赋值:
else:
suffix = suffix + 1
你也可以在这里使用增强赋值:
else:
suffix += 1
看起来你的代码会在场景中的每个关节上运行,这可能不是你真正想要的效果。
这里有一些基本的方法可以帮助你解决这个问题。
使用列表来进行循环 - 你不需要用'while true',通过循环列表可以遍历列表中的每一个项目。所以你可以这样访问场景中的每个关节:
all_joint = cmds.ls(type='joint') for each_joint in all_joints: do_something(each_joint)
Python有一个非常方便的功能叫做列表推导式。这个功能可以让你很简单地从旧列表中创建新列表。例如:
def suffixed_names (side, suffix) joint_names = ["_Clavicle_", "_UpperArm_", "_UnderArm_", "_Wrist_"] return [side.upper() + jn + str(suffix) for jn in joint_names]
这个和你的代码是一样的,但打字少多了(而且你也可以处理左臂!)
Python还有一个很实用的函数叫做zip,它可以从其他列表中匹配的项目创建一个新列表:
names = ['a', 'b', 'c'] values = [10, 20, 30] name_vals = zip(names, values) # [('a', 10), ('b':20), ('c', 30)]
Python在循环方面很聪明,所以如果你对一个zip后的列表进行循环,你可以这样获取每个部分:
for letter, number in named_vals: print letter, number # a 10 # b 20 # c 30
将你的函数拆分成更小的部分,这样可以让事情变得更清晰。
把这些结合起来,你可能会得到这样的代码:
def get_original_positions(clav, upper, under, wrist):
# get all the underlying positions in order
results = []
for each_bone in [clav, upper, under, wrist]:
results.append(cmd.xform (each_bone, q=True, t=True, ws=True))
return results
def create_named_arm(side, suffix, clav, under, upper, wrist):
original_pos_list = get_original_positions(clav, upper, under, wrist)
suffixed_name_list = suffixed_names (side, suffix)
cmds.select(cl=True) # clear before starting
created_joints = []
for pos, name in zip (original_pos_list, suffixed_name_list):
created_joints.append( cmds.joint(name, p = pos))
# now loop back and orient the joints...
for each_new_joint in created_joints:
cmds.joint(each_new_joint, zso = True, oj= 'xyz')
return created_joints
# you do need to supply the names of the original joints:
create_named_arm ('r', 1, 'DRClavicle', 'DRUpperArm', 'DRUnderArm','DRWrist')
# a second chain:
create_named_arm ('r', 2, 'DRClavicle', 'DRUpperArm', 'DRUnderArm','DRWrist')
这在一开始需要更多的规划,但从长远来看,代码更容易阅读和处理。Python的列表真是太棒了!要学会喜欢它们。