I have only tested this on Blender 2.82
This solution only works if you are trying to get rid of duplicates like mat.001, mat.002 … (etc.)
You should save your work before running the script in case it doesn't produce the results you want
Copy/Paste the code into the Text Editor and run the script
Once it has finished running, all of the duplicate materials (mat.001
, mat.002
…) will be replaced with a single material which will be named mat
.
import bpy
def replace_material(bad_mat, good_mat):
bad_mat.user_remap(good_mat)
bpy.data.materials.remove(bad_mat)
def get_duplicate_materials(og_material):
common_name = og_material.name
if common_name[-3:].isnumeric():
common_name = common_name[:-4]
duplicate_materials = []
for material in bpy.data.materials:
if material is not og_material:
name = material.name
if name[-3:].isnumeric() and name[-4] == ".":
name = name[:-4]
if name == common_name:
duplicate_materials.append(material)
text = "{} duplicate materials found"
print(text.format(len(duplicate_materials)))
return duplicate_materials
def remove_all_duplicate_materials():
i = 0
while i < len(bpy.data.materials):
og_material = bpy.data.materials[i]
print("og material: " + og_material.name)
# get duplicate materials
duplicate_materials = get_duplicate_materials(og_material)
# replace all duplicates
for duplicate_material in duplicate_materials:
replace_material(duplicate_material, og_material)
# adjust name to no trailing numbers
if og_material.name[-3:].isnumeric() and og_material.name[-4] == ".":
og_material.name = og_material.name[:-4]
i = i+1
remove_all_duplicate_materials()
```
Shift D
to duplicate the objects, the materials would have remained singular, even after joining the meshes. The only solution here is a brute-force addon which changes material assignments by name. It's possible but not safe $\endgroup$