关节上的重命名和定位器放置
我正在尝试让这个重命名的功能正常工作,因为定位器的名称重复了,并且被移动到了关节的位置。比如说,如果我有大腿关节(thigh_jnt)、膝关节(knee_jnt)和踝关节(ankle_jnt),那么创建的定位器会被命名为 loc_thigh_jnt、loc_knee_jnt 等等。
不过这对我来说并不奏效,因为我遇到了错误,比如 # ValueError: No object matches name: loc_0 #
。
不用说,定位器可能是创建了,但它并不在关节的位置上。此外,我想问一下,是否可以为 所有
的关节创建定位器?目前只为大腿和膝盖创建了定位器,但踝关节却没有。
import maya.cmds as cmds
def createLoc():
cmds.select( cmds.listRelatives( type = 'joint', fullPath = True, allDescendents = True ) )
cmds.select( cmds.listRelatives( parent = True, fullPath = True ) )
sel = cmds.ls ( selection = True, type = 'joint' )
if not sel :
cmds.warning( "Please select a joint / No joints in selection " )
return
locGrp = cmds.group(n="loc_Grp_#", em=True)
cmds.addAttr ( locGrp, attributeType = 'double' , longName = 'locScale' , defaultValue = 1.0 , keyable = 1 )
masterLoc = cmds.spaceLocator(n="loc_0")[0]
cmds.parent( masterLoc, locGrp )
for attr in ["scaleZ", "scaleY", "scaleX"]:
cmds.connectAttr ( locGrp + ".locScale" , "%s.%s" % ( masterLoc, attr ) )
for jnt in sel:
print jnt
coords = cmds.xform ( jnt, query = True, worldSpace = True, pivots = True )[0:3]
cmds.select( masterLoc, replace = True )
cmds.duplicate( returnRootsOnly = True , inputConnections = True )
# This is where the errors starts
#cmds.rename(str(masterLoc), ("loc_" + str(sel)))
cmds.move( coords[0], coords[1], coords[2], rotatePivotRelative = True )
1 个回答
这是你的代码片段,经过一些修改和修正,使它能够正常工作。
import maya.cmds as cmds
def createLoc():
cmds.select( cmds.listRelatives( type='joint', fullPath=True, allDescendents=True ), add=True )
cmds.select( cmds.listRelatives( parent=True, fullPath=True ), add=True )
sel = cmds.ls ( selection = True, type = 'joint' )
if not sel :
cmds.warning( "Please select a joint / No joints in selection " )
return
locGrp = cmds.group(n="loc_Grp_#", em=True)
cmds.addAttr ( locGrp, attributeType='double' , longName='locScale' , defaultValue=1.0 , keyable=1 )
masterLoc = cmds.spaceLocator(n="loc_0")[0]
cmds.parent( masterLoc, locGrp )
for attr in ["scaleZ", "scaleY", "scaleX"]:
cmds.connectAttr ( locGrp + ".locScale" , "%s.%s" % ( masterLoc, attr ) )
is_root_loop = True
loc_to_rename = masterLoc
for jnt in sel:
print jnt
coords = cmds.xform ( jnt, query=True, worldSpace=True, pivots=True )[0:3]
cmds.select( masterLoc, replace=True )
if not is_root_loop:
loc_to_rename = cmds.duplicate( returnRootsOnly=True , inputConnections=True )[0]
# No more errors!
renamed_loc = cmds.rename(str(loc_to_rename), ("loc_" + str(jnt)))
if is_root_loop:
masterLoc = renamed_loc
cmds.move( coords[0], coords[1], coords[2], rotatePivotRelative=True )
is_root_loop = False
在前两个cmds.select()的调用中,我添加了add=True这个标志。如果没有这个标志,cmds.select()默认会把之前的选择替换掉,这就是为什么你的根关节在这个调用后被忽略的原因。
在for循环中,masterLoc被复制了N次,其中N是关节的数量,这样就导致了总共有N+1个定位器(包括masterLoc)。所以我添加了is_root_loop这个标志来检查循环是否第一次运行。在第一次运行时,我们直接操作masterLoc本身(而不是复制它),重命名masterLoc并保存这个名字。从第二次循环开始,我们就用这个masterLoc来复制并重命名复制出来的定位器,就像你之前写的那样。
我做的另一个改变是保存复制出来的定位器的名字。
loc_to_rename = cmds.duplicate( returnRootsOnly=True , inputConnections=True )[0]
然后用这个名字来重命名。这就是你之前出错的地方,因为你在每次循环中都试图重命名masterLoc。
另外,捕捉像cmds.duplicate和cmds.rename这样的命令的返回结果总是很重要,因为它们分配的名字可能并不总是你预期的。如果场景中有名字冲突,Maya会在新名字的后面加上一个数字或递增这个数字。
希望这些对你有帮助!