Geometry Nodes: Log socket values for node tools #120596
|
@ -36,6 +36,7 @@
|
||||||
#include "BKE_pointcloud.hh"
|
#include "BKE_pointcloud.hh"
|
||||||
#include "BKE_report.hh"
|
#include "BKE_report.hh"
|
||||||
#include "BKE_screen.hh"
|
#include "BKE_screen.hh"
|
||||||
|
#include "BKE_workspace.hh"
|
||||||
HooglyBoogly marked this conversation as resolved
Outdated
|
|||||||
|
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_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;
|
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<ComputeContextHash> &r_socket_log_contexts)
|
||||||
|
{
|
||||||
|
wmWindowManager *wm = static_cast<wmWindowManager *>(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<SpaceLink *>(area->spacedata.first);
|
||||||
|
if (sl->spacetype == SPACE_NODE) {
|
||||||
|
const SpaceNode &snode = *reinterpret_cast<const SpaceNode *>(sl);
|
||||||
|
if (snode.edittree == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ComputeContextBuilder compute_context_builder;
|
||||||
|
compute_context_builder.push<bke::OperatorComputeContext>();
|
||||||
|
const Map<const bke::bNodeTreeZone *, ComputeContextHash> 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"
|
* 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,
|
* 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); });
|
BLI_SCOPED_DEFER([&]() { IDP_FreeProperty_ex(properties, false); });
|
||||||
|
|
||||||
bke::OperatorComputeContext compute_context;
|
bke::OperatorComputeContext compute_context;
|
||||||
auto eval_log = std::make_unique<geo_log::GeoModifierLog>();
|
Set<ComputeContextHash> socket_log_contexts;
|
||||||
|
GeoOperatorLog &eval_log = get_static_eval_log();
|
||||||
|
eval_log.log = std::make_unique<geo_log::GeoModifierLog>();
|
||||||
|
eval_log.node_group_name = node_tree->id.name + 2;
|
||||||
|
find_socket_log_contexts(*bmain, socket_log_contexts);
|
||||||
|
|
||||||
for (Object *object : objects) {
|
for (Object *object : objects) {
|
||||||
nodes::GeoNodesOperatorData operator_eval_data{};
|
nodes::GeoNodesOperatorData operator_eval_data{};
|
||||||
|
@ -396,7 +449,11 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||||
|
|
||||||
nodes::GeoNodesCallData call_data{};
|
nodes::GeoNodesCallData call_data{};
|
||||||
call_data.operator_data = &operator_eval_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);
|
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);
|
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();
|
tree_log.ensure_node_warnings();
|
||||||
for (const geo_log::NodeWarning &warning : tree_log.all_warnings) {
|
for (const geo_log::NodeWarning &warning : tree_log.all_warnings) {
|
||||||
if (warning.type == geo_log::NodeWarningType::Info) {
|
if (warning.type == geo_log::NodeWarningType::Info) {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "BLI_generic_pointer.hh"
|
#include "BLI_generic_pointer.hh"
|
||||||
#include "BLI_string_ref.hh"
|
#include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
@ -22,6 +24,9 @@ struct PropertyRNA;
|
||||||
namespace blender::bke {
|
namespace blender::bke {
|
||||||
enum class AttrDomain : int8_t;
|
enum class AttrDomain : int8_t;
|
||||||
}
|
}
|
||||||
|
namespace blender::nodes::geo_eval_log {
|
||||||
|
class GeoModifierLog;
|
||||||
|
}
|
||||||
|
|
||||||
namespace blender::ed::geometry {
|
namespace blender::ed::geometry {
|
||||||
|
|
||||||
|
@ -61,6 +66,16 @@ bool ED_geometry_attribute_convert(Mesh *mesh,
|
||||||
|
|
||||||
namespace blender::ed::geometry {
|
namespace blender::ed::geometry {
|
||||||
|
|
||||||
|
struct GeoOperatorLog {
|
||||||
|
std::string node_group_name;
|
||||||
|
std::unique_ptr<nodes::geo_eval_log::GeoModifierLog> log;
|
||||||
|
|
||||||
|
GeoOperatorLog() = default;
|
||||||
|
~GeoOperatorLog();
|
||||||
|
};
|
||||||
|
|
||||||
|
const GeoOperatorLog &node_group_operator_static_eval_log();
|
||||||
|
|
||||||
MenuType node_group_operator_assets_menu();
|
MenuType node_group_operator_assets_menu();
|
||||||
MenuType node_group_operator_assets_menu_unassigned();
|
MenuType node_group_operator_assets_menu_unassigned();
|
||||||
|
|
||||||
|
|
|
@ -340,6 +340,9 @@ class GeoModifierLog {
|
||||||
*/
|
*/
|
||||||
static Map<const bke::bNodeTreeZone *, ComputeContextHash>
|
static Map<const bke::bNodeTreeZone *, ComputeContextHash>
|
||||||
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, StringRefNull modifier_name);
|
||||||
|
static Map<const bke::bNodeTreeZone *, ComputeContextHash>
|
||||||
|
get_context_hash_by_zone_for_node_editor(const SpaceNode &snode,
|
||||||
|
ComputeContextBuilder &compute_context_builder);
|
||||||
|
|
||||||
static Map<const bke::bNodeTreeZone *, GeoTreeLog *> get_tree_log_by_zone_for_node_editor(
|
static Map<const bke::bNodeTreeZone *, GeoTreeLog *> get_tree_log_by_zone_for_node_editor(
|
||||||
const SpaceNode &snode);
|
const SpaceNode &snode);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "DNA_modifier_types.h"
|
#include "DNA_modifier_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "ED_geometry.hh"
|
||||||
#include "ED_node.hh"
|
#include "ED_node.hh"
|
||||||
#include "ED_viewer_path.hh"
|
#include "ED_viewer_path.hh"
|
||||||
|
|
||||||
|
@ -532,11 +533,9 @@ static void find_tree_zone_hash_recursive(
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<const bNodeTreeZone *, ComputeContextHash> GeoModifierLog::
|
Map<const bNodeTreeZone *, ComputeContextHash> 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<bke::ModifierComputeContext>(modifier_name);
|
|
||||||
|
|
||||||
if (!ed::space_node::push_compute_context_for_tree_path(snode, compute_context_builder)) {
|
if (!ed::space_node::push_compute_context_for_tree_path(snode, compute_context_builder)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -553,27 +552,58 @@ Map<const bNodeTreeZone *, ComputeContextHash> GeoModifierLog::
|
||||||
return hash_by_zone;
|
return hash_by_zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<const bNodeTreeZone *, ComputeContextHash> GeoModifierLog::
|
||||||
|
get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name)
|
||||||
|
{
|
||||||
|
ComputeContextBuilder compute_context_builder;
|
||||||
|
compute_context_builder.push<bke::ModifierComputeContext>(modifier_name);
|
||||||
|
return get_context_hash_by_zone_for_node_editor(snode, compute_context_builder);
|
||||||
|
}
|
||||||
|
|
||||||
Map<const bNodeTreeZone *, GeoTreeLog *> GeoModifierLog::get_tree_log_by_zone_for_node_editor(
|
Map<const bNodeTreeZone *, GeoTreeLog *> GeoModifierLog::get_tree_log_by_zone_for_node_editor(
|
||||||
const SpaceNode &snode)
|
const SpaceNode &snode)
|
||||||
{
|
{
|
||||||
std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
|
switch (SpaceNodeGeometryNodesType(snode.geometry_nodes_type)) {
|
||||||
ed::space_node::get_modifier_for_node_editor(snode);
|
case SNODE_GEOMETRY_MODIFIER: {
|
||||||
if (!object_and_modifier) {
|
std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
|
||||||
return {};
|
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<const bNodeTreeZone *, ComputeContextHash> hash_by_zone =
|
||||||
|
GeoModifierLog::get_context_hash_by_zone_for_node_editor(
|
||||||
|
snode, object_and_modifier->nmd->modifier.name);
|
||||||
|
Map<const bNodeTreeZone *, GeoTreeLog *> 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<bke::OperatorComputeContext>();
|
||||||
|
const Map<const bNodeTreeZone *, ComputeContextHash> hash_by_zone =
|
||||||
|
GeoModifierLog::get_context_hash_by_zone_for_node_editor(snode, compute_context_builder);
|
||||||
|
Map<const bNodeTreeZone *, GeoTreeLog *> 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();
|
BLI_assert_unreachable();
|
||||||
if (modifier_log == nullptr) {
|
return {};
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const Map<const bNodeTreeZone *, ComputeContextHash> hash_by_zone =
|
|
||||||
GeoModifierLog::get_context_hash_by_zone_for_node_editor(
|
|
||||||
snode, object_and_modifier->nmd->modifier.name);
|
|
||||||
Map<const bNodeTreeZone *, GeoTreeLog *> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path)
|
const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path)
|
||||||
|
|
Loading…
Reference in New Issue
.hh