0
$\begingroup$

I would like to created a dictionary which contains material names of all object contained in a scene in Blender version 2.79

Afterwards I could have access to material data by name I think. Am I right?

How would I code this?

I know it's only one question per post but, in Blender when we use a material on a cube, for example, does it have the same material on every polygon, or could we set one material per face?

$\endgroup$
0
$\begingroup$

Materials are globally stored in:

bpy.data.materials

which is an array of materials that you can index per name or per index.

On the other hand, an object has an array of material slots (which correspond to what you see in the material panel of the object):

obj.material_slots

And get the material from the slot is:

obj.material_slots[i].material

and it also has the list of the materials it is using in its data:

obj.data.materials

Each polygon of a mesh knows the index of the material it is using. This index is the index in obj.material_slots (or obj.data.materials):

p = obj.data.polygons[0]

p.material_index

So to answer your question, it depends of what you want to do.

If the goal is to know which materials are referenced by an object, look at obj.data.materials.

If the goal is to know which are really used, you'll need to dig into polygons to check which is really assign to them (you can have more mats in obj.data.materials than the one really used).

Notice that a material slot can be empty. In this case, the material_slot exists but contains no material. And also, obj.data.materials contains an empty element (as these two arrays are internally kept at the same size).

To have all the materials references by the objects of a scene, in a dictionary by name, you can:

import bpy
all_referenced_materials = set((m for o in bpy.context.scene.objects if o.type == 'MESH' for m in o.data.materials if m is not None))
dictionary = {m.name:m for m in all_referenced_materials}

Note: if I remember well, 16 material slots max. So no more than 16 materials per object.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Was the quote formatting intentional here, instead of code formatting? $\endgroup$ – Ray Mairlot Jul 26 '19 at 15:27
  • $\begingroup$ @RayMairlot, yes as it was preliminary explanations $\endgroup$ – lemon Jul 26 '19 at 15:28

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.