Notifications
Clear all

[Closed] Issue with maxscript thinking $ is a symbolic path

Hey all,
I’m having an issue where my users for Relink Bitmaps are having problems when their missing file contains a ‘$’. Maxscript decides when assigning a new filename, that this filename is actually a symbolic filename because of the ‘$’.

Observe with the following code


(
	mat = StandardMaterial name:"TestMaterial"
	mat.diffuseMap = BitmapTexture filename:"C:\maps\$floor.jpg"
	
	mat.diffuseMap.filename = (filenameFromPath mat.diffuseMap.filename)   -- Errors
	
	medit.putMtlToMtlEditor mat 1	
)

Does anyone know a way to reassign the material’s diffuse map’s filename without max thinking it’s a symbolic path?

I can brute force around this issue, but would prefer a more elegant solution if one exists.

Thanks all,
Colin

10 Replies
1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

it’s an interesting puzzle. but it’s very usual situation when some specific rules must be used in a pipeline. i’m pretty sure that many tools and engines don’t like the ‘$’ in file name, or interpret it their own way.

I agree with denisT,
we have had this problem ourselves when we put engineering drawings and 3d models into our realtime graphics engine, often cad drawings contains all kinds of funky characters.
It’s best to get them cleaned up and give them proper names as soon as possible.
It will only give you trouble down the line.

What we did was to just make a tool that let’s you rename all ‘weird’ characters into what you choose (for example a simple underscore), then you can have that rename the texture file names as well.

Thank you for both taking the time to respond to the issue. I agree, it’s probably just bad practice to have ‘$’s in a filename (which I didn’t know you could even do in windows, today I learned).

I can implement a solution to have Relink Bitmaps automatically rename the files for my users, I was just hoping for a simple solution where I could turn off Symbolic paths for the assignment to the material slot.

Thanks again, welcoming any other ideas for solutions.

The really frustrating thing is you can’t even substitute the ‘$’ character out and back in directly, without max complaining:


(
	clearListener()
	mat = StandardMaterial name:"TestMaterial"
	mat.diffuseMap = BitmapTexture filename:"C:\maps\$floor.jpg"
	
	mat.diffuseMap.filename = substituteString mat.diffuseMap.filename "$" "<"
	
	mat.diffuseMap.filename = (filenameFromPath mat.diffuseMap.filename)   -- Errors
	
	mat.diffuseMap.filename = substituteString mat.diffuseMap.filename "<" "$"
	
	medit.putMtlToMtlEditor mat 1	
)

If the problem is that you can’t have a filename without path starting with $, what about you just add \ in front of the filename if you detect that it starts with $?

(
	mat = StandardMaterial name:"TestMaterial"
	mat.diffuseMap = BitmapTexture filename:@"C:\maps\$floor.jpg"
	
	flnStr = (filenameFromPath mat.diffuseMap.filename)
	if flnStr[1] == @"$" then flnStr = @"\"+flnStr
	mat.diffuseMap.filename = flnStr  

	medit.putMtlToMtlEditor mat 1	
)

This seemed to work when I tested it.

And yes you can substitute the $ character in strings just fine, the issue is where you try to assign a filename that starts with “$”. “substituteString mat.diffuseMap.filename “<” “$”” effectively tries to assign a new string there.

The problem isn’t limited to a filename starting with a $, the problem is when a filename contains a $ at all, because MAXScript tries to expand the symbolic link.

In your example the filepath is no longer valid for max finding the bitmap.

1 Reply
(@zhalktis)
Joined: 10 months ago

Posts: 0

Ah, sorry, I made a very silly mistake when testing. Noticed that it works fine with a full path, but doesn’t when it starts with $. Added \ and it worked… I didn’t realize it got the bitmap only because of the max scene and the bitmap being both in the same directory. >_<

I guess the only workaround is to have the full path for these kind of files.

I think I have it working with this code:

Similar to what I’m doing in Relink Bitmaps:


(
	mat = StandardMaterial name:"TestMaterial"
	mat.diffuseMap = BitmapTexture filename:"C:\$floor.jpg"
	
	local newPathToBitmap = "D:\\MyTextures\\"
	
	newPathToBitmap += (filenameFromPath mat.diffuseMap.filename)
	
	mat.diffuseMap.filename = newPathToBitmap
	
	medit.putMtlToMtlEditor mat 1
)

It seems strange this code works, when so many other tests I’ve done didn’t work. (Like the substituteString didn’t).

I think I’ll warn users about bitmaps about bitmap filenames with tokens in them just for their knowledge and proceed accordingly.

i can try to explain why one works and another doesn’t
the action

texturemap.filename = file

does do actually two things:

sets the property

and opens bitmap

there is a rule that max uses to find texture file if it doesn’t exist at specified path.
for example you can put “test.jpg” file and max sets the filename property to “test.jpg” but opens bitmap from first found place “c:\program files\blah,blah,…max\maps est est.jpg”.

so when you put “$test.jpg” you force max to search. and the path “$test.jpg” has special for max meaning (symbolic path).
when you construct full path like “c: est$test.jpg” it looses this meaning. now it’s just a path which max can split on path and name parts, and use name part for searching in case if it couldn’t be found by specified path.

does it make sense now?

Yes Doctor Thanks for the expanded explanation.