Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_node/node_relationships.cc
| Show First 20 Lines • Show All 2,418 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| } // namespace blender::ed::space_node | } // namespace blender::ed::space_node | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Note Link Insert | /** \name Note Link Insert | ||||
| * \{ */ | * \{ */ | ||||
| void ED_node_link_insert(Main *bmain, ScrArea *area) | void ED_node_link_insert(Main *bmain, ScrArea *area) | ||||
HooglyBoogly: It's weird that this function has such high-level parameters, maybe that can be changed in the… | |||||
| { | { | ||||
| using namespace blender::ed::space_node; | using namespace blender::ed::space_node; | ||||
| bNode *select; | bNode *node_to_insert; | ||||
| SpaceNode *snode; | SpaceNode *snode; | ||||
| if (!ed_node_link_conditions(area, true, &snode, &select)) { | if (!ed_node_link_conditions(area, true, &snode, &node_to_insert)) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* get the link */ | /* Find link to insert on. */ | ||||
| bNodeLink *link; | bNodeTree &ntree = *snode->edittree; | ||||
| for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) { | bNodeLink *old_link = nullptr; | ||||
| LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { | |||||
| if (link->flag & NODE_LINKFLAG_HILITE) { | if (link->flag & NODE_LINKFLAG_HILITE) { | ||||
| old_link = link; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (old_link == nullptr) { | |||||
| return; | |||||
| } | |||||
| if (link) { | old_link->flag &= ~NODE_LINKFLAG_HILITE; | ||||
| 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); | bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN); | ||||
| bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT); | |||||
| /* Copy the socket index for the new link, and reset it for the old link. This way the | /* Ignore main sockets when the types don't match. */ | ||||
| * relative order of links is preserved, and the links get drawn in the right place. */ | if (best_input != nullptr && | ||||
| new_link->multi_input_socket_index = link->multi_input_socket_index; | !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type), | ||||
| link->multi_input_socket_index = 0; | 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 */ | /* Set up insert offset data, it needs stuff from here. */ | ||||
| if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { | if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { | ||||
| NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__); | NodeInsertOfsData *iofsd = MEM_cnew<NodeInsertOfsData>(__func__); | ||||
| iofsd->insert = select; | iofsd->insert = node_to_insert; | ||||
| iofsd->prev = link->fromnode; | iofsd->prev = from_node; | ||||
| iofsd->next = node; | iofsd->next = to_node; | ||||
| snode->runtime->iofsd = iofsd; | snode->runtime->iofsd = iofsd; | ||||
| } | } | ||||
| ED_node_tree_propagate_change(nullptr, bmain, snode->edittree); | ED_node_tree_propagate_change(nullptr, bmain, snode->edittree); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
It's weird that this function has such high-level parameters, maybe that can be changed in the future.