Following example creates a new node group called NewGroup
(based on How do I create a custom node group for the compositor?) for the Texture Node Tree, containing three Math nodes as well as one Distorted Noise node plugged together properly:
import bpy
# create a group
test_group = bpy.data.node_groups.new('NewGroup', 'TextureNodeTree')
# create group inputs
group_inputs = test_group.nodes.new('NodeGroupInput')
group_inputs.location = (-350,0)
test_group.inputs.new('NodeSocketFloat','in_to_greater')
test_group.inputs.new('NodeSocketFloat','in_to_less')
# create group outputs
group_outputs = test_group.nodes.new('NodeGroupOutput')
group_outputs.location = (500,0)
test_group.outputs.new('NodeSocketFloat','out_result')
# create three math nodes in a group
node_add = test_group.nodes.new('TextureNodeMath')
node_add.operation = 'ADD'
node_add.location = (100,0)
node_greater = test_group.nodes.new('TextureNodeMath')
node_greater.operation = 'GREATER_THAN'
node_greater.label = 'greater'
node_greater.location = (-100,100)
node_less = test_group.nodes.new('TextureNodeMath')
node_less.operation = 'LESS_THAN'
node_less.label = 'less'
node_less.location = (-100,-100)
node_vorn = test_group.nodes.new('TextureNodeTexDistNoise')
node_vorn.inputs[2].default_value = 10 # Set scale to 10
node_vorn.location = (300,0)
# link nodes together
test_group.links.new(node_add.inputs[0], node_greater.outputs[0])
test_group.links.new(node_add.inputs[1], node_less.outputs[0])
test_group.links.new(node_vorn.inputs[3], node_add.outputs[0])
# link inputs
test_group.links.new(group_inputs.outputs['in_to_greater'], node_greater.inputs[0])
test_group.links.new(group_inputs.outputs['in_to_less'], node_less.inputs[0])
#link output
test_group.links.new(node_vorn.outputs[0], group_outputs.inputs['out_result'])
API link - List of all available node types.
Creating the links outside of the group is basically the same. Following Operator, creates a new Output node and the group node from above as well as linking both together properly:

import bpy
# Create texture group
def create_tex_group(context, operator, group_name):
# Create a group
test_group = bpy.data.node_groups.new(group_name, 'TextureNodeTree')
# Create group inputs
group_inputs = test_group.nodes.new('NodeGroupInput')
group_inputs.location = (-350,0)
test_group.inputs.new('NodeSocketFloat','in_to_greater')
test_group.inputs.new('NodeSocketFloat','in_to_less')
# Create group outputs
group_outputs = test_group.nodes.new('NodeGroupOutput')
group_outputs.location = (300,0)
test_group.outputs.new('NodeSocketFloat','out_result')
# Create three math nodes in a group
node_add = test_group.nodes.new('TextureNodeMath')
node_add.operation = 'ADD'
node_add.location = (100,0)
node_greater = test_group.nodes.new('TextureNodeMath')
node_greater.operation = 'GREATER_THAN'
node_greater.label = 'greater'
node_greater.location = (-100,100)
node_less = test_group.nodes.new('TextureNodeMath')
node_less.operation = 'LESS_THAN'
node_less.label = 'less'
node_less.location = (-100,-100)
# Link nodes together
test_group.links.new(node_add.inputs[0], node_greater.outputs[0])
test_group.links.new(node_add.inputs[1], node_less.outputs[0])
# Link inputs
test_group.links.new(group_inputs.outputs['in_to_greater'], node_greater.inputs[0])
test_group.links.new(group_inputs.outputs['in_to_less'], node_less.inputs[0])
# link output
test_group.links.new(node_add.outputs[0], group_outputs.inputs['out_result'])
# return the group
return test_group
# Operator
class NODE_OT_texGroup(bpy.types.Operator):
"""Tooltip"""
bl_idname = "node.simple_operator"
bl_label = "Add Group (Operator)"
@classmethod
def poll(cls, context):
space = context.space_data
return space.tree_type == 'TextureNodeTree'
def execute(self, context):
tree_id = context.space_data.id
nodes_list = tree_id.node_tree.nodes
# Create Output Node
out = nodes_list.new('TextureNodeOutput')
out.location = (200,100)
# Create Grup
custom_node_name = "my_node"
my_group = create_tex_group(self, context, custom_node_name)
grp_node = nodes_list.new('TextureNodeGroup')
grp_node.node_tree = bpy.data.node_groups[my_group.name]
grp_node.location = (0,0)
# Link Group to Output
tree_id.node_tree.links.new(grp_node.outputs[0], out.inputs[0])
return {'FINISHED'}
# Panel
class NODE_PT_customPanel(bpy.types.Panel):
bl_idname = "NODE_PT_customPanel"
bl_space_type = 'NODE_EDITOR'
bl_label = "Custom Panel"
bl_region_type = "UI"
bl_category = "Custom Category"
@classmethod
def poll(self,context):
return context.object is not None
def draw(self, context):
layout = self.layout
layout.operator(NODE_OT_texGroup.bl_idname)
layout.separator()
# Register
def register():
bpy.utils.register_class(NODE_OT_texGroup)
bpy.utils.register_class(NODE_PT_customPanel)
def unregister():
bpy.utils.unregister_class(NODE_OT_texGroup)
bpy.utils.unregister_class(NODE_PT_customPanel)
if __name__ == "__main__":
register()
In order to use the generated node texture from above directly in the Compositor, you have to create a new Texture node and assign the texture to its slot:

# Operator
class NODE_OT_texGroup(bpy.types.Operator):
"""Operator to generate a texture and add it to the Compositor"""
bl_idname = "node.simple_operator"
bl_label = "Add Texture (Operator)"
@classmethod
def poll(cls, context):
space = context.space_data
#return space.tree_type == 'TextureNodeTree'
#return space.type == 'NODE_EDITOR'
return space.tree_type == 'CompositorNodeTree'
def execute(self, context):
# ---------------------------------------------------------
# Generate the texture
# ---------------------------------------------------------
# Create the texture
my_texture = bpy.data.textures.new('TextureName', 'IMAGE')
# Enable use nodes
my_texture.use_nodes = True
# Get the tree
tex_tree = my_texture.node_tree
# Clear default nodes
for node in tex_tree.nodes:
tex_tree.nodes.remove(node)
# Create Output Node
out = tex_tree.nodes.new('TextureNodeOutput')
out.location = (200,100)
# Create Group
custom_node_name = "my_node"
my_group = create_tex_group(self, context, custom_node_name)
grp_node = tex_tree.nodes.new('TextureNodeGroup')
grp_node.node_tree = bpy.data.node_groups[my_group.name]
grp_node.location = (0,0)
# Link Group to Output
tex_tree.links.new(grp_node.outputs[0], out.inputs[0])
# ---------------------------------------------------------
# Compositor
# ---------------------------------------------------------
# Enable use nodes in the compositor
context.scene.use_nodes = True
# Get the tree
comp_tree = context.scene.node_tree
# Clear default nodes
for node in comp_tree.nodes:
comp_tree.nodes.remove(node)
# Create the texture node
comp_node_texture = comp_tree.nodes.new('CompositorNodeTexture')
# Assign the newly created texture
comp_node_texture.texture = my_texture
# create output node
comp_node_out = comp_tree.nodes.new('CompositorNodeComposite')
comp_node_out.location = 400,0
# link nodes
links = comp_tree.links
link = links.new(comp_node_texture.outputs[0], comp_node_out.inputs[0])
return {'FINISHED'}