Remove Duplicate Materials
The following code will remove duplicate materials from your project. For example, if you have steel_metal and steel_metal.001, it'll turn all of them into steel_metal and delete the duplicate .001, .002, etc. materials.
import bpy
import re
def get_base_material_name(name):
"""Returns the base name of a material by stripping .001, .002, etc."""
return re.sub(r"\.\d{3}$", "", name)
def deduplicate_materials_and_cleanup():
# Track base materials
base_materials = {}
# Map of duplicate materials to their base
duplicate_map = {}
# First pass: build a map of base materials
for mat in bpy.data.materials:
base_name = get_base_material_name(mat.name)
if base_name not in base_materials:
base_materials[base_name] = mat
else:
# Avoid replacing base with another of the same name
if mat != base_materials[base_name]:
duplicate_map[mat] = base_materials[base_name]
# Second pass: replace duplicates on objects
for obj in bpy.data.objects:
if obj.type == 'MESH':
for i, slot in enumerate(obj.material_slots):
mat = slot.material
if mat in duplicate_map:
print(f"Replacing '{mat.name}' with '{duplicate_map[mat].name}' on '{obj.name}'")
slot.material = duplicate_map[mat]
# Third pass: remove unused duplicates
for dup_mat, base_mat in duplicate_map.items():
if dup_mat.users == 0:
print(f"Removing unused duplicate material '{dup_mat.name}'")
bpy.data.materials.remove(dup_mat)
print("Material deduplication and cleanup complete!")
# Run it
deduplicate_materials_and_cleanup()
|