yan
yan

Reputation: 649

Renaming and Locators positioning on Joints

I am trying to get this renaming working as the locators are being duplicated and moved to the position of the joints. For example, if I have a thigh_jnt, knee_jnt, ankle_jnt, the created locators will be named loc_thigh_jnt, loc_knee_jnt etc

However it is not working for me, as I am getting errors such as # ValueError: No object matches name: loc_0 #

Needless to say, the locator may be created but it is not at the position of the joint. Also, can I ask if it is possible to create the locator for all the joint? Currently it is only creating for the thigh and knee but not the ankle

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 )

Upvotes: 1

Views: 1281

Answers (1)

kartikg3
kartikg3

Reputation: 2620

Here is your code snippet with some modifications and corrections to make it work.

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       

In the first two cmds.select() calls, I added add=True flag. Without that flag, cmds.select() will assume replace=True by default. That is why your root joint was being ignored after this call.

In the for loop, the masterLoc was being duplicated N times, where N is the number of joints, thus resulting in N+1 locators (including the masterLoc). So I added the is_root_loop flag to check if the loop is running for the first time. During this run, we manipulate the masterLoc itself (without duplicating it), rename the masterLoc and store the name. From the second iteration of this loop, we use this masterLoc to duplicate and rename the duplicated locators as you had previously written.

Another change I did was storing the name of the duplicated locator

loc_to_rename = cmds.duplicate( returnRootsOnly=True , inputConnections=True )[0]

And used this to rename. That is where you were getting the errors because you were trying to rename masterLoc in every iteration.

Also, it is always important to catch the return results of commands like cmds.duplicate and cmds.rename, as the name they assign may not always be as expected, as Maya will append a number or increment the number at the end of the new name if a name clash occurs with something else in the scene.

I hope this helped!

Upvotes: 2

Related Questions