Blender  V3.3
view3d_cursor_snap.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
10 #include "DNA_object_types.h"
11 
12 #include "BLI_listbase.h"
13 #include "BLI_rect.h"
14 
15 #include "MEM_guardedalloc.h"
16 
17 #include "BKE_context.h"
18 #include "BKE_global.h"
19 #include "BKE_main.h"
20 #include "BKE_object.h"
21 #include "BKE_scene.h"
22 #include "BKE_screen.h"
23 
24 #include "GPU_immediate.h"
25 #include "GPU_matrix.h"
26 
27 #include "ED_screen.h"
28 #include "ED_transform.h"
30 #include "ED_view3d.h"
31 
32 #include "UI_resources.h"
33 
34 #include "RNA_access.h"
35 
36 #include "DEG_depsgraph_query.h"
37 
38 #include "WM_api.h"
39 
40 #define STATE_INTERN_GET(state) \
41  (SnapStateIntern *)((char *)state - offsetof(SnapStateIntern, snap_state))
42 
43 typedef struct SnapStateIntern {
47 
48 typedef struct SnapCursorDataIntern {
52 
54  const Scene *scene;
56 
57  float prevpoint_stack[3];
58 
59  /* Copy of the parameters of the last event state in order to detect updates. */
60  struct {
61  int x;
62  int y;
63 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
65 #endif
67 
68 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
69  struct wmKeyMap *keymap;
70  int snap_on;
71 #endif
72 
74 
77 
80  .snap_elem_force = SCE_SNAP_MODE_GEOM,
81  .plane_axis = 2,
82  .color_point = {255, 255, 255, 255},
83  .color_line = {255, 255, 255, 128},
84  .color_box = {255, 255, 255, 128},
85  .box_dimensions = {1.0f, 1.0f, 1.0f},
86  .draw_point = true}};
87 
92 static const float eps_view_align = 1e-2f;
93 
97 static void v3d_cursor_poject_surface_normal(const float normal[3],
98  const float obmat[4][4],
99  float r_mat[3][3])
100 {
101  float mat[3][3];
102  copy_m3_m4(mat, obmat);
103  normalize_m3(mat);
104 
105  float dot_best = fabsf(dot_v3v3(mat[0], normal));
106  int i_best = 0;
107  for (int i = 1; i < 3; i++) {
108  float dot_test = fabsf(dot_v3v3(mat[i], normal));
109  if (dot_test > dot_best) {
110  i_best = i;
111  dot_best = dot_test;
112  }
113  }
114  if (dot_v3v3(mat[i_best], normal) < 0.0f) {
115  negate_v3(mat[(i_best + 1) % 3]);
116  negate_v3(mat[(i_best + 2) % 3]);
117  }
118  copy_v3_v3(mat[i_best], normal);
119  orthogonalize_m3(mat, i_best);
120  normalize_m3(mat);
121 
122  copy_v3_v3(r_mat[0], mat[(i_best + 1) % 3]);
123  copy_v3_v3(r_mat[1], mat[(i_best + 2) % 3]);
124  copy_v3_v3(r_mat[2], mat[i_best]);
125 }
126 
133  Scene *scene, View3D *v3d, ARegion *region, const float co_relative[3], float co[3])
134 {
135  const float grid_size = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
136  if (UNLIKELY(grid_size == 0.0f)) {
137  return false;
138  }
139 
141  co_relative = NULL;
142  }
143 
144  if (co_relative != NULL) {
145  sub_v3_v3(co, co_relative);
146  }
147  mul_v3_fl(co, 1.0f / grid_size);
148  co[0] = roundf(co[0]);
149  co[1] = roundf(co[1]);
150  co[2] = roundf(co[2]);
151  mul_v3_fl(co, grid_size);
152  if (co_relative != NULL) {
153  add_v3_v3(co, co_relative);
154  }
155 
156  return true;
157 }
158 
162 static bool mat3_align_axis_to_v3(float mat[3][3], const int axis_align, const float v[3])
163 {
164  float dot_best = -1.0f;
165  int axis_found = axis_align;
166  for (int i = 0; i < 3; i++) {
167  const float dot_test = fabsf(dot_v3v3(mat[i], v));
168  if (dot_test > dot_best) {
169  dot_best = dot_test;
170  axis_found = i;
171  }
172  }
173 
174  if (axis_align != axis_found) {
175  float tmat[3][3];
176  copy_m3_m3(tmat, mat);
177  const int offset = mod_i(axis_found - axis_align, 3);
178  for (int i = 0; i < 3; i++) {
179  copy_v3_v3(mat[i], tmat[(i + offset) % 3]);
180  }
181  return true;
182  }
183  return false;
184 }
185 
186 /* -------------------------------------------------------------------- */
190 static void v3d_cursor_plane_draw_grid(const int resolution,
191  const float scale,
192  const float scale_fade,
193  const float matrix[4][4],
194  const int plane_axis,
195  const float color[4])
196 {
197  BLI_assert(scale_fade <= scale);
198  const int resolution_min = resolution - 1;
199  float color_fade[4] = {UNPACK4(color)};
200  const float *center = matrix[3];
201 
203  GPU_line_smooth(true);
204  GPU_line_width(1.0f);
205 
207  const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
208  const uint col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
209 
211 
212  const size_t coords_len = resolution * resolution;
213  float(*coords)[3] = MEM_mallocN(sizeof(*coords) * coords_len, __func__);
214 
215  const int axis_x = (plane_axis + 0) % 3;
216  const int axis_y = (plane_axis + 1) % 3;
217  const int axis_z = (plane_axis + 2) % 3;
218 
219  int i;
220  const float resolution_div = (float)1.0f / (float)resolution;
221  i = 0;
222  for (int x = 0; x < resolution; x++) {
223  const float x_fl = (x * resolution_div) - 0.5f;
224  for (int y = 0; y < resolution; y++) {
225  const float y_fl = (y * resolution_div) - 0.5f;
226  coords[i][axis_x] = 0.0f;
227  coords[i][axis_y] = x_fl * scale;
228  coords[i][axis_z] = y_fl * scale;
229  mul_m4_v3(matrix, coords[i]);
230  i += 1;
231  }
232  }
233  BLI_assert(i == (int)coords_len);
234  immBeginAtMost(GPU_PRIM_LINES, coords_len * 4);
235  i = 0;
236  for (int x = 0; x < resolution_min; x++) {
237  for (int y = 0; y < resolution_min; y++) {
238 
239  /* Add #resolution_div to ensure we fade-out entirely. */
240 #define FADE(v) \
241  max_ff(0.0f, (1.0f - square_f(((len_v3v3(v, center) / scale_fade) + resolution_div) * 2.0f)))
242 
243  const float *v0 = coords[(resolution * x) + y];
244  const float *v1 = coords[(resolution * (x + 1)) + y];
245  const float *v2 = coords[(resolution * x) + (y + 1)];
246 
247  const float f0 = FADE(v0);
248  const float f1 = FADE(v1);
249  const float f2 = FADE(v2);
250 
251  if (f0 > 0.0f || f1 > 0.0f) {
252  color_fade[3] = color[3] * f0;
253  immAttr4fv(col_id, color_fade);
254  immVertex3fv(pos_id, v0);
255  color_fade[3] = color[3] * f1;
256  immAttr4fv(col_id, color_fade);
257  immVertex3fv(pos_id, v1);
258  }
259  if (f0 > 0.0f || f2 > 0.0f) {
260  color_fade[3] = color[3] * f0;
261  immAttr4fv(col_id, color_fade);
262  immVertex3fv(pos_id, v0);
263 
264  color_fade[3] = color[3] * f2;
265  immAttr4fv(col_id, color_fade);
266  immVertex3fv(pos_id, v2);
267  }
268 
269 #undef FADE
270 
271  i++;
272  }
273  }
274 
275  MEM_freeN(coords);
276 
277  immEnd();
278 
280 
281  GPU_line_smooth(false);
283 }
284 
285 static void v3d_cursor_plane_draw(const RegionView3D *rv3d,
286  const int plane_axis,
287  const float matrix[4][4])
288 {
289  /* Draw */
290  float pixel_size;
291 
292  if (rv3d->is_persp) {
293  float center[3];
294  negate_v3_v3(center, rv3d->ofs);
295  pixel_size = ED_view3d_pixel_size(rv3d, center);
296  }
297  else {
298  pixel_size = ED_view3d_pixel_size(rv3d, matrix[3]);
299  }
300 
301  if (pixel_size > FLT_EPSILON) {
302 
303  /* Arbitrary, 1.0 is a little too strong though. */
304  float color_alpha = 0.75f;
305  if (rv3d->is_persp) {
306  /* Scale down the alpha when this is drawn very small,
307  * since the add shader causes the small size to show too dense & bright. */
308  const float relative_pixel_scale = pixel_size / ED_view3d_pixel_size(rv3d, matrix[3]);
309  if (relative_pixel_scale < 1.0f) {
310  color_alpha *= max_ff(square_f(relative_pixel_scale), 0.3f);
311  }
312  }
313 
314  {
315  /* Extra adjustment when it's near view-aligned as it seems overly bright. */
316  float view_vector[3];
317  ED_view3d_global_to_vector(rv3d, matrix[3], view_vector);
318  float view_dot = fabsf(dot_v3v3(matrix[plane_axis], view_vector));
319  color_alpha *= max_ff(0.3f, 1.0f - square_f(square_f(1.0f - view_dot)));
320  }
321 
322  const float scale_mod = U.gizmo_size * 2 * U.dpi_fac / U.pixelsize;
323 
324  float final_scale = (scale_mod * pixel_size);
325 
326  const int lines_subdiv = 10;
327  int lines = lines_subdiv;
328 
329  float final_scale_fade = final_scale;
330  final_scale = ceil_power_of_10(final_scale);
331 
332  float fac = final_scale_fade / final_scale;
333 
334  float color[4] = {1, 1, 1, color_alpha};
335  color[3] *= square_f(1.0f - fac);
336  if (color[3] > 0.0f) {
338  lines * lines_subdiv, final_scale, final_scale_fade, matrix, plane_axis, color);
339  }
340 
341  color[3] = color_alpha;
342  /* When the grid is large, we only need the 2x lines in the middle. */
343  if (fac < 0.2f) {
344  lines = 1;
345  final_scale = final_scale_fade;
346  }
347  v3d_cursor_plane_draw_grid(lines, final_scale, final_scale_fade, matrix, plane_axis, color);
348  }
349 }
350 
351 static void cursor_box_draw(const float dimensions[3], uchar color[4])
352 {
354  const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
355 
357  GPU_line_smooth(true);
358  GPU_line_width(1.0f);
359 
362  imm_draw_cube_corners_3d(pos_id, (const float[3]){0.0f, 0.0f, dimensions[2]}, dimensions, 0.15f);
364 
365  GPU_line_smooth(false);
367 }
368 
370  const float loc_prev[3],
371  const float loc_curr[3],
372  const float normal[3],
373  const uchar color_line[4],
374  const uchar color_point[4],
375  const eSnapMode snap_elem_type)
376 {
377  if (!loc_prev && !loc_curr) {
378  return;
379  }
380 
381  float view_inv[4][4];
382  copy_m4_m4(view_inv, rv3d->viewinv);
383 
384  /* The size of the circle is larger than the vertex size.
385  * This prevents a drawing overlaps the other. */
386  float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
388 
390 
391  if (loc_curr) {
392  immUniformColor4ubv(color_point);
393  imm_drawcircball(loc_curr, ED_view3d_pixel_size(rv3d, loc_curr) * radius, view_inv, pos);
394 
395  /* draw normal if needed */
396  if (normal) {
398  immVertex3fv(pos, loc_curr);
399  immVertex3f(pos, loc_curr[0] + normal[0], loc_curr[1] + normal[1], loc_curr[2] + normal[2]);
400  immEnd();
401  }
402  }
403 
404  if (loc_prev) {
405  /* Draw an "X" indicating where the previous snap point is.
406  * This is useful for indicating perpendicular snap. */
407 
408  /* v1, v2, v3 and v4 indicate the coordinates of the ends of the "X". */
409  float vx[3], vy[3], v1[3], v2[3], v3[3], v4[4];
410 
411  /* Multiply by 0.75f so that the final size of the "X" is close to that of
412  * the circle.
413  * (A closer value is 0.7071f, but we don't need to be exact here). */
414  float x_size = 0.75f * radius * ED_view3d_pixel_size(rv3d, loc_prev);
415 
416  mul_v3_v3fl(vx, view_inv[0], x_size);
417  mul_v3_v3fl(vy, view_inv[1], x_size);
418 
419  add_v3_v3v3(v1, vx, vy);
420  sub_v3_v3v3(v2, vx, vy);
421  negate_v3_v3(v3, v1);
422  negate_v3_v3(v4, v2);
423 
424  add_v3_v3(v1, loc_prev);
425  add_v3_v3(v2, loc_prev);
426  add_v3_v3(v3, loc_prev);
427  add_v3_v3(v4, loc_prev);
428 
429  immUniformColor4ubv(color_line);
431  immVertex3fv(pos, v3);
432  immVertex3fv(pos, v1);
433  immVertex3fv(pos, v4);
434  immVertex3fv(pos, v2);
435  immEnd();
436 
437  if (loc_curr && (snap_elem_type & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
438  /* Dashed line. */
440 
442  float viewport_size[4];
443  GPU_viewport_size_get_f(viewport_size);
444  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
445  immUniform1f("dash_width", 6.0f * U.pixelsize);
446  immUniform1f("dash_factor", 1.0f / 4.0f);
447  immUniformColor4ubv(color_line);
448 
450  immVertex3fv(pos, loc_prev);
451  immVertex3fv(pos, loc_curr);
452  immEnd();
453  }
454  }
455 
457 }
458 
461 /* -------------------------------------------------------------------- */
465 /* Checks if the current event is different from the one captured in the last update. */
468  const wmWindowManager *wm,
469  const int x,
470  const int y)
471 {
472  if (wm && wm->winactive) {
473  const wmEvent *event = wm->winactive->eventstate;
474  if ((x != data_intern->last_eventstate.x) || (y != data_intern->last_eventstate.y)) {
475  return true;
476  }
477 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
478  if (!(state && (state->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE))) {
479  if (event->modifier != data_intern->last_eventstate.modifier) {
480  return true;
481  }
482  }
483 #endif
484  }
485  return false;
486 }
487 
488 /* Copies the current eventstate. */
490  const int x,
491  const int y)
492 {
493  cursor_snap->last_eventstate.x = x;
494  cursor_snap->last_eventstate.y = y;
495 }
496 
497 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
499  const wmWindowManager *wm)
500 {
501  if (!wm || !wm->winactive) {
502  return;
503  }
504  const wmEvent *event = wm->winactive->eventstate;
505  data_intern->last_eventstate.modifier = event->modifier;
506 }
507 
509 {
510  if (!wm || !wm->winactive) {
511  return false;
512  }
513 
514  const wmEvent *event = wm->winactive->eventstate;
515  if (event->modifier == data_intern->last_eventstate.modifier) {
516  /* Nothing has changed. */
517  return data_intern->snap_data.is_snap_invert;
518  }
519 
520  /* Save new eventstate. */
521  data_intern->last_eventstate.modifier = event->modifier;
522 
523  const int snap_on = data_intern->snap_on;
524 
525  wmKeyMap *keymap = WM_keymap_active(wm, data_intern->keymap);
526  for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
527  if (kmi->flag & KMI_INACTIVE) {
528  continue;
529  }
530 
531  if (kmi->propvalue == snap_on) {
532  if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && (event->modifier & KM_CTRL)) ||
533  (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && (event->modifier & KM_SHIFT)) ||
534  (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) ||
535  ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) {
536  return true;
537  }
538  }
539  }
540  return false;
541 }
542 #endif
543 
546 /* -------------------------------------------------------------------- */
551 {
552  eSnapMode snap_elements = snap_state->snap_elem_force;
553  if (!snap_elements) {
554  return scene->toolsettings->snap_mode;
555  }
556  return snap_elements;
557 }
558 
560 {
561  SnapCursorDataIntern *data_intern = &g_data_intern;
562  if (data_intern->snap_context_v3d && (data_intern->scene != scene)) {
564  data_intern->snap_context_v3d = NULL;
565  }
566  if (data_intern->snap_context_v3d == NULL) {
568  data_intern->scene = scene;
569  }
570 }
571 
572 static bool v3d_cursor_snap_calc_plane(void)
573 {
574  /* If any of the states require the plane, calculate the `plane_omat`. */
576  if (state->snap_state.draw_plane || state->snap_state.draw_box) {
577  return true;
578  }
579  }
580  return false;
581 }
582 
584  const bContext *C,
585  wmWindowManager *wm,
587  Scene *scene,
588  ARegion *region,
589  View3D *v3d,
590  int x,
591  int y)
592 {
593  SnapCursorDataIntern *data_intern = &g_data_intern;
594  V3DSnapCursorData *snap_data = &data_intern->snap_data;
595 
596  const bool use_surface_nor = state->plane_orient == V3D_PLACE_ORIENT_SURFACE;
597  const bool use_surface_co = state->plane_depth == V3D_PLACE_DEPTH_SURFACE;
598  const bool calc_plane_omat = v3d_cursor_snap_calc_plane();
599 
600  float co[3], no[3], face_nor[3], obmat[4][4], omat[3][3];
601  eSnapMode snap_elem = SCE_SNAP_MODE_NONE;
602  eSnapMode snap_elements = v3d_cursor_snap_elements(state, scene);
603  int snap_elem_index[3] = {-1, -1, -1};
604  int index = -1;
605 
606  const float mval_fl[2] = {x, y};
607  zero_v3(no);
608  zero_v3(face_nor);
609  unit_m3(omat);
610 
611  if (use_surface_nor || use_surface_co) {
613 
614  data_intern->snap_elem_hidden = SCE_SNAP_MODE_NONE;
615  if (calc_plane_omat && !(snap_elements & SCE_SNAP_MODE_FACE_RAYCAST)) {
617  snap_elements |= SCE_SNAP_MODE_FACE_RAYCAST;
618  }
619 
620  snap_data->is_enabled = true;
621 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
622  if (!(state->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE)) {
623  snap_data->is_snap_invert = v3d_cursor_is_snap_invert(data_intern, wm);
624 
625  const ToolSettings *ts = scene->toolsettings;
626  if (snap_data->is_snap_invert != !(ts->snap_flag & SCE_SNAP)) {
627  snap_data->is_enabled = false;
628  if (!calc_plane_omat) {
629  snap_data->snap_elem = SCE_SNAP_MODE_NONE;
630  return;
631  }
632  snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE_RAYCAST;
633  }
634  }
635 #endif
636 
637  if (snap_elements & SCE_SNAP_MODE_GEOM) {
638  float prev_co[3] = {0.0f};
639  if (state->prevpoint) {
640  copy_v3_v3(prev_co, state->prevpoint);
641  }
642  else {
643  snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
644  }
645 
646  eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ?
651 
652  bool use_occlusion_test = (state->flag & V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE) ? false :
653  true;
654 
655  float dist_px = 12.0f * U.pixelsize;
656 
658  data_intern->snap_context_v3d,
659  depsgraph,
660  region,
661  v3d,
662  snap_elements,
663  &(const struct SnapObjectParams){
664  .snap_target_select = SCE_SNAP_TARGET_ALL,
665  .edit_mode_type = edit_mode_type,
666  .use_occlusion_test = use_occlusion_test,
667  },
668  NULL,
669  mval_fl,
670  prev_co,
671  &dist_px,
672  co,
673  no,
674  &index,
675  NULL,
676  obmat,
677  face_nor);
678  }
679  }
680 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
681  else {
682  v3d_cursor_eventstate_save_modifier(data_intern, wm);
683  }
684 #endif
685 
686  if (calc_plane_omat) {
687  RegionView3D *rv3d = region->regiondata;
688  bool orient_surface = use_surface_nor && (snap_elem != SCE_SNAP_MODE_NONE);
689  if (orient_surface) {
690  copy_m3_m4(omat, obmat);
691  }
692  else {
693  ViewLayer *view_layer = CTX_data_view_layer(C);
694  Object *ob = OBACT(view_layer);
695  const int orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
696  const int pivot_point = scene->toolsettings->transform_pivot_point;
698  scene, view_layer, v3d, rv3d, ob, NULL, orient_index, pivot_point, omat);
699 
700  if (state->use_plane_axis_auto) {
701  mat3_align_axis_to_v3(omat, state->plane_axis, rv3d->viewinv[2]);
702  }
703  }
704 
705  /* Non-orthogonal matrices cause the preview and final result not to match.
706  *
707  * While making orthogonal doesn't always work well (especially with gimbal orientation for
708  * e.g.) it's a corner case, without better alternatives as objects don't support shear. */
709  orthogonalize_m3(omat, state->plane_axis);
710 
711  if (orient_surface) {
712  if (!is_zero_v3(face_nor)) {
713  /* Negate the face normal according to the view. */
714  float ray_dir[3];
715  if (rv3d->is_persp) {
716  BLI_assert_msg(snap_elem != SCE_SNAP_MODE_NONE,
717  "Use of variable `co` without it being computed");
718 
719  sub_v3_v3v3(ray_dir, co, rv3d->viewinv[3]); /* No need to normalize. */
720  }
721  else {
722  negate_v3_v3(ray_dir, rv3d->viewinv[2]);
723  }
724 
725  if (dot_v3v3(ray_dir, face_nor) >= 0.0f) {
726  negate_v3(face_nor);
727  }
728  }
729  else if (!is_zero_v3(no)) {
730  copy_v3_v3(face_nor, no);
731  }
732  else {
733  face_nor[state->plane_axis] = 1.0f;
734  }
735  v3d_cursor_poject_surface_normal(face_nor, obmat, omat);
736  }
737  }
738 
739  if (!use_surface_co) {
740  snap_elem = SCE_SNAP_MODE_NONE;
741  }
742 
743  float *co_depth = (snap_elem != SCE_SNAP_MODE_NONE) ? co : scene->cursor.location;
744  snap_elem &= ~data_intern->snap_elem_hidden;
745  if (snap_elem == SCE_SNAP_MODE_NONE) {
746  RegionView3D *rv3d = region->regiondata;
747  const float *plane_normal = omat[state->plane_axis];
748  bool do_plane_isect = (state->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) &&
749  (rv3d->is_persp ||
750  (fabsf(dot_v3v3(plane_normal, rv3d->viewinv[2])) > eps_view_align));
751 
752  if (do_plane_isect) {
753  float plane[4];
754  plane_from_point_normal_v3(plane, co_depth, plane_normal);
755  do_plane_isect = ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, rv3d->is_persp, co);
756  }
757 
758  if (!do_plane_isect) {
759  ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co);
760  }
761 
762  if (snap_data->is_enabled && (snap_elements & SCE_SNAP_MODE_INCREMENT)) {
763  v3d_cursor_snap_calc_incremental(scene, v3d, region, state->prevpoint, co);
764  }
765  }
766  else if (snap_elem == SCE_SNAP_MODE_VERTEX) {
767  snap_elem_index[0] = index;
768  }
769  else if (snap_elem &
771  snap_elem_index[1] = index;
772  }
773  else if (snap_elem == SCE_SNAP_MODE_FACE_RAYCAST) {
774  snap_elem_index[2] = index;
775  }
776 
777  snap_data->snap_elem = snap_elem;
778  copy_v3_v3(snap_data->loc, co);
779  copy_v3_v3(snap_data->nor, no);
780  copy_m4_m4(snap_data->obmat, obmat);
781  copy_v3_v3_int(snap_data->elem_index, snap_elem_index);
782 
783  copy_m3_m3(snap_data->plane_omat, omat);
784 
785  v3d_cursor_eventstate_save_xy(data_intern, x, y);
786 }
787 
790 /* -------------------------------------------------------------------- */
795 {
796  if (G.moving) {
797  return false;
798  }
799 
801  if (area->spacetype != SPACE_VIEW3D) {
802  return false;
803  }
804 
805  ARegion *region = CTX_wm_region(C);
806  if (region->regiontype != RGN_TYPE_WINDOW) {
807  if (!region->overlap) {
808  return false;
809  }
810  /* Sometimes the cursor may be on an invisible part of an overlapping region. */
811  const wmWindowManager *wm = CTX_wm_manager(C);
812  const wmEvent *event = wm->winactive->eventstate;
813  if (ED_region_overlap_isect_xy(region, event->xy)) {
814  return false;
815  }
816  /* Find the visible region under the cursor.
817  * TODO(Germano): Shouldn't this be the region in context? */
819  }
820 
821  RegionView3D *rv3d = region->regiondata;
822  if (rv3d->rflag & RV3D_NAVIGATING) {
823  /* Don't draw the cursor while navigating. It can be distracting. */
824  return false;
825  };
826 
828  if (state->gzgrp_type) {
829  /* Check the respective gizmo group is in the region. */
830  wmGizmoMap *gzmap = region->gizmo_map;
831  if (WM_gizmomap_group_find_ptr(gzmap, state->gzgrp_type) == NULL) {
832  /* Wrong viewport. */
833  return false;
834  }
835  }
836 
837  return true;
838 }
839 
840 static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(customdata))
841 {
842  SnapCursorDataIntern *data_intern = &g_data_intern;
844  V3DSnapCursorData *snap_data = &data_intern->snap_data;
845 
849  x -= region->winrct.xmin;
850  y -= region->winrct.ymin;
851  if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) {
854  View3D *v3d = CTX_wm_view3d(C);
855  v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
856  }
857 
858  const bool draw_plane = state->draw_plane || state->draw_box;
859  if (snap_data->snap_elem == SCE_SNAP_MODE_NONE && !draw_plane) {
860  return;
861  }
862 
863  /* Setup viewport & matrix. */
864  RegionView3D *rv3d = region->regiondata;
865  wmViewport(&region->winrct);
867  GPU_matrix_set(rv3d->viewmat);
868 
869  float matrix[4][4];
870  if (draw_plane) {
871  copy_m4_m3(matrix, snap_data->plane_omat);
872  copy_v3_v3(matrix[3], snap_data->loc);
873 
874  v3d_cursor_plane_draw(rv3d, state->plane_axis, matrix);
875  }
876 
877  if (snap_data->snap_elem != SCE_SNAP_MODE_NONE && (state->draw_point || state->draw_box)) {
878  const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ?
879  state->prevpoint :
880  NULL;
881 
882  GPU_line_smooth(false);
883  GPU_line_width(1.0f);
884 
886  prev_point,
887  snap_data->loc,
888  NULL,
889  state->color_line,
890  state->color_point,
891  snap_data->snap_elem);
892  }
893 
894  if (state->draw_box) {
895  GPU_matrix_mul(matrix);
896  cursor_box_draw(state->box_dimensions, state->color_box);
897  }
898 
899  /* Restore matrix. */
901 }
902 
906 {
907  SnapCursorDataIntern *data_intern = &g_data_intern;
908  if (BLI_listbase_is_empty(&data_intern->state_intern)) {
910  }
911  return &((SnapStateIntern *)data_intern->state_intern.last)->snap_state;
912 }
913 
914 static void v3d_cursor_snap_activate(void)
915 {
916  SnapCursorDataIntern *data_intern = &g_data_intern;
917 
918  if (!data_intern->handle) {
919  if (!data_intern->is_initiated) {
920  /* Only initiate intern data once.
921  * TODO: ED_view3d_cursor_snap_init */
922 
923 #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
924  struct wmKeyConfig *keyconf = ((wmWindowManager *)G.main->wm.first)->defaultconf;
925 
926  data_intern->keymap = WM_modalkeymap_find(keyconf, "Generic Gizmo Tweak Modal Map");
927  RNA_enum_value_from_id(data_intern->keymap->modal_items, "SNAP_ON", &data_intern->snap_on);
928 #endif
929  data_intern->is_initiated = true;
930  }
931 
934  data_intern->handle = pc;
935  }
936 }
937 
938 static void v3d_cursor_snap_free(void)
939 {
940  SnapCursorDataIntern *data_intern = &g_data_intern;
941  if (data_intern->handle) {
942  if (G_MAIN->wm.first) {
943  WM_paint_cursor_end(data_intern->handle);
944  }
945  data_intern->handle = NULL;
946  }
947  if (data_intern->snap_context_v3d) {
949  data_intern->snap_context_v3d = NULL;
950  }
951 }
952 
954 {
956 
957  /* These values are temporarily set by the tool.
958  * They are not convenient as default values.
959  * So reset to null. */
964 }
965 
967 {
968  SnapCursorDataIntern *data_intern = &g_data_intern;
969  if (!data_intern->handle) {
971  }
972 
973  SnapStateIntern *state_intern = MEM_mallocN(sizeof(*state_intern), __func__);
974  state_intern->snap_state = g_data_intern.state_default;
975  BLI_addtail(&g_data_intern.state_intern, state_intern);
976 
977  return (V3DSnapCursorState *)&state_intern->snap_state;
978 }
979 
981 {
982  SnapCursorDataIntern *data_intern = &g_data_intern;
983  if (BLI_listbase_is_empty(&data_intern->state_intern)) {
984  return;
985  }
986 
987  SnapStateIntern *state_intern = STATE_INTERN_GET(state);
988  BLI_remlink(&data_intern->state_intern, state_intern);
989  MEM_freeN(state_intern);
990  if (BLI_listbase_is_empty(&data_intern->state_intern)) {
992  }
993 }
994 
996 {
997  SnapCursorDataIntern *data_intern = &g_data_intern;
998  if (!state) {
1000  }
1001  if (prev_point) {
1002  copy_v3_v3(data_intern->prevpoint_stack, prev_point);
1003  state->prevpoint = data_intern->prevpoint_stack;
1004  }
1005  else {
1006  state->prevpoint = NULL;
1007  }
1008 }
1009 
1011  const bContext *C,
1012  const int x,
1013  const int y)
1014 {
1015  SnapCursorDataIntern *data_intern = &g_data_intern;
1017  if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) {
1020  ScrArea *area = CTX_wm_area(C);
1022  View3D *v3d = CTX_wm_view3d(C);
1023 
1024  if (!state) {
1026  }
1027  v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
1028  }
1029 }
1030 
1032 {
1033  SnapCursorDataIntern *data_intern = &g_data_intern;
1034  return &data_intern->snap_data;
1035 }
1036 
1038 {
1039  SnapCursorDataIntern *data_intern = &g_data_intern;
1041  return data_intern->snap_context_v3d;
1042 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
#define G_MAIN
Definition: BKE_global.h:267
General operations, lookup, etc. for blender objects.
int BKE_scene_orientation_get_index(struct Scene *scene, int slot_index)
Definition: scene.cc:2470
struct ARegion * BKE_area_find_region_type(const struct ScrArea *area, int type)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
MINLINE float max_ff(float a, float b)
MINLINE int mod_i(int i, int n)
MINLINE float square_f(float a)
float ceil_power_of_10(float f)
Definition: math_base.c:73
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void orthogonalize_m3(float R[3][3], int axis)
Definition: math_matrix.c:1439
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:102
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNPACK4(a)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Scene * DEG_get_input_scene(const Depsgraph *graph)
Object is a sort of wrapper for general info.
#define OBACT(_view_layer)
@ SCE_ORIENT_DEFAULT
@ SCE_SNAP
@ SCE_SNAP_ABS_GRID
eSnapMode
@ SCE_SNAP_MODE_EDGE_MIDPOINT
@ SCE_SNAP_MODE_VERTEX
@ SCE_SNAP_MODE_EDGE
@ SCE_SNAP_MODE_INCREMENT
@ SCE_SNAP_MODE_FACE_RAYCAST
@ SCE_SNAP_MODE_EDGE_PERPENDICULAR
@ SCE_SNAP_MODE_NONE
@ SCE_SNAP_MODE_GEOM
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
#define RV3D_NAVIGATING
bool ED_region_overlap_isect_xy(const ARegion *region, const int event_xy[2])
Definition: area_query.c:44
short ED_transform_calc_orientation_from_type_ex(const struct Scene *scene, struct ViewLayer *view_layer, const struct View3D *v3d, const struct RegionView3D *rv3d, struct Object *ob, struct Object *obedit, short orientation_index, int pivot_point, float r_mat[3][3])
SnapObjectContext * ED_transform_snap_object_context_create(struct Scene *scene, int flag)
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
eSnapMode ED_transform_snap_object_project_view3d_ex(struct SnapObjectContext *sctx, struct Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const eSnapMode snap_to, const struct SnapObjectParams *params, const float init_co[3], const float mval[2], const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3], int *r_index, struct Object **r_ob, float r_obmat[4][4], float r_face_nor[3])
@ V3D_PLACE_ORIENT_SURFACE
Definition: ED_view3d.h:298
bool ED_view3d_win_to_3d_on_plane(const struct ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3])
@ V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL
Definition: ED_view3d.h:287
@ V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE
Definition: ED_view3d.h:284
@ V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE
Definition: ED_view3d.h:285
@ V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE
Definition: ED_view3d.h:288
void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3])
float ED_view3d_grid_view_scale(struct Scene *scene, struct View3D *v3d, struct ARegion *region, const char **r_grid_unit)
Definition: view3d_draw.c:901
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
@ V3D_PLACE_DEPTH_CURSOR_VIEW
Definition: ED_view3d.h:294
@ V3D_PLACE_DEPTH_SURFACE
Definition: ED_view3d.h:292
NSNotificationCenter * center
void immUniformColor4ubv(const unsigned char rgba[4])
void immAttr4fv(uint attr_id, const float data[4])
void immUniform2f(const char *name, float x, float y)
void immUnbindProgram(void)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex3f(uint attr_id, float x, float y, float z)
void immBeginAtMost(GPUPrimType, uint max_vertex_len)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void imm_drawcircball(const float cent[3], float radius, const float tmat[4][4], uint pos)
void imm_draw_cube_corners_3d(uint pos, const float center[3], const float aspect[3], float factor)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
#define GPU_matrix_set(x)
Definition: GPU_matrix.h:225
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
#define GPU_matrix_projection_set(x)
Definition: GPU_matrix.h:226
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_SHADER_3D_SMOOTH_COLOR
Definition: GPU_shader.h:245
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:350
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:230
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
@ GPU_BLEND_ADDITIVE
Definition: GPU_state.h:64
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:75
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
@ 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.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#define C
Definition: RandGen.cpp:25
@ TH_VERTEX_SIZE
Definition: UI_resources.h:81
float UI_GetThemeValuef(int colorid)
Definition: resources.c:1141
@ KM_CTRL
Definition: WM_types.h:239
@ KM_ALT
Definition: WM_types.h:240
@ KM_OSKEY
Definition: WM_types.h:242
@ KM_SHIFT
Definition: WM_types.h:238
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
const Depsgraph * depsgraph
uint pos
IconTextureDrawCall normal
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
static void area(int d1, int d2, int e1, int e2, float weights[2])
static CursorSnapshot cursor_snap
Definition: paint_cursor.c:86
bool RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value)
Definition: rna_access.c:5076
unsigned char uint8_t
Definition: stdint.h:78
void * regiondata
short regiontype
struct wmGizmoMap * gizmo_map
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
float viewmat[4][4]
float viewinv[4][4]
float winmat[4][4]
struct ToolSettings * toolsettings
View3DCursor cursor
V3DSnapCursorState state_default
struct wmPaintCursor * handle
struct wmKeyMap * keymap
V3DSnapCursorData snap_data
struct SnapObjectContext * snap_context_v3d
struct SnapCursorDataIntern::@560 last_eventstate
struct SnapStateIntern * prev
V3DSnapCursorState snap_state
struct SnapStateIntern * next
char transform_pivot_point
eSnapMode snap_elem
Definition: ED_view3d.h:303
float plane_omat[3][3]
Definition: ED_view3d.h:308
float obmat[4][4]
Definition: ED_view3d.h:306
eV3DSnapCursor flag
Definition: ED_view3d.h:317
struct wmGizmoGroupType * gzgrp_type
Definition: ED_view3d.h:323
eSnapMode snap_elem_force
Definition: ED_view3d.h:326
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
const void * modal_items
void * customdata
Definition: wm.h:21
struct wmWindow * winactive
struct wmEvent * eventstate
static bool v3d_cursor_snap_calc_incremental(Scene *scene, View3D *v3d, ARegion *region, const float co_relative[3], float co[3])
void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state, const bContext *C, const int x, const int y)
static void v3d_cursor_eventstate_save_xy(SnapCursorDataIntern *cursor_snap, const int x, const int y)
void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state)
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3])
#define FADE(v)
static void v3d_cursor_eventstate_save_modifier(SnapCursorDataIntern *data_intern, const wmWindowManager *wm)
struct SnapStateIntern SnapStateIntern
static void v3d_cursor_snap_activate(void)
static const float eps_view_align
static bool v3d_cursor_snap_calc_plane(void)
static void cursor_box_draw(const float dimensions[3], uchar color[4])
static void v3d_cursor_snap_update(V3DSnapCursorState *state, const bContext *C, wmWindowManager *wm, Depsgraph *depsgraph, Scene *scene, ARegion *region, View3D *v3d, int x, int y)
static void v3d_cursor_poject_surface_normal(const float normal[3], const float obmat[4][4], float r_mat[3][3])
static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(customdata))
#define STATE_INTERN_GET(state)
static void v3d_cursor_plane_draw(const RegionView3D *rv3d, const int plane_axis, const float matrix[4][4])
static bool v3d_cursor_eventstate_has_changed(SnapCursorDataIntern *data_intern, V3DSnapCursorState *state, const wmWindowManager *wm, const int x, const int y)
static SnapCursorDataIntern g_data_intern
struct SnapCursorDataIntern SnapCursorDataIntern
static bool mat3_align_axis_to_v3(float mat[3][3], const int axis_align, const float v[3])
static eSnapMode v3d_cursor_snap_elements(V3DSnapCursorState *snap_state, Scene *scene)
static bool v3d_cursor_snap_poll_fn(bContext *C)
static void v3d_cursor_snap_context_ensure(Scene *scene)
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d, const float loc_prev[3], const float loc_curr[3], const float normal[3], const uchar color_line[4], const uchar color_point[4], const eSnapMode snap_elem_type)
static void v3d_cursor_snap_free(void)
V3DSnapCursorData * ED_view3d_cursor_snap_data_get()
void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state)
V3DSnapCursorState * ED_view3d_cursor_snap_active(void)
static void v3d_cursor_plane_draw_grid(const int resolution, const float scale, const float scale_fade, const float matrix[4][4], const int plane_axis, const float color[4])
V3DSnapCursorState * ED_view3d_cursor_snap_state_get(void)
static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const wmWindowManager *wm)
struct SnapObjectContext * ED_view3d_cursor_snap_context_ensure(Scene *scene)
@ EVT_RIGHTCTRLKEY
@ EVT_OSKEY
@ EVT_LEFTCTRLKEY
@ EVT_RIGHTALTKEY
@ EVT_LEFTALTKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
wmGizmoGroup * WM_gizmomap_group_find_ptr(struct wmGizmoMap *gzmap, const struct wmGizmoGroupType *gzgt)
Definition: wm_gizmo_map.c:211
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
Definition: wm_keymap.c:914
wmKeyMap * WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
Definition: wm_keymap.c:1943
bool WM_paint_cursor_end(wmPaintCursor *handle)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:21
void wmWindowViewport(wmWindow *win)
Definition: wm_subwindow.c:72