Fix #107152: Automate link indexing updates #107172

Open
Iliya Katushenock wants to merge 2 commits from mod_moder/blender:tmp_fix_link_index_update into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
1 changed files with 21 additions and 22 deletions

View File

@ -2539,6 +2539,22 @@ bNode *node_copy(bNodeTree *dst_tree, const bNode &src_node, const int flag, con
return node_copy_with_mapping(dst_tree, src_node, flag, use_unique, socket_map);
}
/* 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,
const bNodeSocket *sock,
const 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;
}
}
} // namespace blender::bke
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
@ -2599,6 +2615,11 @@ bNodeLink *nodeAddLink(
void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
{
if (link->tosock->is_multi_input()) {
blender::bke::adjust_multi_input_indices_after_removed_link(
Review

It seems very easy to introduce O(n^2) complexity. Not sure I have a better solution, but maybe this needs to be at a higher level to make that more obvious or something

It seems very easy to introduce O(n^2) complexity. Not sure I have a better solution, but maybe this needs to be at a higher level to make that more obvious or something

We might check if cache is computed and use it. But not sure if this can be better.

We might check if cache is computed and use it. But not sure if this can be better.
Review

Hmm, that might work.

Big picture, the only reason this multi input index isn't just runtime data or computed on the fly is the currently dragged link has to add to the indices.

Hmm, that might work. Big picture, the only reason this multi input index isn't just runtime data or computed on the fly is the currently dragged link has to add to the indices.
ntree, link->tosock, link->multi_input_socket_index);
}
/* Can be called for links outside a node tree (e.g. clipboard). */
if (ntree) {
BLI_remlink(&ntree->links, link);
@ -2648,22 +2669,6 @@ bool nodeLinkIsSelected(const bNodeLink *link)
return (link->fromnode->flag & NODE_SELECT) || (link->tonode->flag & NODE_SELECT);
}
/* 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,
const bNodeSocket *sock,
const 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 */
@ -2684,10 +2689,6 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
bNodeLink *fromlink = internal_link ? internal_link->fromsock->link : nullptr;
if (fromlink == nullptr) {
if (link->tosock->is_multi_input()) {
blender::bke::adjust_multi_input_indices_after_removed_link(
ntree, link->tosock, link->multi_input_socket_index);
}
nodeRemLink(ntree, link);
continue;
}
@ -2697,8 +2698,6 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link_to_compare, &ntree->links) {
if (link_to_compare->fromsock == fromlink->fromsock &&
link_to_compare->tosock == link->tosock) {
blender::bke::adjust_multi_input_indices_after_removed_link(
ntree, link_to_compare->tosock, link_to_compare->multi_input_socket_index);
duplicate_links_to_remove.append_non_duplicates(link_to_compare);
}
}