diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index f9dec9d2a80..b2cac0459a4 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2182,6 +2182,12 @@ static void node_draw_basis(const bContext &C, UI_GetThemeColorBlend4f(TH_NODE, color_id, 0.4f, color_header); } + if (tree_draw_ctx.geo_tree_log && + tree_draw_ctx.geo_tree_log->evaluated_node_ids.contains(node.identifier)) + { + copy_v4_fl4(color_header, 0.8f, 0.4f, 0.2f, 1.0f); + } + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); UI_draw_roundbox_4fv(&rect, true, BASIS_RAD, color_header); } @@ -2518,6 +2524,12 @@ static void node_draw_hidden(const bContext &C, color[3] -= 0.2f; } + if (tree_draw_ctx.geo_tree_log && + tree_draw_ctx.geo_tree_log->evaluated_node_ids.contains(node.identifier)) + { + copy_v4_fl4(color, 0.8f, 0.4f, 0.2f, 1.0f); + } + UI_draw_roundbox_4fv(&rct, true, hiddenrad, color); } @@ -3368,6 +3380,7 @@ static void draw_nodetree(const bContext &C, if (tree_draw_ctx.geo_tree_log != nullptr) { tree_draw_ctx.geo_tree_log->ensure_node_warnings(); tree_draw_ctx.geo_tree_log->ensure_node_run_time(); + tree_draw_ctx.geo_tree_log->ensure_evaluated_node_ids(); } const WorkSpace *workspace = CTX_wm_workspace(&C); tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer( diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index bee4e1e8d04..6ecd7abad66 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -208,6 +208,8 @@ class GeoTreeLogger { Vector viewer_node_logs; Vector used_named_attributes; Vector debug_messages; + /** Might contain duplicates. */ + Vector evaluated_node_ids; GeoTreeLogger(); ~GeoTreeLogger(); @@ -266,6 +268,7 @@ class GeoTreeLog { bool reduced_existing_attributes_ = false; bool reduced_used_named_attributes_ = false; bool reduced_debug_messages_ = false; + bool reduced_evaluated_node_ids_ = false; public: Map nodes; @@ -274,6 +277,7 @@ class GeoTreeLog { std::chrono::nanoseconds run_time_sum{0}; Vector existing_attributes; Map used_named_attributes; + Set evaluated_node_ids; GeoTreeLog(GeoModifierLog *modifier_log, Vector tree_loggers); ~GeoTreeLog(); @@ -285,6 +289,7 @@ class GeoTreeLog { void ensure_existing_attributes(); void ensure_used_named_attributes(); void ensure_debug_messages(); + void ensure_evaluated_node_ids(); ValueLog *find_socket_value_log(const bNodeSocket &query_socket); }; diff --git a/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc b/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc index 045a610f9b5..3840a1d4f28 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc @@ -55,9 +55,15 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction { void execute_impl(lf::Params ¶ms, const lf::Context &context) const final { - const GeoNodesLFUserData &user_data = *static_cast( - context.user_data); + const auto &user_data = *static_cast(context.user_data); + const auto &local_user_data = *static_cast( + context.local_user_data); const GeoNodesModifierData &modifier_data = *user_data.modifier_data; + + if (local_user_data.tree_logger) { + local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier); + } + if (modifier_data.current_simulation_state == nullptr) { params.set_default_remaining_outputs(); return; diff --git a/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc b/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc index 45062284cda..bc4649219cb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc @@ -407,11 +407,18 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction { void execute_impl(lf::Params ¶ms, const lf::Context &context) const final { - GeoNodesLFUserData &user_data = *static_cast(context.user_data); + auto &user_data = *static_cast(context.user_data); + auto &local_user_data = *static_cast(context.local_user_data); GeoNodesModifierData &modifier_data = *user_data.modifier_data; EvalData &eval_data = *static_cast(context.storage); BLI_SCOPED_DEFER([&]() { eval_data.is_first_evaluation = false; }); + if (eval_data.is_first_evaluation) { + if (local_user_data.tree_logger) { + local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier); + } + } + const bke::sim::SimulationZoneID zone_id = get_simulation_zone_id(*user_data.compute_context, node_.identifier); diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc index fe64b799409..0a749f86322 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc @@ -146,10 +146,11 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) class LazyFunctionForSwitchNode : public LazyFunction { private: + const bNode &node_; bool can_be_field_ = false; public: - LazyFunctionForSwitchNode(const bNode &node) + LazyFunctionForSwitchNode(const bNode &node) : node_(node) { const NodeSwitch &storage = node_storage(node); const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type); @@ -171,8 +172,13 @@ class LazyFunctionForSwitchNode : public LazyFunction { outputs_.append_as("Value", cpp_type); } - void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + void execute_impl(lf::Params ¶ms, const lf::Context &context) const override { + auto &local_user_data = *static_cast(context.local_user_data); + if (local_user_data.tree_logger) { + local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier); + } + const ValueOrField condition = params.get_input>(0); if (condition.is_field() && can_be_field_) { Field condition_field = condition.as_field(); diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index a6d508288db..00de50e4fcb 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -303,6 +303,7 @@ class LazyFunctionForGeometryNode : public LazyFunction { if (local_user_data.tree_logger) { local_user_data.tree_logger->node_execution_times.append( {node_.identifier, start_time, end_time}); + local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier); } } @@ -649,6 +650,7 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction { */ class LazyFunctionForMultiFunctionNode : public LazyFunction { private: + const bNode &node_; const NodeMultiFunctions::Item fn_item_; Vector input_types_; Vector output_types_; @@ -657,7 +659,7 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction { LazyFunctionForMultiFunctionNode(const bNode &node, NodeMultiFunctions::Item fn_item, MutableSpan r_lf_index_by_bsocket) - : fn_item_(std::move(fn_item)) + : node_(node), fn_item_(std::move(fn_item)) { BLI_assert(fn_item_.fn != nullptr); debug_name_ = node.name; @@ -670,7 +672,7 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction { } } - void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + void execute_impl(lf::Params ¶ms, const lf::Context &context) const override { Vector input_values(inputs_.size()); Vector output_values(outputs_.size()); @@ -685,6 +687,11 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction { for (const int i : outputs_.index_range()) { params.output_set(i); } + + auto &local_user_data = *static_cast(context.local_user_data); + if (local_user_data.tree_logger) { + local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier); + } } }; @@ -799,6 +806,7 @@ class LazyFunctionForViewerNode : public LazyFunction { } local_user_data.tree_logger->log_viewer_node(bnode_, std::move(geometry)); + local_user_data.tree_logger->evaluated_node_ids.append(bnode_.identifier); } }; @@ -947,8 +955,8 @@ class LazyFunctionForGroupNode : public LazyFunction { void execute_impl(lf::Params ¶ms, const lf::Context &context) const override { - GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); - BLI_assert(user_data != nullptr); + auto &user_data = *static_cast(context.user_data); + auto &local_user_data = *static_cast(context.local_user_data); if (has_many_nodes_) { /* If the called node group has many nodes, it's likely that executing it takes a while even @@ -958,15 +966,22 @@ class LazyFunctionForGroupNode : public LazyFunction { Storage *storage = static_cast(context.storage); + /* Only log that the node is executed once. */ + if (!storage->context_hash_cache.has_value()) { + if (local_user_data.tree_logger) { + local_user_data.tree_logger->evaluated_node_ids.append(group_node_.identifier); + } + } + /* The compute context changes when entering a node group. */ bke::NodeGroupComputeContext compute_context{ - user_data->compute_context, group_node_.identifier, storage->context_hash_cache}; + user_data.compute_context, group_node_.identifier, storage->context_hash_cache}; storage->context_hash_cache = compute_context.hash(); - GeoNodesLFUserData group_user_data = *user_data; + GeoNodesLFUserData group_user_data = user_data; group_user_data.compute_context = &compute_context; - if (user_data->modifier_data->socket_log_contexts) { - group_user_data.log_socket_values = user_data->modifier_data->socket_log_contexts->contains( + if (user_data.modifier_data->socket_log_contexts) { + group_user_data.log_socket_values = user_data.modifier_data->socket_log_contexts->contains( compute_context.hash()); } diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index ca8f1ddd060..d647ee8e8ac 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -352,6 +352,19 @@ void GeoTreeLog::ensure_debug_messages() reduced_debug_messages_ = true; } +void GeoTreeLog::ensure_evaluated_node_ids() +{ + if (reduced_evaluated_node_ids_) { + return; + } + for (GeoTreeLogger *tree_logger : tree_loggers_) { + for (const int32_t node_id : tree_logger->evaluated_node_ids) { + this->evaluated_node_ids.add(node_id); + } + } + reduced_evaluated_node_ids_ = true; +} + ValueLog *GeoTreeLog::find_socket_value_log(const bNodeSocket &query_socket) { /**