The problem is not with wanted_object_name but with slot : you need to use its name (slot.name) in order to search into the material_slots collection, like so :
if slot.name in bpy.data.objects[wanted_object_name].material_slots:
I think you have to check if material slots actually exist first.
import bpy
wanted_object_name = "one"
object = bpy.data.objects.get("Cube")
for slot in object.material_slots:
ob_check = bpy.data.objects[wanted_object_name]
if ob_check != None:
if len(ob_check.material_slots):
if slot in ob_check.material_slots:
pass
else:
slot.material_slot_remove()
You can’t test if a bpy.type instance is contained in a bpy_prop_collection by using the instance reference and the collection, you need to compare by name instead.
for slot in object.material_slots:
if slot.name not in (m.name for m in bpy.data.objects[wanted_object_name].material_slots):
slot.material_slot_remove()
Well, it’s true that I have to compare the names of the slots, but there’s an other problem: material_slot_remove doesn’t go with slot!
I have to do this:
mats = []
for slot in object.material_slots:
for slot_dupl in bpy.data.objects[wanted_object_name].material_slots:
if slot_dupl.name == slot.name:
mats.append(slot_dupl.name)
else:
pass
for mat_index in range(len(object.material_slots)):
if object.material_slots[mat_index].name in mats:
pass
else:
bpy.context.scene.objects.active = object
object.active_material_index = mat_index
bpy.ops.object.material_slot_remove()
Worst lines of code in history, yeah!!! :RocknRoll:
import bpy
from functools import reduce
obs = [ob for ob in bpy.context.selected_editable_objects if ob.type == 'MESH']
assert len(obs) > 1
common_mat_names = reduce(set.__and__, ({mat.name for mat in ob.data.materials if mat} for ob in obs))
print(common_mat_names)
for ob in obs:
mats = ob.data.materials
for i, mat in sorted(enumerate(mats), reverse=True):
if not mat or mat.name not in common_mat_names:
mats.pop(i)
Then the nested loops iterate over all selected mesh objects, and each of their materials. It removes all materials not being in the above set.
Because there is no materials.remove(), but only pop(), I use enumerate() to pop by index, and do that in reverse order as the indices change when you remove an item (and would result in wrong materials being removed or IndexErrors raised).
Hmmm, interesting stuff, I certainly have to look at that big Python tome more carefully…
Maybe today I’m gonna release an alpha version of my addon using my code, but I’m surely gonna study yours as well…
But I’m not really sure about readability, I sort of understand my code more clearly, but that could be the fact that I wrote it…
Anyway, thanks!