How To ... Assign Materials Automatically

MAXScript lets you create callback scripts which monitor scene events like object selection, start or stop of rendering etc. This would let you create scripts that perform certain actions automatically whenever monitored system events have been detected.

The following script will automatically assign the material from slot one of the Material Editor to any selected or newly created object.

Related Topics:

Defining Macroscripts and their Event Handlers

Callback Scripts

Assigning Materials

Accessing Material Editor Materials

NATURAL LANGUAGE

Package the code as macroScript to be used as button, menu or shortcut.

Show the macroScript button checked when the callback is active.

When executed, see if it is already active or not – should remember the active state between executions.

If not active, define a callback to go through all materials of selected objects and assign material editor slot one to all of them.

If already active, delete the old callback

MAXSCRIPT

macroScript AutoMat category: "HowTo"
(
 local AutoMat_Enabled
 on isChecked return AutoMat_Enabled
 on Execute do
 (
  if AutoMat_Enabled == undefined then
   AutoMat_Enabled = true
  else
   AutoMat_Enabled = not AutoMat_Enabled
  if AutoMat_Enabled then
  (
   txt ="if superclassof meditmaterials[1] != texturemap do \n"
   txt +="selection.material = meditmaterials[1]"
   callbacks.addscript #selectionSetChanged txt \
    id:#AssignMaterial persistent:false
  )
  else
   callbacks.removescripts id:#AssignMaterial
  updateToolbarButtons()
 )--end Execute
)--end macroScript

Step-By-Step:

macroScript AutoMat category:"HowTo"
(

The macroScript will be called AutoMat . To use the script, you can use Customize... to drag the script from the category "HowTo" to a toolbar, a menu, a quad menu or to assign to a keyboard shortcut.

Defining Macro Scripts

local AutoMat_Enabled

We need to store the state of the AutoMat script in a variable in order to keep track of whether it is active or not. The variable will be declared as local and will contain undefined in the beginning because we have not assigned a value to it yet.

Scope of Variables

on isChecked return AutoMat_Enabled

The isChecked handler should return true or true and determines the state of the button. When true , the button will appear pressed on the toolbar or will have a checkmark in the Menu / QuadMenu. When false , it will be displayed normally. AutoMat_Enabled is a local variable that will contain true when the callback is active, false when it is not active, and undefined when the script has not been started yet.

Macroscript_Body_Event_Handlers

on Execute do
(

The on Execute handler will be executed each time the macroScript is executed (by pressing the button, selecting from the menu, pressing the shortcut etc.). The handler contains the "body" of the script.

Macroscript_Body_Event_Handlers

if AutoMat_Enabled == undefined then
AutoMat_Enabled = true
else
AutoMat_Enabled = not AutoMat_Enabled

In case the script is started for the first time and the variable contains undefined , we assign true to it. Otherwise we invert the current value of the variable using the Not logical expression - if it was true it will become false and vice-versa.

If Expression

Logical Expressions

if AutoMat_Enabled then
(

If the variable contains true , we can go on and create our callback. Note that if expects a Boolean value in order to evaluate either the expression after then or the expression after else . So we don't have to say AutoMat_Enabled == true as the variable itself contains true or false which is enough for if to make the right decision. Both forms would be valid though.

If Expression

txt = "if superclassof meditmaterials[1] != texturemap do \n"

The callback requires a string containing the script to be executed. When the script text is longer than a single line, it is a good idea to store it in a string variable, in our case the variable txt . "\\n" is used to denote the new line/carriage return inside the string.

Since the MaterialEditor can display both materials and maps in its slots, we have to make sure that the slot 1 currently does not contain a texturemap. So we check the superclass of the object in slot 1 against textureMap and only go on when it isn’t a texturteMap.

Class and Object Inspector Functions

txt +="selection.material = meditmaterials[1]"

This line of code adds a string to the string already defined in the previous line and makes it "grow". Because the first line's string contained "\n" at the end, the new string added will be on a new line when the string is evaluated or printed to the Listener.

The code inside the string assigns the object found in slot 1 of the Material Editor to the .material property of the current selection. The .material property is "mappable" which means that MAXScript will iterate internally through all objects found in the selection and assign the material to each one of them. See also How To ... Remove All Materials for a similar case.

Material_Editor_meditMaterials

General Node Properties

callbacks.addscript #selectionSetChanged txt id:#AssignMaterial persistent:false

Now we can add the script to the scene callback scripts. The script will be executed when the selection set changes, will have a unique ID #AssignMaterial so we can remove it later by name, and will not be saved with the MAX scene (it is not persistent) which means it will not run if you save the scene and load it again later.

General Event Callback Mechanism

)
else
callbacks.removescripts id:#AssignMaterial

In case the variable AutoMat_Enabled contains false , we have to disable the script by removing the callback. Having the unique ID, we can easily remove the script from the list of callbacks by supplying its user-defined name #AssignMaterial

Callbacks.removeScripts

updateToolbarButtons ()

To make sure that the button state is updated in the toolbar, we force an update of the toolbar buttons.

updateToolbarButtons

)--end Execute
)--end macroScript

Using the Script

After evaluating the script and customizing a toolbar, you can do a test. You will need some material (for example with a texture map) in the first Material Editor slot. You can also check the Show Map in Viewport icon in the Material Editor to see the map.

If you create some geometry (for example a box) without pressing the script's button, it will have no material as usual. After pressing the button and selecting the same object, the material will be assigned to it automatically.

Newly created objects will also have the material assigned immediately as they become the current selection during creation and trigger the selection callback event inside of 3ds Max.

To disable the script you will have to press the button again – the button / menu item will become unchecked and the callback will be removed. Now you can select and create objects as usual.

Back to

"How To" Tutorials Index Page