automatically rename non-unique nodes?


i sometimes get items that have been duplicated and don’t have unique names. They trip up my batch rendering script and I’m wondering if there’s a way to weed these out and automatically rename them.


Define an object that contains the short name and the full name of an object:

class obj:
	short_name = []
	long_name = []

For each object in your scene, create such an object, and add it to a list.
Sort the list according to the short name. Go through the list, and whenever you find two consecutive items with the same short name, rename the second item to a name of an object that would appear later in the sorted list (e.g. add ‘1’ to the end of the name), and move the item to its sorted place in the list (forward). Continue your check from the first item.

Alternatively you could implement the same idea with two arrays, without using objects.


Probably a daft way to go about it but…

import maya.cmds as cmds

objs =
copy = [x.rpartition('|')[2] for x in objs]

for i in range(len(copy)):
	startIndex = 0
	copyCount = copy.count(copy[i])
	if copyCount > 1:
		dup = copy[i]
		for j in range(copyCount):
			index = copy.index(dup, startIndex)
			copy[index] = cmds.rename(objs[index], (dup + '_' + str(j)))
			startIndex = index+1

Doesn’t include namespaces.


you don’t need to go through all that rigamarole.
If you simply [b]ls[/b] using short names maya will return short names but not non-unique names, so anything in that list that contains a “|” (the DAG path Separator) is not uniquely named.
Here’s some example MEL (as I assume you are still a MEL man Dave…?)

string $allDagNodes[] = `ls -sn -dag`;
for ($node in $allDagNodes)
	if (`gmatch $node "*|*"`)
		print ($node+" is not uniquely named

# python:
allDagNodes =,dag=1)
nonUnique = [ node for node in allDagNodes if '|' in node ]

the trick to uniquely naming a node is not checking it against existing names, but using a built in Maya feature. If you create a DG node on the scene root and give it a name, Maya will only return unique names, so simply create an arbitrary node and give it the same name as your non-unique node, and it will return a uniquely named variation.

string $unique = `createNode "unknown" -n "pCube3"`;
// Result: pCube17

if the returned name happens to be identical to the one you gave then you know it’s a unique name.


Nice trick, I should have thought about at least one of them, but I was in brute force mode.


It’s a nice feature that maya gives a unique name to a node upon creation, but to have to create and delete a node for each node with a non-unique name seems somewhat innefficient. Or am I not understanding it? :o


I don’t think that the emphasis in this task is on a killer performance, and how much creating and deleting a dummy node should cost anyway?!

BTW mlefevre, I think your code is imperfect. What would happen if your copy list already contains a member dup + ‘_’ + str(j) ?
For example: copy = [‘a’, ‘a’, ‘a_0’]

After fixing this, if you are interested in complexity, compare the complexity of your algorithm to mine (something like O(n^2) vs O(nlogn))



heh, you’re probably right. It just seems a bit odd to create a node only to delete it.

I just stumbled through it, so no doubt it is. I’m not quite understanding what you’re getting at though. Would you mind posting a full working example on how to break it. Just for fun!

That’s all well and good, but I failed my maths at school, and I’ve no idea what all that means.
I’m more than happy for you to teach me though :wink:


That’s all well and good, but I failed my maths at school, and I’ve no idea what all that means.
I’m more than happy for you to teach me though

Not important here, don’t bother yourself with it. But the general idea is since you didn’t sort your array, you’ll have to go all over it to test for duplicates each time, while I don’t. It’s a factor of the size of an array concerning performance.

Would you mind posting a full working example on how to break it

I believe I did, but I’ll be more specific. In a new scene execute:

createNode transform -name a_0;
createNode transform -name a -p a_0;
createNode transform -name a -p a;



You broke it! :frowning: …Okay, I’ll take you up on on the challenge!


yey, managed to shorten it a bit more. :slight_smile:

Break it if ye dare Zoharl! :buttrock:

import maya.cmds as cmds

objs = [x for x in if '|' in x]
objs.sort(key=lambda x : x.count('|'))
for i in range(len(objs)):
	cmds.rename(objs[i], objs[i].replace('|', ''))

# proof
if not len([x for x in if '|' in x]):
	print 'no non-unique names :)'


awesome - thanks so much.


We will still stay friends afterwards, right?

createNode transform -name a;
 createNode transform -name a -p a;
 createNode transform -name aa;



Hehe, ofcourse :slight_smile:

Talk about opening a can of worms. On much reflection, Nathans suggestion definately seems the most efficient. I stuck at though just for kicks so here’s another attempt. Screw the performance…I just want it to work now.

import maya.cmds as cmds
import re

objs = [, long=True)[0] for x in, type='transform') if '|' in x]
objs.sort(key=lambda x : x.count('|'), reverse=True)
copy = [x.rpartition('|')[2] for x in objs]

for i in range(len(objs)):
	num = [int(x) for x in list(set([re.findall("[0-9]*$", x)[0] for x in[i] + '_*')])) if x.isdigit()]
	if len(num):
		num = max(num)+1
		num = 1

	cmds.rename(objs[i], copy[i] + '_' + str(num))


Great :thumbsup:

I still don’t understand the function of this line (maybe for luck?):

objs.sort(key=lambda x : x.count('|'), reverse=True)

Nathan with his trick used maya inner mechanism to solve the unique naming for him. What you did is more interesting, you implemented this mechanism yourself.

A recap of your algorithm:

  1. Get the names of all objects with the same short name.
  2. Add for each such name a suffix of '’ and a number. For the number to be unique, you look for all the objects with this pattern (name#), and set your number to the largest number in existence + 1.


hehe, thanks! To rename an object, I had to supply the full path. If I renamed the parent before renaming the child, the path becomes invalid so I had to sort them with that line.


Nice, I didn’t consider this point.


generating a new unique name is easy with MEL/Python.

rename “|group1|pCube1” “|group1|pCube#”

will generate the next unique number for the base name “pCube”

using the “#” in a rename operation tells Maya to use it’s internal mechanism for generating unique names.

no need to write code to look for valid numeric suffixes.


So awesome! :bowdown:


Nice. :thumbsup:

And I believe you meant

rename "|group1|pCube1" "pCube#"

Although still you need to parse the number out of the object name. So Nathan’s method still might be an easier general solution.