3

I have two blender files that have different materials with the same names.

Both were originally in Blender Internal, but I manually converted the BI materials to eevee in one of them.

The other file, which has a lot of materials with the same exact names as in the other, does not have the updated versions yet, and I'd like to easily swap them out for the ones I manually converted.

enter image description here

enter image description here

enter image description here

I have almost 600 materials in the first file that may need to replace the old ones in the second file, so if I can avoid having to go through each one, that would be awesome.

1 Answers1

3

Python script

Change the path on line 3 src_file = "E:/tempmymat.blend"

import bpy

src_file = "E:/tempmymat.blend"

D = bpy.data

def main(): # find materials that you want to replace bad_mats = {m.name:m for m in D.materials if not m.library}

# load materials to replace with
with D.libraries.load(src_file, link=True) as (src, me):
    me.materials = [name for name in src.materials if name in bad_mats]

# create copies of the loaded file's materials, rename them and store
# a convenient dictionary pointing from old materials to new materials
replacements = {}
for m in me.materials:
    new_mat = m.copy()
    bad_mat = bad_mats[m.name]
    new_mat.name = m.name
    replacements[bad_mat] = new_mat

# find old materials and replace with new materials
for o in D.objects:
    for slot in o.material_slots:
        replacement = replacements.get(slot.material)
        if replacement:
            slot.material = replacement

# unlink old materials and the external file (library)
for m in bad_mats.values():
    D.materials.remove(m)
D.libraries.remove(D.libraries[-1])


main()

if not m.library is used on the first line of main() in order to ensure there's a single material with each name. If you need to make it work with materials linked to other files also being replaced, remove that condition. If you're worried that as a result you can indeed get multiple materials with the same name in that dictionary, you need to come up with some other method of associating a loaded material with an existing material.

Related:

How to know which object is using a material

How can I replace a material from Python?

How to Link/Append a data-block using the Python API?

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99