Cleanup multimaterial as script


Hello all,

Here’s my problem,

I’m cleaning a scene’s materials and I have got unused slots in some multimaterials.

Since using Neil Blevin’s collapseSubObjectMaterial script requires to select one by one objects in the scene, I would like to do it on the fly only by parsing the scenematerials array, and without using the clean multimaterial function of the material editor, since this crashes everytime due to memory overflow.

Is there a script for that ?


you could try automating the script… looks like it’s not really designed for that but you could go through the UI:

for o in geometry where ((classOf o.material == Multimaterial) AND (o.numFaces != 0)) do (
	csom_rollout.PickObj.picked o

Might be worth rewriting it to better suit the purpose, but the above should do the trick I suppose.


Actually we already have a “tweaked” version of CSOM that is mapped and therefore can apply to a selection. But this script focuses on some object material instead of the material itself so I was hoping there were a script that could do the trick without parsing geometry…

Thanks though,


well, you could certainly map over any multi/sub-object materials. Keep in mind, though, that at some point you -have- to loop over the geometry that uses those materials as well. Otherwise, how would know which materials are un-used by geometry / how would you re-assign Material IDs to the geometry if you simply collapse un-used multimat slots?


Yes, well you are certainly right about the fact that you need to loop over geometry instead of just the materials.

But for example, let’s say we have a Multimaterial “TheMaterial” which contains 6 slots whose two are unused.

TheMaterial is then applied to object A and object B, which means that out of the six slots, two are used by A, two by B and two unused (AABBUU).

If if launch the script which loop over A then B, what happens ?

Is TheMaterial splitted in two : [i]TheMaterialA/i, [i]TheMaterialB/i, the unused slots being of course deleted ? Or is TheMaterial kept in a single part ? But since from the point of view of A, the BB slots are actually unused, i don’t see how it would keep a single multimaterial ?



Judging by the script, it works on a per-object basis, creating a new multimat for each. So yes, the material would be split up into two separate materials, one for each object, with only those sub-materials that the object in question actually uses.

So if you’d want to keep it as a single material, you’d need a new script :slight_smile:


I dont have max open right now but it ought to be possible to check for dependencies on each sub material. If it doesn’t have any that are objects then you can safely get rid of it. Of course this won’t deal with reassigning face IDs etc


Well now that’s just taking random piles of paperwork scattered all over the office, sifting through it to remove the spam and questionable requests for payment for services you’re quite certain you never ordered except maybe that one from Australia (how did that get in there anyway), then beholding the random piles of filtered paperwork scattered all over the office and saying ‘job well done!’ :slight_smile:

Of course, if you really don’t need neat little stacks of paperwork, Alex is bang on - except that you do still have to parse the mesh(es) to check which MaterialIDs are actually in use; ‘refs.dependents <submat>’ will happily yield a mesh that uses its parent multi/sub, even if the mesh does not have any faces that use the matID corresponding to that submaterial. But at least you can get away with a ‘meshToCheck = snapShotAsMesh <geometry>’ without affecting the stack of the object.


Which, i guess, would leave the multimats full of holes ? The trick is that I would like to optimize a scene’s materials for realtime visualization, so splitting materials over and over each time a new slot becomes unused seems inappropriate…

A developer at our company proposed the following :

  • He already wrote a script that attaches several meshes together (and thus cumulates the former objects’ materials) and that can detach each mesh independantly (reassigning names) to their former state. (“Wtf ? How did you do that” Did I kindly asked him)
  • On the attached big mesh, run CSOM to clean the unused slots
  • Detach the objects to their former states.
  • The “new” former objects would then share the same multimaterial.

The thing is that I felt this method is a little bit risky… The slightest offset in the vertex order in the array and the whole thing collapses, I fear. Besides that, the script becomes increasingly memory consuming due to the attach loop parsing dozens of complex meshes.

I don’t understand why the clean multimaterial suffers from memory overflow. There are only 120~ materials (not all multimaterials) in the scene and it is running on Max9, quad Core, 4 GB ram. Plus it is probably hard coded in C++.

EDIT : I just tried to launch the CSOM script on a bunch of objects.

The resulst is screwed up because before the script : 900~ mats in the scene, 991 maps, after the script, 1600~ mats, 985 maps. So i removed 6 unused maps and created over 700 materials :hmm:


This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.