[Bf-blender-cvs] [ad96830a4b9] functions: support mapping input vsockets to multiple new sockets

Jacques Lucke noreply at git.blender.org
Tue Nov 12 14:30:07 CET 2019


Commit: ad96830a4b9e6069ef61c9cff9db858bceeb1a56
Author: Jacques Lucke
Date:   Tue Nov 12 14:15:08 2019 +0100
Branches: functions
https://developer.blender.org/rBad96830a4b9e6069ef61c9cff9db858bceeb1a56

support mapping input vsockets to multiple new sockets

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

M	source/blender/functions/FN_multi_function_data_type.h
M	source/blender/functions/FN_multi_function_network.h
M	source/blender/functions/FN_vtree_multi_function_network.h
M	source/blender/functions/intern/multi_function_network.cc
M	source/blender/functions/intern/vtree_multi_function_network/builder.cc
M	source/blender/functions/intern/vtree_multi_function_network/builder.h
M	source/blender/functions/intern/vtree_multi_function_network/generate.cc
M	source/blender/simulations/bparticles/node_frontend.cpp
M	source/blender/simulations/bparticles/particle_function_builder.cpp

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

diff --git a/source/blender/functions/FN_multi_function_data_type.h b/source/blender/functions/FN_multi_function_data_type.h
index 4f8b520fa63..9585a031f96 100644
--- a/source/blender/functions/FN_multi_function_data_type.h
+++ b/source/blender/functions/FN_multi_function_data_type.h
@@ -77,6 +77,24 @@ struct MFDataType {
     return !(a == b);
   }
 
+  std::string to_string() const
+  {
+    switch (m_category) {
+      case Single:
+        return m_base_type->name();
+      case Vector:
+        return m_base_type->name() + " Vector";
+    }
+    BLI_assert(false);
+    return "";
+  }
+
+  friend std::ostream &operator<<(std::ostream &stream, MFDataType type)
+  {
+    stream << type.to_string();
+    return stream;
+  }
+
  private:
   Category m_category;
   const CPPType *m_base_type;
diff --git a/source/blender/functions/FN_multi_function_network.h b/source/blender/functions/FN_multi_function_network.h
index 3935cb0ef3b..bf6fd3edb43 100644
--- a/source/blender/functions/FN_multi_function_network.h
+++ b/source/blender/functions/FN_multi_function_network.h
@@ -40,6 +40,9 @@ class MFBuilderNode : BLI::NonCopyable, BLI::NonMovable {
   ArrayRef<MFBuilderInputSocket *> inputs();
   ArrayRef<MFBuilderOutputSocket *> outputs();
 
+  MFBuilderInputSocket &input(uint index);
+  MFBuilderOutputSocket &output(uint index);
+
   StringRefNull name();
 
   uint id();
@@ -293,6 +296,7 @@ class MFNetwork : BLI::NonCopyable, BLI::NonMovable {
 
   const MFNode &node_by_id(uint id) const;
   const MFSocket &socket_by_id(uint id) const;
+  IndexRange socket_ids() const;
 
   Vector<const MFOutputSocket *> find_dummy_dependencies(
       ArrayRef<const MFInputSocket *> sockets) const;
@@ -315,6 +319,16 @@ inline ArrayRef<MFBuilderOutputSocket *> MFBuilderNode::outputs()
   return m_outputs;
 }
 
+inline MFBuilderInputSocket &MFBuilderNode::input(uint index)
+{
+  return *m_inputs[index];
+}
+
+inline MFBuilderOutputSocket &MFBuilderNode::output(uint index)
+{
+  return *m_outputs[index];
+}
+
 inline uint MFBuilderNode::id()
 {
   return m_id;
@@ -576,6 +590,11 @@ inline const MFSocket &MFNetwork::socket_by_id(uint index) const
   return *m_socket_by_id[index];
 }
 
+inline IndexRange MFNetwork::socket_ids() const
+{
+  return IndexRange(m_socket_by_id.size());
+}
+
 }  // namespace FN
 
 #endif /* __FN_MULTI_FUNCTION_NETWORK_H__ */
diff --git a/source/blender/functions/FN_vtree_multi_function_network.h b/source/blender/functions/FN_vtree_multi_function_network.h
index 3fabf4d352b..1ec48338d1f 100644
--- a/source/blender/functions/FN_vtree_multi_function_network.h
+++ b/source/blender/functions/FN_vtree_multi_function_network.h
@@ -3,6 +3,8 @@
 
 #include "BKE_virtual_node_tree.h"
 
+#include "BLI_multi_map.h"
+
 #include "FN_multi_function_network.h"
 
 namespace FN {
@@ -12,28 +14,107 @@ using BKE::VirtualNodeTree;
 using BKE::VNode;
 using BKE::VOutputSocket;
 using BKE::VSocket;
+using BLI::MultiMap;
+
+#define VTreeMFSocketMap_UNMAPPED UINT_MAX
+#define VTreeMFSocketMap_MULTIMAPPED (UINT_MAX - 1)
+
+class VTreeMFSocketMap {
+ private:
+  /* An input vsocket can be mapped to multiple sockets.
+   * An output vsocket can be mapped to at most one socket.
+   */
+  const VirtualNodeTree *m_vtree;
+  const MFNetwork *m_network;
+  Array<uint> m_single_socket_by_vsocket;
+  MultiMap<uint, uint> m_multiple_inputs_by_vsocket;
+  Array<uint> m_vsocket_by_socket;
+
+ public:
+  VTreeMFSocketMap(const VirtualNodeTree &vtree,
+                   const MFNetwork &network,
+                   Array<uint> single_socket_by_vsocket,
+                   MultiMap<uint, uint> multiple_inputs_by_vsocket,
+                   Array<uint> vsocket_by_socket)
+      : m_vtree(&vtree),
+        m_network(&network),
+        m_single_socket_by_vsocket(std::move(single_socket_by_vsocket)),
+        m_multiple_inputs_by_vsocket(std::move(multiple_inputs_by_vsocket)),
+        m_vsocket_by_socket(std::move(vsocket_by_socket))
+  {
+  }
+
+  bool is_mapped(const VSocket &vsocket) const
+  {
+    return m_single_socket_by_vsocket[vsocket.id()] < VTreeMFSocketMap_MULTIMAPPED;
+  }
+
+  bool is_mapped(const MFSocket &socket) const
+  {
+    return m_vsocket_by_socket[socket.id()] != VTreeMFSocketMap_UNMAPPED;
+  }
+
+  const MFInputSocket &lookup_singly_mapped_input_socket(const VInputSocket &vsocket) const
+  {
+    BLI_assert(this->lookup_socket(vsocket).size() == 1);
+    uint mapped_id = m_single_socket_by_vsocket[vsocket.id()];
+    return m_network->socket_by_id(mapped_id).as_input();
+  }
+
+  Vector<const MFInputSocket *> lookup_socket(const VInputSocket &vsocket) const
+  {
+    uint id = vsocket.id();
+    uint mapped_value = m_single_socket_by_vsocket[id];
+    switch (mapped_value) {
+      case VTreeMFSocketMap_UNMAPPED: {
+        return {};
+      }
+      case VTreeMFSocketMap_MULTIMAPPED: {
+        Vector<const MFInputSocket *> sockets;
+        for (uint mapped_id : m_multiple_inputs_by_vsocket.lookup(id)) {
+          sockets.append(&m_network->socket_by_id(mapped_id).as_input());
+        }
+        return sockets;
+      }
+      default: {
+        uint mapped_id = mapped_value;
+        const MFInputSocket &socket = m_network->socket_by_id(mapped_id).as_input();
+        return {&socket};
+      }
+    }
+  }
+
+  const MFOutputSocket &lookup_socket(const VOutputSocket &vsocket) const
+  {
+    uint mapped_id = m_single_socket_by_vsocket[vsocket.id()];
+    return m_network->socket_by_id(mapped_id).as_output();
+  }
+
+  const VInputSocket &lookup_vsocket(const MFInputSocket &socket) const
+  {
+    uint mapped_id = m_vsocket_by_socket[socket.id()];
+    return m_vtree->socket_by_id(mapped_id).as_input();
+  }
+
+  const VOutputSocket &lookup_vsocket(const MFOutputSocket &socket) const
+  {
+    uint mapped_id = m_vsocket_by_socket[socket.id()];
+    return m_vtree->socket_by_id(mapped_id).as_output();
+  }
+};
 
 class VTreeMFNetwork {
  private:
   const VirtualNodeTree &m_vtree;
   std::unique_ptr<MFNetwork> m_network;
-  Array<const MFSocket *> m_socket_by_vsocket;
-  Array<const VSocket *> m_vsocket_by_socket;
+  VTreeMFSocketMap m_socket_map;
 
  public:
   VTreeMFNetwork(const VirtualNodeTree &vtree,
                  std::unique_ptr<MFNetwork> network,
-                 Array<const MFSocket *> socket_map)
-      : m_vtree(vtree), m_network(std::move(network)), m_socket_by_vsocket(std::move(socket_map))
-  {
-    m_vsocket_by_socket = Array<const VSocket *>(m_socket_by_vsocket.size());
-    for (uint vsocket_id = 0; vsocket_id < m_socket_by_vsocket.size(); vsocket_id++) {
-      const MFSocket *socket = m_socket_by_vsocket[vsocket_id];
-      if (socket != nullptr) {
-        const VSocket &vsocket = m_vtree.socket_by_id(vsocket_id);
-        m_vsocket_by_socket[socket->id()] = &vsocket;
-      }
-    }
+                 VTreeMFSocketMap socket_map)
+      : m_vtree(vtree), m_network(std::move(network)), m_socket_map(std::move(socket_map))
+  {
   }
 
   const VirtualNodeTree &vtree() const
@@ -48,36 +129,38 @@ class VTreeMFNetwork {
 
   bool is_mapped(const VSocket &vsocket) const
   {
-    return m_socket_by_vsocket[vsocket.id()] != nullptr;
+    return m_socket_map.is_mapped(vsocket);
   }
 
   bool is_mapped(const MFSocket &socket) const
   {
-    return m_vsocket_by_socket[socket.id()] != nullptr;
+    return m_socket_map.is_mapped(socket);
   }
 
-  const MFInputSocket &lookup_socket(const VInputSocket &vsocket) const
+  const MFInputSocket &lookup_dummy_socket(const VInputSocket &vsocket) const
   {
-    return m_socket_by_vsocket[vsocket.id()]->as_input();
+    const MFInputSocket &socket = m_socket_map.lookup_singly_mapped_input_socket(vsocket);
+    BLI_assert(socket.node().is_dummy());
+    return socket;
   }
 
   const MFOutputSocket &lookup_socket(const VOutputSocket &vsocket) const
   {
-    return m_socket_by_vsocket[vsocket.id()]->as_output();
+    return m_socket_map.lookup_socket(vsocket);
   }
 
   const VInputSocket &lookup_vsocket(const MFInputSocket &socket) const
   {
-    return m_vsocket_by_socket[socket.id()]->as_input();
+    return m_socket_map.lookup_vsocket(socket);
   }
 
   const VOutputSocket &lookup_vsocket(const MFOutputSocket &socket) const
   {
-    return m_vsocket_by_socket[socket.id()]->as_output();
+    return m_socket_map.lookup_vsocket(socket);
   }
 
-  void lookup_sockets(ArrayRef<const VOutputSocket *> vsockets,
-                      MutableArrayRef<const MFOutputSocket *> r_result) const
+  void lookup_dummy_sockets(ArrayRef<const VOutputSocket *> vsockets,
+                            MutableArrayRef<const MFOutputSocket *> r_result) const
   {
     BLI_assert(vsockets.size() == r_result.size());
     for (uint i = 0; i < vsockets.size(); i++) {
@@ -85,12 +168,12 @@ class VTreeMFNetwork {
     }
   }
 
-  void lookup_sockets(ArrayRef<const VInputSocket *> vsockets,
-                      MutableArrayRef<const MFInputSocket *> r_result) const
+  void lookup_dummy_sockets(ArrayRef<const VInputSocket *> vsockets,
+                            MutableArrayRef<const MFInputSocket *> r_result) const
   {
     BLI_assert(vsockets.size() == r_result.size());
     for (uint i = 0; i < vsockets.size(); i++) {
-      r_result[i] = &this->lookup_socket(*vsockets[i]);
+      r_result[i] = &this->lookup_dummy_socket(*vsockets[i]);
     }
   }
 };
diff --git a/source/blender/functions/intern/multi_function_network.cc b/source/blender/functions/intern/multi_function_network.cc
index 69864f2e8ee..b309d67b781 100644
--- a/source/blender/functions/intern/multi_function_network.cc
+++ b/source/blender/functions/intern/multi_function_network.cc
@@ -180,7 +180,7 @@ static void insert_node_table(std::stringstream &ss, MFBuilderNode &node)
     if (i < inputs.size()) {
       MFBuilderInputSocket &socket = *inputs[i];
       ss << "<td align=\"left\" port=" << get_id(socket) << ">";
-      ss << socket.name();
+      ss << socket.name() << " (" << socket.type() << ")";
       ss << "</td>";
     }
     else {
@@ -190,7 +190,7 @@ static void insert_node_table(std::stringstream &ss, MFBuilderNode &node)
     if (i < outputs.size()) {
       MFBuilderOutputSocket &socket = *outputs[i];
       ss << "<td align=\"right\" port=" << g

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list