diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_nodes.cc')
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 183 |
1 files changed, 106 insertions, 77 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 49f2d66e54a..fd798b743c9 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -29,6 +29,7 @@ #include "BLI_float3.hh" #include "BLI_listbase.h" +#include "BLI_multi_value_map.hh" #include "BLI_set.hh" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -76,6 +77,8 @@ #include "MOD_nodes.h" #include "MOD_ui_common.h" +#include "ED_spreadsheet.h" + #include "NOD_derived_node_tree.hh" #include "NOD_geometry.h" #include "NOD_geometry_exec.hh" @@ -1101,108 +1104,129 @@ static void reset_tree_ui_storage(Span<const blender::nodes::NodeTreeRef *> tree } } -static const DTreeContext *find_derived_tree_context_that_matches_tree_path( - const SpaceNode &snode, const DerivedNodeTree &tree) +static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain) { - const DTreeContext &root_context = tree.root_context(); - bNodeTree *root_tree_eval = root_context.tree().btree(); - bNodeTree *root_tree_orig = (bNodeTree *)DEG_get_original_id(&root_tree_eval->id); - if (snode.nodetree != root_tree_orig) { - return nullptr; - } - - const DTreeContext *current_context = &root_context; - bool is_first = true; - LISTBASE_FOREACH (const bNodeTreePath *, path, &snode.treepath) { - if (is_first) { - is_first = false; - continue; - } - StringRef parent_node_name = path->node_name; - const NodeTreeRef &tree_ref = current_context->tree(); - const NodeRef *parent_node_ref = nullptr; - for (const NodeRef *node_ref : tree_ref.nodes()) { - if (node_ref->name() == parent_node_name) { - parent_node_ref = node_ref; - break; + Vector<SpaceSpreadsheet *> spreadsheets; + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + 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) { + spreadsheets.append((SpaceSpreadsheet *)sl); } } - if (parent_node_ref == nullptr) { - return nullptr; - } - current_context = current_context->child_context(*parent_node_ref); - if (current_context == nullptr) { - return nullptr; - } } - return current_context; + return spreadsheets; } -static DNode find_active_preview_node_in_node_editor(const SpaceNode &snode, - const DerivedNodeTree &tree) +using PreviewSocketMap = blender::MultiValueMap<DSocket, uint64_t>; + +static DSocket try_find_preview_socket_in_node(const DNode node) { - const DTreeContext *context = find_derived_tree_context_that_matches_tree_path(snode, tree); - if (context == nullptr) { - return {}; + for (const SocketRef *socket : node->outputs()) { + if (socket->bsocket()->type == SOCK_GEOMETRY) { + return {node.context(), socket}; + } } - const NodeTreeRef &tree_ref = context->tree(); - for (const NodeRef *node_ref : tree_ref.nodes()) { - if (node_ref->bnode()->flag & NODE_ACTIVE_PREVIEW) { - return {context, node_ref}; + for (const SocketRef *socket : node->inputs()) { + if (socket->bsocket()->type == SOCK_GEOMETRY && + (socket->bsocket()->flag & SOCK_MULTI_INPUT) == 0) { + return {node.context(), socket}; } } return {}; } -static DNode find_active_preview_node_in_all_node_editors(Depsgraph *depsgraph, - const DerivedNodeTree &tree) +static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspreadsheet, + NodesModifierData *nmd, + const ModifierEvalContext *ctx, + const DerivedNodeTree &tree) { - Main *bmain = DEG_get_bmain(depsgraph); - wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; - 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; - DNode preview_node = find_active_preview_node_in_node_editor(*snode, tree); - if (!preview_node) { - continue; + Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path; + if (context_path.size() < 3) { + return {}; + } + if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { + return {}; + } + if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) { + return {}; + } + SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0]; + if (object_context->object != DEG_get_original_object(ctx->object)) { + return {}; + } + SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context_path[1]; + if (StringRef(modifier_context->modifier_name) != nmd->modifier.name) { + return {}; + } + for (SpreadsheetContext *context : context_path.as_span().drop_front(2)) { + if (context->type != SPREADSHEET_CONTEXT_NODE) { + return {}; + } + } + + Span<SpreadsheetContextNode *> nested_group_contexts = + context_path.as_span().drop_front(2).drop_back(1).cast<SpreadsheetContextNode *>(); + SpreadsheetContextNode *last_context = (SpreadsheetContextNode *)context_path.last(); + + const DTreeContext *context = &tree.root_context(); + for (SpreadsheetContextNode *node_context : nested_group_contexts) { + const NodeTreeRef &tree_ref = context->tree(); + const NodeRef *found_node = nullptr; + for (const NodeRef *node_ref : tree_ref.nodes()) { + if (node_ref->name() == node_context->node_name) { + found_node = node_ref; + break; } - return preview_node; + } + if (found_node == nullptr) { + return {}; + } + context = context->child_context(*found_node); + if (context == nullptr) { + return {}; + } + } + + const NodeTreeRef &tree_ref = context->tree(); + for (const NodeRef *node_ref : tree_ref.nodes()) { + if (node_ref->name() == last_context->node_name) { + return try_find_preview_socket_in_node({context, node_ref}); } } return {}; } -static DSocket find_preview_socket_in_all_node_editors(Depsgraph *depsgraph, - const DerivedNodeTree &tree) +static void find_sockets_to_preview(NodesModifierData *nmd, + const ModifierEvalContext *ctx, + const DerivedNodeTree &tree, + PreviewSocketMap &r_sockets_to_preview) { - DNode preview_node = find_active_preview_node_in_all_node_editors(depsgraph, tree); - if (!preview_node) { - return {}; - } - for (const SocketRef *socket : preview_node->outputs()) { - if (socket->bsocket()->type == SOCK_GEOMETRY) { - return {preview_node.context(), socket}; - } - } - for (const SocketRef *socket : preview_node->inputs()) { - if (socket->bsocket()->type == SOCK_GEOMETRY && - (socket->bsocket()->flag & SOCK_MULTI_INPUT) == 0) { - return {preview_node.context(), socket}; + Main *bmain = DEG_get_bmain(ctx->depsgraph); + + /* Based on every visible spreadsheet context path, get a list of sockets that need to have their + * intermediate geometries cached for display. */ + Vector<SpaceSpreadsheet *> spreadsheets = find_spreadsheet_editors(bmain); + for (SpaceSpreadsheet *sspreadsheet : spreadsheets) { + const DSocket socket = try_get_socket_to_preview_for_spreadsheet(sspreadsheet, nmd, ctx, tree); + if (socket) { + const uint64_t key = ED_spreadsheet_context_path_hash(sspreadsheet); + r_sockets_to_preview.add_non_duplicates(socket, key); } } - return {}; } -static void log_preview_socket_value(const Span<GPointer> values, Object *object) +static void log_preview_socket_value(const Span<GPointer> values, + Object *object, + Span<uint64_t> keys) { GeometrySet geometry_set = *(const GeometrySet *)values[0].get(); geometry_set.ensure_owns_direct_data(); - BKE_object_set_preview_geometry_set(object, new GeometrySet(std::move(geometry_set))); + for (uint64_t key : keys) { + BKE_object_preview_geometry_set_add(object, key, new GeometrySet(geometry_set)); + } } /** @@ -1260,11 +1284,16 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree, Vector<DInputSocket> group_outputs; group_outputs.append({root_context, &socket_to_compute}); - const DSocket preview_socket = find_preview_socket_in_all_node_editors(ctx->depsgraph, tree); + PreviewSocketMap preview_sockets; + find_sockets_to_preview(nmd, ctx, tree, preview_sockets); auto log_socket_value = [&](const DSocket socket, const Span<GPointer> values) { - if (socket == preview_socket && nmd->modifier.flag & eModifierFlag_Active) { - log_preview_socket_value(values, ctx->object); + if (!DEG_is_active(ctx->depsgraph)) { + return; + } + Span<uint64_t> keys = preview_sockets.lookup(socket); + if (!keys.is_empty()) { + log_preview_socket_value(values, ctx->object, keys); } }; |