6
$\begingroup$

I have been trying to look in the API as well as Google and the search function here and haven't found an answer to how to make the actual Image Node inside the Material a Single User in Python the way we can with pressing the single user button in the interface. I already tried code the made single user of the node tree the image node is inside, but haven't found as way to mimic the button result. I was hoping for someone to have a better idea of how to attack this - the behaviour here isn't the same as making a copy and writing to a new filepath or the like, it is storing the image in memory and ready to dump after use. enter image description here enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ i struggled with this also! And it was a bit disappointing to me that there was not python tooltip for that button to do so! ;) $\endgroup$
    – Chris
    Mar 18, 2022 at 5:55

1 Answer 1

5
$\begingroup$

You have to find the material. In the material you have to find the image texture node. It's not the node, but the image itself that has to be duplicated so you need to find the image and make a copy. Finally you need to set the texture node to point to the image copy. Here's python that will do that.

  • replace "'Material'" by the name of the material you care about.
  • the node = line in the example only handles the case of a single image node, that has the default name.
  • The last two lines can be combine as node.image = node.image.copy() but as written they're easier to follow.
import bpy
material = bpy.data.materials['Material']
node = material.node_tree.nodes['Image Texture']
new_image = node.image.copy()
node.image = new_image

There are several ways to obtain the material, depending on your use case. You could, for instance want the material in the first slot of the active object: material = bpy.context.active_object.material_slots[0].material

The biggest issue is identifying which image texture hold the image and that again depends on your use case. You might have to search through all of the image nodes in the material or you might want to use the active node. In the later case you can use node = material.node_tree.nodes.active but you should then check that node.type == "TEX_IMAGE".

If you wanted to search all of the nodes to find images, here's a function that will do that

def find_nodes_by_type(material, node_type):
    """ Return a list of all of the nodes in the material
        that match the node type.
        Return an empty list if the material doesn't use
        nodes or doesn't have a tree.
    """
    node_list = []
    if material.use_nodes and material.node_tree:
            for n in material.node_tree.nodes:
                if n.type == node_type:
                    node_list.append(n)
    return node_list

You would call it with code like

image_nodes = find_nodes_by_type(material, "TEX_IMAGE")

and then search the resulting list for the image you're interested in, perhaps by looking for it by image name.

Note: The find_nodes_by_type function is spelled out to make it simple to understand. A more Python-ish way of writing it would be to use a list comprehension:

def find_nodes_by_type(material, node_type):
  return  [node for node in material.node_tree.nodes if node.type == node_type]
$\endgroup$
4
  • 1
    $\begingroup$ I got a working version from that first example, but then realized I also need to make a copy of the Material first and THEN a copy of the image as you explained - thank you for the help, this is very easy to understand compared to what I had been reading. $\endgroup$ Mar 18, 2022 at 4:28
  • $\begingroup$ Maybe you should also mention in your answer that you won't have to copy the image. Yes, it "looks" in the UI like it still has multiple users, but as soon as you change the image to another image you will see that it will then change to "single user". I think it is because Blender does this optimal referencing thing as programming languages do this. As long as it it the same image, Blender "reuses" the same object. If you change it, Blender "recognizes" this and then makes a true copy of the image texture node with a link to the new image. Often copying an image makes not much sense. $\endgroup$
    – Chris
    Mar 18, 2022 at 5:54
  • $\begingroup$ But good answer and explanation! +1 $\endgroup$
    – Chris
    Mar 18, 2022 at 5:54
  • $\begingroup$ @CraigDJones thank you very much. You're right. I'd assumed that you already had a node with a multiple use image and only explained the last part. $\endgroup$ Mar 18, 2022 at 13:46

You must log in to answer this question.

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