Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIliya Katueshenock <Moder>2022-10-17 13:00:09 +0300
committerJacques Lucke <jacques@blender.org>2022-10-17 13:00:09 +0300
commita6b83617e9de01c3a4719770f88fc0ad2933e55a (patch)
tree9f05c8ba6ba5e98677f3a26fb29ff8cce668658c
parente5425b566d0f25f60b5895c4025c183fd67c7d9c (diff)
Fix T101705: crash when connecting reroute to multi-input socket
Differential Revision: https://developer.blender.org/D16203
-rw-r--r--source/blender/blenkernel/BKE_node.h6
-rw-r--r--source/blender/blenkernel/intern/node.cc32
-rw-r--r--source/blender/nodes/intern/geometry_nodes_lazy_function.cc37
3 files changed, 43 insertions, 32 deletions
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,