Originally posted by AJ_23
I’ve been using Max for a while now and I’ve finally decided that ‘all those little things’ I do over and over again could be made easier. So (perhaps foolishly) I’ve started to try and learn MaxScript.
Basically, the script I’ve been trying to create should select all materials with a certain name, change the attributes of that material - opacity/diffuse/self illumination (so far, not problem). However, I then want to select all the objects that do not have that material applied (sort of ‘select by material/invert’), and apply one material to them all.
So far the closest I’ve gotten to selecting by material type is Macro Recording the ActionMan for that option, however it still requires me to manually press ‘invert’ then ‘ok’.
Also - my (poor poor) script currently requires the material to be in the active slot, is there anyway to choose the active slot by the material name?
Please be gentle with me - I’m an idiot. :wavey: [/B]
Here is a function that will do the select invert using plain vanilla MAXScript without macroRecorder actions (sorry, I never use the recorder).
–Define a new function with a single parameter - the material not
–to be selected:
fn selectByMaterialInvert mat =
–Loop through all geometry objects and collect those that do
–NOT have the material passed to the function as parameter.
–Then select the result (read below for more info!)
select (for i in geometry where i.material != mat collect i)
–Call the function by passing the Material Editor material
–usually in slot 1 called “1 - Default”. You can also use
–meditMaterials, but you asked about access by name
–The single quotes allow you to use spaces inside the name,
–# denotes a name value.
selectByMaterialInvert (meditmaterials[#‘1 - Default’])
Some words about the for loop. We check only Geometry objects since they are the only ones that make sense (note that you can assign materials to other classes without any visible effect though).
The loop has a variabe ‘i’ which is assigned a single object on each loop iteration. The ‘where’ statement compares the .material property to the material passed to the function and only allows an object to be collected when the materials do not match (!= is ‘not equal to’).
Usually, you would collect the objects in a user variable first,
then select the collection. The code would be more readable that way and would look like
fn selectByMaterialInvert mat =
selArray = for i in geometry where i.material != mat collect i
But since tha assignment to a variable costs memory and time, it is a good practice to remember that MAXScript is expression-based and can handle alot of things without assigning to variables. In addition, a one-liner always looks cooler
In this case, it evaluates all the code inside the brackets and the result of the evaluation is an array. Instead of defining a new variable, writing the array to the variable, then passing the variable to the ‘select’ function, you can pass the result of the expression directly to the select function and - voila! The objects that don’t have the specified material will be selected.
If you have any question, please feel free to ask.