Geometry Nodes: show single value in viewer node directly

This was originally developed for #144050 but was removed there because wanted to do another UI pass.

Pull Request: https://projects.blender.org/blender/blender/pulls/147525
This commit is contained in:
Jacques Lucke
2025-10-07 16:50:47 +02:00
parent 56bb70fee8
commit d343889930

View File

@@ -5,6 +5,7 @@
#include <fmt/format.h>
#include "BKE_context.hh"
#include "BKE_type_conversions.hh"
#include "BLO_read_write.hh"
@@ -34,6 +35,172 @@ namespace blender::nodes::node_geo_viewer_cc {
NODE_STORAGE_FUNCS(NodeGeometryViewer)
static void draw_float(uiLayout &layout, const float value)
{
const std::string label = fmt::format("{:.5f}", value);
layout.label(label, ICON_NONE);
}
static void draw_int(uiLayout &layout, const int value)
{
const std::string label = fmt::format("{}", value);
layout.label(label, ICON_NONE);
}
static void draw_bool(uiLayout &layout, const bool value)
{
layout.label(value ? IFACE_("True") : IFACE_("False"), ICON_NONE);
}
static void draw_vector(uiLayout &layout, const float3 &value)
{
uiLayout &col = layout.column(true);
col.label(fmt::format("{}: {:.5f}", IFACE_("X"), value.x), ICON_NONE);
col.label(fmt::format("{}: {:.5f}", IFACE_("Y"), value.y), ICON_NONE);
col.label(fmt::format("{}: {:.5f}", IFACE_("Z"), value.z), ICON_NONE);
}
static void draw_color(uiLayout &layout, const ColorGeometry4f &value)
{
uiLayout &col = layout.column(true);
col.label(fmt::format("{}: {:.5f}", IFACE_("R"), value.r), ICON_NONE);
col.label(fmt::format("{}: {:.5f}", IFACE_("G"), value.g), ICON_NONE);
col.label(fmt::format("{}: {:.5f}", IFACE_("B"), value.b), ICON_NONE);
col.label(fmt::format("{}: {:.5f}", IFACE_("A"), value.a), ICON_NONE);
}
static void draw_string(uiLayout &layout, const StringRef value)
{
/* The node doesn't get wider than that anyway. */
const int max_display_length = 200;
layout.label(value.substr(0, max_display_length), ICON_NONE);
}
static bool draw_from_viewer_log_value(CustomSocketDrawParams &params,
geo_eval_log::GeoTreeLog &tree_log)
{
tree_log.ensure_viewer_node_logs();
geo_eval_log::ViewerNodeLog *viewer_log = tree_log.viewer_node_logs.lookup_default(
params.node.identifier, nullptr);
if (!viewer_log) {
return false;
}
const int socket_index = params.socket.index();
const auto &storage = *static_cast<NodeGeometryViewer *>(params.node.storage);
const NodeGeometryViewerItem &viewer_item = storage.items[socket_index];
const geo_eval_log::ViewerNodeLog::Item *item_log = viewer_log->items.lookup_key_ptr_as(
viewer_item.identifier);
if (!item_log) {
return false;
}
const bke::SocketValueVariant &value = item_log->value;
if (!value.is_single()) {
return false;
}
const GPointer single_value = value.get_single_ptr();
if (single_value.is_type<float>()) {
draw_float(params.layout, *single_value.get<float>());
return true;
}
if (single_value.is_type<float3>()) {
draw_vector(params.layout, *single_value.get<float3>());
return true;
}
if (single_value.is_type<int>()) {
draw_int(params.layout, *single_value.get<int>());
return true;
}
if (single_value.is_type<bool>()) {
draw_bool(params.layout, *single_value.get<bool>());
return true;
}
if (single_value.is_type<std::string>()) {
draw_string(params.layout, *single_value.get<std::string>());
return true;
}
if (single_value.is_type<ColorGeometry4f>()) {
draw_color(params.layout, *single_value.get<ColorGeometry4f>());
return true;
}
return false;
}
static bool draw_generic_value_log(CustomSocketDrawParams &params, const GPointer &value)
{
const CPPType &value_type = *params.socket.typeinfo->base_cpp_type;
const CPPType &socket_base_cpp_type = *params.socket.typeinfo->base_cpp_type;
const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
if (value_type != socket_base_cpp_type) {
if (!conversions.is_convertible(value_type, socket_base_cpp_type)) {
return false;
}
}
BUFFER_FOR_CPP_TYPE_VALUE(socket_base_cpp_type, socket_value);
conversions.convert_to_uninitialized(
value_type, socket_base_cpp_type, value.get(), socket_value);
BLI_SCOPED_DEFER([&]() { socket_base_cpp_type.destruct(socket_value); });
switch (params.socket.type) {
case SOCK_INT:
draw_int(params.layout, *static_cast<int *>(socket_value));
return true;
case SOCK_FLOAT:
draw_float(params.layout, *static_cast<float *>(socket_value));
return true;
case SOCK_VECTOR:
draw_vector(params.layout, *static_cast<float3 *>(socket_value));
return true;
case SOCK_RGBA:
draw_color(params.layout, *static_cast<ColorGeometry4f *>(socket_value));
return true;
case SOCK_BOOLEAN:
draw_bool(params.layout, *static_cast<bool *>(socket_value));
return true;
default:
return false;
}
return false;
}
static bool draw_from_socket_log_value(CustomSocketDrawParams &params,
geo_eval_log::GeoTreeLog &tree_log)
{
tree_log.ensure_socket_values();
geo_eval_log::ValueLog *value_log = tree_log.find_socket_value_log(params.socket);
if (!value_log) {
return false;
}
if (const auto *generic_value_log = dynamic_cast<const geo_eval_log::GenericValueLog *>(
value_log))
{
return draw_generic_value_log(params, generic_value_log->value);
}
if (const auto *string_value_log = dynamic_cast<const geo_eval_log::StringLog *>(value_log)) {
draw_string(params.layout, string_value_log->value);
return true;
}
return false;
}
static void draw_input_socket(CustomSocketDrawParams &params)
{
SpaceNode *snode = CTX_wm_space_node(&params.C);
if (!snode) {
params.draw_standard(params.layout);
return;
}
snode->edittree->ensure_topology_cache();
const bNodeSocket &socket = params.socket;
if (!socket.is_directly_linked()) {
params.draw_standard(params.layout);
return;
}
const geo_eval_log::ContextualGeoTreeLogs geo_tree_logs =
geo_eval_log::GeoNodesLog::get_contextual_tree_logs(*snode);
geo_eval_log::GeoTreeLog *tree_log = geo_tree_logs.get_main_tree_log(params.node);
if (!tree_log) {
params.draw_standard(params.layout);
return;
}
if (draw_from_viewer_log_value(params, *tree_log)) {
return;
}
if (draw_from_socket_log_value(params, *tree_log)) {
return;
}
params.draw_standard(params.layout);
}
static void node_declare(NodeDeclarationBuilder &b)
{
b.use_custom_socket_order();
@@ -61,6 +228,7 @@ static void node_declare(NodeDeclarationBuilder &b)
input_decl.field_on_all();
}
input_decl.structure_type(StructureType::Dynamic);
input_decl.custom_draw([](CustomSocketDrawParams &params) { draw_input_socket(params); });
}
b.add_input<decl::Extend>("", "__extend__").structure_type(StructureType::Dynamic);