[Maya Python] Inconsistent For Loop Behavior

python

#1

Hi,

I am trying to duplicate a joint and rename it. Got a hit from @Theodox post from the stack overflow

It works well but I got an error whenever I try to change the “grp1” to “grp”. Which is weird because in the outliner there is a grp1 on the duplicate IK joint group

# Error: No object matches name
# Traceback (most recent call last):
#   File "<maya console>", line 20, in <module>
#   File "<maya console>", line 18, in hybridIKFK
# RuntimeError: No object matches name # 

Here is the code in question


import maya.cmds as mc

def hybridIKFK():
    jointBase = 'spine01_jnt_grp'

    ikJoint = cmds.duplicate(jointBase, rr=True)  
    ikJoint += cmds.listRelatives(ikJoint, ad=True, f=True) 
    
    longnames = cmds.ls(ikJoint, l=True)  
    longnames.sort() 
         
    for item in longnames[::-1]:  
        shortname = item.rpartition("|")[-1] 
        cmds.rename(item, shortname.replace("_jnt", "_IK_con"))  
        
    for oldName in ikJoint:  # this is the line that throws an error
        cmds.rename(oldName, oldName.replace("grp1","grp"))

hybridIKFK()

#2

when you call mc.ls trying adding the flatten flag as well mc.ls(ikJoint, long=True, flatten=True)


#3

Here is a general answer. When you are debugging basic Python code - especially while learning - don’t put it inside a function. When you run the function, and it finishes, the scope is gone, and all your variables no longer exist.

If you run the code alone, outside of a function, then you can run one line at a time, to see and debug what is going on.

For example, you could run the code, get the error, and then run print(oldName) or print(ikJoint) to see what is actually inside the variable, oldName or ikJoint.

Anyway, your problem is that you are changing the name of a parent of a bunch of nodes that you are trying to find with longName. When the parent name changes, the longName path is no longer valid.


#4

Also cmds.duplicate() can take a name flag, which will automatically rename the node you are duplicating. So to avoid “grp1” you can specify your own name when you duplicate.

(Also you are importing maya.cmds as mc but still using “cmds” in your script.)


#5

One of the most useful things I figured out, was how to get at stuff inside a function when it was a pain to re-write outside of a function.

import __main__
__main__.__dict__.update(locals())

__main__ is the top-level namespace in python. You start an interpreter, you’re in __main__. You run things in the maya script editor, you’re running them in __main__.
And __main__ stores it’s variables as a dictionary in the __dict__ member. So this just adds all the local function variables (grabbed via locals()) to that top-level namespace.

Put that just before where your error occurs, and you now have access to all the variables defined inside your function directly from the script editor.


#6

I would generally advise against inserting things into a modules namespace by accessing __dict__ like that.

I would recommend getting a debugger setup, PyCharm, Wing, and VS-Code can all attach a debugger to Maya.

Or you can always just use import pdb;pdb.set_trace().


#7

Thank you for the responses. I ended up taking the @clesage suggestion in using the name flag on the duplicate command

@passerby
for some reason, even though I added the flatten command, it still gives me error.

@clesage
“When the parent name changes, the longName path is no longer valid.” Oh okay. Thanks for the insight.

@tfox_TD @R.White

I inserted the code snippet but I get the same error. No worries the duplicate command trick saved me.
Thanks also for giving an intro on how the function work. Might come in handy in sometime.