diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index afebe5c63ec..40822daeb6d 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -644,6 +644,16 @@ inline bool bNode::is_group_output() const return this->type == NODE_GROUP_OUTPUT; } +inline bool bNode::is_selected() const +{ + return this->flag & NODE_SELECT; +} + +inline bool bNode::is_active() const +{ + return this->flag & NODE_ACTIVE; +} + inline blender::Span bNode::internal_links() const { return this->runtime->internal_links; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index e6ebf4b44cd..8fd1e2896ed 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2750,7 +2750,7 @@ namespace blender::bke { bool nodeLinkIsSelected(const bNodeLink *link) { - return (link->fromnode->flag & NODE_SELECT) || (link->tonode->flag & NODE_SELECT); + return (link->fromnode->is_selected()) || (link->tonode->is_selected()); } /* Adjust the indices of links connected to the given multi input socket after deleting the link at @@ -3811,8 +3811,21 @@ bNode *nodeGetActive(bNodeTree *ntree) return nullptr; } + BLI_assert([ntree]() -> bool { + int active_node_count = 0; + for (bNode *node : ntree->all_nodes()) { + if (node->is_active()) { + active_node_count++; + } + } + if (ELEM(active_node_count, 0, 1)) { + return true; + } + return false; + }()); + for (bNode *node : ntree->all_nodes()) { - if (node->flag & NODE_ACTIVE) { + if (node->is_active()) { return node; } } diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc index 5ed91cd4fbe..624fcaa8f55 100644 --- a/source/blender/editors/space_node/clipboard.cc +++ b/source/blender/editors/space_node/clipboard.cc @@ -42,6 +42,7 @@ struct NodeClipboardItem { }; struct NodeClipboard { + bNode *active_node; Vector nodes; Vector links; @@ -52,6 +53,7 @@ struct NodeClipboard { } this->nodes.clear_and_shrink(); this->links.clear_and_shrink(); + this->active_node = nullptr; } /** @@ -130,11 +132,15 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/) Map socket_map; for (const bNode *node : tree.all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { clipboard.add_node(*node, node_map, socket_map); } } + if (bNode *active_node = nodeGetActive(&tree)) { + clipboard.active_node = node_map.lookup_default(active_node, nullptr); + } + for (bNode *new_node : node_map.values()) { /* Parent pointer must be redirected to new node or detached if parent is not copied. */ if (new_node->parent) { @@ -151,7 +157,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/) LISTBASE_FOREACH (bNodeLink *, link, &tree.links) { BLI_assert(link->tonode); BLI_assert(link->fromnode); - if (link->tonode->flag & NODE_SELECT && link->fromnode->flag & NODE_SELECT) { + if (link->tonode->is_selected() && link->fromnode->is_selected()) { bNodeLink new_link{}; new_link.flag = link->flag; new_link.tonode = node_map.lookup(link->tonode); @@ -320,6 +326,11 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) remap_pairing(tree, node_map); + if (clipboard.active_node != nullptr) { + bNode *new_active_node = node_map.lookup(clipboard.active_node); + nodeSetActive(&tree, new_active_node); + } + tree.ensure_topology_cache(); for (bNode *new_node : node_map.values()) { /* Update multi input socket indices in case all connected nodes weren't copied. */ diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index ede3fee7411..826f837a480 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1575,7 +1575,7 @@ void draw_nodespace_back_pix(const bContext &C, bNode *node = (bNode *)snode.edittree->nodes.first; rctf *viewer_border = &snode.nodetree->viewer_border; while (node) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { if (node->typeinfo->draw_backdrop) { node->typeinfo->draw_backdrop(&snode, ibuf, node, x, y); } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 963972c60af..987031b361b 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -215,8 +215,8 @@ static bool compare_node_depth(const bNode *a, const bNode *b) { /* These tell if either the node or any of the parent nodes is selected. * A selected parent means an unselected node is also in foreground! */ - bool a_select = (a->flag & NODE_SELECT) != 0, b_select = (b->flag & NODE_SELECT) != 0; - bool a_active = (a->flag & NODE_ACTIVE) != 0, b_active = (b->flag & NODE_ACTIVE) != 0; + bool a_select = a->is_selected(), b_select = b->is_selected(); + bool a_active = a->is_active(), b_active = b->is_active(); /* If one is an ancestor of the other. */ /* XXX there might be a better sorting algorithm for stable topological sort, @@ -227,10 +227,10 @@ static bool compare_node_depth(const bNode *a, const bNode *b) return false; } /* Any selected ancestor moves the node forward. */ - if (parent->flag & NODE_ACTIVE) { + if (parent->is_active()) { a_active = true; } - if (parent->flag & NODE_SELECT) { + if (parent->is_selected()) { a_select = true; } } @@ -240,10 +240,10 @@ static bool compare_node_depth(const bNode *a, const bNode *b) return true; } /* Any selected ancestor moves the node forward. */ - if (parent->flag & NODE_ACTIVE) { + if (parent->is_active()) { b_active = true; } - if (parent->flag & NODE_SELECT) { + if (parent->is_selected()) { b_select = true; } } @@ -1425,7 +1425,7 @@ static void node_draw_shadow(const SpaceNode &snode, { const rctf &rct = node.runtime->totr; UI_draw_roundbox_corner_set(UI_CNR_ALL); - ui_draw_dropshadow(&rct, radius, snode.runtime->aspect, alpha, node.flag & SELECT); + ui_draw_dropshadow(&rct, radius, snode.runtime->aspect, alpha, node.is_selected()); } static void node_draw_sockets(const View2D &v2d, @@ -2286,14 +2286,6 @@ static void node_draw_basis(const bContext &C, node_add_error_message_button(tree_draw_ctx, node, block, rct, iconofs); - /* Title. */ - if (node.flag & SELECT) { - UI_GetThemeColor4fv(TH_SELECT, color); - } - else { - UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color); - } - /* Collapse/expand icon. */ { const int but_size = U.widget_unit * 0.8f; @@ -2366,7 +2358,7 @@ static void node_draw_basis(const bContext &C, } /* Draw selected nodes fully opaque. */ - if (node.flag & SELECT) { + if (node.is_active()) { color[3] = 1.0f; } @@ -2411,18 +2403,19 @@ static void node_draw_basis(const bContext &C, /* Outline. */ { - const rctf rect = { - rct.xmin - outline_width, - rct.xmax + outline_width, - rct.ymin - outline_width, - rct.ymax + outline_width, - }; + rctf rect = rct; + BLI_rctf_pad(&rect, outline_width, outline_width); /* Color the outline according to active, selected, or undefined status. */ float color_outline[4]; - if (node.flag & SELECT) { - UI_GetThemeColor4fv((node.flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, color_outline); + if (node.is_selected()) { + if (node.is_active()) { + UI_GetThemeColor4fv(TH_ACTIVE, color_outline); + } + else { + UI_GetThemeColor4fv(TH_SELECT, color_outline); + } } else if (bke::node_type_is_undefined(&node)) { UI_GetThemeColor4fv(TH_REDALERT, color_outline); @@ -2509,7 +2502,7 @@ static void node_draw_hidden(const bContext &C, } /* Draw selected nodes fully opaque. */ - if (node.flag & SELECT) { + if (node.is_active()) { color[3] = 1.0f; } @@ -2522,7 +2515,7 @@ static void node_draw_hidden(const bContext &C, } /* Title. */ - if (node.flag & SELECT) { + if (node.is_active()) { UI_GetThemeColor4fv(TH_SELECT, color); } else { @@ -2577,18 +2570,19 @@ static void node_draw_hidden(const bContext &C, /* Outline. */ { const float outline_width = 1.0f; - const rctf rect = { - rct.xmin - outline_width, - rct.xmax + outline_width, - rct.ymin - outline_width, - rct.ymax + outline_width, - }; + rctf rect = rct; + BLI_rctf_pad(&rect, outline_width, outline_width); /* Color the outline according to active, selected, or undefined status. */ float color_outline[4]; - if (node.flag & SELECT) { - UI_GetThemeColor4fv((node.flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, color_outline); + if (node.is_selected()) { + if (node.is_active()) { + UI_GetThemeColor4fv(TH_ACTIVE, color_outline); + } + else { + UI_GetThemeColor4fv(TH_SELECT, color_outline); + } } else if (bke::node_type_is_undefined(&node)) { UI_GetThemeColor4fv(TH_REDALERT, color_outline); @@ -2952,14 +2946,13 @@ static void frame_node_draw(const bContext &C, UI_draw_roundbox_4fv(&rct, true, BASIS_RAD, color); /* Outline active and selected emphasis. */ - if (node.flag & SELECT) { - if (node.flag & NODE_ACTIVE) { + if (node.is_selected()) { + if (node.is_active()) { UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color); } else { UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color); } - UI_draw_roundbox_aa(&rct, false, BASIS_RAD, color); } @@ -3012,7 +3005,7 @@ static void reroute_node_draw( /* Only draw input socket as they all are placed on the same position highlight * if node itself is selected, since we don't display the node body separately. */ - node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT); + node_draw_sockets(region.v2d, C, ntree, node, block, false, node.is_selected()); UI_block_end(&C, &block); UI_block_draw(&C, &block); diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index c9c9f7e79d7..2b4d0211d4d 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1239,7 +1239,7 @@ static void node_duplicate_reparent_recursive(bNodeTree *ntree, /* Find first selected parent. */ for (parent = node->parent; parent; parent = parent->parent) { - if (parent->flag & SELECT) { + if (parent->is_selected()) { if (!(parent->flag & NODE_TEST)) { node_duplicate_reparent_recursive(ntree, node_map, parent); } @@ -1295,6 +1295,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) Map socket_map; Map duplicated_node_groups; + bNode *actibe_node = nodeGetActive(ntree); + for (bNode *node : get_selected_nodes(*ntree)) { bNode *new_node = bke::node_copy_with_mapping( ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map); @@ -1322,8 +1324,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { /* This creates new links between copied nodes. If keep_inputs is set, also copies input links * from unselected (when fromnode is null)! */ - if (link->tonode && (link->tonode->flag & NODE_SELECT) && - (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) + if (link->tonode && (link->tonode->is_selected()) && + (keep_inputs || (link->fromnode && (link->fromnode->is_selected())))) { bNodeLink *newlink = MEM_cnew("bNodeLink"); newlink->flag = link->flag; @@ -1334,7 +1336,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) newlink->multi_input_socket_index = link->multi_input_socket_index; } - if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) { + if (link->fromnode && (link->fromnode->is_selected())) { newlink->fromnode = node_map.lookup(link->fromnode); newlink->fromsock = socket_map.lookup(link->fromsock); } @@ -1370,14 +1372,17 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) remap_pairing(*ntree, node_map); + if (bNode *new_active_node = node_map.lookup_default(actibe_node, nullptr)) { + nodeSetActive(ntree, new_active_node); + } + /* Deselect old nodes, select the copies instead. */ for (const auto item : node_map.items()) { bNode *src_node = item.key; bNode *dst_node = item.value; - - nodeSetSelected(src_node, false); - src_node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE); nodeSetSelected(dst_node, true); + nodeSetSelected(src_node, false); + src_node->flag &= ~(NODE_ACTIVE_TEXTURE); } ED_node_tree_propagate_change(C, bmain, snode->edittree); @@ -1525,7 +1530,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) int tot_eq = 0, tot_neq = 0; for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) { continue; @@ -1545,7 +1550,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) } } for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) { continue; @@ -1641,7 +1646,7 @@ static int node_deactivate_viewer_exec(bContext *C, wmOperator * /*op*/) if (node->type != GEO_NODE_VIEWER) { continue; } - if (!(node->flag & SELECT)) { + if (!(node->is_selected())) { continue; } if (node == active_viewer) { @@ -1715,7 +1720,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator * /*op*/) /* Toggle for all selected nodes */ bool hidden = false; for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { if (node_has_hidden_sockets(node)) { hidden = true; break; @@ -1724,7 +1729,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator * /*op*/) } for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { node_set_hidden_sockets(snode, node, !hidden); } } @@ -1765,7 +1770,7 @@ static int node_mute_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), bmain); for (bNode *node : snode->edittree->all_nodes()) { - if ((node->flag & SELECT) && !node->typeinfo->no_muting) { + if (node->is_selected() && !node->typeinfo->no_muting) { node->flag ^= NODE_MUTED; BKE_ntree_update_tag_node_mute(snode->edittree, node); } @@ -1808,7 +1813,7 @@ static int node_delete_exec(bContext *C, wmOperator * /*op*/) node_select_paired(*snode->edittree); LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { - if (node->flag & SELECT) { + if (node->is_selected()) { nodeRemoveNode(bmain, snode->edittree, node, true); } } @@ -1855,7 +1860,7 @@ static int node_switch_view_exec(bContext *C, wmOperator * /*op*/) SpaceNode *snode = CTX_wm_space_node(C); LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { - if (node->flag & SELECT) { + if (node->is_selected()) { /* Call the update function from the Switch View node. */ node->runtime->update = NODE_UPDATE_OPERATOR; } @@ -1898,7 +1903,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator * /*op*/) node_select_paired(*snode->edittree); LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { - if (node->flag & SELECT) { + if (node->is_selected()) { blender::bke::nodeInternalRelink(snode->edittree, node); nodeRemoveNode(bmain, snode->edittree, node, true); } @@ -2122,7 +2127,7 @@ static int node_copy_color_exec(bContext *C, wmOperator * /*op*/) } for (bNode *node : ntree.all_nodes()) { - if (node->flag & NODE_SELECT && node != active_node) { + if (node->is_selected() && node != active_node) { if (active_node->flag & NODE_CUSTOM_COLOR) { node->flag |= NODE_CUSTOM_COLOR; copy_v3_v3(node->color, active_node->color); diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index af0aa7879bd..52627e97102 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -519,7 +519,7 @@ static bool node_group_separate_selected( } /* ensure valid parent pointers, detach if parent stays inside the group */ - if (newnode->parent && !(newnode->parent->flag & NODE_SELECT)) { + if (newnode->parent && !(newnode->parent->is_selected())) { nodeDetachNode(&ngroup, newnode); } diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index b31b38f4318..6ae7dcbbaac 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -336,7 +336,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const Vector sorted_nodes; for (bNode *node : ntree->all_nodes()) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { sorted_nodes.append(node); } } @@ -1721,7 +1721,7 @@ static int detach_links_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (bNode *node : ntree.all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { bke::nodeInternalRelink(&ntree, node); } } @@ -1763,7 +1763,7 @@ static int node_parent_set_exec(bContext *C, wmOperator * /*op*/) if (node == frame) { continue; } - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { nodeDetachNode(&ntree, node); nodeAttachNode(&ntree, node, frame); } @@ -1894,7 +1894,7 @@ static bNode *node_find_frame_to_attach(ARegion ®ion, LISTBASE_FOREACH_BACKWARD (bNode *, frame, &ntree.nodes) { /* skip selected, those are the nodes we want to attach */ - if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) { + if ((frame->type != NODE_FRAME) || (frame->is_selected())) { continue; } if (BLI_rctf_isect_pt_v(&frame->runtime->totr, cursor)) { @@ -1917,7 +1917,7 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e } LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) { - if (!(node->flag & NODE_SELECT)) { + if (!(node->is_selected())) { continue; } @@ -1990,13 +1990,13 @@ static void node_detach_recursive(bNodeTree &ntree, if (detach_states[node->parent->index()].descendent) { detach_states[node->index()].descendent = true; } - else if (node->flag & NODE_SELECT) { + else if (node->is_selected()) { /* If parent is not a descendant of a selected node, detach. */ nodeDetachNode(&ntree, node); detach_states[node->index()].descendent = true; } } - else if (node->flag & NODE_SELECT) { + else if (node->is_selected()) { detach_states[node->index()].descendent = true; } } @@ -2048,7 +2048,7 @@ static bNode *get_selected_node_for_insertion(bNodeTree &node_tree) bNode *selected_node = nullptr; int selected_node_count = 0; for (bNode *node : node_tree.all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { selected_node = node; selected_node_count++; } @@ -2453,7 +2453,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd, /* check nodes front to back */ for (frame = (bNode *)ntree->nodes.last; frame; frame = frame->prev) { /* skip selected, those are the nodes we want to attach */ - if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) { + if ((frame->type != NODE_FRAME) || (frame->is_selected())) { continue; } diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index bc6601ed0bb..b6cb3d0ac23 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -314,10 +314,10 @@ void node_select_paired(bNodeTree &node_tree) for (bNode *input_node : node_tree.nodes_by_type("GeometryNodeSimulationInput")) { const auto *storage = static_cast(input_node->storage); if (bNode *output_node = node_tree.node_by_id(storage->output_node_id)) { - if (input_node->flag & NODE_SELECT) { + if (input_node->is_selected()) { output_node->flag |= NODE_SELECT; } - if (output_node->flag & NODE_SELECT) { + if (output_node->is_selected()) { input_node->flag |= NODE_SELECT; } } @@ -328,7 +328,7 @@ VectorSet get_selected_nodes(bNodeTree &node_tree) { VectorSet selected_nodes; for (bNode *node : node_tree.all_nodes()) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { selected_nodes.add(node); } } @@ -347,7 +347,7 @@ static bool node_select_grouped_type(bNodeTree &node_tree, bNode &node_act) { bool changed = false; for (bNode *node : node_tree.all_nodes()) { - if ((node->flag & SELECT) == 0) { + if (!node->is_selected()) { if (node->type == node_act.type) { nodeSetSelected(node, true); changed = true; @@ -361,7 +361,7 @@ static bool node_select_grouped_color(bNodeTree &node_tree, bNode &node_act) { bool changed = false; for (bNode *node : node_tree.all_nodes()) { - if ((node->flag & SELECT) == 0) { + if (!node->is_selected()) { if (compare_v3v3(node->color, node_act.color, 0.005f)) { nodeSetSelected(node, true); changed = true; @@ -388,7 +388,7 @@ static bool node_select_grouped_name(bNodeTree &node_tree, bNode &node_act, cons } for (bNode *node : node_tree.all_nodes()) { - if (node->flag & SELECT) { + if (node->is_selected()) { continue; } pref_len_curr = BLI_str_partition_ex_utf8( @@ -566,7 +566,7 @@ static bool node_mouse_select(bContext *C, if (sock) { node = &sock->owner_node(); found = true; - node_was_selected = node->flag & SELECT; + node_was_selected = node->is_selected(); /* NOTE: SOCK_IN does not take into account the extend case... * This feature is not really used anyway currently? */ @@ -578,7 +578,7 @@ static bool node_mouse_select(bContext *C, if (sock) { node = &sock->owner_node(); found = true; - node_was_selected = node->flag & SELECT; + node_was_selected = node->is_selected(); if (sock->flag & SELECT) { if (extend) { @@ -619,10 +619,10 @@ static bool node_mouse_select(bContext *C, /* Find the closest visible node. */ node = node_under_mouse_select(node_tree, cursor); found = (node != nullptr); - node_was_selected = node && (node->flag & SELECT); + node_was_selected = node && node->is_selected(); if (params->sel_op == SEL_OP_SET) { - if ((found && params->select_passthrough) && (node->flag & SELECT)) { + if (found && params->select_passthrough && node->is_selected()) { found = false; } else if (found || params->deselect_all) { @@ -642,7 +642,7 @@ static bool node_mouse_select(bContext *C, break; case SEL_OP_XOR: { /* Check active so clicking on an inactive node activates it. */ - bool is_selected = (node->flag & NODE_SELECT) && (node->flag & NODE_ACTIVE); + bool is_selected = node->is_selected() && node->is_active(); nodeSetSelected(node, !is_selected); break; } @@ -983,7 +983,7 @@ static bool do_lasso_select_node(bContext *C, BLI_lasso_boundbox(&rect, mcoords, mcoords_len); for (bNode *node : node_tree.all_nodes()) { - if (select && (node->flag & NODE_SELECT)) { + if (select && (node->is_selected())) { continue; } @@ -1083,7 +1083,7 @@ void NODE_OT_select_lasso(wmOperatorType *ot) static bool any_node_selected(const bNodeTree &node_tree) { for (const bNode *node : node_tree.all_nodes()) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { return true; } } @@ -1118,7 +1118,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op) break; case SEL_INVERT: for (bNode *node : node_tree.all_nodes()) { - nodeSetSelected(node, !(node->flag & SELECT)); + nodeSetSelected(node, !(node->is_selected())); } break; } diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 9673d5ac541..637530beaee 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -873,7 +873,7 @@ static int /*eContextResult*/ node_context(const bContext *C, if (CTX_data_equals(member, "selected_nodes")) { if (snode->edittree) { LISTBASE_FOREACH_BACKWARD (bNode *, node, &snode->edittree->nodes) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node); } } diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index 3fd6c7edd35..27e8eab4b68 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -91,7 +91,7 @@ static void create_transform_data_for_node(TransData &td, static bool is_node_parent_select(const bNode *node) { while ((node = node->parent)) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { return true; } } @@ -292,7 +292,7 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t) /* remove selected nodes on cancel */ if (ntree) { LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) { - if (node->flag & NODE_SELECT) { + if (node->is_selected()) { nodeRemoveNode(bmain, ntree, node, true); } } diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index a1fc4ba75f2..cf80793b0e9 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -1498,8 +1498,8 @@ bool peelObjectsTransform(TransInfo *t, static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_select) { /* node is use for snapping only if a) snap mode matches and b) node is inside the view */ - return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) || - (snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) && + return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->is_selected())) || + (snap_target_select == SCE_SNAP_TARGET_ALL && !(node->is_active()))) && (node->runtime->totr.xmin < v2d->cur.xmax && node->runtime->totr.xmax > v2d->cur.xmin && node->runtime->totr.ymin < v2d->cur.ymax && node->runtime->totr.ymax > v2d->cur.ymin); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 114285db44d..87e1b68b3e8 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -386,6 +386,9 @@ typedef struct bNode { /** A span containing all internal links when the node is muted. */ blender::Span internal_links() const; + bool is_selected() const; + bool is_active() const; + /* The following methods are only available when #bNodeTree.ensure_topology_cache has been * called. */ diff --git a/source/blender/nodes/shader/node_shader_util.cc b/source/blender/nodes/shader/node_shader_util.cc index c582b291331..ff50007edc4 100644 --- a/source/blender/nodes/shader/node_shader_util.cc +++ b/source/blender/nodes/shader/node_shader_util.cc @@ -236,7 +236,7 @@ static bNode *node_get_active(bNodeTree *ntree, int sub_activity) if (node->flag & sub_activity) { activetexnode = node; /* if active we can return immediately */ - if (node->flag & NODE_ACTIVE) { + if (node->is_active()) { return node; } } @@ -244,7 +244,7 @@ static bNode *node_get_active(bNodeTree *ntree, int sub_activity) inactivenode = node; } else if (node->type == NODE_GROUP) { - if (node->flag & NODE_ACTIVE) { + if (node->is_active()) { activegroup = node; } else {