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
This commit is contained in:
Wannes Malfait
2021-07-28 15:43:24 +02:00
committed by Jacques Lucke
parent f9308a585e
commit 31fcb934a4

View File

@@ -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);