Home Coding, Scripting, Shaders
The BRAWL² Tournament Challenge has been announced!

It starts May 12, and ends Sept 12. Let's see what you got!

https://polycount.com/discussion/237047/the-brawl²-tournament

3ds Max - Remove Duplicate materials from Multi-sub object

mawilbolou
polycounter lvl 11
Offline / Send Message
mawilbolou polycounter lvl 11
Hi guys...

I am working on Max 2012 and am working on quite a big scene.

I have combined a number of models together and sampled the multi-sub material in the Material Editor.

Unfortunately, it seems that Max has generated about 300 different materials, even though I am only using about 20 textures. After looking at some of the materials, I have found that there are alot of duplicate materials that are using one texture.

Is there a script that detects by texture, then deletes the duplicates?

Any help would be massively appreciated..

PS I have tried using the "Clean MultiMaterial Utility"

Cheers

Replies

  • monster
    Offline / Send Message
    monster polycounter
    Hey bro, I had this script laying around. If you are only using diffuse maps it might help you.
    (
    	prevMatCount = scenematerials.count
    	diffuseMapList = #()
    	materialList = #()
    
    	scenemats = scenematerials
    
    
    	for m = 1 to scenemats.count do
    	(
    		dmapFile = scenemats[m].diffuseMap.filename
    		getMat = findItem diffuseMapList dmapFile
    		
    		if getMat == 0 then
    		(
    			--MATERIAL NOT FOUND, ADD IT TO THE MATERIAL LIST
    			append diffuseMapList dmapFile
    			append materialList m
    		)
    		else
    		(
    			--MATERIAL FOUND, APPLY TO ALL IT'S OBJECTS
    			for obj in refs.dependents scenemats[m] do
    			(
    				try
    				(
    					obj.material = scenemats[getMat]
    				)
    				catch()
    			)
    			
    		)
    	)
    	
    	gc lite:true
    	
    	messageBox ("Materials condensed from " + prevMatCount as string + " material(s) to " + materialList.count as string + " material(s).") title:"Materials"
    )
    
  • TorQue[MoD]
    Offline / Send Message
    TorQue[MoD] polycounter lvl 20
    I tried to get Chat GPT to modify the script to not only remove duplicate sub-object ids, but also remove them from the mesh, but it wasn't able to sort it out. Maybe someone who knows MaxScript could fix this?
    (
        -- Get the selected object
        obj = selection[1]
        
        -- Ensure the object is valid and has a Multi/Sub-Object material
        if obj != undefined and isKindOf obj.material MultiMaterial then
        (
            -- Get the Multi/Sub-Object material
            multiMat = obj.material
            matCount = multiMat.numsubs
            
            -- Arrays to store material names and the first instance mappings
            matNameList = #()  -- Stores unique material names
            replacementMap = #()  -- Maps duplicate slots to their first occurrence
            
            -- Step 1: Loop through all sub-materials and find duplicates
            for i = 1 to matCount do
            (
                mat = multiMat.materialList[i]
                if mat != undefined then
                (
                    matName = mat.name
                    getMat = findItem matNameList matName
                    
                    -- If it's the first occurrence of this material name, store it
                    if getMat == 0 then
                    (
                        append matNameList matName
                        replacementMap[i] = mat  -- Keep the first occurrence
                    )
                    else
                    (
                        -- If duplicate, replace with the first occurrence
                        replacementMap[i] = replacementMap[getMat]
                    )
                )
            )
    
            -- Step 2: Reassign cleaned materials to the Multi/Sub-Object material
            for i = 1 to matCount do
            (
                if replacementMap[i] != undefined then
                    multiMat.materialList[i] = replacementMap[i]
            )
    
            -- Step 3: Remove empty slots in the material
            newMaterialList = #()
            for mat in replacementMap do
            (
                if findItem newMaterialList mat == 0 then append newMaterialList mat
            )
            multiMat.materialList = newMaterialList
            multiMat.numsubs = newMaterialList.count
            
            -- Step 4: Reassign Material IDs on the mesh to the first instance
            for face = 1 to obj.numfaces do
            (
                -- Use the correct function to get the material ID for each face
                matID = getFaceMatID obj face
                
                -- Check if the material ID is valid (not undefined)
                if matID != undefined and matID > 0 and matID <= matCount then
                (
                    -- Find the original material that corresponds to the duplicate
                    originalMat = replacementMap[matID]
                    
                    -- Ensure the original material is valid
                    if originalMat != undefined do
                    (
                        -- Find the new material ID in the cleaned list
                        newMatID = findItem newMaterialList originalMat
                        if newMatID != 0 do  -- Only reassign if newMatID is valid
                        (
                            -- Set the new Material ID for the face
                            setFaceMaterialID obj face newMatID
                        )
                    )
                )
            )
            
            -- Garbage collection and message
            gc light:true
            messageBox ("Sub-materials reduced from " + matCount as string + " to " + newMaterialList.count as string) title:"Multi/Sub-Object Cleanup"
        )
        else
        (
            messageBox "Please select an object with a Multi/Sub-Object material." title:"Error"
        )
    )

Sign In or Register to comment.