Fix T91840: do not create invalid links when inserting a node
Differential Revision: https://developer.blender.org/D14050
This commit is contained in:
parent
de71860555
commit
06ac599261
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
Loading…
Reference in New Issue
Block a user