From 31fcb934a4c13563cec9afd41c5a88d50fc845d1 Mon Sep 17 00:00:00 2001 From: Wannes Malfait Date: Wed, 28 Jul 2021 15:43:24 +0200 Subject: Fix T89415: update multi input indices after deleting a node When deleting a node, links attached to that node are deleted, but if one of those links was connected to a multi input socket, the indices of the other links connected to it were not updated. This adds updates both in the case of a normal delete as well as after a delete with reconnect. Differential Revision: https://developer.blender.org/D11716 --- source/blender/blenkernel/intern/node.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index e9608457896..9888e23a7bd 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2504,6 +2504,22 @@ bool nodeLinkIsHidden(const bNodeLink *link) return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock); } +/* Adjust the indices of links connected to the given multi input socket after deleting the link at + * `deleted_index`. This function also works if the link has not yet been deleted. */ +static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree, + bNodeSocket *sock, + int deleted_index) +{ + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { + /* We only need to adjust those with a greater index, because the others will have the same + * index. */ + if (link->tosock != sock || link->multi_input_socket_index <= deleted_index) { + continue; + } + link->multi_input_socket_index -= 1; + } +} + void nodeInternalRelink(bNodeTree *ntree, bNode *node) { /* store link pointers in output sockets, for efficient lookup */ @@ -2537,10 +2553,18 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node) ntree->update |= NTREE_UPDATE_LINKS; } else { + if (link->tosock->flag & SOCK_MULTI_INPUT) { + adjust_multi_input_indices_after_removed_link( + ntree, link->tosock, link->multi_input_socket_index); + } nodeRemLink(ntree, link); } } else { + if (link->tosock->flag & SOCK_MULTI_INPUT) { + adjust_multi_input_indices_after_removed_link( + ntree, link->tosock, link->multi_input_socket_index); + }; nodeRemLink(ntree, link); } } @@ -2991,6 +3015,11 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node) } if (lb) { + /* Only bother adjusting if the socket is not on the node we're deleting. */ + if (link->tonode != node && link->tosock->flag & SOCK_MULTI_INPUT) { + adjust_multi_input_indices_after_removed_link( + ntree, link->tosock, link->multi_input_socket_index); + } LISTBASE_FOREACH (bNodeSocket *, sock, lb) { if (link->fromsock == sock || link->tosock == sock) { nodeRemLink(ntree, link); -- cgit v1.2.3