7
$\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$
  • 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 Jun 5 '17 at 9:34
  • $\begingroup$ @batFINGER Thank you for your suggestion and explanation, it is helpful. $\endgroup$ – rita33cool1 Jun 11 '17 at 10:55
4
$\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$
  • $\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$ – rita33cool1 Jun 7 '17 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$ – rita33cool1 Jun 7 '17 at 14:32
3
$\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$
  • $\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$ – rita33cool1 Jun 5 '17 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 Jun 5 '17 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$ – rita33cool1 Jun 7 '17 at 14:14
  • $\begingroup$ rita33cool1, if @Sambler's answer works for you, please mark it as accurate: blender.stackexchange.com/tour $\endgroup$ – TLousky Jun 7 '17 at 14:17

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.