::Stupid Node Name Paths::

March 23rd, 2011 by hamish download the zooToolBox

I remember when every node name in maya had to be unique.  Made dealing with nodes just using their name really easy.  Then alias introduced name paths so you could have two nodes with the same leaf name as long as the node still had a unique path.  Its been a pain ever since.  Not a big pain mind you – just an annoying ache that keeps coming back over and over again.

Anyway I had an annoying bug with one of my tools the other day.  Basically I was passing in a node – lets say it was called “someNode“.  Anyway at the start of the function call it was totally valid, but by the end of the function it didn’t exist.  There were a couple of problems that teamed up to make it extra annoying.  The first is that objExists will return True if any node with the given leaf name exists.  So by the end of the function – objExists( “someNode” ) was returning True even though any other command would throw a RuntimeError.

As it turns out the function was creating a new node with the same leaf name.  So as soon as the new node was created, the name of “someNode” immediately changed to “|someNode“.

Now I know what you’re thinking – “Dude if you’d just use pymel you wouldn’t have had this drama!“.  And you’re totally right.  If thats the way you roll, good for you.  But I expect you know my stance on pymel already so I won’t go into it.  Honestly this exact case is probably the best reason to commit to pymel.  Those who have already made the transition to it possibly don’t even know what I’m talking about.

Anyway – the fix is easy of course.  And there are a bunch of ways you can go with it.  I went the route of casting the “someNodeobject to an MObject at the start of the function, but I guess you could also detect the name clash before creating the new node and modify its name accordingly – which I guess is the only option you have if you’re using mel.  But it was a frustrating half hour of my life that I’ll never get back!  ;)


This post is public domain

This entry was posted on Wednesday, March 23rd, 2011 at 15:06 and is filed under main. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

  • uiron

    At the very beginning of my acquaintance with python and maya this was one of the first questions that came to me. I never accepted the fact that i’m gonna base my whole code on every node name being unique, this just puts so much more unnecessary garbage into code and into node names – why call node “awesomeRig_L_Leg_UpperTwist_upVector” when in given context it’s just “upVector” ?

    I implemented a wrapper object around MObject, pretty much what pymel does, just it happened few years ago, when pymel itself was out of consideration. This way, you have a code that throws node naming problem out of the window – you just have to make sure that your rig is compatible with 3rd party stuff animators will like to use, like pose manager – which does NOT work with full/partial path names, and will complain if you have two controls with the same name.

  • hamish

    uiron – that is indeed cool. Although I’m curious about your use of MObjects – so have you wrapped all maya.cmds functions to return MObjects? If not do you constantly have to be casting to/from MObject instances?

    I find that for the most part I just am in the habit of using flags like -pa for listRelatives etc… Most mel commands return partial paths anyway, so its not often a problem just using the strings. And using the raw strings is WAY faster than casting to MObjects all the time.

  • http://profiles.google.com/ituden.uiron viktoras m

    to make it compatible with all cmds functions, i override _str_ method in my object to return full node name, so that i can do stuff like that:

    node = NodeHandle(cmds.cube())
    cmds.delete(node) # internally cmds does “str(node)” before using it

    sorry, can’t post the actual NodeHandle code as it’s a part of a property of my employer.

  • Anonymous

    Ok – but you have to explicitly cast. This is basically the same as my implementation as well. apiExtensions.asMObject( someNode ) will return a native MObject, but I’ve overridden the __str__ and __unicode__ methods on autodesk’s MObject wrapper class so that anything that returns an MObject will work directly with maya.cmds functions as well. Makes working with the api and maya.cmds super easy and nice, and has no wrapping/conversion costs.