[Closed] Duplicate Materials
Does anyone have a script or know the commands to remove duplicate materials from a scene and apply the first instance of that material to all objects that have that material then delete the old duplicate material?
I was trying to find a command like
if isvalidnode (getnodebyname (onject[a] as string)) == true then (
)
only for material names so then i could do a search for the name before i apply it and if it exists apply the material that is already in the scene and skip reimporting that material.
If there is a better way or if this is a good way what would the command be to do it?
Thanks so much for any help in advance.
if you don’t use multi-sub material, you can try this
- Run this tool
- Click “Clean matEdit” button (it will clean all your material editor)
- Select all objects in sence
- Click “mat = tex?” button (it will find all objects using same diffuse texture)
- Open material editor –> it will show the number of duplicate texture there
- Choose 1 material on material editor
- Click “Obj same diffuse” button (it will find all objects using currently selected diffuse texture)
- Click apply on material editor to apply your selected material to all objects using same diffuse
- Goto step 3 –> repeat until your material editor will empty after step 4
You select all objects, click “Set mat = tex” button, it will automatically do from 1 to 9 step
(but still remain some minor error)
rollout Tools "Tools" rolledUp:false
(
button btCleanmatEdit "Clean matEdit"
button btCheckTexMat "mat = tex?"
button btSelectObj "Obj same diffuse"
button btSetTexMat "Set mat = tex"
local lstname = #()
local lstdup = #()
local lstdupobj =#()
local recentPath = ""
local lstErrorObjs = #()
function isDuplicate lst sname =
(
local isDup = false;
for s in lst do
if s == sname then isDup = true
return isDup
)
function collectMat sel =
(
local mats = #()
local objs = #()
for obj in sel do
(
try
(
for m in obj.mat do
if (findItem mats m == 0) then
(
append mats m
append objs obj
)
)
catch
(
if (findItem mats obj.mat == 0) then
(
append mats obj.mat
append objs obj
)
)
)
return #(mats,objs)
)
local lstMatError = #()
local lstTexError = #()
function SWV_checkTexMat =
(
local val = collectMat selection
local lstTexture =#()
lstMatError = #()
lstTexError = #()
for m in val[1] do
try
if (m != undefined) then
(
local filename = toLower (filenameFromPath m.diffuseMap.filename)
if (findItem lstTexture filename == 0) then
(
append lstTexture filename
)
else
(
if (findItem lstTexError filename == 0) then
(
append lstMatError m
append lstTexError filename
)
)
)
catch()
local i = 1
for m in lstMatError do
(
if (i < meditMaterials.count) then
(
meditMaterials[i] = m
i += 1
)
)
if (lstTexError.count > 0) then
return ("Same texture = same material: Fail
- Error:"+ lstTexError as string+"
")
else
return ("Same texture = same material: Done!"+"
")
)
local lstDup1 = #()
local lstObj1 = #()
local lstFileFull =#()
local lstObj1File = #()
local lstObj1Bool = #()
on btSelectObj pressed do
(
local mat = meditMaterials[activeMeditSlot]
--local mat = $.mat
local filename = toLower (getFilenameFile mat.diffuseMap.filename)
local objs = #()
for obj in geometry do
try
(
if (toLower (getFilenameFile obj.mat.diffuseMap.filename) == filename) then
(
append objs obj
print obj.name
)
) catch ()
max select none
select objs
)
on btCheckTexMat pressed do
(
local st= SWV_checkTexMat()
MessageBox st
print st
)
on btSetTexMat pressed do
(
local st= SWV_checkTexMat()
print st
for obj in selection do
if (classOf obj == Editable_Poly) then
try
(
local filename = toLower (filenameFromPath obj.mat.diffuseMap.filename)
local i = findItem lstTexError filename
if (i>0) then
(
obj.mat = lstMatError[i]
print filename
)
)
catch ()
)
on btCleanmatEdit pressed do
(
for i=1 to meditMaterials.count do
(
meditmaterials[i] = standardMaterial()
if i<10 then t = "0"+i as string else t = i as string
meditmaterials[i].name = t +" - Default"
)
)
)
createDialog Tools width:180
Thanks for your response I am using multi material but each object part of a character has its own material slot and I want to combine textures if they already exist in the scene.
if so, I think it is very difficult to solve your case. Because some sub material use same texture but different material ID. So I think you should detach all ID and use my tool above. To detach ID, you can try this link
http://www.scriptspot.com/3ds-max/scripts/detach-by-material-id