I want to execute the node tree continuously which will execute every node.
Currently to execute the node tree I have to run this command bpy.data.node_groups['NodeTree'].execute(bpy.context)
every time.
import bpy
from bpy.types import NodeTree, Node, NodeSocket
from bpy.props import *
import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem
class CustomNodeTree(NodeTree):
'''A custom node tree type that will show up in the editor type list'''
bl_label = 'Custom Node Tree'
bl_icon = 'NODETREE'
def execute(self, context):
for node in self.nodes:
node.execute(context)
class BaseNode:
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'CustomNodeTree'
def execute(self, context):
pass
class CustomNodeText(Node, BaseNode):
bl_label = 'Text'
text : StringProperty(name='',)
def init(self, context):
self.outputs.new('NodeSocketString', 'Text')
def draw_buttons(self, context, layout):
layout.prop(self, 'text')
def execute(self, context):
self.outputs['Text'].default_value = self.text
class CustomNodeFloat(Node, BaseNode):
bl_label = 'Float'
float : FloatProperty(name='',)
def init(self, context):
self.outputs.new('NodeSocketFloat', 'Float')
def draw_buttons(self, context, layout):
layout.prop(self, 'float')
def execute(self, context):
self.outputs['Float'].default_value = self.float
def execute(self, context):
self.outputs['Float'].default_value = self.float
class CustomNodePrint(Node, BaseNode):
bl_label = 'Print'
def init(self, context):
self.inputs.new('NodeSocketVirtual', 'Print')
def draw_buttons(self, context, layout):
if self.inputs['Print'].is_linked:
print_value = self.inputs['Print'].links[0].from_socket.default_value
layout.label(text=f'{print_value}')
class CustomNodeCategory(NodeCategory):
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CustomNodeTree'
# all categories in a list
node_categories = [
# identifier, label, items list
CustomNodeCategory('UTILITIES', 'Utilities', items=[
NodeItem('CustomNodeText'),
NodeItem('CustomNodeFloat'),
NodeItem('CustomNodePrint'),
]),
]
classes = (
CustomNodeTree,
CustomNodeText,
CustomNodeFloat,
CustomNodePrint,
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
nodeitems_utils.register_node_categories('CUSTOM', node_categories)
def unregister():
nodeitems_utils.unregister_node_categories('CUSTOM')
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
Added node Join
It's not updating live when I change the value.
import bpy
from bpy.types import NodeTree, Node, NodeSocket
from bpy.props import *
import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem
class CustomNodeTree(NodeTree):
'''A custom node tree type that will show up in the editor type list'''
bl_label = 'Custom Node Tree'
bl_icon = 'NODETREE'
def execute(self, context):
for node in self.nodes:
node.execute(context)
class BaseNode:
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'CustomNodeTree'
def execute(self, context):
pass
class CustomNodeText(Node, BaseNode):
bl_label = 'Text'
text : StringProperty(name='',)
def init(self, context):
self.outputs.new('NodeSocketString', 'Text')
def draw_buttons(self, context, layout):
layout.prop(self, 'text')
def execute(self, context):
self.outputs['Text'].default_value = self.text
class CustomNodeFloat(Node, BaseNode):
bl_label = 'Float'
float : FloatProperty(name='',)
def init(self, context):
self.outputs.new('NodeSocketFloat', 'Float')
def draw_buttons(self, context, layout):
layout.prop(self, 'float')
def execute(self, context):
self.outputs['Float'].default_value = self.float
class CustomNodeJoin(Node, BaseNode):
bl_label = 'Join'
def init(self, context):
self.inputs.new('NodeSocketString', 'Value1')
self.inputs.new('NodeSocketString', 'Value2')
self.outputs.new('NodeSocketString', 'Value')
def draw_buttons(self, context, layout):
pass
def update(self):
if self.inputs['Value1'].is_linked and self.inputs['Value2'].is_linked:
text = self.inputs['Value1'].links[0].from_socket.default_value + self.inputs['Value2'].links[0].from_socket.default_value
elif self.inputs['Value1'].is_linked and not self.inputs['Value2'].is_linked:
text = self.inputs['Value1'].links[0].from_socket.default_value + self.inputs['Value2'].default_value
elif self.inputs['Value2'].is_linked and not self.inputs['Value1'].is_linked:
text = self.inputs['Value1'].default_value + self.inputs['Value2'].links[0].from_socket.default_value
else:
text = self.inputs['Value1'].default_value + self.inputs['Value2'].default_value
self.outputs['Value'].default_value = text
class CustomNodePrint(Node, BaseNode):
bl_label = 'Print'
def init(self, context):
self.inputs.new('NodeSocketString', 'Print')
def draw_buttons(self, context, layout):
if self.inputs['Print'].is_linked:
print_value = self.inputs['Print'].links[0].from_socket.default_value
layout.label(text=f'{print_value}')
class CustomNodeCategory(NodeCategory):
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CustomNodeTree'
# all categories in a list
node_categories = [
# identifier, label, items list
CustomNodeCategory('UTILITIES', 'Utilities', items=[
NodeItem('CustomNodeText'),
NodeItem('CustomNodeFloat'),
NodeItem('CustomNodeJoin'),
NodeItem('CustomNodePrint'),
]),
]
classes = (
CustomNodeTree,
CustomNodeText,
CustomNodeFloat,
CustomNodeJoin,
CustomNodePrint,
)
def execute_active_node_tree():
node_editor = next((a for a in bpy.context.screen.areas if a.type == 'NODE_EDITOR'), None)
if (node_editor == None): return
for space in node_editor.spaces:
node_tree = getattr(space, 'node_tree')
if (node_tree):
node_tree.execute(bpy.context)
break
CUSTOM_NODE_TEXT_HANDLE = 0
CUSTOM_NODE_FLOAT_HANDLE = 1
CUSTOM_NODE_JOIN_HANDLE = 2
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
nodeitems_utils.register_node_categories('CUSTOM', node_categories)
bpy.msgbus.subscribe_rna(
key=CustomNodeText,
owner=CUSTOM_NODE_TEXT_HANDLE,
args = (),
notify=execute_active_node_tree,
options={"PERSISTENT",}
)
bpy.msgbus.subscribe_rna(
key=CustomNodeFloat,
owner=CUSTOM_NODE_FLOAT_HANDLE,
args = (),
notify=execute_active_node_tree,
options={"PERSISTENT",}
)
bpy.msgbus.subscribe_rna(
key=CustomNodeJoin,
owner=CUSTOM_NODE_JOIN_HANDLE,
args = (),
notify=execute_active_node_tree,
options={"PERSISTENT",}
)
def unregister():
bpy.msgbus.clear_by_owner(CUSTOM_NODE_JOIN_HANDLE)
bpy.msgbus.clear_by_owner(CUSTOM_NODE_FLOAT_HANDLE)
bpy.msgbus.clear_by_owner(CUSTOM_NODE_TEXT_HANDLE)
nodeitems_utils.unregister_node_categories('CUSTOM')
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
Scripting > Templates > Python > Custom Nodes
$\endgroup$Geometry, Shader etc
. $\endgroup$