Transfer Material Editor

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!

http://forums.cgsociety.org/showthread.php?f=6&t=1060754

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….

SaveNodes "c:\\TempMATS.max"

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.

<bool>saveNodes <node_collection> <filename_string> [saveAsVersion:<integer>] [quiet:<bool>]

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.

Advertisements

About davewortley

Somewhere between an artist and a programmer, I like technical things, but being creative. I love problem solving and coming up with elaborate solutions. This blog is where I shall share ideas, tips, tutorials and anything that amuses me.
This entry was posted in 3dsmax, MaxScript. Bookmark the permalink.

7 Responses to Transfer Material Editor

  1. davewortley says:

    Edited to show the fix.

    Like

  2. denisT says:

    this method is not 100% correct. material editor’s slot can contain a material or textureMap. in case of textureMap the method will not work.

    Like

  3. Whats the benefit to this method over opening a material library via selecting a .max file?
    Cause you could open the .max file as library then do update scene materials from library from within the slate editor.

    Like

    • davewortley says:

      There’s lots of possibilities for using this system over the standard .mat file. You could build upon this idea so if you have an modifiers necessary for the material to work, VrayDisplacement, special UVW mapping you could grab this at the same time.

      Like

  4. Jumbos says:

    This is quite risky move… Use delete $mat xxxx that is… Better tag the object first using app data or Custom attribute… Or just go back using mat thing method that you neglect it first..

    Like

    • davewortley says:

      True where I do this kind of making objects and deleting them I normally use such an obscure name that there’s not chance anyone would ever create an object with the same name. That being said, yes, tagging them another way would be a good idea.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s