Small note I’ve not run this code in max, so it might work, it might not… if you want to try it and it doesn’t work, find the solution and then post it here for others to see, debugging is the best way to learn!
Quick challenge here, how can we transfer a material editor’s content from one scene to another. We could do some stuff with .mat files but I personally find them a bit of a pain to work with and here’s an alternative solution that uses some different thinking. Lets think in ‘normal’ speak first, we need two scripts, a saver and a loader.
--for every slot in the material editor (24) --Create a new temporary sphere --assign material to sphere --save all spheres to a file --delete all spheres --load spheres files --for every sphere 1 to 24 --take the material from the sphere and put into the material editor slot --delete all spheres
Lets put that into some code, it’s not anything too complicated so I won’t go through it line-by-line but hopefully the pseudo code makes sense to you. I’ll build a simple interface around it as normal.
Try(DestroyDialog RL_CopyMEdits)catch() Rollout RL_CopyMEdits "Copy Material Editor" ( button btn_Save "Save" button btn_Load "Load" on btn_Save pressed do ( --for every slot in the material editor (24) for i = 1 to 24 do ( --Create a new temporary sphere thesphere = Sphere name:("SMATSphere_" + i as string) --assign material to sphere thesphere.material = meditmaterials[i] ) --save all spheres to a file, might need to delete the old file first if doesfileext "c:\\TempMATS.max" then deletefile "c:\\TempMATS.max" SaveNodes "c:\\TempMATS.max" --delete all spheres delete $SMATSphere* ) on btn_load pressed do ( --load spheres files mergemaxfile "c:\\TempMATS.max" quiet:true --for every sphere 1 to 24 for i = 1 to 24 do ( --take the material from the sphere and put into the material editor slot meditmaterials[i] = (getnodebyname("SMATSphere_" + i as string)).material ) --delete all spheres delete $SMATSphere_* ) ) CreateDialog RL_CopyMEdits
There we go fairly easy isn’t it 😉 So what we’re doing, creating 24 spheres assigning the 24 materials of the material editor to each of these sphere, saving them out and then deleting them. If we hit Load, we’re merging in the temporary maxfile and grabbing the material off each sphere, the only really new clever thing we’re doing here is using getnodebyname() to get the node we want. Normally we’re dealing with nodes by saying $Sphere001, but if we need to refer to something by it’s name in this sort of loop we need to get the node, you can’t say $(Sphere + i as string), this doesn’t work, we need to create a string value that is the name of the node then get it using the function. The alternative way to do this is to use execute() which will basically take a string value and run it as if it was code, execute(“$Sphere” + i as string) will work but it’s slower, more sloppy and using execute can cause some security issues for those who know maxscript, but will get into that another day.
I said at the top of this post I wasn’t going to test the script but I did and it breaks in two places… It’s really good to go through and try fix this yourself, it’s only two corrections. Or here’s a break-down of how I debugged it and got it working….
-- Error occurred in btn_Save.pressed(); filename: C:\Scripts\MeditCopy.ms; position: 619; line: 19 -- Frame: -- doesfileext: undefined >> MAXScript Rollout Handler Exception: -- Type error: Call needs function or class, got: undefined <<
This is on the line….
if doesfileext "c:\\TempMATS.max" then deletefile "c:\\TempMATS.max"
Looks like I can’t spell…. doesfileext should be doesfileexist, fix one done… Run again and….
-- Error occurred in btn_Save.pressed(); filename: C:\Scripts\MeditCopy.ms; position: 690; line: 20 -- Frame: >> MAXScript Rollout Handler Exception: -- Argument count error: saveNodes wanted 2, got 1 <<
Lets look at the line….
The error is saying we haven’t provided enough arguments for the SaveNodes() function, it’s expecting 2 arguments… So lets look in the help and see what I’ve missed.
I’ve provided a <filename_string> but I haven’t provided a <node_collection>, which makes sense, I’ve told it to Save the nodes to a file but max doesn’t know which nodes we’re talking about! Just like on the next line we can get a collection of these nodes by using the name with a wildcard *.
SaveNodes $SMATSphere* "c:\\TempMATS.max"
Run again, and ta da….. works like a charm. No apologies for writing a dodgy script first time, hopefully this explanation of the process of debugging will help you.