4
$\begingroup$

If you check the docs for the Mesh(ID) type, you going to see something like this:

class bpy.types.MeshTessFace(bpy_struct) TessFace in a Mesh datablock

material_index Type: int in [0, 32767], default 0

My question is: material_index is an index into what? I am desperately looking for a scene-wide collections of materials, but I can't find it.

$\endgroup$
7
$\begingroup$

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'.

IMAGE

>>> 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']
$\endgroup$
1
  • $\begingroup$ Things start to get a little confusing when you reference the same Mesh from different objects, in particular when assigning different Materials in different objects, but at the same time referencing only one Mesh. $\endgroup$ – zeffii Apr 18 '15 at 14:42
2
$\begingroup$

An object can have multiple material slots. This points to the index of which material from the stack is assigned to the face.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.