I am desperately looking for a scene-wide collections of materials, but I can't find it.
You want scene-wide materials?:
>>> bpy.data.materials[:]
[bpy.data.materials['Material'], bpy.data.materials['Material.001']]
this shows the materials for one object:
>>> bpy.data.objects['Circle'].material_slots[:]
[bpy.data.objects['Circle'].material_slots[0], bpy.data.objects['Circle'].material_slots[1]]
or
>>> [m.name for m in bpy.data.objects['Circle'].material_slots[:]]
['Material.001', 'Material.002']
For completeness then
bpy.data.materials indices
For sake of argument I have a scene with 4 materials
>>> bpy.data.materials[:]
[bpy.data.materials['MAT A'], bpy.data.materials['MAT B'], bpy.data.materials['MAT C'], bpy.data.materials['MAT D']]
We don't often need to get the material index in the materials collection, because we can use the name (a string) directly to get the reference.
>>> my_material = bpy.data.materials['MAT D']
>>> my_material.name
'MAT D'
If you really wanted to find the index of 'MAT A' in .data.materials
, you could do a .find()
because material names are always unique.
>>> bpy.data.materials.find('MAT A')
0
data.materials
is an indexed collection.
>>> bpy.data.materials[0]
bpy.data.materials['MAT A']
material slot indices
The material_slots
indices refer to the order in which your materials appear in the object's 'material stack'.
>>> obj = bpy.data.objects['Icosphere']
>>> obj.material_slots[:]
[bpy.data.objects['Icosphere'].material_slots[0], bpy.data.objects['Icosphere'].material_slots[1]]
If you want a direct reference to the material in a slot:
>>> obj.material_slots[:][0].material
bpy.data.materials['MAT A']
No need to get the name first, but if you wanted to:
>>> obj.material_slots[:][0].name
'MAT A'
If the material_index
is 1, and the object references two materials (MAT D and MAT C), then 1 refers to MAT C and globally MAT C is index 2. It may be a point of some confusion that the term index is used to talk about the location of an item in two different types of collections.
Different Materials assigned to different faces (directly on mesh)
>>> bpy.data.meshes['Icosphere.001'].polygons[42].material_index
0
this zero refers to the material slot index.
>>> ico_mesh = bpy.data.meshes['Icosphere.001']
>>> idx = ico_mesh.polygons[12].material_index
>>> ico_mesh.materials[idx] # get the reference
bpy.data.materials['MAT D']