Blender  V2.93
view3d_gizmo_ruler.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include "BLI_listbase.h"
22 #include "BLI_math.h"
23 #include "BLI_rect.h"
24 #include "BLI_string.h"
25 #include "BLI_utildefines.h"
26 
27 #include "BLT_translation.h"
28 
29 #include "BKE_context.h"
30 #include "BKE_gpencil.h"
31 #include "BKE_main.h"
32 #include "BKE_report.h"
33 
34 #include "BKE_material.h"
35 #include "BKE_object.h"
36 #include "BKE_unit.h"
37 
38 #include "DNA_gpencil_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_view3d_types.h"
42 
43 #include "ED_gizmo_library.h"
44 #include "ED_gizmo_utils.h"
45 #include "ED_gpencil.h"
46 #include "ED_screen.h"
48 #include "ED_view3d.h"
49 
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52 
53 #include "MEM_guardedalloc.h"
54 
55 #include "RNA_access.h"
56 
57 #include "WM_api.h"
58 #include "WM_toolsystem.h"
59 #include "WM_types.h"
60 
61 #include "DEG_depsgraph_query.h"
62 
63 #include "view3d_intern.h" /* own include */
64 
65 #include "GPU_immediate.h"
66 #include "GPU_immediate_util.h"
67 #include "GPU_matrix.h"
68 #include "GPU_state.h"
69 
70 #include "BLF_api.h"
71 
72 static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler";
73 
74 #define MVAL_MAX_PX_DIST 12.0f
75 
76 /* -------------------------------------------------------------------- */
77 /* Ruler Item (we can have many) */
78 
79 enum {
81  RULERITEM_USE_ANGLE = (1 << 0),
84 };
85 
86 /* keep smaller than selection, since we may want click elsewhere without selecting a ruler */
87 #define RULER_PICK_DIST 12.0f
88 #define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST)
89 
90 /* not clicking on a point */
91 #define PART_LINE 0xff
92 
93 /* -------------------------------------------------------------------- */
94 /* Ruler Info (wmGizmoGroup customdata) */
95 
96 enum {
99 };
100 
101 struct RulerItem;
102 
103 typedef struct RulerInfo {
105  int flag;
107  int state;
108 
109  /* wm state */
113  ARegion *region; /* re-assigned every modal update */
114 
115  /* Track changes in state. */
116  struct {
117 #ifndef USE_SNAP_DETECT_FROM_KEYMAP_HACK
118  bool do_snap;
119 #endif
122 
123  struct {
127 
129 
130 /* -------------------------------------------------------------------- */
131 /* Ruler Item (two or three points) */
132 
133 typedef struct RulerItem {
135 
136  /* worldspace coords, middle being optional */
137  float co[3][3];
138 
139  int flag;
140  int raycast_dir; /* RULER_DIRECTION_* */
142 
143 typedef struct RulerInteraction {
144  /* selected coord */
145  char co_index; /* 0 -> 2 */
146  float drag_start_co[3];
148 
149 /* -------------------------------------------------------------------- */
154 {
155  /* could pass this as an arg */
156  const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true);
157  RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL);
158  WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true);
159  return ruler_item;
160 }
161 
162 static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item)
163 {
164  RulerInfo *ruler_info = gzgroup->customdata;
165  if (ruler_info->item_active == ruler_item) {
166  ruler_info->item_active = NULL;
167  }
168  WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C);
169 }
170 
172  RulerItem *ruler_item, UnitSettings *unit, char *numstr, size_t numstr_size, int prec)
173 {
174  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
175  const float ruler_angle = angle_v3v3v3(
176  ruler_item->co[0], ruler_item->co[1], ruler_item->co[2]);
177 
178  if (unit->system == USER_UNIT_NONE) {
179  BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle));
180  }
181  else {
183  numstr, numstr_size, (double)ruler_angle, prec, B_UNIT_ROTATION, unit, false);
184  }
185  }
186  else {
187  const float ruler_len = len_v3v3(ruler_item->co[0], ruler_item->co[2]);
188 
189  if (unit->system == USER_UNIT_NONE) {
190  BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len);
191  }
192  else {
194  numstr_size,
195  (double)(ruler_len * unit->scale_length),
196  prec,
198  unit,
199  false);
200  }
201  }
202 }
203 
204 static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
205  RulerItem *ruler_item,
206  const float mval[2],
207  int *r_co_index)
208 {
209  RulerInfo *ruler_info = gzgroup->customdata;
210  ARegion *region = ruler_info->region;
211  bool found = false;
212 
213  float dist_best = RULER_PICK_DIST_SQ;
214  int co_index_best = -1;
215 
216  {
217  float co_ss[3][2];
218  float dist;
219  int j;
220 
221  /* should these be checked? - ok for now not to */
222  for (j = 0; j < 3; j++) {
223  ED_view3d_project_float_global(region, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
224  }
225 
226  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
227  dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]),
228  dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2]));
229  if (dist < dist_best) {
230  dist_best = dist;
231  found = true;
232 
233  {
234  const float dist_points[3] = {
235  len_squared_v2v2(co_ss[0], mval),
236  len_squared_v2v2(co_ss[1], mval),
237  len_squared_v2v2(co_ss[2], mval),
238  };
239  if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
240  co_index_best = min_axis_v3(dist_points);
241  }
242  else {
243  co_index_best = -1;
244  }
245  }
246  }
247  }
248  else {
249  dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]);
250  if (dist < dist_best) {
251  dist_best = dist;
252  found = true;
253 
254  {
255  const float dist_points[2] = {
256  len_squared_v2v2(co_ss[0], mval),
257  len_squared_v2v2(co_ss[2], mval),
258  };
259  if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
260  co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
261  }
262  else {
263  co_index_best = -1;
264  }
265  }
266  }
267  }
268  }
269 
270  *r_co_index = co_index_best;
271  return found;
272 }
273 
278 static void ruler_state_set(RulerInfo *ruler_info, int state)
279 {
280  if (state == ruler_info->state) {
281  return;
282  }
283 
284  if (state == RULER_STATE_NORMAL) {
285  /* pass */
286  }
287  else if (state == RULER_STATE_DRAG) {
288  memset(&ruler_info->drag_state_prev, 0x0, sizeof(ruler_info->drag_state_prev));
289  }
290  else {
291  BLI_assert(0);
292  }
293 
294  ruler_info->state = state;
295 }
296 
297 static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], const int xy[2])
298 {
299  ED_view3d_win_to_3d_int(ruler_info->area->spacedata.first, ruler_info->region, r_co, xy, r_co);
300 }
301 
302 /* use for mousemove events */
304  RulerInfo *ruler_info,
305  RulerItem *ruler_item,
306  const int mval[2],
307  const bool do_thickness
309  ,
310  const bool do_snap
311 #endif
312 )
313 {
314  wmGizmo *snap_gizmo = ruler_info->snap_data.gizmo;
315  const float eps_bias = 0.0002f;
316  float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
317 
318  if (ruler_item) {
319  RulerInteraction *inter = ruler_item->gz.interaction_data;
320  float *co = ruler_item->co[inter->co_index];
321  /* restore the initial depth */
322  copy_v3_v3(co, inter->drag_start_co);
323  view3d_ruler_item_project(ruler_info, co, mval);
324  if (do_thickness && inter->co_index != 1) {
326  View3D *v3d = ruler_info->area->spacedata.first;
328  scene, ruler_info->region, v3d, snap_gizmo);
329  const float mval_fl[2] = {UNPACK2(mval)};
330  float ray_normal[3];
331  float ray_start[3];
332  float *co_other;
333 
334  co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
335 
337  depsgraph,
339  &(const struct SnapObjectParams){
340  .snap_select = SNAP_ALL,
341  .use_object_edit_cage = true,
342  },
343  mval_fl,
344  NULL,
345  &dist_px,
346  co,
347  ray_normal)) {
348  negate_v3(ray_normal);
349  /* add some bias */
350  madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
352  depsgraph,
353  &(const struct SnapObjectParams){
354  .snap_select = SNAP_ALL,
355  .use_object_edit_cage = true,
356  },
357  ray_start,
358  ray_normal,
359  NULL,
360  co_other,
361  NULL);
362  }
363  }
364  else
365 #ifndef USE_SNAP_DETECT_FROM_KEYMAP_HACK
366  if (do_snap)
367 #endif
368  {
369  View3D *v3d = ruler_info->area->spacedata.first;
370  const float mval_fl[2] = {UNPACK2(mval)};
371  float *prev_point = NULL;
372 
373  if (inter->co_index != 1) {
374  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
375  prev_point = ruler_item->co[1];
376  }
377  else if (inter->co_index == 0) {
378  prev_point = ruler_item->co[2];
379  }
380  else {
381  prev_point = ruler_item->co[0];
382  }
383  }
384  if (prev_point != NULL) {
386  snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point);
387  }
388 
390  snap_gizmo, depsgraph, ruler_info->region, v3d, ruler_info->wm, mval_fl);
391 
392  if (ED_gizmotypes_snap_3d_is_enabled(snap_gizmo)) {
393  ED_gizmotypes_snap_3d_data_get(snap_gizmo, co, NULL, NULL, NULL);
394  }
395  }
396  return true;
397  }
398  return false;
399 }
400 
403 /* -------------------------------------------------------------------- */
407 /* Helper: Find the layer created as ruler. */
409 {
410  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
411  if (gpl->flag & GP_LAYER_IS_RULER) {
412  return gpl;
413  }
414  }
415  return NULL;
416 }
417 
419 {
420 #ifndef NDEBUG
421  RulerInfo *ruler_info = gzgroup->customdata;
422  BLI_assert(gzgroup->gizmos.first == ruler_info->snap_data.gizmo);
423 #endif
424  return (RulerItem *)((wmGizmo *)gzgroup->gizmos.first)->next;
425 }
426 
427 #define RULER_ID "RulerData3D"
429 {
430  // RulerInfo *ruler_info = gzgroup->customdata;
431  Main *bmain = CTX_data_main(C);
433 
434  bGPdata *gpd;
435  bGPDlayer *gpl;
436  bGPDframe *gpf;
437  bGPDstroke *gps;
438  RulerItem *ruler_item;
439  const char *ruler_name = RULER_ID;
440  bool changed = false;
441 
442  if (scene->gpd == NULL) {
443  scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
444  }
445  gpd = scene->gpd;
446 
447  gpl = view3d_ruler_layer_get(gpd);
448  if (gpl == NULL) {
449  gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false);
450  copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
451  gpl->thickness = 1;
453  }
454 
457 
458  for (ruler_item = gzgroup_ruler_item_first_get(gzgroup); ruler_item;
459  ruler_item = (RulerItem *)ruler_item->gz.next) {
460  bGPDspoint *pt;
461  int j;
462 
463  /* allocate memory for a new stroke */
464  gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
465  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
466  gps->totpoints = 3;
467  pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
468  for (j = 0; j < 3; j++) {
469  copy_v3_v3(&pt->x, ruler_item->co[j]);
470  pt->pressure = 1.0f;
471  pt->strength = 1.0f;
472  pt++;
473  }
474  }
475  else {
476  gps->totpoints = 2;
477  pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
478  for (j = 0; j < 3; j += 2) {
479  copy_v3_v3(&pt->x, ruler_item->co[j]);
480  pt->pressure = 1.0f;
481  pt->strength = 1.0f;
482  pt++;
483  }
484  }
485  gps->flag = GP_STROKE_3DSPACE;
486  gps->thickness = 3;
487  gps->hardeness = 1.0f;
488  gps->fill_opacity_fac = 1.0f;
489  copy_v2_fl(gps->aspect_ratio, 1.0f);
490  gps->uv_scale = 1.0f;
491 
492  BLI_addtail(&gpf->strokes, gps);
493  changed = true;
494  }
495 
496  return changed;
497 }
498 
499 static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
500 {
502  bool changed = false;
503 
504  if (scene->gpd) {
505  bGPDlayer *gpl;
507  if (gpl) {
508  bGPDframe *gpf;
510  if (gpf) {
511  bGPDstroke *gps;
512  for (gps = gpf->strokes.first; gps; gps = gps->next) {
513  bGPDspoint *pt = gps->points;
514  int j;
515  RulerItem *ruler_item = NULL;
516  if (gps->totpoints == 3) {
517  ruler_item = ruler_item_add(gzgroup);
518  for (j = 0; j < 3; j++) {
519  copy_v3_v3(ruler_item->co[j], &pt->x);
520  pt++;
521  }
522  ruler_item->flag |= RULERITEM_USE_ANGLE;
523  changed = true;
524  }
525  else if (gps->totpoints == 2) {
526  ruler_item = ruler_item_add(gzgroup);
527  for (j = 0; j < 3; j += 2) {
528  copy_v3_v3(ruler_item->co[j], &pt->x);
529  pt++;
530  }
531  changed = true;
532  }
533  }
534  }
535  }
536  }
537 
538  return changed;
539 }
540 
543 /* -------------------------------------------------------------------- */
547 static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
548 {
550  UnitSettings *unit = &scene->unit;
551  RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
552  RulerItem *ruler_item = (RulerItem *)gz;
553  ARegion *region = ruler_info->region;
554  RegionView3D *rv3d = region->regiondata;
555  const float cap_size = 4.0f * U.dpi_fac;
556  const float bg_margin = 4.0f * U.dpi_fac;
557  const float arc_size = 64.0f * U.dpi_fac;
558 #define ARC_STEPS 24
559  const int arc_steps = ARC_STEPS;
560  const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
561  const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
562  uchar color_text[3];
563  uchar color_wire[3];
564  float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
565 
566  /* Pixel Space. */
568  GPU_matrix_push();
571 
572  /* anti-aliased lines for more consistent appearance */
573  GPU_line_smooth(true);
574  GPU_line_width(1.0f);
575 
577  BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
579 
580  UI_GetThemeColor3ubv(TH_TEXT, color_text);
581  UI_GetThemeColor3ubv(TH_WIRE, color_wire);
582 
583  /* Avoid white on white text. (TODO Fix by using theme) */
584  if ((int)color_text[0] + (int)color_text[1] + (int)color_text[2] > 127 * 3 * 0.6f) {
585  copy_v3_fl(color_back, 0.0f);
586  }
587 
588  const bool is_act = (ruler_info->item_active == ruler_item);
589  float dir_ruler[2];
590  float co_ss[3][2];
591  bool proj_ok[3];
592  int j;
593 
594  /* Check if each corner is behind the near plane. If it is, we do not draw certain lines. */
595  for (j = 0; j < 3; j++) {
597  region, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_CLIP_NEAR);
598  proj_ok[j] = (status == V3D_PROJ_RET_OK);
599  }
600 
601  /* 3d drawing. */
602 
604  GPU_matrix_push();
606  GPU_matrix_set(rv3d->viewmat);
607 
609 
610  const uint shdr_pos_3d = GPU_vertformat_attr_add(
612 
613  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
615 
616  float viewport_size[4];
617  GPU_viewport_size_get_f(viewport_size);
618  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
619 
620  immUniform1i("colors_len", 2); /* "advanced" mode */
621  const float *col = is_act ? color_act : color_base;
623  "colors",
624  (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}},
625  2);
626  immUniform1f("dash_width", 6.0f);
627  immUniform1f("dash_factor", 0.5f);
628 
630 
631  immVertex3fv(shdr_pos_3d, ruler_item->co[0]);
632  immVertex3fv(shdr_pos_3d, ruler_item->co[1]);
633  immVertex3fv(shdr_pos_3d, ruler_item->co[2]);
634 
635  immEnd();
636 
638 
640 
641  /* arc */
642  {
643  float dir_tmp[3];
644  float ar_coord[3];
645 
646  float dir_a[3];
647  float dir_b[3];
648  float quat[4];
649  float axis[3];
650  float angle;
651  const float px_scale = (ED_view3d_pixel_size_no_ui_scale(rv3d, ruler_item->co[1]) *
652  min_fff(arc_size,
653  len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
654  len_v2v2(co_ss[2], co_ss[1]) / 2.0f));
655 
656  sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
657  sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
658  normalize_v3(dir_a);
659  normalize_v3(dir_b);
660 
661  cross_v3_v3v3(axis, dir_a, dir_b);
662  angle = angle_normalized_v3v3(dir_a, dir_b);
663 
664  axis_angle_to_quat(quat, axis, angle / arc_steps);
665 
666  copy_v3_v3(dir_tmp, dir_a);
667 
668  immUniformColor3ubv(color_wire);
669 
670  immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
671 
672  for (j = 0; j <= arc_steps; j++) {
673  madd_v3_v3v3fl(ar_coord, ruler_item->co[1], dir_tmp, px_scale);
674  mul_qt_v3(quat, dir_tmp);
675 
676  immVertex3fv(shdr_pos_3d, ar_coord);
677  }
678 
679  immEnd();
680  }
681 
683  }
684  else {
686 
687  float viewport_size[4];
688  GPU_viewport_size_get_f(viewport_size);
689  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
690 
691  immUniform1i("colors_len", 2); /* "advanced" mode */
692  const float *col = is_act ? color_act : color_base;
694  "colors",
695  (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}},
696  2);
697  immUniform1f("dash_width", 6.0f);
698  immUniform1f("dash_factor", 0.5f);
699 
701 
702  immVertex3fv(shdr_pos_3d, ruler_item->co[0]);
703  immVertex3fv(shdr_pos_3d, ruler_item->co[2]);
704 
705  immEnd();
706 
708  }
709 
710  /* 2d drawing. */
711 
712  GPU_matrix_pop();
714 
715  const uint shdr_pos_2d = GPU_vertformat_attr_add(
717 
718  if (ruler_item->flag & RULERITEM_USE_ANGLE) {
720  /* capping */
721  {
722  float rot_90_vec_a[2];
723  float rot_90_vec_b[2];
724  float cap[2];
725 
726  sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
727  rot_90_vec_a[0] = -dir_ruler[1];
728  rot_90_vec_a[1] = dir_ruler[0];
729  normalize_v2(rot_90_vec_a);
730 
731  sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
732  rot_90_vec_b[0] = -dir_ruler[1];
733  rot_90_vec_b[1] = dir_ruler[0];
734  normalize_v2(rot_90_vec_b);
735 
737 
738  if (proj_ok[1] && is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
739  GPU_line_width(3.0f);
740  immUniformColor3fv(color_act);
742  /* angle vertex */
743  immVertex2f(shdr_pos_2d, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
744  immVertex2f(shdr_pos_2d, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
745  immVertex2f(shdr_pos_2d, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
746  immVertex2f(shdr_pos_2d, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
747 
748  immEnd();
749  GPU_line_width(1.0f);
750  }
751 
752  immUniformColor3ubv(color_wire);
753 
754  if (proj_ok[0] || proj_ok[2] || proj_ok[1]) {
755  immBegin(GPU_PRIM_LINES, proj_ok[0] * 2 + proj_ok[2] * 2 + proj_ok[1] * 4);
756 
757  if (proj_ok[0]) {
758  madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
759  immVertex2fv(shdr_pos_2d, cap);
760  madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
761  immVertex2fv(shdr_pos_2d, cap);
762  }
763 
764  if (proj_ok[2]) {
765  madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
766  immVertex2fv(shdr_pos_2d, cap);
767  madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
768  immVertex2fv(shdr_pos_2d, cap);
769  }
770 
771  /* angle vertex */
772  if (proj_ok[1]) {
773  immVertex2f(shdr_pos_2d, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
774  immVertex2f(shdr_pos_2d, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
775  immVertex2f(shdr_pos_2d, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
776  immVertex2f(shdr_pos_2d, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
777  }
778 
779  immEnd();
780  }
781 
783  }
784 
785  /* text */
786  char numstr[256];
787  float numstr_size[2];
788  float posit[2];
789  const int prec = 2; /* XXX, todo, make optional */
790 
791  ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
792 
793  BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
794 
795  posit[0] = co_ss[1][0] + (cap_size * 2.0f);
796  posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
797 
798  /* draw text (bg) */
799  if (proj_ok[1]) {
800  immUniformColor4fv(color_back);
802  immRectf(shdr_pos_2d,
803  posit[0] - bg_margin,
804  posit[1] - bg_margin,
805  posit[0] + bg_margin + numstr_size[0],
806  posit[1] + bg_margin + numstr_size[1]);
808  }
809 
811 
812  /* draw text */
813  if (proj_ok[1]) {
814  BLF_color3ubv(blf_mono_font, color_text);
815  BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
817  BLF_draw(blf_mono_font, numstr, sizeof(numstr));
818  }
819  }
820  else {
822 
823  sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
824 
825  /* capping */
826  {
827  float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
828  float cap[2];
829 
830  normalize_v2(rot_90_vec);
831 
833 
834  immUniformColor3ubv(color_wire);
835 
836  if (proj_ok[0] || proj_ok[2]) {
837  immBegin(GPU_PRIM_LINES, proj_ok[0] * 2 + proj_ok[2] * 2);
838 
839  if (proj_ok[0]) {
840  madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
841  immVertex2fv(shdr_pos_2d, cap);
842  madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
843  immVertex2fv(shdr_pos_2d, cap);
844  }
845 
846  if (proj_ok[2]) {
847  madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
848  immVertex2fv(shdr_pos_2d, cap);
849  madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
850  immVertex2fv(shdr_pos_2d, cap);
851  }
852 
853  immEnd();
854  }
855 
857  }
858 
859  /* text */
860  char numstr[256];
861  float numstr_size[2];
862  const int prec = 6; /* XXX, todo, make optional */
863  float posit[2];
864 
865  ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
866 
867  BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
868 
869  mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
870 
871  /* center text */
872  posit[0] -= numstr_size[0] / 2.0f;
873  posit[1] -= numstr_size[1] / 2.0f;
874 
875  /* draw text (bg) */
876  if (proj_ok[0] && proj_ok[2]) {
877  immUniformColor4fv(color_back);
879  immRectf(shdr_pos_2d,
880  posit[0] - bg_margin,
881  posit[1] - bg_margin,
882  posit[0] + bg_margin + numstr_size[0],
883  posit[1] + bg_margin + numstr_size[1]);
885  }
886 
888 
889  /* draw text */
890  if (proj_ok[0] && proj_ok[2]) {
891  BLF_color3ubv(blf_mono_font, color_text);
892  BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
893  BLF_draw(blf_mono_font, numstr, sizeof(numstr));
894  }
895  }
896 
897  GPU_line_smooth(false);
898 
900 
901  GPU_matrix_pop();
903 
904 #undef ARC_STEPS
905 }
906 
907 static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
908 {
909  RulerItem *ruler_item_pick = (RulerItem *)gz;
910  const float mval_fl[2] = {UNPACK2(mval)};
911  int co_index;
912 
913  /* select and drag */
914  if (view3d_ruler_pick(gz->parent_gzgroup, ruler_item_pick, mval_fl, &co_index)) {
915  if (co_index == -1) {
916  if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
917  return PART_LINE;
918  }
919  }
920  else {
921  return co_index;
922  }
923  }
924  return -1;
925 }
926 
928  wmGizmo *gz,
929  const wmEvent *event,
930  eWM_GizmoFlagTweak tweak_flag)
931 {
932  bool do_draw = false;
933  int exit_code = OPERATOR_RUNNING_MODAL;
934  RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
935  RulerItem *ruler_item = (RulerItem *)gz;
936  ARegion *region = CTX_wm_region(C);
937  bool do_cursor_update = (event->val == KM_RELEASE) || (event->type == MOUSEMOVE);
938 
939  ruler_info->region = region;
940 
941 #ifndef USE_SNAP_DETECT_FROM_KEYMAP_HACK
942  const bool do_snap = !(tweak_flag & WM_GIZMO_TWEAK_SNAP);
943 #endif
944  const bool do_thickness = tweak_flag & WM_GIZMO_TWEAK_PRECISE;
945  if ((ruler_info->drag_state_prev.do_thickness != do_thickness)) {
946  do_cursor_update = true;
947  }
948 
949  if (do_cursor_update) {
950  if (ruler_info->state == RULER_STATE_DRAG) {
953  ruler_info,
954  ruler_item,
955  event->mval,
956  do_thickness
958  ,
959  do_snap
960 #endif
961  )) {
962  do_draw = true;
963  }
964  }
965  }
966 
967  ruler_info->drag_state_prev.do_thickness = do_thickness;
968 
969  if (do_draw) {
971  }
972  return exit_code;
973 }
974 
975 static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
976 {
977  wmGizmoGroup *gzgroup = gz->parent_gzgroup;
978  RulerInfo *ruler_info = gzgroup->customdata;
979  RulerItem *ruler_item_pick = (RulerItem *)gz;
980  RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
981  gz->interaction_data = inter;
982 
983  ARegion *region = ruler_info->region;
984 
985  const float mval_fl[2] = {UNPACK2(event->mval)};
986 
987  /* select and drag */
988  if (gz->highlight_part == PART_LINE) {
989  if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
990  /* Add Center Point */
991  ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
992  inter->co_index = 1;
993  ruler_state_set(ruler_info, RULER_STATE_DRAG);
994 
995  /* find the factor */
996  {
997  float co_ss[2][2];
998  float fac;
999 
1001  region, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP);
1003  region, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP);
1004 
1005  fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
1006  CLAMP(fac, 0.0f, 1.0f);
1007 
1009  ruler_item_pick->co[1], ruler_item_pick->co[0], ruler_item_pick->co[2], fac);
1010  }
1011 
1012  /* update the new location */
1015  ruler_info,
1016  ruler_item_pick,
1017  event->mval,
1018  false
1020  ,
1021  false
1022 #endif
1023  );
1024  }
1025  }
1026  else {
1027  inter->co_index = gz->highlight_part;
1028  ruler_state_set(ruler_info, RULER_STATE_DRAG);
1029 
1030  /* store the initial depth */
1031  copy_v3_v3(inter->drag_start_co, ruler_item_pick->co[inter->co_index]);
1032  }
1033 
1034  if (inter->co_index == 1) {
1035  ruler_item_pick->flag |= RULERITEM_USE_ANGLE_ACTIVE;
1036  }
1037  else {
1038  ruler_item_pick->flag &= ~RULERITEM_USE_ANGLE_ACTIVE;
1039  }
1040 
1041  {
1042  /* Set Snap prev point. */
1043  float *prev_point;
1044  if (ruler_item_pick->flag & RULERITEM_USE_ANGLE) {
1045  prev_point = (inter->co_index != 1) ? ruler_item_pick->co[1] : NULL;
1046  }
1047  else if (inter->co_index == 0) {
1048  prev_point = ruler_item_pick->co[2];
1049  }
1050  else {
1051  prev_point = ruler_item_pick->co[0];
1052  }
1053 
1054  if (prev_point) {
1056  ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point);
1057  }
1058  else {
1059  RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint);
1060  }
1061  }
1062 
1063  ruler_info->item_active = ruler_item_pick;
1064 
1065  return OPERATOR_RUNNING_MODAL;
1066 }
1067 
1068 static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
1069 {
1070  wmGizmoGroup *gzgroup = gz->parent_gzgroup;
1071  RulerInfo *ruler_info = gzgroup->customdata;
1072 
1073  if (!cancel) {
1074  if (ruler_info->state == RULER_STATE_DRAG) {
1075  RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint);
1076  ruler_state_set(ruler_info, RULER_STATE_NORMAL);
1077  }
1078  /* We could convert only the current gizmo, for now just re-generate. */
1079  view3d_ruler_to_gpencil(C, gzgroup);
1080  }
1081 
1083 
1084  ruler_state_set(ruler_info, RULER_STATE_NORMAL);
1085 }
1086 
1088 {
1089  if (gz->highlight_part == PART_LINE) {
1090  return WM_CURSOR_CROSS;
1091  }
1092  return WM_CURSOR_NSEW_SCROLL;
1093 }
1094 
1096 {
1097  /* identifiers */
1098  gzt->idname = "VIEW3D_GT_ruler_item";
1099 
1100  /* api callbacks */
1101  gzt->draw = gizmo_ruler_draw;
1103  gzt->modal = gizmo_ruler_modal;
1104  gzt->invoke = gizmo_ruler_invoke;
1105  gzt->exit = gizmo_ruler_exit;
1107 
1108  gzt->struct_size = sizeof(RulerItem);
1109 }
1110 
1113 /* -------------------------------------------------------------------- */
1117 static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
1118 {
1119  RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
1120 
1121  wmGizmo *gizmo;
1122  {
1123  /* The gizmo snap has to be the first gizmo. */
1124  const wmGizmoType *gzt_snap;
1125  gzt_snap = WM_gizmotype_find("GIZMO_GT_snap_3d", true);
1126  gizmo = WM_gizmo_new_ptr(gzt_snap, gzgroup, NULL);
1127  RNA_enum_set(gizmo->ptr,
1128  "snap_elements_force",
1130  /* SCE_SNAP_MODE_VOLUME | SCE_SNAP_MODE_GRID | SCE_SNAP_MODE_INCREMENT | */
1132 
1133  WM_gizmo_set_color(gizmo, (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
1134 
1135  wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_ruler_add", true);
1136  WM_gizmo_operator_set(gizmo, 0, ot, NULL);
1137  }
1138 
1139  if (view3d_ruler_from_gpencil(C, gzgroup)) {
1140  /* nop */
1141  }
1142 
1144  wmWindow *win = CTX_wm_window(C);
1145  ScrArea *area = CTX_wm_area(C);
1146  ARegion *region = CTX_wm_region(C);
1147 
1148  ruler_info->wm = wm;
1149  ruler_info->win = win;
1150  ruler_info->area = area;
1151  ruler_info->region = region;
1152  ruler_info->snap_data.gizmo = gizmo;
1153  ruler_info->snap_data.prop_prevpoint = RNA_struct_find_property(gizmo->ptr, "prev_point");
1154 
1155  gzgroup->customdata = ruler_info;
1156 }
1157 
1159 {
1160  gzgt->name = "Ruler Widgets";
1161  gzgt->idname = view3d_gzgt_ruler_id;
1162 
1164 
1167 
1170 }
1171 
1174 /* -------------------------------------------------------------------- */
1179 {
1181  if ((tref_rt == NULL) || !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
1182  CTX_wm_region_view3d(C) == NULL) {
1183  return false;
1184  }
1185  return true;
1186 }
1187 
1188 static int view3d_ruler_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1189 {
1190  ARegion *region = CTX_wm_region(C);
1191  View3D *v3d = CTX_wm_view3d(C);
1192  RegionView3D *rv3d = region->regiondata;
1193 
1195  BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
1196  return OPERATOR_CANCELLED;
1197  }
1198 
1199  wmGizmoMap *gzmap = region->gizmo_map;
1201  const bool use_depth = (v3d->shading.type >= OB_SOLID);
1202 
1203  /* Create new line */
1204  RulerItem *ruler_item;
1205  ruler_item = ruler_item_add(gzgroup);
1206 
1207  /* This is a little weak, but there is no real good way to tweak directly. */
1208  WM_gizmo_highlight_set(gzmap, &ruler_item->gz);
1209  if (WM_operator_name_call(C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_REGION_WIN, NULL) ==
1211  RulerInfo *ruler_info = gzgroup->customdata;
1212  RulerInteraction *inter = ruler_item->gz.interaction_data;
1213  if (use_depth) {
1215  /* snap the first point added, not essential but handy */
1216  inter->co_index = 0;
1218  ruler_info,
1219  ruler_item,
1220  event->mval,
1221  false
1223  ,
1224  true
1225 #endif
1226  );
1227  copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
1229  ruler_info->snap_data.prop_prevpoint,
1230  inter->drag_start_co);
1231  }
1232  else {
1233  negate_v3_v3(inter->drag_start_co, rv3d->ofs);
1234  copy_v3_v3(ruler_item->co[0], inter->drag_start_co);
1235  view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
1236  }
1237 
1238  copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
1239  ruler_item->gz.highlight_part = inter->co_index = 2;
1240  }
1241  return OPERATOR_FINISHED;
1242 }
1243 
1245 {
1246  /* identifiers */
1247  ot->name = "Ruler Add";
1248  ot->idname = "VIEW3D_OT_ruler_add";
1249  ot->description = "Add ruler";
1250 
1253 
1254  /* flags */
1256 }
1257 
1260 /* -------------------------------------------------------------------- */
1265 {
1266  ARegion *region = CTX_wm_region(C);
1267  View3D *v3d = CTX_wm_view3d(C);
1268 
1270  BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
1271  return OPERATOR_CANCELLED;
1272  }
1273 
1274  wmGizmoMap *gzmap = region->gizmo_map;
1276  if (gzgroup) {
1277  RulerInfo *ruler_info = gzgroup->customdata;
1278  if (ruler_info->item_active) {
1279  RulerItem *ruler_item = ruler_info->item_active;
1280  if ((ruler_item->flag & RULERITEM_USE_ANGLE) &&
1281  (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
1283  }
1284  else {
1285  ruler_item_remove(C, gzgroup, ruler_item);
1286  }
1287 
1288  /* Update the annotation layer. */
1289  view3d_ruler_to_gpencil(C, gzgroup);
1290 
1292  return OPERATOR_FINISHED;
1293  }
1294  }
1295  return OPERATOR_PASS_THROUGH;
1296 }
1297 
1299 {
1300  /* identifiers */
1301  ot->name = "Ruler Remove";
1302  ot->idname = "VIEW3D_OT_ruler_remove";
1303 
1306 
1307  /* flags */
1309 }
1310 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
bool BKE_gpencil_free_strokes(struct bGPDframe *gpf)
Definition: gpencil.c:425
struct bGPDframe * BKE_gpencil_layer_frame_get(struct bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
Definition: gpencil.c:1307
struct bGPdata * BKE_gpencil_data_addnew(struct Main *bmain, const char name[])
Definition: gpencil.c:742
struct bGPDlayer * BKE_gpencil_layer_addnew(struct bGPdata *gpd, const char *name, bool setactive)
Definition: gpencil.c:659
@ GP_GETFRAME_ADD_NEW
Definition: BKE_gpencil.h:190
@ GP_GETFRAME_USE_PREV
Definition: BKE_gpencil.h:187
General operations, lookup, etc. for materials.
General operations, lookup, etc. for blender objects.
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
@ B_UNIT_LENGTH
Definition: BKE_unit.h:79
@ B_UNIT_ROTATION
Definition: BKE_unit.h:83
size_t BKE_unit_value_as_string(char *str, int len_max, double value, int prec, int type, const struct UnitSettings *settings, bool pad)
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
Definition: blf.c:411
void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_width, float *r_height) ATTR_NONNULL()
Definition: blf.c:698
void BLF_draw(int fontid, const char *str, size_t len) ATTR_NONNULL(2)
Definition: blf.c:542
void BLF_disable(int fontid, int option)
Definition: blf.c:283
void BLF_rotation(int fontid, float angle)
Definition: blf.c:801
#define BLF_ROTATION
Definition: BLF_api.h:269
int blf_mono_font
Definition: blf.c:70
void BLF_size(int fontid, int size, int dpi)
Definition: blf.c:367
void BLF_enable(int fontid, int option)
Definition: blf.c:274
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:312
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:3469
MINLINE int min_axis_v3(const float vec[3])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:338
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:97
#define RAD2DEGF(_rad)
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
Definition: math_vector.c:277
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:417
MINLINE float normalize_v2(float r[2])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:505
MINLINE void copy_v2_fl(float r[2], float f)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define UNUSED(x)
#define UNPACK3(a)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct Scene * DEG_get_input_scene(const Depsgraph *graph)
@ GP_STROKE_3DSPACE
@ GP_LAYER_IS_RULER
@ GP_LAYER_HIDE
@ OB_SOLID
Object is a sort of wrapper for general info.
#define CFRA
#define USER_UNIT_NONE
#define SCE_SNAP_MODE_FACE
#define SCE_SNAP_MODE_EDGE_PERPENDICULAR
#define SCE_SNAP_MODE_EDGE_MIDPOINT
#define SCE_SNAP_MODE_VERTEX
#define SCE_SNAP_MODE_EDGE
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ V3D_GIZMO_HIDE_TOOL
@ V3D_GIZMO_HIDE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
#define USE_SNAP_DETECT_FROM_KEYMAP_HACK
bool ED_gizmo_poll_or_unlink_delayed_from_tool(const struct bContext *C, struct wmGizmoGroupType *gzgt)
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:706
bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx, struct Depsgraph *depsgraph, const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3])
bool ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx, struct Depsgraph *depsgraph, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3])
@ V3D_PROJ_TEST_CLIP_NEAR
Definition: ED_view3d.h:196
@ V3D_PROJ_TEST_NOP
Definition: ED_view3d.h:193
void ED_view3d_win_to_3d_int(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
eV3DProjStatus
Definition: ED_view3d.h:175
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:176
float ED_view3d_pixel_size_no_ui_scale(const struct RegionView3D *rv3d, const float co[3])
eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
void immUniform2f(const char *name, float x, float y)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immUniformColor3ubv(const unsigned char rgb[3])
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
void immUniformArray4fv(const char *bare_name, const float *data, int count)
void immUniformColor4fv(const float rgba[4])
GPUVertFormat * immVertexFormat(void)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void immUniformColor3fv(const float rgb[3])
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:156
#define GPU_matrix_set(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
#define GPU_matrix_projection_set(x)
Definition: GPU_matrix.h:225
void GPU_matrix_identity_set(void)
Definition: gpu_matrix.cc:184
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:149
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:38
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:366
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:200
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_line_width(float width)
Definition: gpu_state.cc:173
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:85
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
#define C
Definition: RandGen.cpp:39
@ TH_WIRE
Definition: UI_resources.h:85
@ TH_TEXT
Definition: UI_resources.h:58
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
Definition: resources.c:1350
eWM_GizmoFlagTweak
Gizmo tweak flag. Bitflag passed to gizmo while tweaking.
@ WM_GIZMO_TWEAK_PRECISE
@ WM_GIZMO_TWEAK_SNAP
@ WM_GIZMO_DRAW_MODAL
@ WM_GIZMOGROUPTYPE_SCALE
@ WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL
@ WM_GIZMOGROUPTYPE_3D
@ OPTYPE_INTERNAL
Definition: WM_types.h:175
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:198
#define KM_RELEASE
Definition: WM_types.h:243
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
const Depsgraph * depsgraph
uint col
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong state[N]
static void area(int d1, int d2, int e1, int e2, float weights[2])
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:3132
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6665
short ED_gizmotypes_snap_3d_update(wmGizmo *gz, struct Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const wmWindowManager *wm, const float mval_fl[2])
Definition: snap3d_gizmo.c:318
void ED_gizmotypes_snap_3d_data_get(wmGizmo *gz, float r_loc[3], float r_nor[3], int r_elem_index[3], int *r_snap_elem)
Definition: snap3d_gizmo.c:412
bool ED_gizmotypes_snap_3d_is_enabled(wmGizmo *gz)
Definition: snap3d_gizmo.c:312
SnapObjectContext * ED_gizmotypes_snap_3d_context_ensure(Scene *scene, const ARegion *region, const View3D *v3d, wmGizmo *gz)
Definition: snap3d_gizmo.c:271
void * regiondata
struct wmGizmoMap * gizmo_map
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
float viewmat[4][4]
float winmat[4][4]
wmWindowManager * wm
ScrArea * area
wmGizmo * gizmo
ARegion * region
struct RulerInfo::@553 drag_state_prev
struct RulerItem * item_active
PropertyRNA * prop_prevpoint
struct RulerInfo::@554 snap_data
wmWindow * win
float co[3][3]
struct bGPdata * gpd
struct UnitSettings unit
ListBase spacedata
char gizmo_flag
View3DShading shading
ListBase strokes
float color[4]
bGPDspoint * points
float fill_opacity_fac
float aspect_ratio[2]
struct bGPDstroke * next
ListBase layers
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
wmGizmoGroupFnInit setup
const char * idname
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupFnPoll poll
struct wmGizmoMapType_Params gzmap_params
const char * name
ListBase gizmos
struct wmGizmoMap * parent_gzmap
wmGizmoFnDraw draw
wmGizmoFnModal modal
const char * idname
wmGizmoFnTestSelect test_select
wmGizmoFnExit exit
wmGizmoFnCursorGet cursor_get
wmGizmoFnInvoke invoke
void * interaction_data
struct wmGizmoGroup * parent_gzgroup
int highlight_part
struct wmGizmo * next
struct PointerRNA * ptr
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
const char * description
Definition: WM_types.h:726
struct ReportList * reports
static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item)
struct RulerInteraction RulerInteraction
@ RULERITEM_USE_ANGLE
@ RULERITEM_USE_ANGLE_ACTIVE
static bGPDlayer * view3d_ruler_layer_get(bGPdata *gpd)
static int view3d_ruler_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool view3d_ruler_poll(bContext *C)
static void ruler_state_set(RulerInfo *ruler_info, int state)
static const char * view3d_gzgt_ruler_id
#define ARC_STEPS
void VIEW3D_OT_ruler_remove(wmOperatorType *ot)
static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt)
static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
void VIEW3D_OT_ruler_add(wmOperatorType *ot)
static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, char *numstr, size_t numstr_size, int prec)
static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], const int xy[2])
@ RULER_STATE_DRAG
@ RULER_STATE_NORMAL
static RulerItem * gzgroup_ruler_item_first_get(wmGizmoGroup *gzgroup)
static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph, RulerInfo *ruler_info, RulerItem *ruler_item, const int mval[2], const bool do_thickness)
static RulerItem * ruler_item_add(wmGizmoGroup *gzgroup)
static int gizmo_ruler_cursor_get(wmGizmo *gz)
#define PART_LINE
static int gizmo_ruler_modal(bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag)
static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
#define RULER_ID
struct RulerItem RulerItem
static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
struct RulerInfo RulerInfo
static bool view3d_ruler_pick(wmGizmoGroup *gzgroup, RulerItem *ruler_item, const float mval[2], int *r_co_index)
void VIEW3D_GT_ruler_item(wmGizmoType *gzt)
#define RULER_PICK_DIST_SQ
#define MVAL_MAX_PX_DIST
@ WM_CURSOR_NSEW_SCROLL
Definition: wm_cursors.h:67
@ WM_CURSOR_CROSS
Definition: wm_cursors.h:42
int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
@ MOUSEMOVE
wmOperatorType * ot
Definition: wm_files.c:3156
PointerRNA * WM_gizmo_operator_set(wmGizmo *gz, int part_index, wmOperatorType *ot, IDProperty *properties)
Definition: wm_gizmo.c:232
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition: wm_gizmo.c:96
bool WM_gizmo_highlight_set(wmGizmoMap *gzmap, wmGizmo *gz)
Definition: wm_gizmo.c:443
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition: wm_gizmo.c:339
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
Definition: wm_gizmo.c:363
void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C)
Definition: wm_gizmo.c:194
wmGizmoGroup * WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
Definition: wm_gizmo_map.c:219
const wmGizmoType * WM_gizmotype_find(const char *idname, bool quiet)
Definition: wm_gizmo_type.c:58
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void wmOrtho2_region_pixelspace(const ARegion *region)
Definition: wm_subwindow.c:120
struct bToolRef_Runtime * WM_toolsystem_runtime_from_context(struct bContext *C)
Definition: wm_toolsystem.c:91