From 06ac5992618a75c453e495e06af7c5faf30499a7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Feb 2022 11:19:11 +0100 Subject: Fix T91840: do not create invalid links when inserting a node Differential Revision: https://developer.blender.org/D14050 --- .../editors/space_node/node_relationships.cc | 79 ++++++++++++++-------- 1 file changed, 49 insertions(+), 30 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index bc79925b51d..2a197e93f42 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -2428,54 +2428,73 @@ void ED_node_link_insert(Main *bmain, ScrArea *area) { using namespace blender::ed::space_node; - bNode *select; + bNode *node_to_insert; SpaceNode *snode; - if (!ed_node_link_conditions(area, true, &snode, &select)) { + if (!ed_node_link_conditions(area, true, &snode, &node_to_insert)) { return; } - /* get the link */ - bNodeLink *link; - for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) { + /* Find link to insert on. */ + bNodeTree &ntree = *snode->edittree; + bNodeLink *old_link = nullptr; + LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { if (link->flag & NODE_LINKFLAG_HILITE) { + old_link = link; break; } } + if (old_link == nullptr) { + return; + } - if (link) { - bNodeSocket *best_input = get_main_socket(*snode->edittree, *select, SOCK_IN); - bNodeSocket *best_output = get_main_socket(*snode->edittree, *select, SOCK_OUT); + old_link->flag &= ~NODE_LINKFLAG_HILITE; - if (best_input && best_output) { - bNode *node = link->tonode; - bNodeSocket *sockto = link->tosock; + bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN); + bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT); - link->tonode = select; - link->tosock = best_input; - node_remove_extra_links(*snode, *link); - link->flag &= ~NODE_LINKFLAG_HILITE; + /* Ignore main sockets when the types don't match. */ + if (best_input != nullptr && + !ntree.typeinfo->validate_link(static_cast(old_link->fromsock->type), + static_cast(best_input->type))) { + best_input = nullptr; + } + if (best_output != nullptr && + !ntree.typeinfo->validate_link(static_cast(best_output->type), + static_cast(old_link->tosock->type))) { + best_output = nullptr; + } - bNodeLink *new_link = nodeAddLink(snode->edittree, select, best_output, node, sockto); + bNode *from_node = old_link->fromnode; + bNodeSocket *from_socket = old_link->fromsock; + bNode *to_node = old_link->tonode; - /* Copy the socket index for the new link, and reset it for the old link. This way the - * relative order of links is preserved, and the links get drawn in the right place. */ - new_link->multi_input_socket_index = link->multi_input_socket_index; - link->multi_input_socket_index = 0; + if (best_output != nullptr) { + /* Relink the "start" of the existing link to the newly inserted node. */ + old_link->fromnode = node_to_insert; + old_link->fromsock = best_output; + BKE_ntree_update_tag_link_changed(&ntree); + } + else { + nodeRemLink(&ntree, old_link); + } - /* set up insert offset data, it needs stuff from here */ - if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { - NodeInsertOfsData *iofsd = MEM_cnew(__func__); + if (best_input != nullptr) { + /* Add a new link that connects the node on the left to the newly inserted node. */ + nodeAddLink(&ntree, from_node, from_socket, node_to_insert, best_input); + } - iofsd->insert = select; - iofsd->prev = link->fromnode; - iofsd->next = node; + /* Set up insert offset data, it needs stuff from here. */ + if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { + NodeInsertOfsData *iofsd = MEM_cnew(__func__); - snode->runtime->iofsd = iofsd; - } + iofsd->insert = node_to_insert; + iofsd->prev = from_node; + iofsd->next = to_node; - ED_node_tree_propagate_change(nullptr, bmain, snode->edittree); - } + snode->runtime->iofsd = iofsd; } + + ED_node_tree_propagate_change(nullptr, bmain, snode->edittree); } /** \} */ -- cgit v1.2.3