I have an .obj file that contains hundreds of materials. These are however not correctly named. The vast majority of them are duplicates of the original materials. Somehow every instance of the original materials have been assigned their own variant of that material.

For example we have mtl_brick, and in every other instance where that material is assigned a duplicate has been created called, mtl_brick.001. In some cases, where that material is assigned in a lot of places, there are more than 50 variants of this.

The material variants are exactly the same they just have different names. So I tried to rename it correctly using its Base Color texture name. So in our example, mtl_brick would use brick_c.png. I tried to write a simple script doing the renaming.

import bpy

i = 0
while i < len(bpy.data.materials):
    mat = bpy.data.materials[i]
    if mat.name != 'Dots Stroke' and mat.name != 'Material':
        mat = bpy.data.materials[i]
        l = len(mat.node_tree.nodes['Image Texture'].image.name)
        mat.name = mat.node_tree.nodes['Image Texture'].image.name[l:-6]
    i = i + 1

This script does not work. When it encounters a duplicate it simply renames it into Material.001,002,003 etc.

The process that I want to script, and not do manually is going into the Material Properties tab, selecting the variant materials, Browse Material to be linked and Choose Material data-block to be assigned to this user, in order to reassign the variant materials to the original.

screen shot of material slots showing multiple identical materials

How do I use python scripting to re-assign all of these variants to its original material?

  • $\begingroup$ I'm not sure what you want. I assume your screenshot is of a single object that has many copies of the same material assigned to it. Do you want to remove all but the first material, or do you want to fill all of the material slots in the object with the first material, replacing the duplicates? I can do code for either but I'd like to be clear on your goal first. $\endgroup$ Commented May 21, 2022 at 16:30

1 Answer 1


Try this. Save beforehand in case something goes wrong.

import bpy

for ob in bpy.data.objects:
    for slot in ob.material_slots:
            name = slot.material.node_tree.nodes['Image Texture'].image.name
        except Exception:

        if name not in bpy.data.materials:
            slot.material.name = name
            slot.material = bpy.data.materials[name]

Afterwards, you can use File > Clean Up > Unused Data Blocks to remove the extra unused materials.

  • 1
    $\begingroup$ Thank you very much! This script worked wonders. I only added a line to remove the '_c.png' from my material names. name = name.removesuffix('_c.png') $\endgroup$ Commented May 22, 2022 at 11:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .