[Bf-blender-cvs] [8e9323cafa6] functions: experiment with different ways to group unlinked inputs

Jacques Lucke noreply at git.blender.org
Fri Aug 2 19:15:27 CEST 2019


Commit: 8e9323cafa6237e660165b47acd2bde7966021fe
Author: Jacques Lucke
Date:   Fri Aug 2 19:12:13 2019 +0200
Branches: functions
https://developer.blender.org/rB8e9323cafa6237e660165b47acd2bde7966021fe

experiment with different ways to group unlinked inputs

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

M	source/blender/functions/CMakeLists.txt
M	source/blender/functions/FN_data_flow_nodes.hpp
M	source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
M	source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
A	source/blender/functions/frontends/data_flow_nodes/unlinked_input_groupers.cpp
A	source/blender/functions/frontends/data_flow_nodes/unlinked_input_groupers.hpp

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

diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index 6953941126f..634bc0ccc1f 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -149,6 +149,8 @@ set(SRC
   frontends/data_flow_nodes/vtree_data_graph.cpp
   frontends/data_flow_nodes/input_inserters.hpp
   frontends/data_flow_nodes/input_inserters.cpp
+  frontends/data_flow_nodes/unlinked_input_groupers.hpp
+  frontends/data_flow_nodes/unlinked_input_groupers.cpp
   frontends/data_flow_nodes/mappings.hpp
   frontends/data_flow_nodes/mappings.cpp
   frontends/data_flow_nodes/mappings/registry.hpp
diff --git a/source/blender/functions/FN_data_flow_nodes.hpp b/source/blender/functions/FN_data_flow_nodes.hpp
index 3514ffe19de..48867c5a023 100644
--- a/source/blender/functions/FN_data_flow_nodes.hpp
+++ b/source/blender/functions/FN_data_flow_nodes.hpp
@@ -5,3 +5,4 @@
 #include "frontends/data_flow_nodes/graph_generation.hpp"
 #include "frontends/data_flow_nodes/vtree_data_graph.hpp"
 #include "frontends/data_flow_nodes/input_inserters.hpp"
+#include "frontends/data_flow_nodes/unlinked_input_groupers.hpp"
diff --git a/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp b/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
index d5854c27898..e88e2a06e8b 100644
--- a/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
@@ -48,32 +48,6 @@ static bool insert_links(VTreeDataGraphBuilder &builder)
   return true;
 }
 
-class SeparateNodeInputs : public UnlinkedInputsHandler {
- public:
-  void handle(VTreeDataGraphBuilder &builder, InputInserter &inserter) override
-{
-  for (VirtualNode *vnode : builder.vtree().nodes()) {
-    Vector<VirtualSocket *> vsockets;
-    Vector<BuilderInputSocket *> sockets;
-
-    for (VirtualSocket *vsocket : vnode->inputs()) {
-      if (builder.is_data_socket(vsocket)) {
-        BuilderInputSocket *socket = builder.lookup_input_socket(vsocket);
-        if (socket->origin() == nullptr) {
-          vsockets.append(vsocket);
-          sockets.append(socket);
-        }
-      }
-    }
-
-    if (vsockets.size() > 0) {
-      Vector<BuilderOutputSocket *> new_origins(vsockets.size());
-        inserter.insert(builder, vsockets, new_origins);
-      builder.insert_links(new_origins, sockets);
-    }
-  }
-}
-
 ValueOrError<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree)
 {
   VTreeDataGraphBuilder builder(vtree);
@@ -87,7 +61,8 @@ ValueOrError<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree)
   }
 
   ConstantInputsHandler input_inserter;
-  insert_unlinked_inputs(builder, input_inserter);
+  GroupByNodeUsage unlinked_input_handler;
+  unlinked_input_handler.handle(builder, input_inserter);
 
   return builder.build();
 }
diff --git a/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp b/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
index 6f421d7c105..e5a8b565259 100644
--- a/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
+++ b/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
@@ -12,6 +12,11 @@ class InputInserter {
                       ArrayRef<BuilderOutputSocket *> r_new_origins) = 0;
 };
 
+class UnlinkedInputGrouper {
+ public:
+  virtual void handle(VTreeDataGraphBuilder &builder, InputInserter &inserter) = 0;
+};
+
 ValueOrError<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree);
 
 }  // namespace DataFlowNodes
diff --git a/source/blender/functions/frontends/data_flow_nodes/unlinked_input_groupers.cpp b/source/blender/functions/frontends/data_flow_nodes/unlinked_input_groupers.cpp
new file mode 100644
index 00000000000..fc43c21abd6
--- /dev/null
+++ b/source/blender/functions/frontends/data_flow_nodes/unlinked_input_groupers.cpp
@@ -0,0 +1,170 @@
+#include "unlinked_input_groupers.hpp"
+
+namespace FN {
+namespace DataFlowNodes {
+
+void SeparateNodeInputs::handle(VTreeDataGraphBuilder &builder, InputInserter &inserter)
+{
+  for (VirtualNode *vnode : builder.vtree().nodes()) {
+    Vector<VirtualSocket *> vsockets;
+    Vector<BuilderInputSocket *> sockets;
+
+    for (VirtualSocket *vsocket : vnode->inputs()) {
+      if (builder.is_data_socket(vsocket)) {
+        BuilderInputSocket *socket = builder.lookup_input_socket(vsocket);
+        if (socket->origin() == nullptr) {
+          vsockets.append(vsocket);
+          sockets.append(socket);
+        }
+      }
+    }
+
+    if (vsockets.size() > 0) {
+      Vector<BuilderOutputSocket *> new_origins(vsockets.size());
+      inserter.insert(builder, vsockets, new_origins);
+      builder.insert_links(new_origins, sockets);
+    }
+  }
+}
+
+void SeparateSocketInputs::handle(VTreeDataGraphBuilder &builder, InputInserter &inserter)
+{
+  for (VirtualNode *vnode : builder.vtree().nodes()) {
+    for (VirtualSocket *vsocket : vnode->inputs()) {
+      if (builder.is_data_socket(vsocket)) {
+        BuilderInputSocket *socket = builder.lookup_input_socket(vsocket);
+        if (socket->origin() == nullptr) {
+          std::array<BuilderOutputSocket *, 1> new_origin;
+          inserter.insert(builder, {vsocket}, new_origin);
+          BLI_assert(new_origin[0]);
+          builder.insert_link(new_origin[0], socket);
+        }
+      }
+    }
+  }
+}
+
+void AllInOneSocketInputs::handle(VTreeDataGraphBuilder &builder, InputInserter &inserter)
+{
+  Vector<VirtualSocket *> unlinked_input_vsockets;
+  Vector<BuilderInputSocket *> unlinked_input_sockets;
+  for (VirtualNode *vnode : builder.vtree().nodes()) {
+    for (VirtualSocket *vsocket : vnode->inputs()) {
+      if (builder.is_data_socket(vsocket)) {
+        BuilderInputSocket *socket = builder.lookup_input_socket(vsocket);
+        if (socket->origin() == nullptr) {
+          unlinked_input_vsockets.append(vsocket);
+          unlinked_input_sockets.append(socket);
+        }
+      }
+    }
+  }
+
+  Vector<BuilderOutputSocket *> new_origins(unlinked_input_vsockets.size());
+  inserter.insert(builder, unlinked_input_vsockets, new_origins);
+  builder.insert_links(new_origins, unlinked_input_sockets);
+}
+
+static void update_hash_of_used_vsockets(VTreeDataGraphBuilder &builder,
+                                         VirtualSocket *vsocket,
+                                         uint random,
+                                         ArrayRef<uint> hash_per_vsocket,
+                                         ArrayRef<bool> was_updated_per_vsocket,
+                                         Vector<uint> &updated_vsockets)
+{
+  hash_per_vsocket[vsocket->id()] ^= random;
+  was_updated_per_vsocket[vsocket->id()] = true;
+  updated_vsockets.append(vsocket->id());
+
+  if (vsocket->is_input()) {
+    for (VirtualSocket *origin : vsocket->links()) {
+      if (builder.is_data_socket(origin) && !was_updated_per_vsocket[origin->id()]) {
+        update_hash_of_used_vsockets(
+            builder, origin, random, hash_per_vsocket, was_updated_per_vsocket, updated_vsockets);
+      }
+    }
+  }
+  else {
+    for (VirtualSocket *input : vsocket->vnode()->inputs()) {
+      if (builder.is_data_socket(input) && !was_updated_per_vsocket[input->id()]) {
+        update_hash_of_used_vsockets(
+            builder, input, random, hash_per_vsocket, was_updated_per_vsocket, updated_vsockets);
+      }
+    }
+  }
+}
+
+static void insert_input_node_for_sockets_with_same_hash(VTreeDataGraphBuilder &builder,
+                                                         ArrayRef<uint> hash_per_vsocket,
+                                                         InputInserter &inserter)
+{
+  MultiMap<uint, VirtualSocket *> unlinked_inputs_by_hash;
+  for (VirtualNode *vnode : builder.vtree().nodes()) {
+    for (VirtualSocket *vsocket : vnode->inputs()) {
+      if (builder.is_data_socket(vsocket)) {
+        BuilderInputSocket *socket = builder.lookup_input_socket(vsocket);
+        if (socket->origin() == nullptr) {
+          unlinked_inputs_by_hash.add(hash_per_vsocket[vsocket->id()], vsocket);
+        }
+      }
+    }
+  }
+
+  /* TODO(jacques): replace with values iterator when it exists. */
+  for (uint key : unlinked_inputs_by_hash.keys()) {
+    ArrayRef<VirtualSocket *> unlinked_vsockets = unlinked_inputs_by_hash.lookup(key);
+    BLI_assert(unlinked_vsockets.size() > 0);
+    Vector<BuilderOutputSocket *> new_origins(unlinked_vsockets.size());
+    inserter.insert(builder, unlinked_vsockets, new_origins);
+
+    for (uint i = 0; i < unlinked_vsockets.size(); i++) {
+      builder.insert_link(new_origins[i], builder.lookup_input_socket(unlinked_vsockets[i]));
+    }
+  }
+}
+
+void GroupByNodeUsage::handle(VTreeDataGraphBuilder &builder, InputInserter &inserter)
+{
+  uint socket_count = builder.vtree().socket_count();
+
+  Vector<uint> hash_per_vsocket(socket_count, 0);
+  Vector<bool> was_updated_per_vsocket(socket_count, false);
+  Vector<uint> updated_vsockets;
+
+  for (BuilderNode *node : builder.placeholder_nodes()) {
+    VNodePlaceholderBody &placeholder_info = node->function()->body<VNodePlaceholderBody>();
+    uint random = rand();
+    for (VirtualSocket *vsocket : placeholder_info.inputs()) {
+      update_hash_of_used_vsockets(
+          builder, vsocket, random, hash_per_vsocket, was_updated_per_vsocket, updated_vsockets);
+    }
+    was_updated_per_vsocket.fill_indices(updated_vsockets, false);
+    updated_vsockets.clear();
+  }
+
+  insert_input_node_for_sockets_with_same_hash(builder, hash_per_vsocket, inserter);
+}
+
+void GroupBySocketUsage::handle(VTreeDataGraphBuilder &builder, InputInserter &inserter)
+{
+  uint socket_count = builder.vtree().socket_count();
+
+  Vector<uint> hash_per_vsocket(socket_count, 0);
+  Vector<bool> was_updated_per_vsocket(socket_count, false);
+  Vector<uint> updated_vsockets;
+
+  for (BuilderNode *node : builder.placeholder_nodes()) {
+    VNodePlaceholderBody &placeholder_info = node->function()->body<VNodePlaceholderBody>();
+    for (VirtualSocket *vsocket : placeholder_info.inputs()) {
+      update_hash_of_used_vsockets(
+          builder, vsocket, rand(), hash_per_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list