diff --git a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc index 50c46bcf69f..364b46db519 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc @@ -5,6 +5,7 @@ #include #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(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()) { + draw_float(params.layout, *single_value.get()); + return true; + } + if (single_value.is_type()) { + draw_vector(params.layout, *single_value.get()); + return true; + } + if (single_value.is_type()) { + draw_int(params.layout, *single_value.get()); + return true; + } + if (single_value.is_type()) { + draw_bool(params.layout, *single_value.get()); + return true; + } + if (single_value.is_type()) { + draw_string(params.layout, *single_value.get()); + return true; + } + if (single_value.is_type()) { + draw_color(params.layout, *single_value.get()); + 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(socket_value)); + return true; + case SOCK_FLOAT: + draw_float(params.layout, *static_cast(socket_value)); + return true; + case SOCK_VECTOR: + draw_vector(params.layout, *static_cast(socket_value)); + return true; + case SOCK_RGBA: + draw_color(params.layout, *static_cast(socket_value)); + return true; + case SOCK_BOOLEAN: + draw_bool(params.layout, *static_cast(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( + value_log)) + { + return draw_generic_value_log(params, generic_value_log->value); + } + if (const auto *string_value_log = dynamic_cast(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("", "__extend__").structure_type(StructureType::Dynamic);