Commit: 4127c7ff87600bae3da7b74a85b152d49ca5f166 Author: Jacques Lucke Date: Tue Dec 3 15:07:40 2019 +0100 Branches: functions https://developer.blender.org/rB4127c7ff87600bae3da7b74a85b152d49ca5f166
make execute and influence sockets work in groups =================================================================== M release/scripts/startup/nodes/declaration/__init__.py M release/scripts/startup/nodes/declaration/bparticles.py M release/scripts/startup/nodes/function_nodes/groups.py M release/scripts/startup/nodes/function_tree.py M release/scripts/startup/nodes/node_builder.py M release/scripts/startup/nodes/node_operators.py M source/blender/blenkernel/intern/inlined_node_tree.cc M source/blender/functions/intern/inlined_tree_multi_function_network/generate.cc M source/blender/simulations/bparticles/particle_function.cpp =================================================================== diff --git a/release/scripts/startup/nodes/declaration/__init__.py b/release/scripts/startup/nodes/declaration/__init__.py index a67bcbfe059..ea1185b4b5a 100644 --- a/release/scripts/startup/nodes/declaration/__init__.py +++ b/release/scripts/startup/nodes/declaration/__init__.py @@ -8,5 +8,6 @@ from . vectorized import VectorizedInputDecl, VectorizedOutputDecl from . bparticles import ( InfluencesSocketDecl, ExecuteOutputDecl, + ExecuteInputDecl, ExecuteInputListDecl, ) diff --git a/release/scripts/startup/nodes/declaration/bparticles.py b/release/scripts/startup/nodes/declaration/bparticles.py index f4b2d96c810..cd7bf1fc49a 100644 --- a/release/scripts/startup/nodes/declaration/bparticles.py +++ b/release/scripts/startup/nodes/declaration/bparticles.py @@ -56,6 +56,27 @@ class ExecuteOutputDecl(SocketDeclBase): return False return True + +class ExecuteInputDecl(SocketDeclBase): + def __init__(self, node, identifier: str, display_name: str): + self.node = node + self.identifier = identifier + self.display_name = display_name + + def build(self, node_sockets): + return [node_sockets.new("fn_ExecuteSocket", self.display_name, identifier=self.identifier)] + + def amount(self): + return 1 + + def validate(self, sockets): + if len(sockets) != 1: + return False + if sockets[0].bl_idname != "fn_ExecuteSocket": + return False + return True + + class ExecuteInputListDecl(SocketDeclBase): def __init__(self, node, identifier: str, prop_name: str, display_name: str): self.node = node diff --git a/release/scripts/startup/nodes/function_nodes/groups.py b/release/scripts/startup/nodes/function_nodes/groups.py index a3d765d29a8..db306aeff87 100644 --- a/release/scripts/startup/nodes/function_nodes/groups.py +++ b/release/scripts/startup/nodes/function_nodes/groups.py @@ -6,62 +6,106 @@ from .. function_tree import FunctionTree from .. node_builder import NodeBuilder from .. ui import NodeSidebarPanel -class GroupInputNode(BaseNode): - sort_index: IntProperty() - -class GroupOutputNode(BaseNode): - sort_index: IntProperty() +interface_type_items = [ + ("DATA", "Data", "Some data type like integer or vector", "NONE", 0), + ("EXECUTE", "Control Flow", "", "NONE", 1), + ("INFLUENCES", "Influences", "", "NONE", 2), +] -class GroupDataInputNode(bpy.types.Node, GroupInputNode): - bl_idname = "fn_GroupDataInputNode" - bl_label = "Group Data Input" +class GroupInputNode(bpy.types.Node, BaseNode): + bl_idname = "fn_GroupInputNode" + bl_label = "Group Input" input_name: StringProperty( default="Name", - update=GroupInputNode.sync_tree, + update=BaseNode.sync_tree, + ) + + sort_index: IntProperty() + + interface_type: EnumProperty( + items=interface_type_items, + default="DATA", + update= BaseNode.sync_tree, ) data_type: StringProperty( default="Float", - update=GroupInputNode.sync_tree, + update=BaseNode.sync_tree, ) def declaration(self, builder: NodeBuilder): - builder.fixed_output("value", "Value", self.data_type) + builder.background_color((0.8, 0.8, 0.8)) + + if self.interface_type == "DATA": + builder.fixed_output("value", "Value", self.data_type) + elif self.interface_type == "EXECUTE": + builder.execute_output("execute", "Execute") + elif self.interface_type == "INFLUENCES": + builder.influences_output("influences", "Influences") + else: + assert False def draw(self, layout): - layout.prop(self, "input_name", text="") + col = layout.column() + col.prop(self, "input_name", text="") + + if self.interface_type == "DATA": + if hasattr(self.outputs[0], "draw_property"): + self.outputs[0].draw_property(col, self, "Default") - if hasattr(self.outputs[0], "draw_property"): - self.outputs[0].draw_property(layout, self, "Default") + self.invoke_type_selection(col, "set_data_type", "Select Type") - self.invoke_type_selection(layout, "set_type", "Select Type") + def draw_advanced(self, layout): + layout.prop(self, "interface_type", text="") - def set_type(self, data_type): + def set_data_type(self, data_type): self.data_type = data_type -class GroupDataOutputNode(bpy.types.Node, GroupOutputNode): - bl_idname = "fn_GroupDataOutputNode" - bl_label = "Group Data Output" + +class GroupOutputNode(bpy.types.Node, BaseNode): + bl_idname = "fn_GroupOutputNode" + bl_label = "Group Output" + + sort_index: IntProperty() output_name: StringProperty( default="Name", - update=GroupOutputNode.sync_tree, + update=BaseNode.sync_tree, + ) + + interface_type: EnumProperty( + items=interface_type_items, + default="DATA", + update= BaseNode.sync_tree, ) data_type: StringProperty( default="Float", - update=GroupOutputNode.sync_tree, + update=BaseNode.sync_tree, ) def declaration(self, builder: NodeBuilder): - builder.fixed_input("value", "Value", self.data_type) + builder.background_color((0.8, 0.8, 0.8)) + + if self.interface_type == "DATA": + builder.fixed_input("value", "Value", self.data_type) + elif self.interface_type == "EXECUTE": + builder.single_execute_input("execute", "Execute") + elif self.interface_type == "INFLUENCES": + builder.influences_input("influences", "Influences") def draw(self, layout): - layout.prop(self, "output_name", text="") - self.invoke_type_selection(layout, "set_type", "Select Type") + col = layout.column() + col.prop(self, "output_name", text="") + + if self.interface_type == "DATA": + self.invoke_type_selection(col, "set_type_type", "Select Type") + + def draw_advanced(self, layout): + layout.prop(self, "interface_type", text="") - def set_type(self, data_type): + def set_type_type(self, data_type): self.data_type = data_type class GroupNode(bpy.types.Node, FunctionNode): @@ -78,17 +122,31 @@ class GroupNode(bpy.types.Node, FunctionNode): return for input_node in self.node_group.get_input_nodes(): - builder.fixed_input( - input_node.identifier, - input_node.input_name, - input_node.data_type, - default=input_node.outputs[0].get_state()) + if input_node.interface_type == "DATA": + builder.fixed_input( + input_node.identifier, + input_node.input_name, + input_node.data_type, + default=input_node.outputs[0].get_state()) + elif input_node.interface_type == "EXECUTE": + builder.single_execute_input(input_node.identifier, input_node.input_name) + elif input_node.interface_type == "INFLUENCES": + builder.influences_input(input_node.identifier, input_node.input_name) + else: + assert False for output_node in self.node_group.get_output_nodes(): - builder.fixed_output( - output_node.identifier, - output_node.output_name, - output_node.data_type) + if output_node.interface_type == "DATA": + builder.fixed_output( + output_node.identifier, + output_node.output_name, + output_node.data_type) + elif output_node.interface_type == "EXECUTE": + builder.execute_output(output_node.identifier, output_node.output_name) + elif output_node.interface_type == "INFLUENCES": + builder.influences_output(output_node.identifier, output_node.output_name) + else: + assert False def draw(self, layout): text = "Select Group" if self.node_group is None else self.node_group.name diff --git a/release/scripts/startup/nodes/function_tree.py b/release/scripts/startup/nodes/function_tree.py index 48c7bbc40d4..227c6d8b8e8 100644 --- a/release/scripts/startup/nodes/function_tree.py +++ b/release/scripts/startup/nodes/function_tree.py @@ -10,12 +10,12 @@ class FunctionTree(bpy.types.NodeTree, BaseTree): bl_label = "Function Nodes" def get_input_nodes(self): - input_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupDataInputNode"] + input_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupInputNode"] sorted_input_nodes = sorted(input_nodes, key=lambda node: (node.sort_index, node.name)) return sorted_input_nodes def get_output_nodes(self): - output_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupDataOutputNode"] + output_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupOutputNode"] sorted_output_nodes = sorted(output_nodes, key=lambda node: (node.sort_index, node.name)) return sorted_output_nodes diff --git a/release/scripts/startup/nodes/node_builder.py b/release/scripts/startup/nodes/node_builder.py index 31933ee9681..af2c6f45137 100644 --- a/release/scripts/startup/nodes/node_builder.py +++ b/release/scripts/startup/nodes/node_builder.py @@ -8,6 +8,7 @@ from . declaration import ( InfluencesSocketDecl, ExecuteOutputDecl, ExecuteInputListDecl, + ExecuteInputDecl, NoDefaultValue, ) @@ -198,6 +199,10 @@ class NodeBuilder: decl = ExecuteInputListDecl(self.node, identifier, prop_name, display_name) self._add_input(decl) + def single_execute_input(self, identifier, name): + decl = ExecuteInputDecl(self.node, identifier, name) + self._add_input(decl) + def execute_output(self, identifier, name): decl = ExecuteOutputDecl(self.node, identifier, name) self._add_output(decl) diff --git a/release/scripts/start @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs