9
$\begingroup$

I would like to get the name of of image of "Image Texture" like "Wood8" or "Wood8.png" below with python.

enter image description here

I tried to use object.material_slots[index].material to get materials, and it work.

However, then I tried to use material.texture_slots.texture.name to get it, it didn't work at all.

I have no idea what to do next?

2017/06/05 edited @TLousky

I tried to use

import bpy
import bmesh
'''
I would like to get all textures 
'''
scene = bpy.context.scene
objects_in_scene = bpy.data.objects
texture_list = []
for obj in objects_in_scene :
    # Enter EDIT mode of this object since bmesh only can be acess in EDIT mode
    if obj.type == 'MESH':
        scene.objects.active = obj
        bpy.ops.object.mode_set(mode = 'EDIT')
        me = obj.data
        # Acess bmesh of this mesh
        bm = bmesh.from_edit_mesh(me)
        for f in bm.faces:
            if len(obj.material_slots) != 0:
                mat = obj.material_slots[f.material_index].material
                # Check there is a material in this material slot 
                if mat is not None:
                    # go through all texture slots in the material slot
                    for mtext_slot in mat.texture_slots:
                        #print(mtext_slot)
                        # Check the texture slot is not None
                        if mtext_slot is not None:
                            text = mtext_slot.texture
                            # Check there is a texture in this texture slot 
                            if text is not None:
                                # If the texture hasn't be counted ever, then Count it
                                if text.type == 'IMAGE':
                                        if text.image.name not in tList: 
                                            tList.append(text.image.name)
                                            print(text.image.name)
print(texture_list)`

to get all textures of all objects in the scene.

However, I got "[]" meaning nothing as feedback.

Then I added print(mtext_slot) in line 24 to get what is in the material.texture_slots

And I got the following feedback

`<bpy_struct, MaterialTextureSlot("Tex")>
None
None
None
None
None
None
None
None
None
<bpy_struct, MaterialTextureSlot("Tex")>
None
None
None
None
None
...

It seems there was something wrong in my codes

$\endgroup$
2
  • 1
    $\begingroup$ Would suggest using objects_in_scene = scene.objects is a list of objects in a scene, whereas bpy.data.objects is all objects in a file, linked or unlinked to a scene. Test for obj.material_slots , for length ( and hence the validity of face.material_index), once per object, rather than on a per face basis. $\endgroup$
    – batFINGER
    Commented Jun 5, 2017 at 9:34
  • $\begingroup$ @batFINGER Thank you for your suggestion and explanation, it is helpful. $\endgroup$ Commented Jun 11, 2017 at 10:55

2 Answers 2

5
$\begingroup$

The screenshot of your texture indicates you are using cycles, the material texture slots are only used by blender internal. For a cycles material, you need to loop through the node tree and get the image info from any image texture nodes to find what images are being used.

import bpy

texture_list = []

for obj in bpy.context.scene.objects:
    for s in obj.material_slots:
        if s.material and s.material.use_nodes:
            for n in s.material.node_tree.nodes:
                if n.type == 'TEX_IMAGE':
                    texture_list += [n.image]
                    print(obj.name,'uses',n.image.name,'saved at',n.image.filepath)

print(texture_list)

If you wanted to list by face what images are used then you can loop through the objects face data -

for obj in bpy.context.scene.objects:
    if obj.type == 'MESH':
        for f in obj.data.polygons:
            mat = obj.material_slots[f.material_index].material
            if mat and mat.use_nodes:
                for n in mat.node_tree.nodes:
                    if n.type == 'TEX_IMAGE':
                        texture_list += [n.image]
                        print('Face', f.index, 'uses', n.image.name)

print(texture_list)
$\endgroup$
2
  • $\begingroup$ Thanks a lot, that's what I need. I am a noob of blender and never use node tree. I think I should practice more about node tree now. Thank you very much, you really gave me a big favor. $\endgroup$ Commented Jun 7, 2017 at 14:22
  • 1
    $\begingroup$ By the way, it is better to add if len(obj.material_slots) != 0: after line 3 in the second script because It is possible that there is no material_slots of a object. $\endgroup$ Commented Jun 7, 2017 at 14:32
4
$\begingroup$

Assuming your image texture is in the first texture slot (index=0), and that it is indeed an image texture, get the full image file path via:

material.texture_slots[0].texture.image.filepath

And the image filename only through:

bpy.path.basename( material.texture_slots[0].texture.image.filepath )

If you want the image name (which by default is identical to the file name), access it through:

material.texture_slots[0].texture.image.name

If you want to find all the image textures names of all the objects and materials in the scene, this should do the trick:

import bpy

imageTextures = []
# Iterate over all the objects in the scene
for o in bpy.context.scene.objects:
    # Iterate over all of the current object's material slots
    for m in o.material_slots:
        if m.material:
            # Iterate over all the current material's texture slots
            for t in m.material.texture_slots:
                # If this is an image texture, with an active image append its name to the list
                if t and t.texture.type == 'IMAGE' and t.texture.image:
                    imageTextures.append( t.texture.image.name )
$\endgroup$
4
  • $\begingroup$ Thanks for your answering, but something is still wrong in my codes. I have updated my post. Please read it if you are available. Thanks a lot, it's kind of you. $\endgroup$ Commented Jun 5, 2017 at 8:47
  • $\begingroup$ @rita33cool1, I've added a code sample to perform what you're aiming for, including checks to prevent exceptions if material slots or texture slots are empty $\endgroup$
    – TLousky
    Commented Jun 5, 2017 at 9:36
  • 1
    $\begingroup$ Thanks a lot, but It still doesn't work. I think the reason is just like the answer Sambler said. Thank you very much. $\endgroup$ Commented Jun 7, 2017 at 14:14
  • $\begingroup$ rita33cool1, if @Sambler's answer works for you, please mark it as accurate: blender.stackexchange.com/tour $\endgroup$
    – TLousky
    Commented Jun 7, 2017 at 14:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .