Fix #105601: Remove duplicates when inserting links into multi inputs #105631

Merged
Leon Schittek merged 3 commits from lone_noel/blender:fix-105601-multi-input-node-links into blender-v3.5-release 2023-03-11 08:28:07 +01:00
1 changed files with 49 additions and 28 deletions

View File

@ -898,27 +898,31 @@ static void displace_links(bNodeTree *ntree, const bNode *node, bNodeLink *inser
bNodeSocket *replacement_socket = node_find_linkable_socket(*ntree, node, linked_socket); bNodeSocket *replacement_socket = node_find_linkable_socket(*ntree, node, linked_socket);
if (linked_socket->is_input()) { 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; return;
lone_noel marked this conversation as resolved

The nodeRemLink function is already calling BKE_ntree_update_tag_link_removed

The `nodeRemLink` function is already calling `BKE_ntree_update_tag_link_removed`
Review

Good catch! That one slipped through the last review. :)

Good catch! That one slipped through the last review. :)
} }
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { displaced_link->tosock = replacement_socket;
if (link->tosock == linked_socket) {
if (!replacement_socket) { if (replacement_socket->is_multi_input()) {
nodeRemLink(ntree, link); /* Check for duplicate links when linking to multi input sockets. */
BKE_ntree_update_tag_link_removed(ntree); for (bNodeLink *existing_link : replacement_socket->runtime->directly_linked_links) {
if (existing_link->fromsock == displaced_link->fromsock) {
nodeRemLink(ntree, displaced_link);
return; 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) { LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
@ -976,29 +980,46 @@ static void node_remove_existing_links_if_needed(bNodeLinkDrag &nldrag, bNodeTre
{ {
bNodeSocket &linked_socket = *nldrag.hovered_socket; 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); const int link_limit = nodeSocketLinkLimit(&linked_socket);
Set<bNodeLink *> links_to_remove;
if (link_count < link_limit) { ntree.ensure_topology_cache();
return;
}
if (linked_socket.is_input()) { /* Remove duplicate links first. */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { for (const bNodeLink dragged_link : nldrag.links) {
if (link->tosock == &linked_socket) { if (linked_socket.is_input()) {
nodeRemLink(&ntree, link); for (bNodeLink *link : linked_socket.runtime->directly_linked_links) {
return; 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) { for (bNodeLink *link : linked_socket.runtime->directly_linked_links) {
if (link->fromsock == &linked_socket) { const bool link_limit_exceeded = !(link_count < link_limit);
nodeRemLink(&ntree, link); if (link_limit_exceeded) {
return; 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) static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag)