How do I loop over objects in a file and replace materials with corresponding asset library materials?
Setup:
I have a bunch of models in separate files where their materials are local.
I also have a material asset library, containing the same materials, but not yet tied to each model.
I now want to open each model file and run a script that finds e.g. that there is a ‘Red’ in the asset library, and replace the local ‘Red’ currently used by the model with a linked ‘Red’ that is in the material assets file.
Problem:
I am able to open my asset library, and I can see the names of the materials, but I cannot find a way to get slot.material = “linked material”. The material properties, in the GUI, has a LF Red
, that I am unable to find in bpy.data.materials. On trying to import, blender complains about ID MARed
is alread linked, but it only complains for some (one?) materials, even though several others are previously linked. It also does not seem to like how I go about getting materials to data_to from data_from.
Thus, I seem to have both LF Red
and MARed
, but formally I can only find Red
- and am unable to tell my slot to change to my linked material. I am also stumped on how to better get materials from data_from to data_to, when all I have is strings of material names.
This is what I have so far:
import bpy
from pathlib import Path
# Find un-linked material slots
SlotsToChange = []
materialsToLink = []
for obj in bpy.data.objects:
for slot in obj.material_slots:
if not slot.material.library:
SlotsToChange.append(slot)
if slot.material.name not in materialsToLink:
materialsToLink.append(slot.material.name)
# Load asset file, find corresponding indices to slots that don't have a linked material an try to bring those
assetFile = 'C:\Materials.blend'
with bpy.data.libraries.load(str(assetFile), assets_only = True, link = True) as (data_from, data_to):
idList = []
for slot in SlotsToChange:
if slot.material.name in data_from.materials:
id = data_from.materials.index(slot.material.name)
if not id in idList:
idList.append(id)
for mat in materialsToLink:
data_to.materials = [name for name in data_from.materials if name==mat]
#Here: How to set slot.material = data_from.materials[slot.material.name]???