Typically links between nodes in Blender are created by simply dragging and dropping between the desired input and output node sockets. However, if necessary, we can also connect nodes using the Blender Python API.
All links between nodes are stored in the node tree structure, both for shaders and for Geometry Nodes.
Shader Editor
We can access the material node tree through a pointer to the object’s material.
For example, for the active mesh object:
1 2 |
bpy.context.object.active_material.node_tree # bpy.data.materials['Material'].node_tree |
Links between nodes are stored in the “links” collection:
1 2 |
bpy.context.object.active_material.node_tree.links # bpy.data.materials['Simple Glitter'].node_tree.links |
We can create a new link between two nodes using the new() collection command.
We need to pass two parameters to the called command:
- pointer to the output socket of the first node – where the link will go from
- pointer to the input socket of the second node – where the link will come
A pointer to a desired node can be obtained by its name from the “nodes” collection of the node tree:
1 2 |
bpy.context.object.active_material.node_tree.nodes['Emission'] # bpy.data.materials['Material'].node_tree.nodes["Emission"] |
A pointer to the desired output socket can be obtained from the “outputs” collection of the node. It can be obtained by the ordinal number, or by name.
1 2 3 4 5 |
bpy.context.object.active_material.node_tree.nodes['Emission'].outputs[0] # bpy.data.materials['Material.001'].node_tree.nodes["Emission"].outputs[0] bpy.context.object.active_material.node_tree.nodes['Emission'].outputs['Emission'] # bpy.data.materials['Material.001'].node_tree.nodes["Emission"].outputs[0] |
The pointer to the input socket can be obtained from the node’s “inputs” collection. Likewise by index or by name.
1 2 3 4 5 |
bpy.context.object.active_material.node_tree.nodes['Material Output'].inputs[0] # bpy.data.materials['Material.001'].node_tree.nodes["Material Output"].inputs[0] bpy.context.object.active_material.node_tree.nodes['Material Output'].inputs['Surface'] # bpy.data.materials['Material.001'].node_tree.nodes["Material Output"].inputs[0] |
Having pointers to the input and output sockets of two nodes, we can create a link between them:
1 2 3 4 |
bpy.context.object.active_material.node_tree.links.new( bpy.context.object.active_material.node_tree.nodes['Emission'].outputs['Emission'], bpy.context.object.active_material.node_tree.nodes['Material Output'].inputs['Surface'] ) |
Geometry Nodes Editor
For geometry nodes, the principle of creating links between nodes is exactly the same as for materials.
The node tree for Geometry Nodes is accessed from the modifier.
1 2 |
bpy.context.object.modifiers['GeometryNodes'].node_group # bpy.data.node_groups['Geometry Nodes'] |
Pay attention that the pointer to the node tree in the case of Geometry Nodes is named “node_group”.
Otherwise, everything is exactly the same as for materials.
Links between nodes are stored in the “links” collection:
1 2 |
bpy.context.object.modifiers['GeometryNodes'].node_group.links # bpy.data.node_groups['Geometry Nodes'].links |
A link between two nodes is created by the same new() command, in the parameters of which it is necessary to pass pointers to two sockets – the output on the first node and the input on the second.
We get the pointer to the nodes by name from the “nodes” collection of the node tree:
1 2 |
bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Cube'] # bpy.data.node_groups['Geometry Nodes'].nodes["Cube"] |
We can get a pointer to the desired output socket by index or by name from the “outputs” collection of the node.
1 2 3 4 5 |
bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Cube'].outputs[0] # bpy.data.node_groups['Geometry Nodes'].nodes["Cube"].outputs[0] bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Cube'].outputs['Mesh'] # bpy.data.node_groups['Geometry Nodes'].nodes["Cube"].outputs[0] |
And the pointer to the input socket we can get from the node’s “inputs” collection, also by index or by name.
1 2 3 4 5 |
bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Group Output'].inputs[0] # bpy.data.node_groups['Geometry Nodes'].nodes["Group Output"].inputs[0] bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Group Output'].inputs['Geometry'] # bpy.data.node_groups['Geometry Nodes'].nodes["Group Output"].inputs[0] |
Having pointers to the required sockets, we can create a link between them:
1 2 3 4 |
bpy.context.object.modifiers['GeometryNodes'].node_group.links.new( bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Cube'].outputs['Mesh'], bpy.context.object.modifiers['GeometryNodes'].node_group.nodes['Group Output'].inputs['Geometry'] ) |
When i try to use in [‘Group Output’].inputs[1] it works in 3.4 but in 3.5 it does not work.Do you know if this is a bug?:
bpy.context.object.modifiers[‘GeometryNodes’].node_group.links.new(
bpy.context.object.modifiers[‘GeometryNodes’].node_group.nodes[‘Cube’].outputs[‘Mesh’],
bpy.context.object.modifiers[‘GeometryNodes’].node_group.nodes[‘Group Output’].inputs[1]
)
Hi!
It seems that developers removed the automatically new input/output creation when connecting to the _extend_ node input/output. So first it needs to be manually created, for example for geometry output:
bpy.context.object.modifiers[‘GeometryNodes’].node_group.outputs.new(type=’NodeSocketGeometry’, name=’new output’)
next, you can link to it in a common way.