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:
@@ -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 ¶ms,
|
||||
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 ¶ms, 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 ¶ms,
|
||||
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 ¶ms)
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(¶ms.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 ¶ms) { draw_input_socket(params); });
|
||||
}
|
||||
|
||||
b.add_input<decl::Extend>("", "__extend__").structure_type(StructureType::Dynamic);
|
||||
|
||||
Reference in New Issue
Block a user