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
8
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")) {
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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
@ 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
bke::AttributeAccessor attributes() 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)
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
void OVERLAY_viewer_attribute_text(const Object &object)
const struct Curves * curve_eval
CurvesGeometry geometry
const blender::bke::GeometrySet * preview_base_geometry
int preview_instance_index
const Instances * get_instances() const