4
$\begingroup$

Scenario:

node groups

I have these two node group instances "Test 1" and "Test 2" containing image textures. Now I would like to modify nodes inside of a selected node group in python.

To access the nodes inside a node group I have to know the name of the node group (e.g. "Material.Input 1" for node group "Test 1"):

img_node = bpy.data.node_groups ["Material.Input 1"].nodes ["Image Texture 1"]

But I would like to do this dynamically using the selected node group like this:

active_node = context.active_node
# active_node.name: Group.003
# active_node.group: Test 1
img_node = bpy.data.node_groups [active_node.???].nodes ["Image Texture 1"]

How can I achieve this?

$\endgroup$
4
$\begingroup$

First off, to get the currently active node, you can use

currNode = context.active_node

from within an addon / Operator (which I suppose you're doing, otherwise there would be no bpy.context.selected_nodes). From the Python Console, getting the currently active node in the compositing tree would be

currNode = bpy.context.scene.node_tree.nodes.active

From there, you can use

currNode.id_data

to retrieve the tree this node lives in. This also works in Material Node Trees. To retrieve the materials (remember it could theoretical be more than one material using the same node tree) you can to:

print ([x for x in D.materials if x.node_tree == currNode.id_data])

So in your example:

# get a node first
x = D.node_groups['NodeGroup'].nodes['Group Input']

# now get the tree of this node (which is the node group)
x.id_data    # this gives you 'Node Group' again

Edit: Find the node tree of a group

After the question has been rephrased, this solution would be smarter: Node groups simply have an own Node Tree themselves. You can think of it like:

ShaderNodeTree.nodes[someGroup].node_tree.nodes[someOtherGroup].node_tree.nodes.thisCanGoOnForever

So in your case:

active_node = context.active_node
# active_node.name: Group.003
# active_node.group: Test 1

# find an image node in the group node tree
# groups have their own node tree to collect nodes
img_node = active_node.node_tree.nodes.get("Image Texture 1")

If the Image Texture named "Image Texture 1" exists, img_node will be the object. Otherwise, img_node will be None.

$\endgroup$
  • $\begingroup$ Thanks for the quick response! Unfortunately calling currNode.getNodeTree() throws an error (object has no attribute "getNodeTree"). Furthermore this function doesn't appear in the blender documentation. $\endgroup$ – Steffen Dec 1 '16 at 13:06
  • $\begingroup$ @Steffen DOH, must be an addon which adds that method. I'll investigate and report back. $\endgroup$ – aliasguru Dec 1 '16 at 13:15
  • $\begingroup$ @Steffen OK, found it, it's part of the Animation Nodes addon. I'll adapt the answer later $\endgroup$ – aliasguru Dec 1 '16 at 13:19
  • $\begingroup$ @Steffen ok, answer is updated. there is an id_data property that gives you the exact same thing. $\endgroup$ – aliasguru Dec 1 '16 at 13:22
  • $\begingroup$ Thanks again for the advice! I did some tests but didn't find the solution yet. I updated my question a little bit to make things clearer, maybe you have an idea... $\endgroup$ – Steffen Dec 1 '16 at 14:58

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.