[Bf-blender-cvs] [758a751fb29] functions: new group nodes

Jacques Lucke noreply at git.blender.org
Thu Nov 14 13:59:17 CET 2019


Commit: 758a751fb29805bc7952daf813fdead67161b957
Author: Jacques Lucke
Date:   Wed Nov 13 15:29:00 2019 +0100
Branches: functions
https://developer.blender.org/rB758a751fb29805bc7952daf813fdead67161b957

new group nodes

===================================================================

M	release/scripts/startup/nodes/declaration/__init__.py
D	release/scripts/startup/nodes/declaration/tree_interface.py
M	release/scripts/startup/nodes/function_nodes/groups.py
M	release/scripts/startup/nodes/function_tree.py
M	release/scripts/startup/nodes/inferencing.py
M	release/scripts/startup/nodes/node_builder.py

===================================================================

diff --git a/release/scripts/startup/nodes/declaration/__init__.py b/release/scripts/startup/nodes/declaration/__init__.py
index c61aeae8406..a67bcbfe059 100644
--- a/release/scripts/startup/nodes/declaration/__init__.py
+++ b/release/scripts/startup/nodes/declaration/__init__.py
@@ -2,7 +2,6 @@ from . base import NoDefaultValue
 from . fixed_type import FixedSocketDecl
 from . dynamic_list import ListSocketDecl
 from . base_list_variadic import BaseListVariadic
-from . tree_interface import TreeInterfaceDecl
 from . variadic import AnyVariadicDecl
 from . vectorized import VectorizedInputDecl, VectorizedOutputDecl
 
diff --git a/release/scripts/startup/nodes/declaration/tree_interface.py b/release/scripts/startup/nodes/declaration/tree_interface.py
deleted file mode 100644
index ca7fe0a1908..00000000000
--- a/release/scripts/startup/nodes/declaration/tree_interface.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import typing as T
-
-from . base import SocketDeclBase
-from .. types import type_infos
-from .. function_tree import FunctionTree
-
-class TreeInterfaceDecl(SocketDeclBase):
-    def __init__(self, node, identifier: str, tree: FunctionTree, in_or_out: str, ignored: T.Set[T.Tuple[str, str]]):
-        assert tree is not None
-        self.node = node
-        self.identifier = identifier
-        self.tree = tree
-        self.in_or_out = in_or_out
-        self.ignored = ignored
-
-    def build(self, node_sockets):
-        if self.in_or_out == "IN":
-            return list(self._build_inputs(node_sockets))
-        elif self.in_or_out == "OUT":
-            return list(self._build_outputs(node_sockets))
-        else:
-            assert False
-
-    def _build_inputs(self, node_sockets):
-        for data_type, name, identifier in self.iter_filtered_inputs():
-            yield type_infos.build(
-                data_type,
-                node_sockets,
-                name,
-                self.identifier + identifier)
-
-    def _build_outputs(self, node_sockets):
-        for data_type, name, identifier in self.iter_filtered_outputs():
-            yield type_infos.build(
-                data_type,
-                node_sockets,
-                name,
-                self.identifier + identifier)
-
-    def validate(self, sockets):
-        if self.in_or_out == "IN":
-            return self.validate_in(sockets)
-        elif self.in_or_out == "OUT":
-            return self.validate_out(sockets)
-        else:
-            assert False
-
-    def validate_in(self, sockets):
-        params = list(self.iter_filtered_inputs())
-        if len(params) != len(sockets):
-            return False
-
-        for param, socket in zip(params, sockets):
-            identifier = self.identifier + param.identifier
-            if not self._data_socket_test(socket, param.name, param.data_type, identifier):
-                return False
-
-        return True
-
-    def validate_out(self, sockets):
-        params = list(self.iter_filtered_outputs())
-        if len(params) != len(sockets):
-            return False
-
-        for param, socket in zip(params, sockets):
-            identifier = self.identifier + param.identifier
-            if not self._data_socket_test(socket, param.name, param.data_type, identifier):
-                return False
-
-        return True
-
-    def amount(self):
-        if self.in_or_out == "IN":
-            return len(tuple(self.iter_filtered_inputs()))
-        elif self.in_or_out == "OUT":
-            return len(tuple(self.iter_filtered_outputs()))
-        else:
-            assert False
-
-    def iter_filtered_inputs(self):
-        for item in self.tree.iter_function_inputs():
-            if (item.data_type, item.name) not in self.ignored:
-                yield item
-
-    def iter_filtered_outputs(self):
-        for item in self.tree.iter_function_outputs():
-            if (item.data_type, item.name) not in self.ignored:
-                yield item
diff --git a/release/scripts/startup/nodes/function_nodes/groups.py b/release/scripts/startup/nodes/function_nodes/groups.py
index ff3ccb68ae5..c55c856842c 100644
--- a/release/scripts/startup/nodes/function_nodes/groups.py
+++ b/release/scripts/startup/nodes/function_nodes/groups.py
@@ -1,7 +1,7 @@
 import bpy
 from bpy.props import *
 from .. types import type_infos
-from .. base import BaseNode
+from .. base import BaseNode, FunctionNode
 from .. function_tree import FunctionTree
 from .. node_builder import NodeBuilder
 from .. ui import NodeSidebarPanel
@@ -9,21 +9,88 @@ from .. ui import NodeSidebarPanel
 class GroupInputNode(BaseNode):
     sort_index: IntProperty()
 
+class GroupOutputNode(BaseNode):
+    sort_index: IntProperty()
+
 class GroupDataInputNode(bpy.types.Node, GroupInputNode):
     bl_idname = "fn_GroupDataInputNode"
     bl_label = "Group Data Input"
 
-    data_type: StringProperty(default="Float")
+    input_name: StringProperty(
+        default="Name",
+        update=GroupInputNode.sync_tree,
+    )
+
+    data_type: StringProperty(
+        default="Float",
+        update=GroupInputNode.sync_tree,
+    )
 
     def declaration(self, builder: NodeBuilder):
         builder.fixed_output("value", "Value", self.data_type)
 
     def draw(self, layout):
+        layout.prop(self, "input_name", text="")
+        self.invoke_type_selection(layout, "set_type", "Select Type")
+
+    def set_type(self, data_type):
+        self.data_type = data_type
+
+class GroupDataOutputNode(bpy.types.Node, GroupOutputNode):
+    bl_idname = "fn_GroupDataOutputNode"
+    bl_label = "Group Data Output"
+
+    output_name: StringProperty(
+        default="Name",
+        update=GroupOutputNode.sync_tree,
+    )
+
+    data_type: StringProperty(
+        default="Float",
+        update=GroupOutputNode.sync_tree,
+    )
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("value", "Value", self.data_type)
+
+    def draw(self, layout):
+        layout.prop(self, "output_name", text="")
         self.invoke_type_selection(layout, "set_type", "Select Type")
 
     def set_type(self, data_type):
         self.data_type = data_type
-        self.sync_tree()
+
+class GroupNode(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_GroupNode"
+    bl_label = "Group"
+
+    node_group: PointerProperty(
+        type=bpy.types.NodeTree,
+        update=FunctionNode.sync_tree,
+    )
+
+    def declaration(self, builder: NodeBuilder):
+        if self.node_group is None:
+            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)
+
+        for output_node in self.node_group.get_output_nodes():
+            builder.fixed_output(
+                output_node.identifier,
+                output_node.output_name,
+                output_node.data_type)
+
+    def draw(self, layout):
+        layout.prop(self, "node_group", text="")
+
+    def iter_dependency_trees(self):
+        if self.node_group is not None:
+            yield self.node_group
 
 
 class GroupInterfacePanel(bpy.types.Panel, NodeSidebarPanel):
@@ -39,9 +106,12 @@ class GroupInterfacePanel(bpy.types.Panel, NodeSidebarPanel):
         layout = self.layout
         tree = context.space_data.edit_tree
 
-        input_nodes = [node for node in tree.nodes if isinstance(node, GroupDataInputNode)]
-        input_nodes = sorted(input_nodes, key=lambda node: (node.sort_index, node.name))
+        col = layout.column(align=True)
+        col.label(text="Inputs:")
+        for node in tree.get_input_nodes():
+            layout.label(text=node.input_name)
 
         col = layout.column(align=True)
-        for node in input_nodes:
-            layout.label(text=node.name)
+        col.label(text="Outputs:")
+        for node in tree.get_output_nodes():
+            layout.label(text=node.output_name)
diff --git a/release/scripts/startup/nodes/function_tree.py b/release/scripts/startup/nodes/function_tree.py
index d03bd5a31a2..a23f74323a4 100644
--- a/release/scripts/startup/nodes/function_tree.py
+++ b/release/scripts/startup/nodes/function_tree.py
@@ -3,50 +3,20 @@ from collections import namedtuple
 
 from . base import BaseTree, BaseNode
 
-FunctionInput = namedtuple("FunctionInput",
-    ["data_type", "name", "identifier"])
-
-FunctionOutput = namedtuple("FunctionOutput",
-    ["data_type", "name", "identifier"])
-
 class FunctionTree(bpy.types.NodeTree, BaseTree):
     bl_idname = "FunctionTree"
     bl_icon = "MOD_DATA_TRANSFER"
     bl_label = "Function Nodes"
 
-    def iter_function_inputs(self):
-        node = self.get_input_node()
-        if node is None:
-            return
-
-        for socket in node.outputs[:-1]:
-            yield FunctionInput(
-                socket.data_type,
-                socket.name,
-                socket.identifier)
-
-    def iter_function_outputs(self):
-        node = self.get_output_node()
-        if node is None:
-            return
+    def get_input_nodes(self):
+        input_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupDataInputNode"]
+        sorted_input_nodes = sorted(input_nodes, key=lambda node: (node.sort_index, node.name))
+        return sorted_input_nodes
 
-        for socket in node.inputs[:-1]:
-            yield FunctionOutput(
-                socket.data_type,
-                socket.name,
-                socket.identifier)
-
-    def get_input_node(self):
-        for node in self.nodes:
-            if node.bl_idname == "fn_FunctionInputNode":
-                return node
-        return None
-
-    def get_output_node(self):
-        for node in self.nodes:
-            if node.bl_idname == "fn_FunctionOutputNode":
-                return node
-        return None
+    def get_output_nodes(self):
+        output_nodes = [node for node in self.nodes if node.bl_idname == "fn_GroupDataOutputNode"]
+        sorted_output_nodes = sorted(output_nodes, key=lambda node: (node.sort_index, node.name))
+        return sorted_output_nodes
 
     def iter_dependency_trees(self):
         trees = set()
diff --git a/release/

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list