[Bf-blender-cvs] [2ddb3dc617a] master: Nodes: support default function for partially implemented nodes

Jacques Lucke noreply at git.blender.org
Thu Jul 16 13:42:02 CEST 2020


Commit: 2ddb3dc617a5ad3dd5882cde8c088127bd57f916
Author: Jacques Lucke
Date:   Thu Jul 16 13:38:23 2020 +0200
Branches: master
https://developer.blender.org/rB2ddb3dc617a5ad3dd5882cde8c088127bd57f916

Nodes: support default function for partially implemented nodes

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

M	source/blender/blenkernel/BKE_node_tree_multi_function.hh
M	source/blender/blenkernel/intern/node_tree_multi_function.cc
M	source/blender/functions/FN_multi_function_builder.hh
M	source/blender/functions/intern/multi_function_builder.cc

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

diff --git a/source/blender/blenkernel/BKE_node_tree_multi_function.hh b/source/blender/blenkernel/BKE_node_tree_multi_function.hh
index dcbd551591f..95a6c61da7f 100644
--- a/source/blender/blenkernel/BKE_node_tree_multi_function.hh
+++ b/source/blender/blenkernel/BKE_node_tree_multi_function.hh
@@ -88,6 +88,7 @@ class MFNetworkTreeMap {
   void add(const DSocket &dsocket, fn::MFSocket &socket)
   {
     BLI_assert(dsocket.is_input() == socket.is_input());
+    BLI_assert(dsocket.is_input() || sockets_by_dsocket_id_[dsocket.id()].size() == 0);
     sockets_by_dsocket_id_[dsocket.id()].append(&socket);
   }
 
@@ -98,6 +99,8 @@ class MFNetworkTreeMap {
 
   void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket)
   {
+    /* There can be at most one matching output socket. */
+    BLI_assert(sockets_by_dsocket_id_[dsocket.id()].size() == 0);
     sockets_by_dsocket_id_[dsocket.id()].append(&socket);
   }
 
@@ -319,11 +322,11 @@ class SocketMFNetworkBuilder : public MFNetworkBuilderBase {
  */
 class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
  private:
-  const DNode &node_;
+  const DNode &dnode_;
 
  public:
-  NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &node)
-      : MFNetworkBuilderBase(common), node_(node)
+  NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &dnode)
+      : MFNetworkBuilderBase(common), dnode_(dnode)
   {
   }
 
@@ -331,12 +334,20 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
    * Tells the builder to build a function that corresponds to the node that is being built. It
    * will try to match up sockets.
    */
-  template<typename T, typename... Args> void construct_and_set_matching_fn(Args &&... args)
+  template<typename T, typename... Args> T &construct_and_set_matching_fn(Args &&... args)
   {
-    const fn::MultiFunction &function = this->construct_fn<T>(std::forward<Args>(args)...);
+    T &function = this->construct_fn<T>(std::forward<Args>(args)...);
     this->set_matching_fn(function);
+    return function;
   }
 
+  const fn::MultiFunction &get_not_implemented_fn()
+  {
+    return this->get_default_fn("Not Implemented (" + dnode_.name() + ")");
+  }
+
+  const fn::MultiFunction &get_default_fn(StringRef name);
+
   /**
    * Tells the builder that the given function corresponds to the node that is being built. It will
    * try to match up sockets. For that it skips unavailable and non-data sockets.
@@ -344,7 +355,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
   void set_matching_fn(const fn::MultiFunction &function)
   {
     fn::MFFunctionNode &node = common_.network.add_function(function);
-    common_.network_map.add_try_match(node_, node);
+    common_.network_map.add_try_match(dnode_, node);
   }
 
   /**
@@ -352,7 +363,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
    */
   bNode &bnode()
   {
-    return *node_.node_ref().bnode();
+    return *dnode_.node_ref().bnode();
   }
 
   /**
@@ -360,7 +371,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
    */
   const DNode &dnode() const
   {
-    return node_;
+    return dnode_;
   }
 };
 
diff --git a/source/blender/blenkernel/intern/node_tree_multi_function.cc b/source/blender/blenkernel/intern/node_tree_multi_function.cc
index 4e505db9b9d..942f8e9a87a 100644
--- a/source/blender/blenkernel/intern/node_tree_multi_function.cc
+++ b/source/blender/blenkernel/intern/node_tree_multi_function.cc
@@ -31,6 +31,35 @@ static std::optional<fn::MFDataType> try_get_multi_function_data_type_of_socket(
   return bsocket->typeinfo->get_mf_data_type();
 }
 
+const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name)
+{
+  Vector<fn::MFDataType, 10> input_types;
+  Vector<fn::MFDataType, 10> output_types;
+
+  for (const DInputSocket *dsocket : dnode_.inputs()) {
+    if (dsocket->is_available()) {
+      std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+          dsocket->bsocket());
+      if (data_type.has_value()) {
+        input_types.append(*data_type);
+      }
+    }
+  }
+  for (const DOutputSocket *dsocket : dnode_.outputs()) {
+    if (dsocket->is_available()) {
+      std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+          dsocket->bsocket());
+      if (data_type.has_value()) {
+        output_types.append(*data_type);
+      }
+    }
+  }
+
+  const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_DefaultOutput>(
+      name, input_types, output_types);
+  return fn;
+}
+
 static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode)
 {
   constexpr uint stack_capacity = 10;
@@ -138,20 +167,21 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
   }
 
   if (from_dsockets.size() == 1) {
-    if (is_multi_function_data_socket(from_dsockets[0]->bsocket())) {
-      return &common.network_map.lookup(*from_dsockets[0]);
-    }
-    else {
+    const DOutputSocket &from_dsocket = *from_dsockets[0];
+    if (!from_dsocket.is_available()) {
       return nullptr;
     }
+    if (is_multi_function_data_socket(from_dsocket.bsocket())) {
+      return &common.network_map.lookup(from_dsocket);
+    }
+    return nullptr;
   }
   else {
-    if (is_multi_function_data_socket(from_group_inputs[0]->bsocket())) {
-      return &common.network_map.lookup(*from_group_inputs[0]);
-    }
-    else {
-      return nullptr;
+    const DGroupInput &from_group_input = *from_group_inputs[0];
+    if (is_multi_function_data_socket(from_group_input.bsocket())) {
+      return &common.network_map.lookup(from_group_input);
     }
+    return nullptr;
   }
 }
 
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index 6e7efb21850..c2c95f7c355 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -302,6 +302,17 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
   }
 };
 
+class CustomMF_DefaultOutput : public MultiFunction {
+ private:
+  uint output_amount_;
+
+ public:
+  CustomMF_DefaultOutput(StringRef name,
+                         Span<MFDataType> input_types,
+                         Span<MFDataType> output_types);
+  void call(IndexMask mask, MFParams params, MFContext context) const override;
+};
+
 }  // namespace blender::fn
 
 #endif /* __FN_MULTI_FUNCTION_BUILDER_HH__ */
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 889a2595aab..7797c19d563 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -87,4 +87,33 @@ void CustomMF_GenericConstantArray::call(IndexMask mask,
   }
 }
 
+CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name,
+                                               Span<MFDataType> input_types,
+                                               Span<MFDataType> output_types)
+    : output_amount_(output_types.size())
+{
+  MFSignatureBuilder signature = this->get_builder(name);
+  for (MFDataType data_type : input_types) {
+    signature.input("Input", data_type);
+  }
+  for (MFDataType data_type : output_types) {
+    signature.output("Output", data_type);
+  }
+}
+void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+  for (uint param_index : this->param_indices()) {
+    MFParamType param_type = this->param_type(param_index);
+    if (!param_type.is_output()) {
+      continue;
+    }
+
+    if (param_type.data_type().is_single()) {
+      GMutableSpan span = params.uninitialized_single_output(param_index);
+      const CPPType &type = span.type();
+      type.fill_uninitialized_indices(type.default_value(), span.buffer(), mask);
+    }
+  }
+}
+
 }  // namespace blender::fn



More information about the Bf-blender-cvs mailing list