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);
|
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_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
|
||||||
UI_draw_roundbox_4fv(&rect, true, BASIS_RAD, color_header);
|
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;
|
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);
|
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) {
|
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_warnings();
|
||||||
tree_draw_ctx.geo_tree_log->ensure_node_run_time();
|
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);
|
const WorkSpace *workspace = CTX_wm_workspace(&C);
|
||||||
tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer(
|
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<ViewerNodeLogWithNode, 0> viewer_node_logs;
|
||||||
Vector<AttributeUsageWithNode, 0> used_named_attributes;
|
Vector<AttributeUsageWithNode, 0> used_named_attributes;
|
||||||
Vector<DebugMessage, 0> debug_messages;
|
Vector<DebugMessage, 0> debug_messages;
|
||||||
|
/** Might contain duplicates. */
|
||||||
|
Vector<int32_t> evaluated_node_ids;
|
||||||
|
|
||||||
GeoTreeLogger();
|
GeoTreeLogger();
|
||||||
~GeoTreeLogger();
|
~GeoTreeLogger();
|
||||||
@ -266,6 +268,7 @@ class GeoTreeLog {
|
|||||||
bool reduced_existing_attributes_ = false;
|
bool reduced_existing_attributes_ = false;
|
||||||
bool reduced_used_named_attributes_ = false;
|
bool reduced_used_named_attributes_ = false;
|
||||||
bool reduced_debug_messages_ = false;
|
bool reduced_debug_messages_ = false;
|
||||||
|
bool reduced_evaluated_node_ids_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Map<int32_t, GeoNodeLog> nodes;
|
Map<int32_t, GeoNodeLog> nodes;
|
||||||
@ -274,6 +277,7 @@ class GeoTreeLog {
|
|||||||
std::chrono::nanoseconds run_time_sum{0};
|
std::chrono::nanoseconds run_time_sum{0};
|
||||||
Vector<const GeometryAttributeInfo *> existing_attributes;
|
Vector<const GeometryAttributeInfo *> existing_attributes;
|
||||||
Map<StringRefNull, NamedAttributeUsage> used_named_attributes;
|
Map<StringRefNull, NamedAttributeUsage> used_named_attributes;
|
||||||
|
Set<int32_t> evaluated_node_ids;
|
||||||
|
|
||||||
GeoTreeLog(GeoModifierLog *modifier_log, Vector<GeoTreeLogger *> tree_loggers);
|
GeoTreeLog(GeoModifierLog *modifier_log, Vector<GeoTreeLogger *> tree_loggers);
|
||||||
~GeoTreeLog();
|
~GeoTreeLog();
|
||||||
@ -285,6 +289,7 @@ class GeoTreeLog {
|
|||||||
void ensure_existing_attributes();
|
void ensure_existing_attributes();
|
||||||
void ensure_used_named_attributes();
|
void ensure_used_named_attributes();
|
||||||
void ensure_debug_messages();
|
void ensure_debug_messages();
|
||||||
|
void ensure_evaluated_node_ids();
|
||||||
|
|
||||||
ValueLog *find_socket_value_log(const bNodeSocket &query_socket);
|
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
|
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
||||||
{
|
{
|
||||||
const GeoNodesLFUserData &user_data = *static_cast<const GeoNodesLFUserData *>(
|
const auto &user_data = *static_cast<const GeoNodesLFUserData *>(context.user_data);
|
||||||
context.user_data);
|
const auto &local_user_data = *static_cast<const GeoNodesLFLocalUserData *>(
|
||||||
|
context.local_user_data);
|
||||||
const GeoNodesModifierData &modifier_data = *user_data.modifier_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) {
|
if (modifier_data.current_simulation_state == nullptr) {
|
||||||
params.set_default_remaining_outputs();
|
params.set_default_remaining_outputs();
|
||||||
return;
|
return;
|
||||||
|
@ -407,11 +407,18 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
|||||||
|
|
||||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
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;
|
GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||||
EvalData &eval_data = *static_cast<EvalData *>(context.storage);
|
EvalData &eval_data = *static_cast<EvalData *>(context.storage);
|
||||||
BLI_SCOPED_DEFER([&]() { eval_data.is_first_evaluation = false; });
|
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,
|
const bke::sim::SimulationZoneID zone_id = get_simulation_zone_id(*user_data.compute_context,
|
||||||
node_.identifier);
|
node_.identifier);
|
||||||
|
|
||||||
|
@ -146,10 +146,11 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||||||
|
|
||||||
class LazyFunctionForSwitchNode : public LazyFunction {
|
class LazyFunctionForSwitchNode : public LazyFunction {
|
||||||
private:
|
private:
|
||||||
|
const bNode &node_;
|
||||||
bool can_be_field_ = false;
|
bool can_be_field_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LazyFunctionForSwitchNode(const bNode &node)
|
LazyFunctionForSwitchNode(const bNode &node) : node_(node)
|
||||||
{
|
{
|
||||||
const NodeSwitch &storage = node_storage(node);
|
const NodeSwitch &storage = node_storage(node);
|
||||||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type);
|
const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type);
|
||||||
@ -171,8 +172,13 @@ class LazyFunctionForSwitchNode : public LazyFunction {
|
|||||||
outputs_.append_as("Value", cpp_type);
|
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);
|
const ValueOrField<bool> condition = params.get_input<ValueOrField<bool>>(0);
|
||||||
if (condition.is_field() && can_be_field_) {
|
if (condition.is_field() && can_be_field_) {
|
||||||
Field<bool> condition_field = condition.as_field();
|
Field<bool> condition_field = condition.as_field();
|
||||||
|
@ -303,6 +303,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
|||||||
if (local_user_data.tree_logger) {
|
if (local_user_data.tree_logger) {
|
||||||
local_user_data.tree_logger->node_execution_times.append(
|
local_user_data.tree_logger->node_execution_times.append(
|
||||||
{node_.identifier, start_time, end_time});
|
{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 {
|
class LazyFunctionForMultiFunctionNode : public LazyFunction {
|
||||||
private:
|
private:
|
||||||
|
const bNode &node_;
|
||||||
const NodeMultiFunctions::Item fn_item_;
|
const NodeMultiFunctions::Item fn_item_;
|
||||||
Vector<const ValueOrFieldCPPType *> input_types_;
|
Vector<const ValueOrFieldCPPType *> input_types_;
|
||||||
Vector<const ValueOrFieldCPPType *> output_types_;
|
Vector<const ValueOrFieldCPPType *> output_types_;
|
||||||
@ -657,7 +659,7 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
|
|||||||
LazyFunctionForMultiFunctionNode(const bNode &node,
|
LazyFunctionForMultiFunctionNode(const bNode &node,
|
||||||
NodeMultiFunctions::Item fn_item,
|
NodeMultiFunctions::Item fn_item,
|
||||||
MutableSpan<int> r_lf_index_by_bsocket)
|
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);
|
BLI_assert(fn_item_.fn != nullptr);
|
||||||
debug_name_ = node.name;
|
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<const void *> input_values(inputs_.size());
|
||||||
Vector<void *> output_values(outputs_.size());
|
Vector<void *> output_values(outputs_.size());
|
||||||
@ -685,6 +687,11 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
|
|||||||
for (const int i : outputs_.index_range()) {
|
for (const int i : outputs_.index_range()) {
|
||||||
params.output_set(i);
|
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->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
|
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||||
{
|
{
|
||||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||||
BLI_assert(user_data != nullptr);
|
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||||
|
|
||||||
if (has_many_nodes_) {
|
if (has_many_nodes_) {
|
||||||
/* If the called node group has many nodes, it's likely that executing it takes a while even
|
/* 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);
|
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. */
|
/* The compute context changes when entering a node group. */
|
||||||
bke::NodeGroupComputeContext compute_context{
|
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();
|
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;
|
group_user_data.compute_context = &compute_context;
|
||||||
if (user_data->modifier_data->socket_log_contexts) {
|
if (user_data.modifier_data->socket_log_contexts) {
|
||||||
group_user_data.log_socket_values = user_data->modifier_data->socket_log_contexts->contains(
|
group_user_data.log_socket_values = user_data.modifier_data->socket_log_contexts->contains(
|
||||||
compute_context.hash());
|
compute_context.hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +352,19 @@ void GeoTreeLog::ensure_debug_messages()
|
|||||||
reduced_debug_messages_ = true;
|
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)
|
ValueLog *GeoTreeLog::find_socket_value_log(const bNodeSocket &query_socket)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user