Pymel - object vs strings problem

Hey guys,

Please run this code:

import pymel.core as pm

for i in range(2 ):
    
    pm.select (cl=True)
    up = pm.joint ( p = (1 ,0, 0 ) )
    mid = pm.joint ( p = (3 ,0, -1 ) )
    down = pm.joint ( p = (5 ,0, 0 ) )
    
    p = pm.polyCube()[0]
    
    cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" , n = "arm_ikh" )
    cube = cubes[0]
    print cube
    print type(cube)
    pm.parent (cube, p)

You’ll see it runs correctly the first time but not the second time, since the result of cube is a string not the actual object.

Why the first time ikHandle returns an object but second time, it returns a string?!

And how can I solve it?

Thanks a million.

Not exactly sure why it behaves that way. There is a problem with having two objects named “arm_ikh”, but making the names unique fixes it.


import pymel.core as pm

for i in range(2 ):
    
    pm.select (cl=True)
    up = pm.joint ( p = (1 ,0, 0 ) )
    mid = pm.joint ( p = (3 ,0, -1 ) )
    down = pm.joint ( p = (5 ,0, 0 ) )
    
    p = pm.polyCube()[0]
    
    ik_handle_name = "arm_ikh" + str(i)
    cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" , n = ik_handle_name )
    cube = cubes[0]
    print cube
    print type(cube)
    pm.parent (cube, p)

[QUOTE=roham;13735]Hey guys,

Please run this code:

import pymel.core as pm

for i in range(2 ):
    
    pm.select (cl=True)
    up = pm.joint ( p = (1 ,0, 0 ) )
    mid = pm.joint ( p = (3 ,0, -1 ) )
    down = pm.joint ( p = (5 ,0, 0 ) )
    
    p = pm.polyCube()[0]
    
    cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" , n = "arm_ikh" )
    cube = cubes[0]
    print cube
    print type(cube)
    pm.parent (cube, p)

You’ll see it runs correctly the first time but not the second time, since the result of cube is a string not the actual object.

Why the first time ikHandle returns an object but second time, it returns a string?!

And how can I solve it?

Thanks a million.[/QUOTE]


#Try this:
cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" , n = "arm_ikh#" )

Both ways work correctly.

There is just one thing. Would you explain why it gives me a string the second time?

Is it a bug or my mistake?

[QUOTE=roham;13743]
Is it a bug or my mistake?[/QUOTE]

A little bit of both, but more of a pymel bug i’m guessing. You should always try and ensure unique names, even if something is hierarchy protected, despite the fact that in alot of cases Maya handles name mangling for you. If i read your code, i should be able to tell right off that something is getting a unique name, vs wondering why it looks like you’re passing the same name string to a creation function in a loop. That’s just good practice.

That all said, I’m not sure what the bug is specifically yet, I traced through the pymel code a little bit and got to where it looks like something is returning early or None, but I haven’t determined why it’s doing that yet. I’ll have to spend a little more time stepping through it when I get home from work today…

That’ll be great Seth, thanks for your time.

Please let me know if you find any reason why it happens.

This piece of script is a simplified version of my problem. I need to know this.

It really appears to be some weird bug with the ikHandle class. I lowered your loop to 1, and run it multiple times. Did you notice it only fails on the 2nd time? The 3,4,5,n… times run just fine.

Also, if you eliminate the last parenting command, the bug doesn’t occur either… As a potential workaround, (or as a potential clue to solving the bug) you could store up each ikHandle in a list, and then run the parenting outside of the loop. A bit of a hack, but I tested it and it works. (code below)

I’m curious though. Giving it a unique name avoids the bug, why don’t you just do that?


import pymel.core as pm

listOfHandles = []
listOfCubes = []
for i in range(2 ):
    
    pm.select (cl=True)
    up = pm.joint ( p = (1 ,0, 0 ) )
    mid = pm.joint ( p = (3 ,0, -1 ) )
    down = pm.joint ( p = (5 ,0, 0 ) )
    
    p = pm.polyCube()[0]
    
    cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" , n = "arm_ikh" )
    cube = cubes[0]
    print cube
    print type(cube)
    listOfCubes.append(p)
    listOfHandles.append(cube)

for i in range(2):
    pm.parent(listOfHandles[i],listOfCubes[i])

One more workaround. Rename the effector after the fact.


    cubes =   pm.ikHandle(  sj = up, ee = down, solver = "ikRPsolver" )
    pm.rename(cubes[0], "arm_ikh")

[QUOTE=roham;13763]That’ll be great Seth, thanks for your time.

Please let me know if you find any reason why it happens.

This piece of script is a simplified version of my problem. I need to know this.[/QUOTE]

Will do, it’s always fun to hack around the pymel codebase, if nothing else, it’s a great learning experience…

Thank you guys, it was very helpful. :D: