From fa66b52d0ae6f74386809cae2f7f7fd9fdfc4ca6 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Thu, 25 Apr 2024 10:48:06 +0200 Subject: [PATCH] Nodes: tooltips for value of dangling reroute node Dangling reroute nodes have no source of value. For that reason, such reroute nodes are ignored by geometry nodes. Other node systems still have to handle this case more explicitly. To users this behavior generally makes sense, but it's also not completely obvious. Now, there is a new tooltip when hovering over dangling reroute nodes that mentions how those work. Pull Request: https://projects.blender.org/blender/blender/pulls/120851 --- .../blender/editors/space_node/node_draw.cc | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 0f49cddcdc1..35507d363a7 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -1589,7 +1589,11 @@ static void create_inspection_string_for_default_socket_value(const bNodeSocket if (!socket.is_input()) { return; } - if (socket.is_directly_linked()) { + if (socket.is_multi_input()) { + return; + } + const Span connected_sockets = socket.directly_linked_sockets(); + if (!connected_sockets.is_empty() && !connected_sockets[0]->owner_node().is_dangling_reroute()) { return; } if (const nodes::SocketDeclaration *socket_decl = socket.runtime->declaration) { @@ -1769,6 +1773,65 @@ static std::optional create_default_value_inspection_string(const b return str; } +static const bNodeSocket *target_for_reroute(const bNodeSocket &reroute_output) +{ + const bNodeSocket *output = &reroute_output; + Set visited_nodes; + visited_nodes.add(&reroute_output.owner_node()); + while (true) { + const Span linked_sockets = output->directly_linked_sockets(); + if (linked_sockets.size() != 1) { + return nullptr; + } + const bNode &target_node = linked_sockets[0]->owner_node(); + if (!visited_nodes.add(&target_node)) { + return nullptr; + } + if (!target_node.is_dangling_reroute()) { + return linked_sockets[0]; + } + output = target_node.output_sockets()[0]; + } +} + +static std::optional create_dangling_reroute_inspection_string( + const bNodeTree &ntree, const bNodeSocket &socket) +{ + if (ntree.type != NTREE_GEOMETRY) { + return std::nullopt; + } + + const bNode &node = socket.owner_node(); + if (!node.is_dangling_reroute()) { + return std::nullopt; + } + + const bNodeSocket &output_socket = *node.output_sockets()[0]; + const bNodeSocket *target_socket = target_for_reroute(output_socket); + + if (target_socket == nullptr) { + if (!output_socket.directly_linked_sockets().is_empty()) { + return TIP_("Dangling reroute is ignored by all targets"); + } + return std::nullopt; + } + + if (target_socket->is_multi_input()) { + return TIP_("Dangling reroute branch is ignored by multi input socket"); + } + + std::stringstream ss; + create_inspection_string_for_default_socket_value(*target_socket, ss); + if (ss.str().empty()) { + return TIP_("Dangling reroute is ignored"); + } + ss << ".\n\n"; + ss << TIP_("Dangling reroute is ignored, default value of target socket is used"); + return ss.str(); + + return std::nullopt; +} + static std::string node_socket_get_tooltip(const SpaceNode *snode, const bNodeTree &ntree, const bNodeSocket &socket) @@ -1791,6 +1854,11 @@ static std::string node_socket_get_tooltip(const SpaceNode *snode, if (std::optional info = create_log_inspection_string(geo_tree_log, socket)) { inspection_strings.append(std::move(*info)); } + else if (std::optional info = create_dangling_reroute_inspection_string(ntree, + socket)) + { + inspection_strings.append(std::move(*info)); + } else if (std::optional info = create_default_value_inspection_string(socket)) { inspection_strings.append(std::move(*info)); }