1
$\begingroup$

I want to select all meshes which a transparent material (e.g. glass) has been applied, when using Cycles (if it matters at all)? I just know how to select meshes with any kind of material applied to them as follow:

bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
    if obj.type == 'MESH':
        for slot in obj.material_slots:
            if slot.material:
                obj.select = True

How can I instead only select meshes with transparent materials? You can also work with nodes. In that case, you may want to download this object that I'm currently using and need to select its transparent meshes. If you want to use the mesh I am providing, select Cycles renderer first and then load the mesh you will get something like this in the node editor:

enter image description here

$\endgroup$
2
$\begingroup$

Generally determining if a given node setup is transparent is rather tricky; for instance, a material may be transparent only in some areas (textured transparency) and other such complications. However, in your case, it seems that checking if the value of the "Mix Color/Alpha" node is < 1 should be sufficient.

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        for slot in obj.material_slots:
            if slot.material:
                mat = slot.material
                for node in mat.node_tree.nodes:
                    if node.label == "Mix Color/Alpha":
                        if node.inputs[1].default_value[0] < 1:
                            print("Material '%s' on object '%s' seems transparent" % (mat.name, obj.name))

The importer seems to create both cycles and BI materials, so you could also check the BI material property (even while cycles is active):

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        for slot in obj.material_slots:
            if slot.material:
                mat = slot.material
                if mat.use_transparency:
                    print("Material '%s' on object '%s' seems transparent" % (mat.name, obj.name))
$\endgroup$
  • $\begingroup$ Could be more efficient to go the other way, ie make a set of material names that may be transparent (for mat in bpy.data.materials:) and then check on a per o in scene.objects basis if the set made from o.material_slots.keys() intersects your transparent materials set. $\endgroup$ – batFINGER Feb 26 '18 at 6:08
  • $\begingroup$ Thank you. Is there any way to add relevant nodes like what you suggested here to these transparent materials through Python? If so, would it be possible for you to update your code in my new question here so that I can add the shader nodes and their corresponding links easily? $\endgroup$ – Amir Feb 26 '18 at 14:59

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.