# How to replace an existing material with one from other blend file with python?

Currently, I'm working on a lot of files imported from Autodesk Maya to be rendered in Blender 2.8 EEVEE. And of course, the material looks bad when rendered. And will be a lot of work to fix all of these materials on every blend file by hand. So, I tried this python script to replace materials in the current file with the fixed one from other file:

import bpy

scn = bpy.context.scene
D = bpy.data
filepath = '//10_rrd.blend'

data_to.materials = data_from.materials

for mat in D.materials:
for mat_fix in data_to.materials:
if mat_fix.name == mat.name:
print('Found a material copy for '+mat.name+' with name '+mat_fix.name)
mat.diffuse_color = mat_fix.diffuse_color
mat.metallic = mat_fix.metallic
mat.roughness = mat_fix.roughness
mat.specular_intensity = mat_fix.specular_intensity


## The problem is:

Instead of replacing the properties of the material in current blend file, It appends the full material as a new material (with those '.001' suffix) in the current file without touching the materials that needs to be replaced.

What's wrong with my code? Is there is any fix? or should I stick with traditional way of replacing material of every object after it's appended?

By the way, It's not a problem of EEVEE.

• I guess bpy.data.libraries.load()... appends the material as a new one. Does it print your "Found a material..." in the console? – Benedikt Apr 29 at 7:03
• Yes, it is. But it doesn't change the existing material, just print that there is a copy of the material. – SyahrielIbnu_x86 Apr 29 at 7:51

This code

with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
data_to.materials = data_from.materials


works correctly and you will get appended materials with suffix*.001* in your actual blend file. I propose , maybe not very elegant solution, but it works I have tested on my side. And it gives you possibility not to replace all materials after adding. The script looks in next way:

import bpy

scn = bpy.context.scene
D = bpy.data
filepath = '//10_rrd.blend'

actual_names = []
dict_names = {}

for i in range(len(D.materials)):
s = D.materials[i].name + "_actual"
dict_names[s] = D.materials[i].name
D.materials[i].name = s
actual_names.append(D.materials[i].name)

data_to.materials = data_from.materials

all_names = []
for m in bpy.data.materials:
all_names.append(m.name)

# finding name of added materials
s = set(actual_names)
new_added = [x for x in all_names if x not in s]

for mat in D.materials:
value = dict_names.get(mat.name, None)
if mat_fix_name == value:
print('Found a material copy for '+mat.name+' with name '+mat_fix_name)
mat.diffuse_color = D.materials[value].diffuse_color
mat.metallic = D.materials[value].metallic
mat.roughness = D.materials[value].roughness
mat.specular_intensity = D.materials[value].specular_intensity

print('-----------------------------------------------')

#clear appended materials