[Bf-blender-cvs] [70f8f3231b9] functions: Custom Emitter functions can have inputs now

Jacques Lucke noreply at git.blender.org
Tue Jul 16 18:20:13 CEST 2019


Commit: 70f8f3231b9f02d62890423c12944e7cec40f3b3
Author: Jacques Lucke
Date:   Tue Jul 16 14:33:08 2019 +0200
Branches: functions
https://developer.blender.org/rB70f8f3231b9f02d62890423c12944e7cec40f3b3

Custom Emitter functions can have inputs now

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

M	release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
M	release/scripts/startup/nodes/declaration/tree_interface.py
M	release/scripts/startup/nodes/socket_builder.py
M	source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
M	source/blender/functions/backends/tuple_call/tuple_call.hpp
M	source/blender/functions/core/data_flow_graph.hpp
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/inserters.cpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
index fe0abd881b3..859dab80695 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
@@ -15,7 +15,8 @@ class CustomEmitterNode(bpy.types.Node, FunctionNode):
 
     def declaration(self, builder: SocketBuilder):
         if self.function_tree:
-            builder.tree_interface_input("inputs", self.function_tree, 'IN')
+            builder.tree_interface_input("inputs", self.function_tree, 'IN',
+                ignored={("Float", "Time Step"), ("Float", "Start Time")})
 
         builder.emitter_output("emitter", "Emitter")
 
diff --git a/release/scripts/startup/nodes/declaration/tree_interface.py b/release/scripts/startup/nodes/declaration/tree_interface.py
index 158ff9a2cbe..ca7fe0a1908 100644
--- a/release/scripts/startup/nodes/declaration/tree_interface.py
+++ b/release/scripts/startup/nodes/declaration/tree_interface.py
@@ -1,14 +1,17 @@
+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):
+    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":
@@ -19,7 +22,7 @@ class TreeInterfaceDecl(SocketDeclBase):
             assert False
 
     def _build_inputs(self, node_sockets):
-        for data_type, name, identifier in self.tree.iter_function_inputs():
+        for data_type, name, identifier in self.iter_filtered_inputs():
             yield type_infos.build(
                 data_type,
                 node_sockets,
@@ -27,7 +30,7 @@ class TreeInterfaceDecl(SocketDeclBase):
                 self.identifier + identifier)
 
     def _build_outputs(self, node_sockets):
-        for data_type, name, identifier in self.tree.iter_function_outputs():
+        for data_type, name, identifier in self.iter_filtered_outputs():
             yield type_infos.build(
                 data_type,
                 node_sockets,
@@ -43,7 +46,7 @@ class TreeInterfaceDecl(SocketDeclBase):
             assert False
 
     def validate_in(self, sockets):
-        params = list(self.tree.iter_function_inputs())
+        params = list(self.iter_filtered_inputs())
         if len(params) != len(sockets):
             return False
 
@@ -55,7 +58,7 @@ class TreeInterfaceDecl(SocketDeclBase):
         return True
 
     def validate_out(self, sockets):
-        params = list(self.tree.iter_function_outputs())
+        params = list(self.iter_filtered_outputs())
         if len(params) != len(sockets):
             return False
 
@@ -68,8 +71,18 @@ class TreeInterfaceDecl(SocketDeclBase):
 
     def amount(self):
         if self.in_or_out == "IN":
-            return len(tuple(self.tree.iter_function_inputs()))
+            return len(tuple(self.iter_filtered_inputs()))
         elif self.in_or_out == "OUT":
-            return len(tuple(self.tree.iter_function_outputs()))
+            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/socket_builder.py b/release/scripts/startup/nodes/socket_builder.py
index 1994a74efde..7d7fc0fc643 100644
--- a/release/scripts/startup/nodes/socket_builder.py
+++ b/release/scripts/startup/nodes/socket_builder.py
@@ -148,8 +148,8 @@ class SocketBuilder:
     # Tree Interface
     ##################################
 
-    def tree_interface_input(self, identifier, tree, in_or_out):
-        decl = TreeInterfaceDecl(self.node, identifier, tree, in_or_out)
+    def tree_interface_input(self, identifier, tree, in_or_out, *, ignored=set()):
+        decl = TreeInterfaceDecl(self.node, identifier, tree, in_or_out, ignored)
         self._add_input(decl)
 
     def tree_interface_output(self, identifier, tree, in_or_out):
diff --git a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
index 04b9d105363..34ca1a997a7 100644
--- a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
+++ b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
@@ -192,6 +192,8 @@ class ExecuteFGraph : public TupleCallBody {
 
   void call(Tuple &fn_in, Tuple &fn_out, ExecutionContext &ctx) const override
   {
+    BLI_assert(fn_in.all_initialized());
+
     SocketValueStorage storage(*this);
     storage.m_input_values = alloca(m_inputs_buffer_size);
     storage.m_output_values = alloca(m_outputs_buffer_size);
diff --git a/source/blender/functions/backends/tuple_call/tuple_call.hpp b/source/blender/functions/backends/tuple_call/tuple_call.hpp
index 28b630b514c..f7679e83a82 100644
--- a/source/blender/functions/backends/tuple_call/tuple_call.hpp
+++ b/source/blender/functions/backends/tuple_call/tuple_call.hpp
@@ -62,6 +62,16 @@ class TupleCallBodyBase : public FunctionBody {
     return tuple.get<T>(index);
   }
   template<typename T>
+  void set_input(Tuple &tuple, uint index, StringRef expected_name, const T &value) const
+  {
+#ifdef DEBUG
+    StringRef real_name = this->owner()->input_name(index);
+    BLI_assert(real_name == expected_name);
+#endif
+    UNUSED_VARS_NDEBUG(expected_name);
+    tuple.set<T>(index, value);
+  }
+  template<typename T>
   void set_output(Tuple &tuple, uint index, StringRef expected_name, const T &value) const
   {
 #ifdef DEBUG
diff --git a/source/blender/functions/core/data_flow_graph.hpp b/source/blender/functions/core/data_flow_graph.hpp
index 8f0a640e8f1..6305a48551a 100644
--- a/source/blender/functions/core/data_flow_graph.hpp
+++ b/source/blender/functions/core/data_flow_graph.hpp
@@ -204,10 +204,11 @@ class DataFlowGraph : public RefCountedBase {
       }
     }
 
-    SmallVector<DFGraphSocket> map_sockets(ArrayRef<DFGB_Socket> dfgb_sockets)
+    template<typename ContainerT>
+    SmallVector<DFGraphSocket> map_sockets(const ContainerT &dfgb_sockets)
     {
       SmallVector<DFGraphSocket> sockets;
-      for (auto socket : dfgb_sockets) {
+      for (DFGB_Socket socket : dfgb_sockets) {
         sockets.append(this->map_socket(socket));
       }
       return sockets;
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index 4bbae24cf47..8f89d610abb 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -128,11 +128,10 @@ void CustomFunctionEmitter::emit(EmitterInterface &interface)
   TupleCallBody *body = m_function->body<TupleCallBody>();
   BLI_assert(body);
 
-  if (m_function->input_amount() > 0) {
-    return;
-  }
-
   FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
+
+  body->set_input<float>(fn_in, 0, "Start Time", interface.time_span().start());
+  body->set_input<float>(fn_in, 1, "Time Step", interface.time_span().duration());
   body->call__setup_execution_context(fn_in, fn_out);
 
   auto &float_list_type = FN::Types::GET_TYPE_float_list();
diff --git a/source/blender/simulations/bparticles/inserters.cpp b/source/blender/simulations/bparticles/inserters.cpp
index 719185b5b9b..c682fc0dcbe 100644
--- a/source/blender/simulations/bparticles/inserters.cpp
+++ b/source/blender/simulations/bparticles/inserters.cpp
@@ -2,6 +2,7 @@
 #include "FN_data_flow_nodes.hpp"
 #include "FN_tuple_call.hpp"
 #include "FN_dependencies.hpp"
+#include "FN_types.hpp"
 
 #include "BLI_timeit.hpp"
 #include "BLI_lazy_init.hpp"
@@ -280,12 +281,53 @@ static std::unique_ptr<Emitter> BUILD_EMITTER_custom_function(BuildContext &ctx,
     return {};
   }
 
-  Optional<SharedFunction> fn = FN::DataFlowNodes::generate_function(btree);
-  if (!fn.has_value()) {
+  Optional<SharedFunction> fn_emitter_ = FN::DataFlowNodes::generate_function(btree);
+  if (!fn_emitter_.has_value()) {
     return {};
   }
+  SharedFunction fn_emitter = fn_emitter_.value();
 
-  return std::unique_ptr<Emitter>(new CustomFunctionEmitter(particle_type_name, fn.value()));
+  SharedFunction fn_inputs = create_function_for_data_inputs(
+      bnode, ctx.indexed_tree, ctx.data_graph);
+
+  FN::FunctionBuilder fn_builder;
+  fn_builder.add_output("Start Time", FN::Types::GET_TYPE_float());
+  fn_builder.add_output("Time Step", FN::Types::GET_TYPE_float());
+  SharedFunction fn_reserved_inputs = fn_builder.build("Reserved Inputs");
+
+  FN::DataFlowGraphBuilder builder;
+  FN::DFGB_Node *inputs_node = builder.insert_function(fn_inputs);
+  FN::DFGB_Node *emitter_node = builder.insert_function(fn_emitter);
+  FN::DFGB_Node *reserved_inputs_node = builder.insert_function(fn_reserved_inputs);
+
+  uint offset = 0;
+  for (uint i = 0; i < fn_emitter->input_amount(); i++) {
+    StringRef input_name = fn_emitter->input_name(i);
+    FN::SharedType &input_type = fn_emitter->input_type(i);
+
+    bool is_reserved_input = false;
+    for (uint j = 0; j < fn_reserved_inputs->output_amount(); j++) {
+      if (fn_reserved_inputs->output_name(j) == input_name &&
+          fn_reserved_inputs->output_type(j) == input_type) {
+        builder.insert_link(reserved_inputs_node->output(j), emitter_node->input(i));
+        is_reserved_input = true;
+      }
+    }
+
+    if (!is_reserved_input) {
+      builder.insert_link(inputs_node->output(offset), emitter_node->input(i));
+      offset++;
+    }
+  }
+
+  auto build_result = FN::

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list