Since I am used to code with Python in Maya I have trouble getting things to work in Blender.

I want to do something specific based on the name of its material that is applied.

But I am really confused with all the '[...].data.[...]' / '[...].ops.[...]' and it is really hard to remember all that stuff.

How do I get the name of the material of my selected objects. Note that I am using Blender 2.79.

New contributor
Lala_Ghost is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
up vote 2 down vote accepted

Python language itself is only a small part of the whole experience. You should expect Blender's and Maya's Python APIs to be very different.

The materials are assigned to material slots of objects in Blender, every object's faces have material indices matching those slots.

You can reach your selected objects using context. That would be bpy.context.selected_objects. You can loop through them.

Faces are stored in object's data, so, you would need to work with a specific object for example first one from the selection bpy.context.selected_objects[0].data.polygons. You can loop trough them and see material indices:

import bpy

for face in bpy.context.selected_objects[0].data.polygons: 
     print('Material index of face ' + str(face.index) + ' : ' + str(face.material_index))

You can change material indices, but you do not need to do that if you only want to assign a material to an object. You can just add a material to an object as described here that will create the slots automatically. You can see material slots bpy.context.selected_objects[0].material_slots and materials assigned to them bpy.context.selected_objects[0].material_slots[0].material.name

You can also reassign materials to material slots. Materials are stored in bpy.data.materials so let's say you wanted to change an existing material that is assigned to the active object's already existing second material slot with one that is called 'Material':

import bpy

obj = bpy.context.active_object
material = bpy.data.materials.get("Material")
obj.data.material_slots[1].material = material

or you could just make a new slot:

obj.data.materials.append(material)

By this point I am sure you are frustrated about how in the world one is supposed to know where what is in Blender's Python API. Well there is a nice structure there that you can explore easily with the auto complete function of the Python Console in Blender. Just start typing and hit ctrl+space:

enter image description here

You can see everything there. That is how I found that faces have material indices:

enter image description here

For functions and operators you can just use Google, that will most likely point you to Blender Stack Exchange or Blender's Python API documentation that is really useful.

You can also explore Text Editor's Templates menu for examples and also every single add-on that you get your hands on is a great resource for learning.

Edit: Oh, I forgot to actually answer the question. You can get the diffuse color of your selected objects like this(assuming you use Cycles and you use nodes in the materials):

import bpy
C=bpy.context

for o in C.selected_objects:
    if o.type in {'MESH', 'SURFACE'} and len(o.material_slots) > 0: 
        i = 0
        for s in o.material_slots:
            if s.name:
                print('Object ' + o.name + ' has a material "' 
                      + s.material.name + '" in slot ' + str(i)
                     )
                if s.material.use_nodes:
                    for n in s.material.node_tree.nodes:
                        if n.type=='BSDF_DIFFUSE':
                            print("The color of it's Diffuse BSDF named '" 
                                  + n.name + "' is " 
                                  + str(n.inputs[0].default_value[:]) 
                                  + '\n'
                                 )
            i += 1
  • Worth noting it's not necessary to convert a print statements arguments to a single concatenated string with string addition. print(a, b, c) will print a repr of each argument no matter what type. Or use string formatting Best Practice. – batFINGER Nov 9 at 5:22
  • It's a little irrelevant here, but thanks. I like to use strings with arithmetic operators because you can do other interesting things like for example multiplying a string with a boolean that returns an empty string if it's False. It is easier for me to read if I see a '+'. If performance is an issue with the script example maybe it would be better to only go trough materials in the object's data instead of material slots. I thought that would be the first issue to pick on, only after that string concatenation. – Martin Z Nov 9 at 8:35
  • Best to go via slots as materials may be object linked. Yep string arithmetic can be useful. I didn't write String addition - this is the slowest option, don’t use if you can help it, especially when writing data in a loop. I do agree it is good, and relevant, advice, especially for someone starting in python such as the OP, Pointing this out is IMO not you being picked on – batFINGER Nov 9 at 9:16
  • OK, you are actually right, sorry I am being inadequately defensive here. That bit of information is actually really useful, as it is probably reasonable to wrongly expect that these little things would be automatically optimized if the language permits them. I guess this might be indeed extremely relevant when exporting data from Blender and is really worth noting. – Martin Z Nov 9 at 11:54

Your Answer

Lala_Ghost is a new contributor. Be nice, and check out our Code of Conduct.
 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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