Blender V4.3
draw_manager_text.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "BLI_math_geom.h"
12#include "BLI_math_matrix.h"
13#include "BLI_math_matrix.hh"
14#include "BLI_math_rotation.h"
15#include "BLI_math_vector.h"
16#include "BLI_memiter.h"
17#include "BLI_rect.h"
18#include "BLI_string.h"
19
20#include "BKE_editmesh.hh"
21#include "BKE_editmesh_cache.hh"
22#include "BKE_global.hh"
23#include "BKE_mesh.hh"
24#include "BKE_mesh_types.hh"
25#include "BKE_mesh_wrapper.hh"
26#include "BKE_object.hh"
27#include "BKE_unit.hh"
28
29#include "DNA_mesh_types.h"
30#include "DNA_object_types.h"
31#include "DNA_scene_types.h"
32#include "DNA_screen_types.h"
33#include "DNA_view3d_types.h"
34
35#include "GPU_matrix.hh"
36#include "GPU_state.hh"
37
38#include "ED_screen.hh"
39#include "ED_view3d.hh"
40
41#include "UI_interface.hh"
42#include "UI_resources.hh"
43
44#include "BLF_api.hh"
45#include "WM_api.hh"
46
47#include "draw_manager_text.hh"
49
50using blender::float3;
51using blender::Span;
52
54 float vec[3];
55 union {
57 int pack;
58 } col;
59 short sco[2];
60 short xoffs, yoffs;
61 short flag;
63 bool shadow;
65
66 /* str is allocated past the end */
67 char str[0];
68};
69
73
75{
76 DRWTextStore *dt = MEM_cnew<DRWTextStore>(__func__);
77 dt->cache_strings = BLI_memiter_create(1 << 14); /* 16kb */
78 return dt;
79}
80
86
88 const float co[3],
89 const char *str,
90 const int str_len,
91 short xoffs,
92 short yoffs,
93 short flag,
94 const uchar col[4],
95 const bool shadow,
96 const bool align_center)
97{
98 int alloc_len;
100
102 BLI_assert(str_len == strlen(str));
103 alloc_len = sizeof(void *);
104 }
105 else {
106 alloc_len = str_len + 1;
107 }
108
109 vos = static_cast<ViewCachedString *>(
110 BLI_memiter_alloc(dt->cache_strings, sizeof(ViewCachedString) + alloc_len));
111
112 copy_v3_v3(vos->vec, co);
113 copy_v4_v4_uchar(vos->col.ub, col);
114 vos->xoffs = xoffs;
115 vos->yoffs = yoffs;
116 vos->flag = flag;
117 vos->str_len = str_len;
118 vos->shadow = shadow;
119 vos->align_center = align_center;
120
121 /* allocate past the end */
123 memcpy(vos->str, &str, alloc_len);
124 }
125 else {
126 memcpy(vos->str, str, alloc_len);
127 }
128}
129
131{
132 ViewCachedString *vos;
134 int col_pack_prev = 0;
135
136 float original_proj[4][4];
137 GPU_matrix_projection_get(original_proj);
139
142
143 BLF_default_size(UI_style_get()->widget.points);
144 const int font_id = BLF_set_default();
145
146 float outline_dark_color[4] = {0, 0, 0, 0.8f};
147 float outline_light_color[4] = {1, 1, 1, 0.8f};
148 bool outline_is_dark = true;
149
151 while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
152 if (vos->sco[0] != IS_CLIPPED) {
153 if (col_pack_prev != vos->col.pack) {
154 BLF_color4ubv(font_id, vos->col.ub);
155 const uchar lightness = rgb_to_grayscale_byte(vos->col.ub);
156 outline_is_dark = lightness > 96;
157 col_pack_prev = vos->col.pack;
158 }
159
160 if (vos->align_center) {
161 /* Measure the size of the string, then offset to align to the vertex. */
162 float width, height;
163 BLF_width_and_height(font_id,
164 (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) :
165 vos->str,
166 vos->str_len,
167 &width,
168 &height);
169 vos->xoffs -= short(width / 2.0f);
170 vos->yoffs -= short(height / 2.0f);
171 }
172
173 const int font_id = BLF_default();
174 if (vos->shadow) {
175 BLF_enable(font_id, BLF_SHADOW);
176 BLF_shadow(font_id,
178 outline_is_dark ? outline_dark_color : outline_light_color);
179 BLF_shadow_offset(font_id, 0, 0);
180 }
181 else {
182 BLF_disable(font_id, BLF_SHADOW);
183 }
184 BLF_draw_default(float(vos->sco[0] + vos->xoffs),
185 float(vos->sco[1] + vos->yoffs),
186 2.0f,
187 (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) :
188 vos->str,
189 vos->str_len);
190 }
191 }
192
194 GPU_matrix_projection_set(original_proj);
195}
196
198{
199 ViewCachedString *vos;
200 if (v3d) {
201 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
202 int tot = 0;
203 /* project first and test */
206 while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
208 region,
209 (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
210 (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0,
211 vos->vec,
212 vos->sco,
215 {
216 tot++;
217 }
218 else {
219 vos->sco[0] = IS_CLIPPED;
220 }
221 }
222
223 if (tot) {
224 /* Disable clipping for text */
225 const bool rv3d_clipping_enabled = RV3D_CLIPPING_ENABLED(v3d, rv3d);
226 if (rv3d_clipping_enabled) {
228 }
229
230 drw_text_cache_draw_ex(dt, region);
231
232 if (rv3d_clipping_enabled) {
234 }
235 }
236 }
237 else {
238 /* project first */
241 View2D *v2d = &region->v2d;
242 float viewmat[4][4];
243 rctf region_space = {0.0f, float(region->winx), 0.0f, float(region->winy)};
244 BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
245
246 while ((vos = static_cast<ViewCachedString *>(BLI_memiter_iter_step(&it)))) {
247 float p[3];
248 copy_v3_v3(p, vos->vec);
249 mul_m4_v3(viewmat, p);
250
251 vos->sco[0] = p[0];
252 vos->sco[1] = p[1];
253 }
254
255 drw_text_cache_draw_ex(dt, region);
256 }
257}
258
260 const View3D *v3d,
261 const Object *ob,
262 const UnitSettings *unit,
263 DRWTextStore *dt)
264{
265 /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square,
266 * etc.). See bug #36090.
267 */
268 const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE;
269 const Mesh *mesh = BKE_object_get_editmesh_eval_cage(ob);
270 const BMEditMesh *em = mesh->runtime->edit_mesh.get();
271 char numstr[32]; /* Stores the measurement display text here */
272 const char *conv_float; /* Use a float conversion matching the grid size */
273 blender::uchar4 col = {0, 0, 0, 255}; /* color of the text to draw */
274 const float grid = unit->system ? unit->scale_length : v3d->grid;
275 const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0;
276 const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0;
277 blender::float4x4 clip_planes;
278 /* allow for displaying shape keys and deform mods */
279 BMIter iter;
280 const Span<float3> vert_positions = BKE_mesh_wrapper_vert_coords(mesh);
281 const bool use_coords = !vert_positions.is_empty();
282
283 /* when 2 or more edge-info options are enabled, space apart */
284 short edge_tex_count = 0;
286 edge_tex_count += 1;
287 }
289 edge_tex_count += 1;
290 }
292 edge_tex_count += 1;
293 }
294 const short edge_tex_sep = short((edge_tex_count - 1) * 5.0f * UI_SCALE_FAC);
295
296 /* Make the precision of the display value proportionate to the grid-size. */
297
298 if (grid <= 0.01f) {
299 conv_float = "%.6g";
300 }
301 else if (grid <= 0.1f) {
302 conv_float = "%.5g";
303 }
304 else if (grid <= 1.0f) {
305 conv_float = "%.4g";
306 }
307 else if (grid <= 10.0f) {
308 conv_float = "%.3g";
309 }
310 else {
311 conv_float = "%.2g";
312 }
313
314 if (v3d->overlay.edit_flag &
316 {
317 BoundBox bb;
318 const rcti rect = {0, region->winx, 0, region->winy};
319
320 ED_view3d_clipping_calc(&bb, clip_planes.ptr(), region, ob, &rect);
321 }
322
324 BMEdge *eed;
325
327
328 if (use_coords) {
330 }
331
332 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
333 /* draw selected edges, or edges next to selected verts while dragging */
335 (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
337 {
338 float3 v1, v2;
339 float3 v1_clip, v2_clip;
340
341 if (use_coords) {
342 v1 = vert_positions[BM_elem_index_get(eed->v1)];
343 v2 = vert_positions[BM_elem_index_get(eed->v2)];
344 }
345 else {
346 v1 = eed->v1->co;
347 v2 = eed->v2->co;
348 }
349
350 if (clip_segment_v3_plane_n(v1, v2, clip_planes.ptr(), 4, v1_clip, v2_clip)) {
351 const float3 co = blender::math::transform_point(ob->object_to_world(),
352 0.5 * (v1_clip + v2_clip));
353
354 if (do_global) {
355 v1 = ob->object_to_world().view<3, 3>() * v1;
356 v2 = ob->object_to_world().view<3, 3>() * v2;
357 }
358
359 const size_t numstr_len = unit->system ?
361 sizeof(numstr),
362 len_v3v3(v1, v2) *
363 unit->scale_length,
364 3,
366 unit,
367 false) :
368 SNPRINTF_RLEN(numstr, conv_float, len_v3v3(v1, v2));
369
370 DRW_text_cache_add(dt, co, numstr, numstr_len, 0, edge_tex_sep, txt_flag, col);
371 }
372 }
373 }
374 }
375
377 const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS);
378 BMEdge *eed;
379
381
382 Span<float3> face_normals;
383 if (use_coords) {
385 /* TODO: This is not const correct for wrapper meshes, but it should be okay because
386 * every evaluated object gets its own evaluated cage mesh (they are not shared). */
387 face_normals = BKE_mesh_wrapper_face_normals(const_cast<Mesh *>(mesh));
388 }
389
390 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
391 BMLoop *l_a, *l_b;
392 if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
393 /* Draw selected edges, or edges next to selected verts while dragging. */
395 (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
397 /* Special case, this is useful to show when verts connected
398 * to this edge via a face are being transformed. */
403 {
404 float3 v1, v2;
405 float3 v1_clip, v2_clip;
406
407 if (use_coords) {
408 v1 = vert_positions[BM_elem_index_get(eed->v1)];
409 v2 = vert_positions[BM_elem_index_get(eed->v2)];
410 }
411 else {
412 v1 = eed->v1->co;
413 v2 = eed->v2->co;
414 }
415
416 if (clip_segment_v3_plane_n(v1, v2, clip_planes.ptr(), 4, v1_clip, v2_clip)) {
417 float3 no_a, no_b;
418
419 const float3 co = blender::math::transform_point(ob->object_to_world(),
420 0.5 * (v1_clip + v2_clip));
421
422 if (use_coords) {
423 no_a = face_normals[BM_elem_index_get(l_a->f)];
424 no_b = face_normals[BM_elem_index_get(l_b->f)];
425 }
426 else {
427 no_a = l_a->f->no;
428 no_b = l_b->f->no;
429 }
430
431 if (do_global) {
432 no_a = blender::math::normalize(ob->world_to_object().view<3, 3>() * no_a);
433 no_b = blender::math::normalize(ob->world_to_object().view<3, 3>() * no_b);
434 }
435
436 const float angle = angle_normalized_v3v3(no_a, no_b);
437
438 const size_t numstr_len = SNPRINTF_RLEN(numstr,
439 "%.3f%s",
440 (is_rad) ? angle : RAD2DEGF(angle),
441 (is_rad) ? "r" : BLI_STR_UTF8_DEGREE_SIGN);
442
443 DRW_text_cache_add(dt, co, numstr, numstr_len, 0, -edge_tex_sep, txt_flag, col);
444 }
445 }
446 }
447 }
448 }
449
451 /* would be nice to use BM_face_calc_area, but that is for 2d faces
452 * so instead add up tessellation triangle areas */
453
455
456 int i;
457 BMFace *f = nullptr;
458 /* Alternative to using `poly_to_tri_count(i, BM_elem_index_get(f->l_first))`
459 * without having to add an extra loop. */
460 int tri_index = 0;
461 BM_ITER_MESH_INDEX (f, &iter, em->bm, BM_FACES_OF_MESH, i) {
462 const int f_corner_tris_len = f->len - 2;
464 int n = 0;
465 float area = 0; /* area of the face */
466 float3 vmid(0.0f);
467 const std::array<BMLoop *, 3> *ltri_array = &em->looptris[tri_index];
468 for (int j = 0; j < f_corner_tris_len; j++) {
469 float3 v1, v2, v3;
470
471 if (use_coords) {
472 v1 = vert_positions[BM_elem_index_get(ltri_array[j][0]->v)];
473 v2 = vert_positions[BM_elem_index_get(ltri_array[j][1]->v)];
474 v3 = vert_positions[BM_elem_index_get(ltri_array[j][2]->v)];
475 }
476 else {
477 v1 = ltri_array[j][0]->v->co;
478 v2 = ltri_array[j][1]->v->co;
479 v3 = ltri_array[j][2]->v->co;
480 }
481
482 vmid += v1;
483 vmid += v2;
484 vmid += v3;
485 n += 3;
486
487 if (do_global) {
488 v1 = ob->object_to_world().view<3, 3>() * v1;
489 v2 = ob->object_to_world().view<3, 3>() * v2;
490 v3 = ob->object_to_world().view<3, 3>() * v3;
491 }
492
493 area += area_tri_v3(v1, v2, v3);
494 }
495
496 vmid *= 1.0f / float(n);
497 vmid = blender::math::transform_point(ob->object_to_world(), vmid);
498
499 const size_t numstr_len = unit->system ?
501 numstr,
502 sizeof(numstr),
503 double(area * unit->scale_length * unit->scale_length),
504 3,
506 unit,
507 false) :
508 SNPRINTF_RLEN(numstr, conv_float, area);
509
510 DRW_text_cache_add(dt, vmid, numstr, numstr_len, 0, 0, txt_flag, col);
511 }
512 tri_index += f_corner_tris_len;
513 }
514 }
515
517 BMFace *efa;
518 const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS);
519
521
522 if (use_coords) {
524 }
525
526 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
527 const bool is_face_sel = BM_elem_flag_test_bool(efa, BM_ELEM_SELECT);
528
529 if (is_face_sel || do_moving) {
530 BMIter liter;
531 BMLoop *loop;
532 bool is_first = true;
533
534 BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
535 if (is_face_sel || (do_moving && (BM_elem_flag_test(loop->v, BM_ELEM_SELECT) ||
538 {
539 float3 v1, v2, v3;
540 float3 vmid;
541
542 /* lazy init center calc */
543 if (is_first) {
544 if (use_coords) {
545 BM_face_calc_center_bounds_vcos(em->bm, efa, vmid, vert_positions);
546 }
547 else {
549 }
550 is_first = false;
551 }
552 if (use_coords) {
553 v1 = vert_positions[BM_elem_index_get(loop->prev->v)];
554 v2 = vert_positions[BM_elem_index_get(loop->v)];
555 v3 = vert_positions[BM_elem_index_get(loop->next->v)];
556 }
557 else {
558 v1 = loop->prev->v->co;
559 v2 = loop->v->co;
560 v3 = loop->next->v->co;
561 }
562
563 const float3 v2_local = v2;
564
565 if (do_global) {
566 v1 = ob->object_to_world().view<3, 3>() * v1;
567 v2 = ob->object_to_world().view<3, 3>() * v2;
568 v3 = ob->object_to_world().view<3, 3>() * v3;
569 }
570
571 const float angle = angle_v3v3v3(v1, v2, v3);
572
573 const size_t numstr_len = SNPRINTF_RLEN(numstr,
574 "%.3f%s",
575 (is_rad) ? angle : RAD2DEGF(angle),
576 (is_rad) ? "r" : BLI_STR_UTF8_DEGREE_SIGN);
578 ob->object_to_world(), blender::math::interpolate(vmid, v2_local, 0.8f));
579 DRW_text_cache_add(dt, co, numstr, numstr_len, 0, 0, txt_flag, col);
580 }
581 }
582 }
583 }
584 }
585
586 /* This option is for mesh ops and addons debugging; only available in UI if Blender starts
587 * with
588 * --debug */
590 int i;
591
592 /* For now, reuse an appropriate theme color */
594
595 if (em->selectmode & SCE_SELECT_VERTEX) {
596 BMVert *v;
597
598 if (use_coords) {
600 }
601 BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
604 ob->object_to_world(), use_coords ? vert_positions[BM_elem_index_get(v)] : v->co);
605
606 const size_t numstr_len = SNPRINTF_RLEN(numstr, "%d", i);
607 DRW_text_cache_add(dt, co, numstr, numstr_len, 0, 0, txt_flag, col);
608 }
609 }
610 }
611
612 if (em->selectmode & SCE_SELECT_EDGE) {
613 BMEdge *eed;
614
615 const bool use_edge_tex_sep = (edge_tex_count == 2);
616 const bool use_edge_tex_len = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGE_LEN);
617
618 BM_ITER_MESH_INDEX (eed, &iter, em->bm, BM_EDGES_OF_MESH, i) {
620 float3 v1, v2;
621 float3 v1_clip, v2_clip;
622
623 if (use_coords) {
624 v1 = vert_positions[BM_elem_index_get(eed->v1)];
625 v2 = vert_positions[BM_elem_index_get(eed->v2)];
626 }
627 else {
628 v1 = eed->v1->co;
629 v2 = eed->v2->co;
630 }
631
632 if (clip_segment_v3_plane_n(v1, v2, clip_planes.ptr(), 4, v1_clip, v2_clip)) {
633 const float3 co = blender::math::transform_point(ob->object_to_world(),
634 0.5 * (v1_clip + v2_clip));
635
636 const size_t numstr_len = SNPRINTF_RLEN(numstr, "%d", i);
638 dt,
639 co,
640 numstr,
641 numstr_len,
642 0,
643 (use_edge_tex_sep) ? (use_edge_tex_len) ? -edge_tex_sep : edge_tex_sep : 0,
644 txt_flag,
645 col);
646 }
647 }
648 }
649 }
650
651 if (em->selectmode & SCE_SELECT_FACE) {
652 BMFace *f;
653
654 if (use_coords) {
656 }
657
658 BM_ITER_MESH_INDEX (f, &iter, em->bm, BM_FACES_OF_MESH, i) {
660 float3 co;
661
662 if (use_coords) {
663 BM_face_calc_center_median_vcos(em->bm, f, co, vert_positions);
664 }
665 else {
667 }
668
669 co = blender::math::transform_point(ob->object_to_world(), co);
670
671 const size_t numstr_len = SNPRINTF_RLEN(numstr, "%d", i);
672 DRW_text_cache_add(dt, co, numstr, numstr_len, 0, 0, txt_flag, col);
673 }
674 }
675 }
676 }
677}
@ G_TRANSFORM_EDIT
blender::Span< blender::float3 > BKE_mesh_wrapper_face_normals(Mesh *mesh)
blender::Span< blender::float3 > BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
@ B_UNIT_AREA
Definition BKE_unit.hh:108
@ B_UNIT_LENGTH
Definition BKE_unit.hh:107
size_t BKE_unit_value_as_string(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings *settings, bool pad)
Definition unit.cc:1876
int BLF_set_default()
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4]=nullptr)
Definition blf.cc:902
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
Definition blf.cc:778
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:914
void BLF_disable(int fontid, int option)
Definition blf.cc:321
int BLF_default()
void BLF_default_size(float size)
void BLF_enable(int fontid, int option)
Definition blf.cc:312
@ BLF_SHADOW
Definition BLF_api.hh:363
void BLF_color4ubv(int fontid, const unsigned char rgba[4])
Definition blf.cc:435
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3])
bool clip_segment_v3_plane_n(const float p1[3], const float p2[3], const float plane_array[][4], int plane_num, float r_p1[3], float r_p2[3])
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition math_geom.cc:98
void mul_m4_v3(const float M[4][4], float r[3])
#define RAD2DEGF(_rad)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
void BLI_memiter_destroy(BLI_memiter *mi) ATTR_NONNULL(1)
void * BLI_memiter_iter_step(BLI_memiter_handle *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
BLI_memiter * BLI_memiter_create(unsigned int chunk_size_min) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
void * BLI_memiter_alloc(BLI_memiter *mi, unsigned int elem_size) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_memiter_iter_init(BLI_memiter *mi, BLI_memiter_handle *iter) ATTR_NONNULL(1
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
Definition rct.c:555
#define SNPRINTF_RLEN(dst, format,...)
Definition BLI_string.h:598
#define BLI_STR_UTF8_DEGREE_SIGN
unsigned char uchar
Object is a sort of wrapper for general info.
@ USER_UNIT_ROT_RADIANS
@ SCE_SELECT_FACE
@ SCE_SELECT_VERTEX
@ SCE_SELECT_EDGE
#define UI_SCALE_FAC
@ V3D_OVERLAY_EDIT_INDICES
@ V3D_OVERLAY_EDIT_FACE_AREA
@ V3D_OVERLAY_EDIT_EDGE_ANG
@ V3D_OVERLAY_EDIT_FACE_ANG
@ V3D_OVERLAY_EDIT_EDGE_LEN
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ V3D_GLOBAL_STATS
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *region, const Object *ob, const rcti *rect)
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:269
@ V3D_PROJ_TEST_CLIP_WIN
Definition ED_view3d.hh:268
@ V3D_PROJ_TEST_CLIP_BB
Definition ED_view3d.hh:267
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
#define IS_CLIPPED
Definition ED_view3d.hh:239
eV3DProjStatus ED_view3d_project_short_ex(const ARegion *region, float perspmat[4][4], bool is_local, const float co[3], short r_co[2], eV3DProjTest flag)
void GPU_matrix_identity_set()
void GPU_matrix_push()
#define GPU_matrix_projection_get(x)
#define GPU_matrix_projection_set(x)
void GPU_matrix_pop()
void GPU_clip_distances(int distances_enabled)
Definition gpu_state.cc:124
Read Guarded memory(de)allocation.
const uiStyle * UI_style_get()
@ TH_DRAWEXTRA_EDGEANG
@ TH_DRAWEXTRA_FACEANG
@ TH_DRAWEXTRA_EDGELEN
@ TH_DRAWEXTRA_FACEAREA
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
@ BM_ELEM_SELECT
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_test_bool(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_FACE
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
#define BM_FACE
#define BM_VERT
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
void BM_face_calc_center_bounds_vcos(const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_face_calc_center_median_vcos(const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr bool is_empty() const
Definition BLI_span.hh:261
void DRW_text_cache_add(DRWTextStore *dt, const float co[3], const char *str, const int str_len, short xoffs, short yoffs, short flag, const uchar col[4], const bool shadow, const bool align_center)
DRWTextStore * DRW_text_cache_create()
void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, View3D *v3d)
static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region)
void DRW_text_cache_destroy(DRWTextStore *dt)
void DRW_text_edit_mesh_measure_stats(const ARegion *region, const View3D *v3d, const Object *ob, const UnitSettings *unit, DRWTextStore *dt)
@ DRW_TEXT_CACHE_LOCALCLIP
@ DRW_TEXT_CACHE_GLOBALSPACE
@ DRW_TEXT_CACHE_STRING_PTR
draw_view in_light_buf[] float
#define str(s)
uint col
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
BMVert * v1
BMVert * v2
short selectmode
blender::Array< std::array< BMLoop *, 3 > > looptris
float no[3]
struct BMVert * v
struct BMLoop * prev
struct BMFace * f
struct BMLoop * next
float co[3]
BLI_memiter * cache_strings
float persmat[4][4]
float persmatob[4][4]
View3DOverlay overlay
union ViewCachedString::@296 col
const c_style_mat & ptr() const
void wmOrtho2_region_pixelspace(const ARegion *region)
uint8_t flag
Definition wm_window.cc:138