[Bf-blender-cvs] [a6b83617e9d] master: Fix T101705: crash when connecting reroute to multi-input socket

Iliya Katueshenock noreply at git.blender.org
Mon Oct 17 12:01:27 CEST 2022


Commit: a6b83617e9de01c3a4719770f88fc0ad2933e55a
Author: Iliya Katueshenock
Date:   Mon Oct 17 12:00:09 2022 +0200
Branches: master
https://developer.blender.org/rBa6b83617e9de01c3a4719770f88fc0ad2933e55a

Fix T101705: crash when connecting reroute to multi-input socket

Differential Revision: https://developer.blender.org/D16203

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/nodes/intern/geometry_nodes_lazy_function.cc

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b1b4045370c..ecf7a556459 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -792,6 +792,12 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
  */
 void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
 
+/**
+ * A dangling reroute node is a reroute node that does *not* have a "data source", i.e. no
+ * non-reroute node is connected to its input.
+ */
+bool nodeIsDanglingReroute(const struct bNodeTree *ntree, const struct bNode *node);
+
 struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,
                                const struct bNodeSocket *from,
                                const struct bNodeSocket *to);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 654eb06a781..8028f990c42 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -2157,6 +2157,38 @@ void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userd
   }
 }
 
+bool nodeIsDanglingReroute(const bNodeTree *ntree, const bNode *node)
+{
+  ntree->ensure_topology_cache();
+  BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*ntree));
+  BLI_assert(!ntree->has_available_link_cycle());
+
+  const bNode *iter_node = node;
+  if (!iter_node->is_reroute()) {
+    return false;
+  }
+
+  while (true) {
+    const blender::Span<const bNodeLink *> links =
+        iter_node->input_socket(0).directly_linked_links();
+    BLI_assert(links.size() <= 1);
+    if (links.is_empty()) {
+      return true;
+    }
+    const bNodeLink &link = *links[0];
+    if (!link.is_available()) {
+      return false;
+    }
+    if (link.is_muted()) {
+      return false;
+    }
+    iter_node = link.fromnode;
+    if (!iter_node->is_reroute()) {
+      return false;
+    }
+  }
+}
+
 /* ************** Add stuff ********** */
 
 void nodeUniqueName(bNodeTree *ntree, bNode *node)
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
index 6475a16477a..5bf245f1832 100644
--- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
+++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
@@ -158,8 +158,9 @@ class LazyFunctionForMultiInput : public LazyFunction {
     base_type_ = get_socket_cpp_type(socket);
     BLI_assert(base_type_ != nullptr);
     BLI_assert(socket.is_multi_input());
+    const bNodeTree &btree = socket.owner_tree();
     for (const bNodeLink *link : socket.directly_linked_links()) {
-      if (!link->is_muted()) {
+      if (!(link->is_muted() || nodeIsDanglingReroute(&btree, link->fromnode))) {
         inputs_.append({"Input", *base_type_});
       }
     }
@@ -1073,9 +1074,7 @@ struct GeometryNodesLazyFunctionGraphBuilder {
 
   void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket)
   {
-    const bNode &from_bnode = from_bsocket.owner_node();
-    if (this->is_dangling_reroute_input(from_bnode)) {
-      /* Dangling reroutes should not be used as source of values. */
+    if (nodeIsDanglingReroute(&btree_, &from_bsocket.owner_node())) {
       return;
     }
 
@@ -1145,7 +1144,8 @@ struct GeometryNodesLazyFunctionGraphBuilder {
             if (multi_input_link == link) {
               break;
             }
-            if (!multi_input_link->is_muted()) {
+            if (!(multi_input_link->is_muted() ||
+                  nodeIsDanglingReroute(&btree_, multi_input_link->fromnode))) {
               link_index++;
             }
           }
@@ -1174,33 +1174,6 @@ struct GeometryNodesLazyFunctionGraphBuilder {
     }
   }
 
-  bool is_dangling_reroute_input(const bNode &node)
-  {
-    if (!node.is_reroute()) {
-      return false;
-    }
-    const bNode *iter_node = &node;
-    /* It is guaranteed at a higher level that there are no link cycles. */
-    while (true) {
-      const Span<const bNodeLink *> links = iter_node->input_socket(0).directly_linked_links();
-      BLI_assert(links.size() <= 1);
-      if (links.is_empty()) {
-        return true;
-      }
-      const bNodeLink &link = *links[0];
-      if (!link.is_available()) {
-        return false;
-      }
-      if (link.is_muted()) {
-        return false;
-      }
-      iter_node = link.fromnode;
-      if (!iter_node->is_reroute()) {
-        return false;
-      }
-    }
-  }
-
   lf::OutputSocket *insert_type_conversion_if_necessary(
       lf::OutputSocket &from_socket,
       const CPPType &to_type,



More information about the Bf-blender-cvs mailing list