diff --git a/source/blender/editors/geometry/node_group_operator.cc b/source/blender/editors/geometry/node_group_operator.cc index a996c6fabad..b1560691447 100644 --- a/source/blender/editors/geometry/node_group_operator.cc +++ b/source/blender/editors/geometry/node_group_operator.cc @@ -36,6 +36,7 @@ #include "BKE_pointcloud.hh" #include "BKE_report.hh" #include "BKE_screen.hh" +#include "BKE_workspace.hh" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -113,6 +114,54 @@ static const bNodeTree *get_node_group(const bContext &C, PointerRNA &ptr, Repor return group; } +GeoOperatorLog::~GeoOperatorLog() {} + +/** + * The socket value log is stored statically so it can be used in the node editor. A fancier + * storage system shouldn't be necessary, since the goal is just to be able to debug intermediate + * values when building a tool. + */ +static GeoOperatorLog &get_static_eval_log() +{ + static GeoOperatorLog log; + return log; +} + +const GeoOperatorLog &node_group_operator_static_eval_log() +{ + return get_static_eval_log(); +} + +/** Find all the visible node editors to log values for. */ +static void find_socket_log_contexts(const Main &bmain, + Set &r_socket_log_contexts) +{ + wmWindowManager *wm = static_cast(bmain.wm.first); + if (wm == nullptr) { + return; + } + LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) { + const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { + const SpaceLink *sl = static_cast(area->spacedata.first); + if (sl->spacetype == SPACE_NODE) { + const SpaceNode &snode = *reinterpret_cast(sl); + if (snode.edittree == nullptr) { + continue; + } + ComputeContextBuilder compute_context_builder; + compute_context_builder.push(); + const Map hash_by_zone = + geo_log::GeoModifierLog::get_context_hash_by_zone_for_node_editor( + snode, compute_context_builder); + for (const ComputeContextHash &hash : hash_by_zone.values()) { + r_socket_log_contexts.add(hash); + } + } + } + } +} + /** * Geometry nodes currently requires working on "evaluated" data-blocks (rather than "original" * data-blocks that are part of a #Main data-base). This could change in the future, but for now, @@ -385,7 +434,11 @@ static int run_node_group_exec(bContext *C, wmOperator *op) BLI_SCOPED_DEFER([&]() { IDP_FreeProperty_ex(properties, false); }); bke::OperatorComputeContext compute_context; - auto eval_log = std::make_unique(); + Set socket_log_contexts; + GeoOperatorLog &eval_log = get_static_eval_log(); + eval_log.log = std::make_unique(); + eval_log.node_group_name = node_tree->id.name + 2; + find_socket_log_contexts(*bmain, socket_log_contexts); for (Object *object : objects) { nodes::GeoNodesOperatorData operator_eval_data{}; @@ -396,7 +449,11 @@ static int run_node_group_exec(bContext *C, wmOperator *op) nodes::GeoNodesCallData call_data{}; call_data.operator_data = &operator_eval_data; - call_data.eval_log = eval_log.get(); + call_data.eval_log = eval_log.log.get(); + if (object == active_object) { + /* Only log values from the active object. */ + call_data.socket_log_contexts = &socket_log_contexts; + } bke::GeometrySet geometry_orig = get_original_geometry_eval_copy(*object); @@ -409,7 +466,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_GEOM | ND_DATA, object->data); } - geo_log::GeoTreeLog &tree_log = eval_log->get_tree_log(compute_context.hash()); + geo_log::GeoTreeLog &tree_log = eval_log.log->get_tree_log(compute_context.hash()); tree_log.ensure_node_warnings(); for (const geo_log::NodeWarning &warning : tree_log.all_warnings) { if (warning.type == geo_log::NodeWarningType::Info) { diff --git a/source/blender/editors/include/ED_geometry.hh b/source/blender/editors/include/ED_geometry.hh index a4346df49c0..405e42d66a4 100644 --- a/source/blender/editors/include/ED_geometry.hh +++ b/source/blender/editors/include/ED_geometry.hh @@ -8,6 +8,8 @@ #pragma once +#include + #include "BLI_generic_pointer.hh" #include "BLI_string_ref.hh" @@ -22,6 +24,9 @@ struct PropertyRNA; namespace blender::bke { enum class AttrDomain : int8_t; } +namespace blender::nodes::geo_eval_log { +class GeoModifierLog; +} namespace blender::ed::geometry { @@ -61,6 +66,16 @@ bool ED_geometry_attribute_convert(Mesh *mesh, namespace blender::ed::geometry { +struct GeoOperatorLog { + std::string node_group_name; + std::unique_ptr log; + + GeoOperatorLog() = default; + ~GeoOperatorLog(); +}; + +const GeoOperatorLog &node_group_operator_static_eval_log(); + MenuType node_group_operator_assets_menu(); MenuType node_group_operator_assets_menu_unassigned(); diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index 16682e3ccb0..b08e29e72e3 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -340,6 +340,9 @@ class GeoModifierLog { */ static Map get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name); + static Map + get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, + ComputeContextBuilder &compute_context_builder); static Map get_tree_log_by_zone_for_node_editor( const SpaceNode &snode); diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 8194405201c..659728cffcd 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -14,6 +14,7 @@ #include "DNA_modifier_types.h" #include "DNA_space_types.h" +#include "ED_geometry.hh" #include "ED_node.hh" #include "ED_viewer_path.hh" @@ -532,11 +533,9 @@ static void find_tree_zone_hash_recursive( } Map GeoModifierLog:: - get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name) + get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, + ComputeContextBuilder &compute_context_builder) { - ComputeContextBuilder compute_context_builder; - compute_context_builder.push(modifier_name); - if (!ed::space_node::push_compute_context_for_tree_path(snode, compute_context_builder)) { return {}; } @@ -553,27 +552,58 @@ Map GeoModifierLog:: return hash_by_zone; } +Map GeoModifierLog:: + get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name) +{ + ComputeContextBuilder compute_context_builder; + compute_context_builder.push(modifier_name); + return get_context_hash_by_zone_for_node_editor(snode, compute_context_builder); +} + Map GeoModifierLog::get_tree_log_by_zone_for_node_editor( const SpaceNode &snode) { - std::optional object_and_modifier = - ed::space_node::get_modifier_for_node_editor(snode); - if (!object_and_modifier) { - return {}; + switch (SpaceNodeGeometryNodesType(snode.geometry_nodes_type)) { + case SNODE_GEOMETRY_MODIFIER: { + std::optional object_and_modifier = + ed::space_node::get_modifier_for_node_editor(snode); + if (!object_and_modifier) { + return {}; + } + GeoModifierLog *modifier_log = object_and_modifier->nmd->runtime->eval_log.get(); + if (modifier_log == nullptr) { + return {}; + } + const Map hash_by_zone = + GeoModifierLog::get_context_hash_by_zone_for_node_editor( + snode, object_and_modifier->nmd->modifier.name); + Map log_by_zone; + for (const auto item : hash_by_zone.items()) { + GeoTreeLog &tree_log = modifier_log->get_tree_log(item.value); + log_by_zone.add(item.key, &tree_log); + } + return log_by_zone; + } + case SNODE_GEOMETRY_TOOL: { + const ed::geometry::GeoOperatorLog &log = + ed::geometry::node_group_operator_static_eval_log(); + if (snode.geometry_nodes_tool_tree->id.name + 2 != log.node_group_name) { + return {}; + } + ComputeContextBuilder compute_context_builder; + compute_context_builder.push(); + const Map hash_by_zone = + GeoModifierLog::get_context_hash_by_zone_for_node_editor(snode, compute_context_builder); + Map log_by_zone; + for (const auto item : hash_by_zone.items()) { + GeoTreeLog &tree_log = log.log->get_tree_log(item.value); + log_by_zone.add(item.key, &tree_log); + } + return log_by_zone; + } } - GeoModifierLog *modifier_log = object_and_modifier->nmd->runtime->eval_log.get(); - if (modifier_log == nullptr) { - return {}; - } - const Map hash_by_zone = - GeoModifierLog::get_context_hash_by_zone_for_node_editor( - snode, object_and_modifier->nmd->modifier.name); - Map log_by_zone; - for (const auto item : hash_by_zone.items()) { - GeoTreeLog &tree_log = modifier_log->get_tree_log(item.value); - log_by_zone.add(item.key, &tree_log); - } - return log_by_zone; + BLI_assert_unreachable(); + return {}; } const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path)