Blender V4.3
overlay_viewer_text.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "DNA_curve_types.h"
12
13#include "BKE_attribute.hh"
14#include "BKE_curves.hh"
15#include "BKE_duplilist.hh"
16#include "BKE_geometry_set.hh"
17#include "BKE_instances.hh"
18#include "BKE_mesh.hh"
19#include "BKE_pointcloud.hh"
20
21#include "DRW_render.hh"
22
23#include "UI_resources.hh"
24
25#include "draw_manager_text.hh"
26
27#include "overlay_private.hh"
28
29namespace blender::draw::overlay {
30
31static void add_values_to_text_cache(const GVArray &values,
32 const Span<float3> positions,
33 const float4x4 &object_to_world)
34{
36
37 uchar col[4];
39
40 bke::attribute_math::convert_to_static_type(values.type(), [&](auto dummy) {
41 using T = decltype(dummy);
42 const VArray<T> &values_typed = values.typed<T>();
43 for (const int i : values.index_range()) {
44 const float3 position = math::transform_point(object_to_world, positions[i]);
45 const T &value = values_typed[i];
46
47 char numstr[64];
48 size_t numstr_len = 0;
49 if constexpr (std::is_same_v<T, bool>) {
50 numstr_len = SNPRINTF_RLEN(numstr, "%s", value ? "True" : "False");
51 }
52 else if constexpr (std::is_same_v<T, int8_t>) {
53 numstr_len = SNPRINTF_RLEN(numstr, "%d", int(value));
54 }
55 else if constexpr (std::is_same_v<T, int>) {
56 numstr_len = SNPRINTF_RLEN(numstr, "%d", value);
57 }
58 else if constexpr (std::is_same_v<T, int2>) {
59 numstr_len = SNPRINTF_RLEN(numstr, "(%d, %d)", value.x, value.y);
60 }
61 else if constexpr (std::is_same_v<T, float>) {
62 numstr_len = SNPRINTF_RLEN(numstr, "%g", value);
63 }
64 else if constexpr (std::is_same_v<T, float2>) {
65 numstr_len = SNPRINTF_RLEN(numstr, "(%g, %g)", value.x, value.y);
66 }
67 else if constexpr (std::is_same_v<T, float3>) {
68 numstr_len = SNPRINTF_RLEN(numstr, "(%g, %g, %g)", value.x, value.y, value.z);
69 }
70 else if constexpr (std::is_same_v<T, ColorGeometry4b>) {
71 const ColorGeometry4f color = value.decode();
72 numstr_len = SNPRINTF_RLEN(
73 numstr, "(%.3f, %.3f, %.3f, %.3f)", color.r, color.g, color.b, color.a);
74 }
75 else if constexpr (std::is_same_v<T, ColorGeometry4f>) {
76 numstr_len = SNPRINTF_RLEN(
77 numstr, "(%.3f, %.3f, %.3f, %.3f)", value.r, value.g, value.b, value.a);
78 }
79 else if constexpr (std::is_same_v<T, math::Quaternion>) {
80 numstr_len = SNPRINTF_RLEN(
81 numstr, "(%.3f, %.3f, %.3f, %.3f)", value.w, value.x, value.y, value.z);
82 }
83 else {
84 BLI_assert_unreachable();
85 }
86
87 DRW_text_cache_add(
88 dt, position, numstr, numstr_len, 0, 0, DRW_TEXT_CACHE_GLOBALSPACE, col, true, true);
89 }
90 });
91}
92
94 const float4x4 &object_to_world)
95{
96 if (!attribute_accessor.contains(".viewer")) {
97 return;
98 }
99
100 const bke::GAttributeReader attribute = attribute_accessor.lookup(".viewer");
101 const VArraySpan<float3> positions = *attribute_accessor.lookup<float3>("position",
102 attribute.domain);
103
104 add_values_to_text_cache(attribute.varray, positions, object_to_world);
105}
106
108 const float4x4 &object_to_world,
109 int instance_index)
110{
111 /* Data from instances are read as a single value from a given index. The data is converted back
112 * to an array so one function can handle both instance and object data. */
113 const GVArray attribute = attribute_accessor.lookup(".viewer").varray.slice(
114 IndexRange(instance_index, 1));
115
116 add_values_to_text_cache(attribute, {float3(0, 0, 0)}, object_to_world);
117}
118
119} // namespace blender::draw::overlay
120
122{
123 using namespace blender;
124 using namespace blender::draw::overlay;
125 const float4x4 &object_to_world = object.object_to_world();
126 DupliObject *dupli_object = DRW_object_get_dupli(&object);
127
128 if (dupli_object->preview_instance_index >= 0) {
129 const bke::Instances *instances = dupli_object->preview_base_geometry->get_instances();
130 if (instances->attributes().contains(".viewer")) {
131 add_instance_attributes_to_text_cache(
132 instances->attributes(), object_to_world, dupli_object->preview_instance_index);
133
134 return;
135 }
136 }
137
138 switch (object.type) {
139 case OB_MESH: {
140 const Mesh *mesh = static_cast<Mesh *>(object.data);
141 add_attributes_to_text_cache(mesh->attributes(), object_to_world);
142 break;
143 }
144 case OB_POINTCLOUD: {
145 const PointCloud *pointcloud = static_cast<PointCloud *>(object.data);
146 add_attributes_to_text_cache(pointcloud->attributes(), object_to_world);
147 break;
148 }
149 case OB_CURVES_LEGACY: {
150 const Curve *curve = static_cast<Curve *>(object.data);
151 if (curve->curve_eval) {
152 const bke::CurvesGeometry &curves = curve->curve_eval->geometry.wrap();
153 add_attributes_to_text_cache(curves.attributes(), object_to_world);
154 }
155 break;
156 }
157 case OB_CURVES: {
158 const Curves *curves_id = static_cast<Curves *>(object.data);
159 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
160 add_attributes_to_text_cache(curves.attributes(), object_to_world);
161 break;
162 }
163 }
164}
Low-level operations for curves.
General operations for point clouds.
unsigned char uchar
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES_LEGACY
@ OB_CURVES
@ TH_TEXT_HI
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
AttributeSet attributes
GVArray slice(IndexRange slice) const
GAttributeReader lookup(const StringRef attribute_id) const
bool contains(const StringRef attribute_id) const
DRWTextStore * DRW_text_cache_ensure()
DupliObject * DRW_object_get_dupli(const Object *)
uint col
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
static void add_attributes_to_text_cache(bke::AttributeAccessor attribute_accessor, const float4x4 &object_to_world)
static void add_values_to_text_cache(const GVArray &values, const Span< float3 > positions, const float4x4 &object_to_world)
static void add_instance_attributes_to_text_cache(bke::AttributeAccessor attribute_accessor, const float4x4 &object_to_world, int instance_index)
void OVERLAY_viewer_attribute_text(const Object &object)
CurvesGeometry geometry
const blender::bke::GeometrySet * preview_base_geometry
int preview_instance_index
const Instances * get_instances() const