Fix T91840: do not create invalid links when inserting a node

Differential Revision: https://developer.blender.org/D14050
This commit is contained in:
Jacques Lucke 2022-02-09 11:19:11 +01:00
parent de71860555
commit 06ac599261
Notes: blender-bot 2023-02-14 03:34:17 +01:00
Referenced by commit 37d2c774c1, Fix T96073: Don't remove links when inserting reroute nodes
Referenced by issue #91840, Don't create invalid links when inserting a node on a link
1 changed files with 58 additions and 39 deletions

View File

@ -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 (link) {
bNodeSocket *best_input = get_main_socket(*snode->edittree, *select, SOCK_IN);
bNodeSocket *best_output = get_main_socket(*snode->edittree, *select, SOCK_OUT);
if (best_input && best_output) {
bNode *node = link->tonode;
bNodeSocket *sockto = link->tosock;
link->tonode = select;
link->tosock = best_input;
node_remove_extra_links(*snode, *link);
link->flag &= ~NODE_LINKFLAG_HILITE;
bNodeLink *new_link = nodeAddLink(snode->edittree, select, best_output, node, sockto);
/* 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;
/* set up insert offset data, it needs stuff from here */
if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__);
iofsd->insert = select;
iofsd->prev = link->fromnode;
iofsd->next = node;
snode->runtime->iofsd = iofsd;
}
ED_node_tree_propagate_change(nullptr, bmain, snode->edittree);
}
if (old_link == nullptr) {
return;
}
old_link->flag &= ~NODE_LINKFLAG_HILITE;
bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN);
bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT);
/* Ignore main sockets when the types don't match. */
if (best_input != nullptr &&
!ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type),
static_cast<eNodeSocketDatatype>(best_input->type))) {
best_input = nullptr;
}
if (best_output != nullptr &&
!ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(best_output->type),
static_cast<eNodeSocketDatatype>(old_link->tosock->type))) {
best_output = nullptr;
}
bNode *from_node = old_link->fromnode;
bNodeSocket *from_socket = old_link->fromsock;
bNode *to_node = old_link->tonode;
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);
}
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);
}
/* Set up insert offset data, it needs stuff from here. */
if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__);
iofsd->insert = node_to_insert;
iofsd->prev = from_node;
iofsd->next = to_node;
snode->runtime->iofsd = iofsd;
}
ED_node_tree_propagate_change(nullptr, bmain, snode->edittree);
}
/** \} */