How do I access materials in maxscript without material editor?

Wolfgang Haak picture Wolfgang Haak · Mar 12, 2014 · Viewed 9.8k times · Source

There appear to be two options to access materials in maxscript, through the compact Material Editor and the Slate material editor. The problems is that a scrip that attempts to access/modify materials via the compact editor (currentMaterialLibrary , sceneMaterials, meditMaterials) fail if max is set to use the Slate editor and vice versa.

Is there a way to access the materials directly in maxscript, irrespective of which editor is used?

Once I have the material, I would like to:

  1. Purge unassigned materials from the scene so that missing textures on unused materials don't throw error's on scene open/network rendering.
  2. Check certain material properties (i.e. Glossy subdivision) so purchased models with "unnecessarily high values" don't ruin render times.

Answer

FrozenKiwi picture FrozenKiwi · Mar 13, 2014

If you want to find all existing materials (in the scene or not), the following snippet will do that for you

for aMtlType in material.classes do 
(
    for aMtl in (getClassInstances aMtlType processAllAnimatables:true) do
    (
        print aMtl
        -- Does this material exist in the scene or not?
        if (findItem sceneMaterials aMtl) == 0 do (print "This material does not exist in the scene")
    )
)

I'm not quite sure how to purge it from the scene. You could get dependents (refs.dependents aMtl) then replace any references to this material to a new default material. That should work, although I haven't tried it (or even tried to run it). So... test it well and use with care :-).

defMtl = ...
for d in refs.dependents aMtl do (
    refIdx = 0
    for i = 1 to refs.getNumRefs d do ( if (refs.getreference d i) == aMtl ) do ( refIdx = i )
    refs.replaceReference aMtl refIdx defMtl
)

For your second question - checking properties - you can check if it has the apropriate property and set the value as necessary

if (hasProperty aMtl "diffuse") do ( aMtl.diffuse = 0 )