From 29a5d43d77e505207902b2eb580f13925763f711 Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Fri, 10 Mar 2023 11:24:37 +0100 Subject: [PATCH 1/2] Fix #105601: Remove duplicates when inserting links into multi inputs Fix a regression that allowed to create several links between an output socket and a multi input socket. This regression was caused by commit 89aae4ac82. --- .../editors/space_node/node_relationships.cc | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 97ab6b7786c..c156fa82a2f 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -918,6 +918,8 @@ static void displace_links(bNodeTree *ntree, const bNode *node, bNodeLink *inser BKE_ntree_update_tag_link_changed(ntree); return; } + const int multi_input_index = node_socket_count_links(*ntree, *replacement_socket) - 1; + displaced_link->multi_input_socket_index = multi_input_index; } } @@ -976,29 +978,46 @@ static void node_remove_existing_links_if_needed(bNodeLinkDrag &nldrag, bNodeTre { bNodeSocket &linked_socket = *nldrag.hovered_socket; - const int link_count = node_socket_count_links(ntree, linked_socket); + int link_count = node_socket_count_links(ntree, linked_socket); const int link_limit = nodeSocketLinkLimit(&linked_socket); + Set links_to_remove; - if (link_count < link_limit) { - return; - } + ntree.ensure_topology_cache(); - if (linked_socket.is_input()) { - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { - if (link->tosock == &linked_socket) { - nodeRemLink(&ntree, link); - return; + /* Remove duplicate links first. */ + for (const bNodeLink dragged_link : nldrag.links) { + if (linked_socket.is_input()) { + for (bNodeLink *link : linked_socket.runtime->directly_linked_links) { + const bool duplicate_link = link->fromsock == dragged_link.fromsock; + if (duplicate_link) { + links_to_remove.add(link); + link_count--; + } + } + } + else { + for (bNodeLink *link : linked_socket.runtime->directly_linked_links) { + const bool duplicate_link = link->tosock == dragged_link.tosock; + if (duplicate_link) { + links_to_remove.add(link); + link_count--; + } } } } - else { - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { - if (link->fromsock == &linked_socket) { - nodeRemLink(&ntree, link); - return; + + for (bNodeLink *link : linked_socket.runtime->directly_linked_links) { + const bool link_limit_exceeded = !(link_count < link_limit); + if (link_limit_exceeded) { + if (links_to_remove.add(link)) { + link_count--; } } } + + for (bNodeLink *link : links_to_remove) { + nodeRemLink(&ntree, link); + } } static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) -- 2.30.2 From 56dc1bbdc1201dc855b1f22bbc59143c5105e5ee Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Fri, 10 Mar 2023 11:31:30 +0100 Subject: [PATCH 2/2] Fix: Node Editor: Remove duplicate links when swapping links Remove duplicate links when reconnecting displaced links into multi input socket nodes. This edge case wasn't handled when the feature was introduced in commit 89aae4ac82. --- .../editors/space_node/node_relationships.cc | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index c156fa82a2f..6cd0705a402 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -898,29 +898,31 @@ static void displace_links(bNodeTree *ntree, const bNode *node, bNodeLink *inser bNodeSocket *replacement_socket = node_find_linkable_socket(*ntree, node, linked_socket); if (linked_socket->is_input()) { - if (linked_socket->limit + 1 < nodeSocketLinkLimit(linked_socket)) { + BLI_assert(!linked_socket->is_multi_input()); + ntree->ensure_topology_cache(); + bNodeLink *displaced_link = linked_socket->runtime->directly_linked_links.first(); + + if (!replacement_socket) { + nodeRemLink(ntree, displaced_link); return; } - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { - if (link->tosock == linked_socket) { - if (!replacement_socket) { - nodeRemLink(ntree, link); - BKE_ntree_update_tag_link_removed(ntree); + displaced_link->tosock = replacement_socket; + + if (replacement_socket->is_multi_input()) { + /* Check for duplicate links when linking to multi input sockets. */ + for (bNodeLink *existing_link : replacement_socket->runtime->directly_linked_links) { + if (existing_link->fromsock == displaced_link->fromsock) { + nodeRemLink(ntree, displaced_link); return; } - - link->tosock = replacement_socket; - if (replacement_socket->is_multi_input()) { - link->multi_input_socket_index = node_socket_count_links(*ntree, *replacement_socket) - - 1; - } - BKE_ntree_update_tag_link_changed(ntree); - return; } const int multi_input_index = node_socket_count_links(*ntree, *replacement_socket) - 1; displaced_link->multi_input_socket_index = multi_input_index; } + + BKE_ntree_update_tag_link_changed(ntree); + return; } LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { -- 2.30.2