0
$\begingroup$

I am new to python in blender and am looking to make an add-on that finds all duplicate textures, deletes them, and then assigns the object the original texture.

This is all well and good but I can't find any documentation on how to return a list of the nodes in a material texture.

I have tried this:

import bpy

nodes = bpy.data.materials['Material'].node_tree.nodes
print(nodes)

But it returns this: <bpy_collection[2], Nodes>

If anyone knows how to return the nodes in a material that would be great.

Similar post but code didn't work: Return list of nodes inside material?

Thanks, Will

$\endgroup$
1
  • $\begingroup$ <bpy_collection[2], Nodes> is a collection. You only need to iterate over it: for n in nodes: ... $\endgroup$
    – taiyo
    Commented Sep 11, 2023 at 6:06

2 Answers 2

1
$\begingroup$

You could just make it a list:

import bpy

nodes = bpy.data.materials['Material'].node_tree.nodes
print(list(nodes))

This would also work:

print(nodes[:])

or

print(*nodes)

If you wanted only names you could use list comprehension:

import bpy

nodes = bpy.data.materials['Material'].node_tree.nodes
print([node.name for node in nodes])

or a for loop:

import bpy

nodes = []
for node in bpy.data.materials['Material'].node_tree.nodes:
    nodes.append(node.name) #or just node    
print(nodes)
$\endgroup$
1
  • $\begingroup$ Thanks, this is very efficient and helpful solution. $\endgroup$ Commented Sep 11, 2023 at 22:51
0
$\begingroup$

The post you linked has a functional solution, but it isn't doing what you ask here.

tree = context.space_data.node_tree

# set the location if node type is
for n in tree.nodes:
    if n.type == "TEX_IMAGE":
        print (n.location.x)
        n.location.x += 50

# filter by type
image_texture_nodes = [n for n in tree.nodes if n.type == "TEX_IMAGE"]

# get the names
image_texture_names =  [n.name for n in image_texture_nodes]

# check the console
print (image_texture_nodes)
print (image_texture_names)

The only things it prints are the X location and name of Image Texture nodes. It isn't designed to print all the nodes' names in the material you run that operator from. You need to tweak that code for that.

import bpy

class NodeOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "node.simple_operator"
    bl_label = "Simple Node Operator"

    # make sure we are in the Node Editor to run the operator
    @classmethod
    def poll(cls, context):
        space = context.space_data
        return space.type == 'NODE_EDITOR'

    def execute(self, context):
        # get the current node tree in the editor
        tree = context.space_data.node_tree

        # cycle through each nodes in the node tree
        for n in tree.nodes:
            # print the node's name
            print(n.name)

        return {'FINISHED'}


def register():
    bpy.utils.register_class(NodeOperator)


def unregister():
    bpy.utils.unregister_class(NodeOperator)


if __name__ == "__main__":
    register()

That being said, if your goal is to work on specific kinds of nodes like image texture nodes, then you need to add back the if n.type == "TEX_IMAGE": condition in the for loop, like the other post's answer did.

I highly recommand you to check the documentation, it doesn't just describe the python API, it also explains things like how to access data.

$\endgroup$
1
  • $\begingroup$ Thanks, I had been struggling to find any documentation and this is great! $\endgroup$ Commented Sep 11, 2023 at 22:32

You must log in to answer this question.

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