need help with custom attributes

What I'm trying to do is set up some controls for a pair of materials. I've got a ui set up with spinners, etc that will adjust properties of both materials at the same time. That all works fine after running an initial script that creates the materials sets up all the connections. However, I want to be able to close down Max, restart it, open my scene file with those materials in it, and still have the CA be able to tweak the settings.

My first problem is that upon restarting max, I get a missing DLL error. I'm pretty certain this has something to do with where I saved the CA script file. I've tried it in maxRoot/scripts/myfolder, scripts/startup, stdplugins/stdscripts, and none of those seem to make any difference.

My second problem is that in the script I use variables to identify the materials I want to tweak. When I restart Max, those variable are undefined, and I'm not sure how to define those variables automatically, or how to "hard code" them into the scene (if that's even possible). I will eventually be distributing this script publicly so I don't want to rely on the user in any way to define variables. One option I was hoping to figure out is similar to using the $ for scene objects, but do materials have something similar? For instance, if you're in the Material editor looking at the custom attribute rollout of a material, is there any way to script something like "foo = thisMaterial.diffusemap" where "thisMaterial" would be the same as using $ for scene objects?

Well... that's enough for the moment. Any help would be seriously appreciated.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
lutteral's picture

you don't need to define the

you don't need to define the custom attributes each time you start max.
Actually, you define the CA, then you apply to a node, or a global track, then save the scene. The CA will be loaded with the scene, because is stuck with the node or the track you assigned. Avoid using persistent globals, because they have a lot of issues, check "how to make it better" in maxscript help.


digitalx3d's picture

Hey Lutteral, Thanks for

Hey Lutteral,
Thanks for helping out with this... both here and on CGTalk. I'm beginning to get a better grasp on how CAs work. You last suggestion of using "foo = custattributes.getowner this" worked. However, it worked for my simplified example and when I tried to apply that to my real project, I still get an error. Let me try to explain my goal here as simple as I can...

I have two materials and I want to control various parameters of the maps in each material with 1 single tool (custom attribute rollout).

To me, it makes most sense to place this tool as close as possible to the actual nodes I'm trying to control. So, I'm placing a CA on ONE of the materials. (As opposed to a scripted modifier on the geometry, or a CA on the geometry baseobject.

What I've most recently attempted is placing the main CA with all the texture controls on, we'll call it "Mat1", and placing another CA on "mat2". In each CA OUTSIDE and BEFORE the param block and rollout there is a line defining the variable "global mat1 = custattributes.getowner this". In the CA for Mat2, "global mat2 = custattributes.getowner this" is basically the only line, as the only purpose of this CA is define the variable "mat2". However, also in the mat1 CA I'm attempting to control properties of mat2. For example, "mat2.diffuse = mat1.diffuse" so that the color of mat2 is always the same as the color of mat1. However, upon closing max and reopening the scene, it seems like mat2 is not being defined before the mat1 CA is evaluated, and it gives me the error "Unknown property: "diffuse" in undefined".

I'm almost at a loss here. It seems like it should be a simple enough thing to do, right?? Drive parameters for multiple materials from within a single interface? Should I be taking a different approach??

digitalx3d's picture

Ok, I'm still having problems

Ok, I'm still having problems getting errors after I reload max.  I've recreated a simplified version of my script that I can share here and hopefully it will clear things up.  The error I'm seeing is "Unknown property: "diffuseMap" in undefined".  The diffusemap property belongs to the variable "rTile" which has been already been defined in the scene as a persistent variable.  So I don't understand why it's saying rTile is undefined.  (The listener shows me that it IS defined).  I read about the issues that can be caused by persistent variables but I'm hoping my situation doesn't really apply and I can still use them.  However, I'm fairly new to scripting, and since I don't fully understand the issues with persistent variables, my hopes of using them may be unrealistic, or just plain stupid. :)  Anyway, here it is....

testCA = attributes "tile color"

    parameters main rollout:tileControls
         tileClr type:#color ui:tileClrPkr default:red
        on tileClr set newCol do
            rtile.diffusemap.brick_color = newCol
            showTextureMap rTile rTile.diffuseMap on
    rollout tileControls "Tile Color Controls"
        group "Tile Color Properties"
                colorpicker tileClrPkr "Pick tile color:" color:red across:2 modal:false

custAttributes.add rtile testCA

digitalx3d's picture

Anubis, Thanks so much!

Anubis, Thanks so much! Persistent globals is exactly what I needed. I'm still having trouble though getting my Custom Attribute script to load successfully.

So even though my first script is setting the persistent globals in my scene file, when I close and restart Max, Max starts and evaluates the CA script which makes references to scene materials (by variable name) and it's giving me an "unable to convert undefined to MaxObject" error.

I would assume most CA scripts refer to specific scene elements which are undefined at the time Max starts, no? So how do you handle this? Is there a way to have the CA script be evaluated when you load your scene instead of when Max starts?

Anubis's picture

After adding CAs to a node or

After adding CAs to a node or material they saved into the scene file,
so I cant imagine what exactly you did to have missing DLL error.
And to save (hard code) variable to the scene file use persistent globals.

-- example form the help:
persistent global foo, baz, bar

About the "foo = thisMaterial.diffusemap" try:
foo = (custAttributes.getOwner this).diffusemap

my recent MAXScripts RSS (archive here)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.