4
$\begingroup$

I have this script, but its not working as expected

import bpy

for img in bpy.data.images:
    print("%s" % img.name)
    if( ".0" in img.name):
        img.name=img.name[:-4]
        print("%s" % img.name)

I want to have one texture on different materials, now i have something like this enter image description here

Edit: Solved.

for mat in bpy.data.materials:
    if mat.node_tree:
        for n in mat.node_tree.nodes:
            if n.type == 'TEX_IMAGE':
                if n.image is none:
                    print(mat.name,'has an image node with no image')
                elif n.image.name[-3:].isdigit():
                    n.image = bpy.data.images[n.image.name[:-4]]

for imgs in bpy.data.images:
    if imgs.name[-3:].isdigit():
        print(imgs.name)
        imgs.user_clear()

Thanks to all who helped. ok!

$\endgroup$
3
  • 1
    $\begingroup$ what are expecting ? you are just renaming the images ( they won't have the same name blender will add the numbers back ) $\endgroup$
    – Chebhou
    Jan 31, 2016 at 21:44
  • $\begingroup$ I'm fairly new to python, but you should probably not try to rename the textures but to reload Tex.Generic_Spec.png if Image Texture File has a number in the materials. $\endgroup$
    – maegmaeg
    Jan 31, 2016 at 21:52
  • 1
    $\begingroup$ PProbably this related topic gives you some idea how to do it: blender.stackexchange.com/questions/38052/… $\endgroup$
    – maegmaeg
    Jan 31, 2016 at 22:06

2 Answers 2

6
$\begingroup$

img.name=img.name[:-4] is renaming the image to match the original image name, as this name already exists a numeric suffix is added to the other image with that name, which just undoes the change.

You need to go through your material nodes and get each image node to use the same image.

for mat in bpy.data.materials:
    if mat.node_tree:
        for n in mat.node_tree.nodes:
            if n.type == 'TEX_IMAGE':
                if n.image is None:
                    print(mat.name,'has an image node with no image')
                elif n.image.name[-3:].isdigit():
                    n.image = bpy.data.images[n.image.name[:-4]]

Note that the last line doesn't just change the name used, it changes the image data block that the image node is linked to.

Once you have removed the users of the duplicate images they will be removed after you save and re-open the file.

$\endgroup$
5
  • 1
    $\begingroup$ Is 'if n.type == 'TEX_IMAGE' and '.0' in n.image.name:' sufficent to find only the image textures mentioned? $\endgroup$
    – maegmaeg
    Feb 1, 2016 at 11:52
  • 1
    $\begingroup$ That will find all image texture nodes that use an image with '.0' in the name, using the same example test from your code. if n.type == 'TEX_IMAGE' and n.image.name[-3:].isdigit() should be a more accurate test. It does assume that bpy.data.images[n.image.name[:-4]] actually exists. $\endgroup$
    – sambler
    Feb 1, 2016 at 12:21
  • $\begingroup$ It works! on the test scene i had, but not on my real scene, n.image.name[-3:] returns "NoneType" $\endgroup$
    – r3aktormk
    Feb 2, 2016 at 2:52
  • 1
    $\begingroup$ if ` n.image.name[-3:]` returns NoneType then you don't have an image on that node. $\endgroup$
    – sambler
    Feb 2, 2016 at 4:08
  • $\begingroup$ Suggest adding a filepath test too, for the same image filename, different folder side case. (and for generated images?). Making a lookup / replacement table from bpy.data.images to start with could be the go. $\endgroup$
    – batFINGER
    Jul 24, 2018 at 17:31
0
$\begingroup$

The solution posted above bugs out in several situations. always have to check if data exists before pulling it, also if the original image has digits then remove it.

# for material check for texture nodes
# if it has a digit check if the original exists
# if original has also digits remove

for mat in bpy.data.materials:
    if mat.node_tree:
        for n in mat.node_tree.nodes:
            if n.type == 'TEX_IMAGE':
                if n.image is None:
                    print(mat.name,'has an image node with no image')
                elif n.image.name[-3:].isdigit():
                    name = n.image.name[:-4]
                    exists = False
                    for img in bpy.data.images:
                        if img.name in name:
                            exists = True
                    if exists:
                        n.image = bpy.data.images[name]
                    else:
                        n.image.name = name
$\endgroup$

You must log in to answer this question.

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