关节上的重命名和定位器放置

1 投票
1 回答
1257 浏览
提问于 2025-04-30 19:17

我正在尝试让这个重命名的功能正常工作,因为定位器的名称重复了,并且被移动到了关节的位置。比如说,如果我有大腿关节(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 个回答

2

这是你的代码片段,经过一些修改和修正,使它能够正常工作。

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会在新名字的后面加上一个数字或递增这个数字。

希望这些对你有帮助!

撰写回答