Notifications
Clear all

[Closed] Duplicated mapname in different location

I’m trying to make a script that find texture with same filename but in different location in the scene and relocate all of them to the same path.

Ex.:
Before running the script:
Material_A = C:\Texture.jpg
Material_B = C:\folder\folder\Texture.jpg
Material_C = D:\Texture.jpg

After running the script:
Material_A = C:\Texture.jpg
Material_B = C:\Texture.jpg
Material_C = C:\Texture.jpg

–My idea was:
AllTex = #()
txs = getclassinstances bitmaptexture
for tx in txs do
(
if tx.filename exist in AllTex then (tx.filename = existing tx.filename) –I don’t know how to write that part
else (append AllTex tx.filename)
)

Thank you

6 Replies

first you need to collect all the textures and group them by file name.
so that the files can be compared, we will uniform their pathnames…

fn getEnumeratedFiles node: pattern: unify:on = 
(
	fn add_file file args = 
	(
		fn unify_pathname name = 
		(
			name = pathConfig.convertPathToLowerCase name
			substitutestring name @"\" "/"
		)

		_allmaps = args[1]
		_pattern = args[2]
		_convert = args[3]
		
		if _convert != false do file = unify_pathname file
		if not iskindof _pattern string or matchpattern file pattern:_pattern do 
		(
			appendifunique _allmaps file
		)
	)
	local args = #(#(), pattern, unify)
	if iskindof node MAXWrapper then enumerateFiles node add_file args else enumerateFiles add_file args
	args[1]
)

fn groupMapFiles maps = 
(
	d = dictionary #string
	for map in maps do 
	(
		filename = filenamefrompath map
		if d[filename] == undefined do d[filename] = #()
		d[filename] = append d[filename] map
	)
	d
)

/*
allscenemaps = getEnumeratedFiles()
mapdict = groupMapFiles allscenemaps  
*/

after that we can go ahead and decide what to do with the duplicates…
so we need couple rules:

  • Where should we search and replace duplicates?
  • What name (path) must be used in case of name duplication?

OMG thank you for helping me.

Where should we search and replace duplicates?

Search all bitmap in the scene

What name (path) must be used in case of name duplication?

Pick the location of the first duplicated. (or anyone of them, that don’t really matter)

fn getEnumeratedFiles target: pattern: unify:on = 
(
	fn add_file file args = 
	(
		fn unify_pathname name = 
		(
			name = pathConfig.convertPathToLowerCase name
			substitutestring name @"\" "/"
		)
		
		if args.unify == true do file = unify_pathname file
		if not iskindof args.pattern string or matchpattern file pattern:args.pattern do 
		(
			appendifunique args.list file
		)
	)
	args = (struct __ (list = #(), pattern = "*.*", unify = on);)()
	if iskindof target MAXWrapper then enumerateFiles target add_file args else enumerateFiles add_file args
	args.list
)

fn groupMapFiles maps = 
(
	d = dictionary #string
	for map in maps do 
	(
		filename = filenamefrompath map
		if d[filename] == undefined do d[filename] = #()
		d[filename] = append d[filename] map
	)
	d
)

/*
allscenemaps = getEnumeratedFiles()
groupedmaps = groupMapFiles allscenemaps  
*/

fn replaceMapDuplicates mapdict target: =
(
	bms = getclassinstances bitmaptexture target:target
	changed = 0
	for bm in bms where (map = bm.filename) != undefined do
	(
		filename = filenamefrompath map
		dups = mapdict[filename]
		if iskindof dups array and dups.count > 1 do
		(
			if not pathConfig.pathsResolveEquivalent map dups[1] do 
			(
				bm.filename = dups[1]
				changed += 1
			)
		)
	)
	changed
)

/*
replaceMapDuplicates groupedmaps
*/

I copy your code in the listener, select it, and press shift+enter to run it.
I got this:

getEnumeratedFiles()
groupMapFiles()
replaceMapDuplicates()

But unfortunately nothing change in the scene or in the asset tracking

Am I missing something?
I don’t understand a lot in coding, but you seem to define 3 fonctions. Do I have to call them somehow?

again, big thank you for your support

the entire executable part is commented out. you also need to run the commented lines

Ok even with the comment brackets remove it does nothing.
But you give me idea and now my code is working:

here what I do:

–START

AllTex = #()
AllPath = #()
txs = getclassinstances bitmaptexture
for tx in txs do
(
UniqueFile = toLower (filenameFromPath tx.filename)
UniquePath = (getFilenamePath tx.filename)
if (findItem AllTex UniqueFile == 0) then
(
print (“adding ” + UniqueFile + ” to unique list”)
append AllTex UniqueFile
append AllPath UniquePath
)
else
(
foundPosition = (findItem AllTex UniqueFile)
tx.filename = (Allpath[foundPosition] + AllTex[foundPosition])
print (Allpath[foundPosition] + AllTex[foundPosition])
print “double removed”
)
)
print “finished”

–END

I can’t tell you how happy I am. Even if your code does work for me your are part of the reason of this success.
Have a nice day.