diff options
Diffstat (limited to 'source/blender/editors')
12 files changed, 375 insertions, 87 deletions
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 73a1548362c..058d4fa91a3 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -40,6 +40,7 @@ struct bNodeSocketType; struct bNodeTree; struct bNodeTreeType; struct bNodeType; +struct SpaceNode; typedef enum { NODE_TOP = 1, @@ -114,6 +115,7 @@ bool ED_node_select_check(const ListBase *lb); void ED_node_select_all(ListBase *lb, int action); void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree); void ED_node_set_active(struct Main *bmain, + struct SpaceNode *snode, struct bNodeTree *ntree, struct bNode *node, bool *r_active_texture_changed); diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h index 88bc4738c0b..ff77135a51c 100644 --- a/source/blender/editors/include/ED_spreadsheet.h +++ b/source/blender/editors/include/ED_spreadsheet.h @@ -21,6 +21,9 @@ struct SpaceSpreadsheet; struct SpaceNode; struct ID; struct bNode; +struct Main; +struct bContext; +struct Object; #ifdef __cplusplus extern "C" { @@ -29,14 +32,25 @@ extern "C" { struct SpreadsheetContext *ED_spreadsheet_context_new(int type); void ED_spreadsheet_context_free(struct SpreadsheetContext *context); void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet); -void ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet); +bool ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet); uint64_t ED_spreadsheet_context_path_hash(const struct SpaceSpreadsheet *sspreadsheet); struct ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet); -void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet, - struct SpaceNode *snode, - struct bNode *node); +void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet, + struct SpaceNode *snode, + struct bNode *node); +void ED_spreadsheet_context_paths_set_geometry_node(struct Main *bmain, + struct SpaceNode *snode, + struct bNode *node); +void ED_spreadsheet_context_path_set_evaluated_object(struct SpaceSpreadsheet *sspreadsheet, + struct Object *object); + +void ED_spreadsheet_context_path_guess(const struct bContext *C, + struct SpaceSpreadsheet *sspreadsheet); +bool ED_spreadsheet_context_path_is_active(const struct bContext *C, + struct SpaceSpreadsheet *sspreadsheet); +bool ED_spreadsheet_context_path_exists(struct Main *bmain, struct SpaceSpreadsheet *sspreadsheet); #ifdef __cplusplus } diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 97e3cb750c1..f1debcef5a9 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -451,7 +451,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg) /* set user as active */ if (user->node) { - ED_node_set_active(CTX_data_main(C), user->ntree, user->node, NULL); + ED_node_set_active(CTX_data_main(C), NULL, user->ntree, user->node, NULL); ct->texture = NULL; /* Not totally sure if we should also change selection? */ diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 6143af8ed70..c167744de01 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -90,7 +90,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx nodeSetSelected(node, true); ntreeUpdateTree(bmain, snode->edittree); - ED_node_set_active(bmain, snode->edittree, node, nullptr); + ED_node_set_active(bmain, snode, snode->edittree, node, nullptr); snode_update(snode, node); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index c15cc4240a5..8a341da0b5c 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -1405,28 +1405,6 @@ static void node_draw_basis(const bContext *C, ""); UI_block_emboss_set(node->block, UI_EMBOSS); } - if (ntree->type == NTREE_GEOMETRY) { - /* Active preview toggle. */ - iconofs -= iconbutw; - UI_block_emboss_set(node->block, UI_EMBOSS_NONE); - int icon = (node->flag & NODE_ACTIVE_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON; - uiBut *but = uiDefIconBut(node->block, - UI_BTYPE_BUT_TOGGLE, - 0, - icon, - iconofs, - rct->ymax - NODE_DY, - iconbutw, - UI_UNIT_Y, - nullptr, - 0, - 0, - 0, - 0, - "Show this node's geometry output in the spreadsheet"); - UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_active_preview_toggle"); - UI_block_emboss_set(node->block, UI_EMBOSS); - } node_add_error_message_button(C, *ntree, *node, *rct, iconofs); diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 56064e92d70..9a6603eb589 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -54,6 +54,7 @@ #include "ED_render.h" #include "ED_screen.h" #include "ED_select_utils.h" +#include "ED_spreadsheet.h" #include "RNA_access.h" #include "RNA_define.h" @@ -662,7 +663,8 @@ void snode_update(SpaceNode *snode, bNode *node) } } -void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed) +void ED_node_set_active( + Main *bmain, SpaceNode *snode, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed) { const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0; if (r_active_texture_changed) { @@ -782,6 +784,19 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti } #endif } + else if (ntree->type == NTREE_GEOMETRY) { + if (node->type == GEO_NODE_VIEWER) { + if ((node->flag & NODE_DO_OUTPUT) == 0) { + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (node_iter->type == GEO_NODE_VIEWER) { + node_iter->flag &= ~NODE_DO_OUTPUT; + } + } + node->flag |= NODE_DO_OUTPUT; + ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, node); + } + } + } } } @@ -1318,7 +1333,6 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) nodeSetSelected(node, false); node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE); nodeSetSelected(newnode, true); - newnode->flag &= ~NODE_ACTIVE_PREVIEW; do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode)); } diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 58c3c8181b2..e69f0cbea7f 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -279,7 +279,6 @@ void NODE_OT_hide_toggle(struct wmOperatorType *ot); void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot); void NODE_OT_preview_toggle(struct wmOperatorType *ot); void NODE_OT_options_toggle(struct wmOperatorType *ot); -void NODE_OT_active_preview_toggle(struct wmOperatorType *ot); void NODE_OT_node_copy_color(struct wmOperatorType *ot); void NODE_OT_read_viewlayers(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index a1b8e4e3395..aadf93961e9 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -40,11 +40,14 @@ #include "ED_node.h" /* own include */ #include "ED_render.h" #include "ED_screen.h" +#include "ED_spreadsheet.h" #include "ED_util.h" #include "RNA_access.h" #include "RNA_define.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -160,6 +163,11 @@ bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node) return true; } } + if (current_node->type == GEO_NODE_VIEWER) { + if (ntree_check_nodes_connected(ntree, node, current_node)) { + return true; + } + } } return false; } @@ -610,14 +618,14 @@ static int node_link_viewer(const bContext *C, bNode *tonode) if (tonode == nullptr || BLI_listbase_is_empty(&tonode->outputs)) { return OPERATOR_CANCELLED; } - if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) { return OPERATOR_CANCELLED; } /* get viewer */ bNode *viewer_node = nullptr; LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { - if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) { if (node->flag & NODE_DO_OUTPUT) { viewer_node = node; break; @@ -627,7 +635,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode) /* no viewer, we make one active */ if (viewer_node == nullptr) { LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { - if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) { node->flag |= NODE_DO_OUTPUT; viewer_node = node; break; @@ -686,7 +694,8 @@ static int node_link_viewer(const bContext *C, bNode *tonode) /* add a new viewer if none exists yet */ if (!viewer_node) { /* XXX location is a quick hack, just place it next to the linked socket */ - viewer_node = node_add_node(C, nullptr, CMP_NODE_VIEWER, sock->locx + 100, sock->locy); + const int viewer_type = ED_node_is_compositor(snode) ? CMP_NODE_VIEWER : GEO_NODE_VIEWER; + viewer_node = node_add_node(C, nullptr, viewer_type, sock->locx + 100, sock->locy); if (!viewer_node) { return OPERATOR_CANCELLED; } @@ -712,8 +721,13 @@ static int node_link_viewer(const bContext *C, bNode *tonode) /* make sure the dependency sorting is updated */ snode->edittree->update |= NTREE_UPDATE_LINKS; } + if (ED_node_is_geometry(snode)) { + ED_spreadsheet_context_paths_set_geometry_node(CTX_data_main(C), snode, viewer_node); + } + ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_update(snode, viewer_node); + DEG_id_tag_update(&snode->edittree->id, 0); } return OPERATOR_FINISHED; @@ -739,6 +753,15 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +static bool node_active_link_viewer_poll(bContext *C) +{ + if (!ED_operator_node_editable(C)) { + return false; + } + SpaceNode *snode = CTX_wm_space_node(C); + return ED_node_is_compositor(snode) || ED_node_is_geometry(snode); +} + void NODE_OT_link_viewer(wmOperatorType *ot) { /* identifiers */ @@ -748,7 +771,7 @@ void NODE_OT_link_viewer(wmOperatorType *ot) /* api callbacks */ ot->exec = node_active_link_viewer_exec; - ot->poll = composite_node_editable; + ot->poll = node_active_link_viewer_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 2c8e78de8d2..a081cc83481 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -44,6 +44,7 @@ #include "ED_node.h" /* own include */ #include "ED_screen.h" #include "ED_select_utils.h" +#include "ED_spreadsheet.h" #include "ED_view3d.h" #include "RNA_access.h" @@ -469,7 +470,7 @@ void node_select_single(bContext *C, bNode *node) } nodeSetSelected(node, true); - ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed); + ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed); ED_node_set_active_viewer_key(snode); ED_node_sort(snode->edittree); @@ -606,12 +607,18 @@ static int node_mouse_select(bContext *C, /* update node order */ if (ret_value != OPERATOR_CANCELLED) { bool active_texture_changed = false; + bool viewer_node_changed = false; if (node != nullptr && ret_value != OPERATOR_RUNNING_MODAL) { - ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed); + viewer_node_changed = (node->flag & NODE_DO_OUTPUT) == 0 && node->type == GEO_NODE_VIEWER; + ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed); + } + else if (node != nullptr && node->type == GEO_NODE_VIEWER) { + ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, node); } ED_node_set_active_viewer_key(snode); ED_node_sort(snode->edittree); - if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) { + if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) || + viewer_node_changed) { DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE); } diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 07517f9e60f..fcc92345bea 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -222,24 +222,11 @@ ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet) static void update_pinned_context_path_if_outdated(const bContext *C) { SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); - - /* Currently, this only checks if the object has been deleted. In the future we can have a more - * sophisticated check for the entire context (including modifier and nodes). */ - LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) { - if (context->type == SPREADSHEET_CONTEXT_OBJECT) { - SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context; - if (object_context->object == nullptr) { - ED_spreadsheet_context_path_clear(sspreadsheet); - break; - } - } - } - if (BLI_listbase_is_empty(&sspreadsheet->context_path)) { - Object *active_object = CTX_data_active_object(C); - if (active_object != nullptr) { - SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT); - ((SpreadsheetContextObject *)new_context)->object = active_object; - BLI_addtail(&sspreadsheet->context_path, new_context); + Main *bmain = CTX_data_main(C); + if (!ED_spreadsheet_context_path_exists(bmain, sspreadsheet)) { + ED_spreadsheet_context_path_guess(C, sspreadsheet); + if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) { + ED_area_tag_redraw(CTX_wm_area(C)); } } @@ -252,25 +239,12 @@ static void update_pinned_context_path_if_outdated(const bContext *C) static void update_context_path_from_context(const bContext *C) { SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); - Object *active_object = CTX_data_active_object(C); - if (active_object == nullptr) { - ED_spreadsheet_context_path_clear(sspreadsheet); - return; - } - if (!BLI_listbase_is_empty(&sspreadsheet->context_path)) { - SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first; - if (root_context->type == SPREADSHEET_CONTEXT_OBJECT) { - SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context; - if (object_context->object != active_object) { - ED_spreadsheet_context_path_clear(sspreadsheet); - } + if (!ED_spreadsheet_context_path_is_active(C, sspreadsheet)) { + ED_spreadsheet_context_path_guess(C, sspreadsheet); + if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) { + ED_area_tag_redraw(CTX_wm_area(C)); } } - if (BLI_listbase_is_empty(&sspreadsheet->context_path)) { - SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT); - ((SpreadsheetContextObject *)new_context)->object = active_object; - BLI_addtail(&sspreadsheet->context_path, new_context); - } } void spreadsheet_update_context_path(const bContext *C) diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc index af6ab5d1b92..93d7c6d9804 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc @@ -24,16 +24,28 @@ #include "BLI_utildefines.h" #include "BLI_vector.hh" +#include "ED_screen.h" #include "ED_spreadsheet.h" #include "DEG_depsgraph.h" +#include "BKE_context.h" #include "BKE_main.h" #include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_object.h" +#include "BKE_workspace.h" + +#include "DNA_modifier_types.h" +#include "DNA_windowmanager_types.h" #include "spreadsheet_context.hh" +using blender::IndexRange; +using blender::Span; +using blender::StringRef; +using blender::Vector; + namespace blender::ed::spreadsheet { static SpreadsheetContextObject *spreadsheet_context_object_new() @@ -206,28 +218,30 @@ void spreadsheet_context_free(SpreadsheetContext *context) /** * Tag any data relevant to the spreadsheet's context for recalculation in order to collect * information to display in the editor, which may be cached during evaluation. + * \return True when any data has been tagged for update. */ -static void spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet) +static bool spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet) { using namespace blender; Vector<const SpreadsheetContext *> context_path = sspreadsheet->context_path; if (context_path.is_empty()) { - return; + return false; } if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { - return; + return false; } SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0]; Object *object = object_context->object; if (object == nullptr) { - return; + return false; } if (context_path.size() == 1) { /* No need to reevaluate, when the final or original object is viewed. */ - return; + return false; } DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); + return true; } } // namespace blender::ed::spreadsheet @@ -250,9 +264,9 @@ void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet) BLI_listbase_clear(&sspreadsheet->context_path); } -void ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet) +bool ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet) { - blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet); + return blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet); } uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet) @@ -265,15 +279,32 @@ uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet) return BLI_hash_mm2a_end(&mm2); } -void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet, - struct SpaceNode *snode, - struct bNode *node) +void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet, + struct SpaceNode *snode, + struct bNode *node) { using namespace blender::ed::spreadsheet; - ED_spreadsheet_context_path_clear(sspreadsheet); Object *object = (Object *)snode->id; + /* Try to find the modifier the node tree belongs to. */ ModifierData *modifier = BKE_object_active_modifier(object); + if (modifier && modifier->type != eModifierType_Nodes) { + modifier = nullptr; + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->type == eModifierType_Nodes) { + NodesModifierData *nmd = (NodesModifierData *)md; + if (nmd->node_group == snode->nodetree) { + modifier = md; + break; + } + } + } + } + if (modifier == nullptr) { + return; + } + + ED_spreadsheet_context_path_clear(sspreadsheet); { SpreadsheetContextObject *context = spreadsheet_context_object_new(); @@ -302,5 +333,251 @@ void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsh BLI_addtail(&sspreadsheet->context_path, context); } - sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED; + sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE; +} + +void ED_spreadsheet_context_paths_set_geometry_node(Main *bmain, SpaceNode *snode, bNode *node) +{ + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + if (wm == nullptr) { + return; + } + LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { + bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + SpaceLink *sl = (SpaceLink *)area->spacedata.first; + if (sl->spacetype == SPACE_SPREADSHEET) { + SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl; + if ((sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) == 0) { + const uint64_t context_hash_before = ED_spreadsheet_context_path_hash(sspreadsheet); + ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node); + const uint64_t context_hash_after = ED_spreadsheet_context_path_hash(sspreadsheet); + if (context_hash_before != context_hash_after) { + ED_spreadsheet_context_path_update_tag(sspreadsheet); + } + ED_area_tag_redraw(area); + } + } + } + } +} + +void ED_spreadsheet_context_path_set_evaluated_object(SpaceSpreadsheet *sspreadsheet, + Object *object) +{ + using namespace blender::ed::spreadsheet; + ED_spreadsheet_context_path_clear(sspreadsheet); + + SpreadsheetContextObject *context = spreadsheet_context_object_new(); + context->object = object; + BLI_addtail(&sspreadsheet->context_path, context); +} + +void ED_spreadsheet_context_path_guess(const bContext *C, SpaceSpreadsheet *sspreadsheet) +{ + ED_spreadsheet_context_path_clear(sspreadsheet); + + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + if (wm == nullptr) { + return; + } + + if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) { + LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { + bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + SpaceLink *sl = (SpaceLink *)area->spacedata.first; + if (sl->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + if (snode->edittree != nullptr) { + if (snode->edittree->type == NTREE_GEOMETRY) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { + if (node->type == GEO_NODE_VIEWER) { + if (node->flag & NODE_DO_OUTPUT) { + ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node); + return; + } + } + } + } + } + } + } + } + } + + Object *active_object = CTX_data_active_object(C); + if (active_object != nullptr) { + ED_spreadsheet_context_path_set_evaluated_object(sspreadsheet, active_object); + return; + } +} + +bool ED_spreadsheet_context_path_is_active(const bContext *C, SpaceSpreadsheet *sspreadsheet) +{ + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + if (wm == nullptr) { + return false; + } + Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path; + if (context_path.is_empty()) { + return false; + } + if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { + return false; + } + Object *object = ((SpreadsheetContextObject *)context_path[0])->object; + if (object == nullptr) { + return false; + } + if (context_path.size() == 1) { + if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) { + return false; + } + Object *active_object = CTX_data_active_object(C); + return object == active_object; + } + if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) { + return false; + } + if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) { + return false; + } + const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name; + const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name); + if (modifier == nullptr) { + return false; + } + if (!(modifier->flag & eModifierFlag_Active)) { + return false; + } + if (modifier->type != eModifierType_Nodes) { + return false; + } + bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group; + if (root_node_tree == nullptr) { + return false; + } + const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2); + if (node_context_path.is_empty()) { + return false; + } + + LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { + bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + SpaceLink *sl = (SpaceLink *)area->spacedata.first; + if (sl->spacetype != SPACE_NODE) { + continue; + } + SpaceNode *snode = (SpaceNode *)sl; + if (snode->nodetree != root_node_tree) { + continue; + } + if (snode->id != &object->id) { + continue; + } + Vector<bNodeTreePath *> tree_path = snode->treepath; + if (node_context_path.size() != tree_path.size()) { + continue; + } + int valid_count = 0; + for (const int i : IndexRange(tree_path.size() - 1)) { + if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) { + break; + } + SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)node_context_path[i]; + if (!STREQ(node_context->node_name, tree_path[i]->node_name)) { + break; + } + valid_count++; + } + if (valid_count != tree_path.size() - 1) { + continue; + } + SpreadsheetContext *last_context = node_context_path.last(); + if (last_context->type != SPREADSHEET_CONTEXT_NODE) { + return false; + } + const char *node_name = ((SpreadsheetContextNode *)last_context)->node_name; + bNode *node = nodeFindNodebyName(snode->edittree, node_name); + if (node == nullptr) { + return false; + } + if (node->type != GEO_NODE_VIEWER) { + return false; + } + if (!(node->flag & NODE_DO_OUTPUT)) { + return false; + } + return true; + } + } + return false; +} + +bool ED_spreadsheet_context_path_exists(Main *UNUSED(bmain), SpaceSpreadsheet *sspreadsheet) +{ + Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path; + if (context_path.is_empty()) { + return false; + } + if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { + return false; + } + Object *object = ((SpreadsheetContextObject *)context_path[0])->object; + if (object == nullptr) { + return false; + } + if (context_path.size() == 1) { + return true; + } + if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) { + return false; + } + const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name; + const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name); + if (modifier == nullptr) { + return false; + } + if (modifier->type != eModifierType_Nodes) { + return false; + } + bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group; + if (root_node_tree == nullptr) { + return false; + } + const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2); + if (node_context_path.is_empty()) { + return false; + } + bNodeTree *node_tree = root_node_tree; + for (const int i : node_context_path.index_range()) { + if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) { + return false; + } + const char *node_name = ((SpreadsheetContextNode *)node_context_path[i])->node_name; + bNode *node = nodeFindNodebyName(node_tree, node_name); + if (node == nullptr) { + return false; + } + if (node->type == GEO_NODE_VIEWER) { + if (i == node_context_path.index_range().last()) { + return true; + } + return false; + } + else if (node->id != nullptr) { + if (GS(node->id->name) != ID_NT) { + return false; + } + node_tree = (bNodeTree *)node->id; + } + else { + return false; + } + } + return false; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 6d244a1bda6..f730f199ca4 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -419,7 +419,7 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly); } } - else if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED) { + else { if (used_component_type == GEO_COMPONENT_TYPE_MESH && object_eval->mode == OB_MODE_EDIT) { Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(object_eval, false); if (mesh == nullptr) { |