Reputation: 649
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
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