Geometry Nodes: visualize evaluated nodes #107780
@ -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(
|
||||
|
@ -208,6 +208,8 @@ class GeoTreeLogger {
|
||||
Vector<ViewerNodeLogWithNode, 0> viewer_node_logs;
|
||||
Vector<AttributeUsageWithNode, 0> used_named_attributes;
|
||||
Vector<DebugMessage, 0> debug_messages;
|
||||
/** Might contain duplicates. */
|
||||
Vector<int32_t> 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<int32_t, GeoNodeLog> nodes;
|
||||
@ -274,6 +277,7 @@ class GeoTreeLog {
|
||||
std::chrono::nanoseconds run_time_sum{0};
|
||||
Vector<const GeometryAttributeInfo *> existing_attributes;
|
||||
Map<StringRefNull, NamedAttributeUsage> used_named_attributes;
|
||||
Set<int32_t> evaluated_node_ids;
|
||||
|
||||
GeoTreeLog(GeoModifierLog *modifier_log, Vector<GeoTreeLogger *> 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);
|
||||
};
|
||||
|
@ -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<const GeoNodesLFUserData *>(
|
||||
context.user_data);
|
||||
const auto &user_data = *static_cast<const GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<const GeoNodesLFLocalUserData *>(
|
||||
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;
|
||||
|
@ -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<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||
EvalData &eval_data = *static_cast<EvalData *>(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);
|
||||
|
||||
|
@ -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<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
if (local_user_data.tree_logger) {
|
||||
local_user_data.tree_logger->evaluated_node_ids.append(node_.identifier);
|
||||
}
|
||||
|
||||
const ValueOrField<bool> condition = params.get_input<ValueOrField<bool>>(0);
|
||||
if (condition.is_field() && can_be_field_) {
|
||||
Field<bool> condition_field = condition.as_field();
|
||||
|
@ -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<const ValueOrFieldCPPType *> input_types_;
|
||||
Vector<const ValueOrFieldCPPType *> output_types_;
|
||||
@ -657,7 +659,7 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
|
||||
LazyFunctionForMultiFunctionNode(const bNode &node,
|
||||
NodeMultiFunctions::Item fn_item,
|
||||
MutableSpan<int> 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<const void *> input_values(inputs_.size());
|
||||
Vector<void *> 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<GeoNodesLFLocalUserData *>(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<GeoNodesLFUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(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<Storage *>(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());
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user