MAXScript: How to find duplicate texturemap names via maxscript?


It was the first thing that I tried to use as a replacement for getClassInstances, but unfortunately it crashes max on provided scene file.
Perhaps, EnumerateAllAnimatables is the only way to go


Unfortunately, there are such problems due to the same map names that some people have, who often use all sorts of scene managers focused on the names of nodes in their work (for example, a script that performs the task of outputting the render pass depending on which map is actually loaded). There are many different cases where the same names in a scene can cause all sorts of problems. In general, having duplicate names for different independent nodes is a bad practice.

Perhaps you are right, and if a quick and correct solution is not found to rename only duplicate names, then most likely you will have to go this way. The only thing that can be annoying in this case is the large digital values in such maps names.

This is not a very convenient way, since renaming maps is just a part of one big maxscript script. Moreover, I am not very well versed in C# and C++, and I do not understand how to combine this with maxscript.

What I noticed is that the getClassInstances function works pretty quickly for me. Moreover, in the process of searching and dividing maps with the same names, I do not use getClassInstances, but use a ready-made array of all scene maps. My code looks like this:

mapsArray -- array of all texturemaps from scene
fn MakeUniqueTexmapName base_name keys cntNum format_string =
	local tempName=base_name + (formattedPrint cntNum format:format_string)
	if (finditem keys tempName)!=0 do (
		MakeUniqueTexmapName base_name keys (cntNum += 1) format_string

fn renMapsName mapsArray = 
keys       = #()
textures   = #()
duplicates = #{}

	for tex in mapsArray do
		key   = toLower tex.Name		
		index = findItem keys key
		if index > 0 then 
			append textures[ index ] tex
			duplicates[ index ] = true
			append keys key
			textures[ keys.Count ] = #( tex )	

for index in duplicates do
	unique_duplicates = makeUniqueArray textures[ index ]
	if unique_duplicates.count > 1 do
		map_name = unique_duplicates[1].Name
		base_name = trimRight map_name "0123456789"
		num_digits = map_name.Count - base_name.Count
		num = (substring map_name (1 + base_name.Count) num_digits) as integer
		format_string = "0" + num_digits as string + "d"
		i = num
		for j = 2 to unique_duplicates.Count do
			new_name = MakeUniqueTexmapName base_name keys (i += 1) format_string
			unique_duplicates[j].Name = new_name
			append keys (tolower new_name)
renMapsName mapsArray

It seems to me that the problem occurs in the last part of the code in the MakeUniqueTexmapName function, when it passes an additional check for existing names in the array. However, duplicate names are still sometimes skipped.
Perhaps I am making a mistake somewhere.


what if you replace custom map name maker function with assignNewName function as denisT suggested?

btw. there could be a recursion problem here. Imagine having two maps named Map#01 and the rest named Map#02 … till Map#666
how deep your recursion will be in this case? Map#667 is going be the first unused name. ( At this point you have 666 tempName string variables held on stack. Or maybe not strings but only pointers to string values stored on heap. Anyway no matter where exactly, all these 665 temp names are stored without any purpose, thus bloating the heap size and probably overflowing the stack? )

If you still want to use custom namemaker replace recursion with while loop

new_name = MakeNewName()
while (finditem keys new_name ) > 0 do new_name = MakeNewName() = new_name
append keys new_name


Yes, I can also use the assignNewName function in the same way, but I don’t like that it creates new names with large numeric values ​​such as “Map #64205647329555631… etc”

As for the while loop - I missed it for some reason :roll_eyes:, although it might be a solution. Thanks!


yeah, unless you rename all the maps and materials with such weird indexes and save the scene there’s no way to deal with it.
afaik there’s no other way to reset indexing even with c++