Blender  V2.93
wm_gizmo_map.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  * The Original Code is Copyright (C) 2014 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <string.h>
25 
26 #include "BLI_buffer.h"
27 #include "BLI_ghash.h"
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 #include "BLI_math_bits.h"
31 #include "BLI_rect.h"
32 
33 #include "BKE_context.h"
34 #include "BKE_global.h"
35 #include "BKE_main.h"
36 
37 #include "ED_screen.h"
38 #include "ED_select_utils.h"
39 #include "ED_view3d.h"
40 
41 #include "GPU_matrix.h"
42 #include "GPU_select.h"
43 #include "GPU_state.h"
44 
45 #include "MEM_guardedalloc.h"
46 
47 #include "WM_api.h"
48 #include "WM_types.h"
49 #include "wm_event_system.h"
50 
51 /* for tool-tips */
52 #include "UI_interface.h"
53 
54 #include "DEG_depsgraph.h"
55 
56 /* own includes */
57 #include "wm_gizmo_intern.h"
58 #include "wm_gizmo_wmapi.h"
59 
65 
69 /* so operator removal can trigger update */
75 
79 
81 
85 enum {
89 };
90 
91 /* -------------------------------------------------------------------- */
99 {
101  if (len <= msel->len_alloc) {
102  return;
103  }
104  msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * len);
105  msel->len_alloc = len;
106 }
107 
109 {
111  MEM_SAFE_FREE(msel->items);
112  msel->len = 0;
113  msel->len_alloc = 0;
114 }
115 
116 void wm_gizmomap_select_array_shrink(wmGizmoMap *gzmap, int len_subtract)
117 {
119  msel->len -= len_subtract;
120  if (msel->len <= 0) {
122  }
123  else {
124  if (msel->len < msel->len_alloc / 2) {
125  msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * msel->len);
126  msel->len_alloc = msel->len;
127  }
128  }
129 }
130 
132 {
134  BLI_assert(msel->len <= msel->len_alloc);
135  if (msel->len == msel->len_alloc) {
136  msel->len_alloc = (msel->len + 1) * 2;
137  msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * msel->len_alloc);
138  }
139  msel->items[msel->len++] = gz;
140 }
141 
143 {
145  /* remove gizmo from selected_gizmos array */
146  for (int i = 0; i < msel->len; i++) {
147  if (msel->items[i] == gz) {
148  for (int j = i; j < (msel->len - 1); j++) {
149  msel->items[j] = msel->items[j + 1];
150  }
152  break;
153  }
154  }
155 }
156 
159 /* -------------------------------------------------------------------- */
164  wmGizmoMap *gzmap)
165 {
166  gzmap->type = gzmap_type;
167  gzmap->is_init = true;
169 
170  /* create all gizmo-groups for this gizmo-map. We may create an empty one
171  * too in anticipation of gizmos from operators etc */
172  LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
173  wm_gizmogroup_new_from_type(gzmap, gzgt_ref->type);
174  }
175 
176  return gzmap;
177 }
178 
183 {
184  wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(gzmap_params);
185  wmGizmoMap *gzmap = MEM_callocN(sizeof(wmGizmoMap), "GizmoMap");
186  wm_gizmomap_new_from_type_ex(gzmap_type, gzmap);
187  return gzmap;
188 }
189 
191 {
192  /* Clear first so further calls don't waste time trying to maintain correct array state. */
194 
195  for (wmGizmoGroup *gzgroup = gzmap->groups.first, *gzgroup_next; gzgroup;
196  gzgroup = gzgroup_next) {
197  gzgroup_next = gzgroup->next;
198  BLI_assert(gzgroup->parent_gzmap == gzmap);
199  wm_gizmogroup_free(NULL, gzgroup);
200  }
202 }
203 
205 {
206  wm_gizmomap_free_data(gzmap);
207  MEM_freeN(gzmap);
208 }
209 
212 {
213  wmGizmoMapType *gzmap_type = gzmap->type;
214  wm_gizmomap_free_data(gzmap);
215  memset(gzmap, 0x0, sizeof(*gzmap));
216  wm_gizmomap_new_from_type_ex(gzmap_type, gzmap);
217 }
218 
219 wmGizmoGroup *WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
220 {
221  wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
222  if (gzgt) {
223  return WM_gizmomap_group_find_ptr(gzmap, gzgt);
224  }
225  return NULL;
226 }
227 
229  const struct wmGizmoGroupType *gzgt)
230 {
231  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
232  if (gzgroup->type == gzgt) {
233  return gzgroup;
234  }
235  }
236  return NULL;
237 }
238 
240 {
241  return &gzmap->groups;
242 }
243 
245 {
246  return gzmap->gzmap_context.select.len != 0;
247 }
248 
252 bool WM_gizmomap_minmax(const wmGizmoMap *gzmap,
253  bool UNUSED(use_hidden),
254  bool use_select,
255  float r_min[3],
256  float r_max[3])
257 {
258  if (use_select) {
259  int i;
260  for (i = 0; i < gzmap->gzmap_context.select.len; i++) {
261  minmax_v3v3_v3(r_min, r_max, gzmap->gzmap_context.select.items[i]->matrix_basis[3]);
262  }
263  return i != 0;
264  }
265 
266  bool ok = false;
267  BLI_assert(!"TODO");
268  return ok;
269 }
270 
281  wmGizmoMap *gzmap,
282  bool (*poll)(const wmGizmo *, void *),
283  void *data,
284  const eWM_GizmoFlag flag_exclude)
285 {
286  GHash *hash = BLI_ghash_ptr_new(__func__);
287 
288  /* collect gizmos */
289  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
290  if (WM_gizmo_group_type_poll(C, gzgroup->type)) {
291  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
292  if (((flag_exclude == 0) || ((gz->flag & flag_exclude) == 0)) &&
293  (!poll || poll(gz, data))) {
294  BLI_ghash_insert(hash, gz, gz);
295  }
296  }
297  }
298  }
299 
300  return hash;
301 }
302 
304 {
306  if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
308  }
309  else {
311  }
312  return step;
313 }
314 
316 {
318  if (gzmap) {
320  }
321 }
322 
324 {
325  if (gzmap) {
326  for (int i = 0; i < WM_GIZMOMAP_DRAWSTEP_MAX; i++) {
328  }
329  }
330 }
331 
333 {
334  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
335  if (gzgroup->hide.delay_refresh_for_tweak) {
336  return true;
337  }
338  }
339  return false;
340 }
341 
343  wmGizmo *gz,
344  const bContext *C,
345  ListBase *draw_gizmos,
346  const eWM_GizmoFlagMapDrawStep drawstep)
347 {
348  int do_draw = wm_gizmo_is_visible(gz);
349  if (do_draw == 0) {
350  /* skip */
351  }
352  else {
353  /* Ensure we get RNA updates */
354  if (do_draw & WM_GIZMO_IS_VISIBLE_UPDATE) {
355  /* hover gizmos need updating, even if we don't draw them */
356  wm_gizmo_update(gz, C, (gzmap->update_flag[drawstep] & GIZMOMAP_IS_PREPARE_DRAW) != 0);
357  }
358  if (do_draw & WM_GIZMO_IS_VISIBLE_DRAW) {
359  BLI_addhead(draw_gizmos, BLI_genericNodeN(gz));
360  }
361  return true;
362  }
363 
364  return false;
365 }
366 
372  const bContext *C,
373  ListBase *draw_gizmos,
374  const eWM_GizmoFlagMapDrawStep drawstep)
375 {
376  if (!gzmap || BLI_listbase_is_empty(&gzmap->groups)) {
377  return;
378  }
379 
380  gzmap->is_init = false;
381 
382  wmGizmo *gz_modal = gzmap->gzmap_context.modal;
383 
384  /* only active gizmo needs updating */
385  if (gz_modal) {
386  if ((gz_modal->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL) == 0) {
387  if ((gz_modal->parent_gzgroup->hide.any == 0) &&
389  if (gizmo_prepare_drawing(gzmap, gz_modal, C, draw_gizmos, drawstep)) {
390  gzmap->update_flag[drawstep] &= ~GIZMOMAP_IS_PREPARE_DRAW;
391  }
392  }
393  /* don't draw any other gizmos */
394  return;
395  }
396  }
397 
398  /* Allow refresh functions to ask to be refreshed again, clear before the loop below. */
399  const bool do_refresh = gzmap->update_flag[drawstep] & GIZMOMAP_IS_REFRESH_CALLBACK;
400  gzmap->update_flag[drawstep] &= ~GIZMOMAP_IS_REFRESH_CALLBACK;
401 
402  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
403  /* check group visibility - drawstep first to avoid unnecessary call of group poll callback */
404  if (!wm_gizmogroup_is_visible_in_drawstep(gzgroup, drawstep) ||
405  !WM_gizmo_group_type_poll(C, gzgroup->type)) {
406  continue;
407  }
408 
409  /* Needs to be initialized on first draw. */
410  /* XXX weak: Gizmo-group may skip refreshing if it's invisible
411  * (map gets untagged nevertheless). */
412  if (do_refresh) {
413  /* force refresh again. */
414  gzgroup->init_flag &= ~WM_GIZMOGROUP_INIT_REFRESH;
415  }
416  /* Calls `setup`, `setup_keymap` and `refresh` if they're defined. */
417  WM_gizmogroup_ensure_init(C, gzgroup);
418 
419  /* Check after ensure which can run refresh and update this value. */
420  if (gzgroup->hide.any != 0) {
421  continue;
422  }
423 
424  /* prepare drawing */
425  if (gzgroup->type->draw_prepare) {
426  gzgroup->type->draw_prepare(C, gzgroup);
427  }
428 
429  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
430  gizmo_prepare_drawing(gzmap, gz, C, draw_gizmos, drawstep);
431  }
432  }
433 
434  gzmap->update_flag[drawstep] &= ~GIZMOMAP_IS_PREPARE_DRAW;
435 }
436 
441 static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBase *draw_gizmos)
442 {
443  /* Can be empty if we're dynamically added and removed. */
444  if ((gzmap == NULL) || BLI_listbase_is_empty(&gzmap->groups)) {
445  return;
446  }
447 
448  /* TODO(campbell): This will need it own shader probably?
449  * Don't think it can be handled from that point though. */
450  /* const bool use_lighting = (U.gizmo_flag & V3D_GIZMO_SHADED) != 0; */
451 
452  bool is_depth_prev = false;
453 
454  /* draw_gizmos contains all visible gizmos - draw them */
455  for (LinkData *link = draw_gizmos->first, *link_next; link; link = link_next) {
456  wmGizmo *gz = link->data;
457  link_next = link->next;
458 
459  bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0;
460 
461  /* Weak! since we don't 100% support depth yet (select ignores depth)
462  * always show highlighted. */
463  if (is_depth && (gz->state & WM_GIZMO_STATE_HIGHLIGHT)) {
464  is_depth = false;
465  }
466 
467  if (is_depth == is_depth_prev) {
468  /* pass */
469  }
470  else {
471  if (is_depth) {
473  }
474  else {
476  }
477  is_depth_prev = is_depth;
478  }
479 
480  /* XXX force AntiAlias Gizmos. */
481  GPU_line_smooth(true);
482  GPU_polygon_smooth(true);
483 
484  gz->type->draw(C, gz);
485 
486  GPU_line_smooth(false);
487  GPU_polygon_smooth(false);
488 
489  /* free/remove gizmo link after drawing */
490  BLI_freelinkN(draw_gizmos, link);
491  }
492 
493  if (is_depth_prev) {
495  }
496 }
497 
499  const bContext *C,
500  const eWM_GizmoFlagMapDrawStep drawstep)
501 {
502  if (!WM_gizmo_context_check_drawstep(C, drawstep)) {
503  return;
504  }
505 
506  ListBase draw_gizmos = {NULL};
507 
508  gizmomap_prepare_drawing(gzmap, C, &draw_gizmos, drawstep);
509  gizmos_draw_list(gzmap, C, &draw_gizmos);
510  BLI_assert(BLI_listbase_is_empty(&draw_gizmos));
511 }
512 
514  wmGizmo **visible_gizmos,
515  const int visible_gizmos_len,
516  bool *r_use_select_bias)
517 {
518 
519  /* TODO(campbell): this depends on depth buffer being written to,
520  * currently broken for the 3D view. */
521  bool is_depth_prev = false;
522  bool is_depth_skip_prev = false;
523 
524  for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
525  wmGizmo *gz = visible_gizmos[select_id];
526  if (gz->type->draw_select == NULL) {
527  continue;
528  }
529 
530  bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0;
531  if (is_depth == is_depth_prev) {
532  /* pass */
533  }
534  else {
535  if (is_depth) {
537  }
538  else {
540  }
541  is_depth_prev = is_depth;
542  }
543  bool is_depth_skip = (gz->flag & WM_GIZMO_SELECT_BACKGROUND) != 0;
544  if (is_depth_skip == is_depth_skip_prev) {
545  /* pass */
546  }
547  else {
548  GPU_depth_mask(!is_depth_skip);
549  is_depth_skip_prev = is_depth_skip;
550  }
551 
552  if (gz->select_bias != 0.0) {
553  *r_use_select_bias = true;
554  }
555 
556  /* pass the selection id shifted by 8 bits. Last 8 bits are used for selected gizmo part id */
557 
558  gz->type->draw_select(C, gz, select_id << 8);
559  }
560 
561  if (is_depth_prev) {
563  }
564  if (is_depth_skip_prev) {
565  GPU_depth_mask(true);
566  }
567 }
568 
569 static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
570  const int visible_gizmos_len,
571  const bContext *C,
572  const int co[2],
573  const int hotspot)
574 {
575  const wmWindowManager *wm = CTX_wm_manager(C);
577  ARegion *region = CTX_wm_region(C);
578  View3D *v3d = area->spacedata.first;
580  rcti rect;
581  /* Almost certainly overkill, but allow for many custom gizmos. */
583  short hits;
584 
585  BLI_rcti_init_pt_radius(&rect, co, hotspot);
586 
588  wm, CTX_wm_window(C), depsgraph, CTX_data_scene(C), region, v3d, NULL, NULL, &rect);
589 
590  bool use_select_bias = false;
591 
592  /* TODO: waiting for the GPU in the middle of the event loop for every
593  * mouse move is bad for performance, we need to find a solution to not
594  * use the GPU or draw something once. (see T61474) */
596  /* do the drawing */
597  gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
598 
599  hits = GPU_select_end();
600 
601  if (hits > 0) {
603  gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
604  GPU_select_end();
605  }
606 
608  wm, CTX_wm_window(C), depsgraph, CTX_data_scene(C), region, v3d, NULL, NULL, NULL);
609 
610  if (use_select_bias && (hits > 1)) {
611  float co_direction[3];
612  float co_screen[3] = {co[0], co[1], 0.0f};
613  ED_view3d_win_to_vector(region, (float[2]){UNPACK2(co)}, co_direction);
614 
615  RegionView3D *rv3d = region->regiondata;
616  const int viewport[4] = {0, 0, region->winx, region->winy};
617  float co_3d_origin[3];
618 
619  /* Avoid multiple calculations. */
620  struct GPUMatrixUnproject_Precalc unproj_precalc;
621  GPU_matrix_unproject_precalc(&unproj_precalc, rv3d->viewmat, rv3d->winmat, viewport);
622 
623  GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d_origin);
624 
625  uint *buf_iter = buffer;
626  int hit_found = -1;
627  float dot_best = FLT_MAX;
628 
629  for (int i = 0; i < hits; i++, buf_iter += 4) {
630  BLI_assert(buf_iter[3] != -1);
631  wmGizmo *gz = visible_gizmos[buf_iter[3] >> 8];
632  float co_3d[3];
633  co_screen[2] = int_as_float(buf_iter[1]);
634  GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d);
635  float select_bias = gz->select_bias;
636  if ((gz->flag & WM_GIZMO_DRAW_NO_SCALE) == 0) {
637  select_bias *= gz->scale_final;
638  }
639  sub_v3_v3(co_3d, co_3d_origin);
640  const float dot_test = dot_v3v3(co_3d, co_direction) - select_bias;
641  if (dot_best > dot_test) {
642  dot_best = dot_test;
643  hit_found = buf_iter[3];
644  }
645  }
646  return hit_found;
647  }
648 
649  const uint *hit_near = GPU_select_buffer_near(buffer, hits);
650  return hit_near ? hit_near[3] : -1;
651 }
652 
657  const int co[2],
658  wmGizmo **visible_gizmos,
659  const int visible_gizmos_len,
660  int *r_part)
661 {
662  wmGizmo *result = NULL;
663  int visible_gizmos_len_trim = visible_gizmos_len;
664  int hit = -1;
665 
666  *r_part = 0;
667 
668  /* set up view matrices */
670 
671  /* Search for 3D gizmo's that use the 2D callback for checking intersections. */
672  bool has_3d = false;
673  {
674  for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
675  wmGizmo *gz = visible_gizmos[select_id];
676  /* With both defined, favor the 3D, in case the gizmo can be used in 2D or 3D views. */
677  if (gz->type->test_select && (gz->type->draw_select == NULL)) {
678  if ((*r_part = gz->type->test_select(C, gz, co)) != -1) {
679  hit = select_id;
680  result = gz;
681  /* Don't search past this when checking intersections. */
682  visible_gizmos_len_trim = select_id;
683  break;
684  }
685  }
686  else if (gz->type->draw_select != NULL) {
687  has_3d = true;
688  }
689  }
690  }
691 
692  /* Search for 3D intersections if they're before 2D that have been found (if any).
693  * This way we always use the first hit. */
694  if (has_3d) {
695  const int hotspot_radii[] = {
696  3 * U.pixelsize,
697  /* This runs on mouse move, careful doing too many tests! */
698  10 * U.pixelsize,
699  };
700  for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) {
702  visible_gizmos, visible_gizmos_len_trim, C, co, hotspot_radii[i]);
703  if (hit != -1) {
704  break;
705  }
706  }
707 
708  if (hit != -1) {
709  const int select_id = hit >> 8;
710  const int select_part = hit & 0xff;
711  BLI_assert(select_id < visible_gizmos_len);
712  *r_part = select_part;
713  result = visible_gizmos[select_id];
714  }
715  }
716 
717  return result;
718 }
719 
725  bContext *C,
726  const wmEvent *event,
727  int *r_part)
728 {
730  wmGizmo *gz = NULL;
731  BLI_buffer_declare_static(wmGizmo *, visible_3d_gizmos, BLI_BUFFER_NOP, 128);
732  bool do_step[WM_GIZMOMAP_DRAWSTEP_MAX];
733 
734  for (int i = 0; i < ARRAY_SIZE(do_step); i++) {
735  do_step[i] = WM_gizmo_context_check_drawstep(C, i);
736  }
737 
738  const int event_modifier = WM_event_modifier_flag(event);
739 
740  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
741 
742  /* If it were important we could initialize here,
743  * but this only happens when events are handled before drawing,
744  * just skip to keep code-path for initializing gizmos simple. */
745  if ((gzgroup->hide.any != 0) || ((gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0)) {
746  continue;
747  }
748 
749  if (WM_gizmo_group_type_poll(C, gzgroup->type)) {
751  if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
753  }
754  else {
756  }
757 
758  if (do_step[step]) {
759  if (gzmap->update_flag[step] & GIZMOMAP_IS_REFRESH_CALLBACK) {
760  WM_gizmo_group_refresh(C, gzgroup);
761  /* cleared below */
762  }
763  if (step == WM_GIZMOMAP_DRAWSTEP_3D) {
765  wm, gzgroup, event_modifier, &visible_3d_gizmos);
766  }
767  else if (step == WM_GIZMOMAP_DRAWSTEP_2D) {
769  wm, gzgroup, C, event_modifier, event->mval, r_part))) {
770  break;
771  }
772  }
773  }
774  }
775  }
776 
777  if (visible_3d_gizmos.count) {
778  /* 2D gizmos get priority. */
779  if (gz == NULL) {
781  C, event->mval, visible_3d_gizmos.data, visible_3d_gizmos.count, r_part);
782  }
783  }
784  BLI_buffer_free(&visible_3d_gizmos);
785 
788 
789  return gz;
790 }
791 
793 {
794  LISTBASE_FOREACH (wmEventHandler *, handler_base, &region->handlers) {
795  if (handler_base->type == WM_HANDLER_TYPE_GIZMO) {
796  wmEventHandler_Gizmo *handler = (wmEventHandler_Gizmo *)handler_base;
797  if (handler->gizmo_map == gzmap) {
798  return;
799  }
800  }
801  }
802 
803  wmEventHandler_Gizmo *handler = MEM_callocN(sizeof(*handler), __func__);
804  handler->head.type = WM_HANDLER_TYPE_GIZMO;
805  BLI_assert(gzmap == region->gizmo_map);
806  handler->gizmo_map = gzmap;
807  BLI_addtail(&region->handlers, handler);
808 }
809 
811 {
812  const bool modal_running = (handler->op != NULL);
813 
814  /* happens on render or when joining areas */
815  if (!handler->context.region || !handler->context.region->gizmo_map) {
816  return;
817  }
818 
819  wmGizmoMap *gzmap = handler->context.region->gizmo_map;
820  wmGizmo *gz = wm_gizmomap_modal_get(gzmap);
822  ARegion *region = CTX_wm_region(C);
823 
825 
826  /* regular update for running operator */
827  if (modal_running) {
828  wmGizmoOpElem *gzop = gz ? WM_gizmo_operator_get(gz, gz->highlight_part) : NULL;
829  if (gz && gzop && (gzop->type != NULL) && (gzop->type == handler->op->type)) {
830  wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal;
831  if (modal_fn != NULL) {
832  int retval = modal_fn(C, gz, event, 0);
833  /* The gizmo is tried to the operator, we can't choose when to exit. */
835  UNUSED_VARS_NDEBUG(retval);
836  }
837  }
838  }
839  /* operator not running anymore */
840  else {
841  wm_gizmomap_highlight_set(gzmap, C, NULL, 0);
842  if (gz) {
843  /* This isn't defined if it ends because of success of cancel, we may want to change. */
844  bool cancel = true;
845  if (gz->type->exit) {
846  gz->type->exit(C, gz, cancel);
847  }
848  wm_gizmomap_modal_set(gzmap, C, gz, NULL, false);
849  }
850  }
851 
852  /* restore the area */
854  CTX_wm_region_set(C, region);
855 }
856 
862 {
864 
865  if (msel->items == NULL || msel->len == 0) {
866  return false;
867  }
868 
869  for (int i = 0; i < msel->len; i++) {
870  wm_gizmo_select_set_ex(gzmap, msel->items[i], false, false, true);
871  }
872 
874 
875  /* always return true, we already checked
876  * if there's anything to deselect */
877  return true;
878 }
879 
881 {
883 }
884 
890 {
892  /* GHash is used here to avoid having to loop over all gizmos twice (once to
893  * get tot_sel for allocating, once for actually selecting). Instead we collect
894  * selectable gizmos in hash table and use this to get tot_sel and do selection */
895 
898  GHashIterator gh_iter;
899  int i;
900  bool changed = false;
901 
903 
904  GHASH_ITER_INDEX (gh_iter, hash, i) {
905  wmGizmo *gz_iter = BLI_ghashIterator_getValue(&gh_iter);
906  WM_gizmo_select_set(gzmap, gz_iter, true);
907  }
908  /* highlight first gizmo */
909  wm_gizmomap_highlight_set(gzmap, C, msel->items[0], msel->items[0]->highlight_part);
910 
911  BLI_assert(BLI_ghash_len(hash) == msel->len);
912 
914  return changed;
915 }
916 
923 bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, const int action)
924 {
925  bool changed = false;
926 
927  switch (action) {
928  case SEL_SELECT:
929  changed = wm_gizmomap_select_all_intern(C, gzmap);
930  break;
931  case SEL_DESELECT:
932  changed = wm_gizmomap_deselect_all(gzmap);
933  break;
934  default:
936  break;
937  }
938 
939  if (changed) {
941  }
942 
943  return changed;
944 }
945 
951 {
952  bScreen *screen = CTX_wm_screen(C);
953 
954  if (screen) {
955  ScrArea *area;
956 
957  for (area = screen->areabase.first; area; area = area->next) {
958  if (area == handler->context.area) {
959  break;
960  }
961  }
962  if (area == NULL) {
963  /* when changing screen layouts with running modal handlers (like render display), this
964  * is not an error to print */
965  printf("internal error: modal gizmo-map handler has invalid area\n");
966  }
967  else {
968  ARegion *region;
970  for (region = area->regionbase.first; region; region = region->next) {
971  if (region == handler->context.region) {
972  break;
973  }
974  }
975  /* XXX no warning print here, after full-area and back regions are remade */
976  if (region) {
977  CTX_wm_region_set(C, region);
978  }
979  }
980  }
981 }
982 
984 {
985  /* pass */
986 }
987 
989 {
990  wmGizmo *gz = gzmap->gzmap_context.highlight;
991  if (gz && gz->type->cursor_get) {
992  WM_cursor_set(win, gz->type->cursor_get(gz));
993  return true;
994  }
995 
996  return false;
997 }
998 
999 bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part)
1000 {
1001  if ((gz != gzmap->gzmap_context.highlight) || (gz && part != gz->highlight_part)) {
1002  const bool init_last_cursor = !(gzmap->gzmap_context.highlight &&
1003  gzmap->gzmap_context.last_cursor != -1);
1004  if (gzmap->gzmap_context.highlight) {
1006  gzmap->gzmap_context.highlight->highlight_part = -1;
1007  }
1008 
1009  gzmap->gzmap_context.highlight = gz;
1010 
1011  if (gz) {
1013  gz->highlight_part = part;
1014  if (init_last_cursor) {
1015  gzmap->gzmap_context.last_cursor = -1;
1016  }
1017 
1018  if (C && gz->type->cursor_get) {
1019  wmWindow *win = CTX_wm_window(C);
1020  if (init_last_cursor) {
1021  gzmap->gzmap_context.last_cursor = win->cursor;
1022  }
1023  WM_cursor_set(win, gz->type->cursor_get(gz));
1024  }
1025  }
1026  else {
1027  if (C && gzmap->gzmap_context.last_cursor != -1) {
1028  wmWindow *win = CTX_wm_window(C);
1030  }
1031  gzmap->gzmap_context.last_cursor = -1;
1032  }
1033 
1034  /* tag the region for redraw */
1035  if (C) {
1036  ARegion *region = CTX_wm_region(C);
1038  }
1039 
1040  return true;
1041  }
1042 
1043  return false;
1044 }
1045 
1047 {
1048  return gzmap->gzmap_context.highlight;
1049 }
1050 
1055  wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event, bool enable)
1056 {
1057  if (enable) {
1058  BLI_assert(gzmap->gzmap_context.modal == NULL);
1059  wmWindow *win = CTX_wm_window(C);
1060 
1061  WM_tooltip_clear(C, win);
1062 
1063  /* Use even if we don't have invoke, so we can setup data before an operator runs. */
1064  if (gz->parent_gzgroup->type->invoke_prepare) {
1065  gz->parent_gzgroup->type->invoke_prepare(C, gz->parent_gzgroup, gz, event);
1066  }
1067 
1068  if (gz->type->invoke && (gz->type->modal || gz->custom_modal)) {
1069  const int retval = gz->type->invoke(C, gz, event);
1070  if ((retval & OPERATOR_RUNNING_MODAL) == 0) {
1071  return;
1072  }
1073  }
1074 
1075  gz->state |= WM_GIZMO_STATE_MODAL;
1076  gzmap->gzmap_context.modal = gz;
1077 
1078  if ((gz->flag & WM_GIZMO_MOVE_CURSOR) && (event->tablet.is_motion_absolute == false)) {
1080  copy_v2_v2_int(gzmap->gzmap_context.event_xy, &event->x);
1082  }
1083  else {
1084  gzmap->gzmap_context.event_xy[0] = INT_MAX;
1085  }
1086 
1087  struct wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, gz->highlight_part);
1088  if (gzop && gzop->type) {
1089  const int retval = WM_gizmo_operator_invoke(C, gz, gzop);
1090  if ((retval & OPERATOR_RUNNING_MODAL) == 0) {
1091  wm_gizmomap_modal_set(gzmap, C, gz, event, false);
1092  }
1093 
1094  /* we failed to hook the gizmo to the operator handler or operator was cancelled, return */
1095  if (!gzmap->gzmap_context.modal) {
1096  gz->state &= ~WM_GIZMO_STATE_MODAL;
1098  }
1099  return;
1100  }
1101  }
1102  else {
1103  BLI_assert(ELEM(gzmap->gzmap_context.modal, NULL, gz));
1104 
1105  /* deactivate, gizmo but first take care of some stuff */
1106  if (gz) {
1107  gz->state &= ~WM_GIZMO_STATE_MODAL;
1109  }
1110  gzmap->gzmap_context.modal = NULL;
1111 
1112  if (C) {
1113  wmWindow *win = CTX_wm_window(C);
1114  if (gzmap->gzmap_context.event_xy[0] != INT_MAX) {
1115  /* Check if some other part of Blender (typically operators)
1116  * have adjusted the grab mode since it was set.
1117  * If so: warp, so we have a predictable outcome. */
1118  if (gzmap->gzmap_context.event_grabcursor == win->grabcursor) {
1120  }
1121  else {
1123  }
1124  }
1127  }
1128 
1129  gzmap->gzmap_context.event_xy[0] = INT_MAX;
1130  }
1131 }
1132 
1134 {
1135  return gzmap->gzmap_context.modal;
1136 }
1137 
1138 wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *gzmap, int *r_selected_len)
1139 {
1140  *r_selected_len = gzmap->gzmap_context.select.len;
1141  return gzmap->gzmap_context.select.items;
1142 }
1143 
1145 {
1146  return &gzmap->groups;
1147 }
1148 
1150  wmGizmoMap *gzmap,
1151  ARegion *region,
1152  struct wmMsgBus *mbus)
1153 {
1154  LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
1155  if ((gzgroup->hide.any != 0) || (gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0 ||
1156  !WM_gizmo_group_type_poll(C, gzgroup->type)) {
1157  continue;
1158  }
1159  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
1160  if (gz->flag & WM_GIZMO_HIDDEN) {
1161  continue;
1162  }
1163  WM_gizmo_target_property_subscribe_all(gz, mbus, region);
1164  }
1165  if (gzgroup->type->message_subscribe != NULL) {
1166  gzgroup->type->message_subscribe(C, gzgroup, mbus);
1167  }
1168  }
1169 }
1170  /* wmGizmoMap */
1172 
1173 /* -------------------------------------------------------------------- */
1178  struct ARegion *region,
1179  int *UNUSED(r_pass),
1180  double *UNUSED(pass_delay),
1181  bool *r_exit_on_event)
1182 {
1183  wmGizmoMap *gzmap = region->gizmo_map;
1184  *r_exit_on_event = false;
1185  if (gzmap) {
1186  wmGizmo *gz = gzmap->gzmap_context.highlight;
1187  if (gz) {
1188  wmGizmoGroup *gzgroup = gz->parent_gzgroup;
1189  if ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0) {
1190  /* On screen area of 3D gizmos may be large, exit on cursor motion. */
1191  *r_exit_on_event = true;
1192  }
1193  return UI_tooltip_create_from_gizmo(C, gz);
1194  }
1195  }
1196  return NULL;
1197 }
1198  /* wmGizmoMapType */
1200 
1201 /* -------------------------------------------------------------------- */
1206 {
1207  LISTBASE_FOREACH (wmGizmoMapType *, gzmap_type, &gizmomaptypes) {
1208  if (gzmap_type->spaceid == gzmap_params->spaceid &&
1209  gzmap_type->regionid == gzmap_params->regionid) {
1210  return gzmap_type;
1211  }
1212  }
1213 
1214  return NULL;
1215 }
1216 
1218 {
1219  wmGizmoMapType *gzmap_type = WM_gizmomaptype_find(gzmap_params);
1220 
1221  if (gzmap_type) {
1222  return gzmap_type;
1223  }
1224 
1225  gzmap_type = MEM_callocN(sizeof(wmGizmoMapType), "gizmotype list");
1226  gzmap_type->spaceid = gzmap_params->spaceid;
1227  gzmap_type->regionid = gzmap_params->regionid;
1228  BLI_addhead(&gizmomaptypes, gzmap_type);
1229 
1230  return gzmap_type;
1231 }
1232 
1234 {
1235  for (wmGizmoMapType *gzmap_type = gizmomaptypes.first, *gzmap_type_next; gzmap_type;
1236  gzmap_type = gzmap_type_next) {
1237  gzmap_type_next = gzmap_type->next;
1238  for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first, *gzgt_next; gzgt_ref;
1239  gzgt_ref = gzgt_next) {
1240  gzgt_next = gzgt_ref->next;
1241  WM_gizmomaptype_group_free(gzgt_ref);
1242  }
1243  MEM_freeN(gzmap_type);
1244  }
1245 }
1246 
1251 {
1252  LISTBASE_FOREACH (wmGizmoMapType *, gzmap_type, &gizmomaptypes) {
1253  LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
1254  wm_gizmogrouptype_setup_keymap(gzgt_ref->type, keyconf);
1255  }
1256  }
1257 
1259 }
1260  /* wmGizmoMapType */
1262 
1263 /* -------------------------------------------------------------------- */
1268 {
1269  /* tag for update on next use */
1272 
1274 }
1275 
1277  wmGizmoGroupType *gzgt)
1278 {
1279  /* tag for update on next use */
1282 
1284 }
1285 
1287 {
1288  gzmap->tag_remove_group = true;
1289 
1291 }
1292 
1297 void WM_gizmoconfig_update(struct Main *bmain)
1298 {
1299  if (G.background) {
1300  return;
1301  }
1302 
1303  if (wm_gzmap_type_update_flag == 0) {
1304  return;
1305  }
1306 
1308  LISTBASE_FOREACH (wmGizmoMapType *, gzmap_type, &gizmomaptypes) {
1309  if (gzmap_type->type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE) {
1310  gzmap_type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE;
1311  for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first, *gzgt_ref_next;
1312  gzgt_ref;
1313  gzgt_ref = gzgt_ref_next) {
1314  gzgt_ref_next = gzgt_ref->next;
1315  if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_REMOVE) {
1316  gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE;
1317  WM_gizmomaptype_group_unlink(NULL, bmain, gzmap_type, gzgt_ref->type);
1318  }
1319  }
1320  }
1321  }
1322 
1324  }
1325 
1327  LISTBASE_FOREACH (wmGizmoMapType *, gzmap_type, &gizmomaptypes) {
1329  if (gzmap_type->type_update_flag & type_update_all) {
1330  gzmap_type->type_update_flag &= ~type_update_all;
1331  LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
1332  if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_KEYMAP_INIT) {
1333  WM_gizmomaptype_group_init_runtime_keymap(bmain, gzgt_ref->type);
1334  gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT;
1335  }
1336 
1337  if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_INIT) {
1338  WM_gizmomaptype_group_init_runtime(bmain, gzmap_type, gzgt_ref->type);
1339  gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_INIT;
1340  }
1341  }
1342  }
1343  }
1344 
1346  }
1347 
1349  for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
1350  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1351  LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1352  ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1353  &sl->regionbase;
1354  LISTBASE_FOREACH (ARegion *, region, regionbase) {
1355  wmGizmoMap *gzmap = region->gizmo_map;
1356  if (gzmap != NULL && gzmap->tag_remove_group) {
1357  gzmap->tag_remove_group = false;
1358 
1359  for (wmGizmoGroup *gzgroup = gzmap->groups.first, *gzgroup_next; gzgroup;
1360  gzgroup = gzgroup_next) {
1361  gzgroup_next = gzgroup->next;
1362  if (gzgroup->tag_remove) {
1363  wm_gizmogroup_free(NULL, gzgroup);
1365  }
1366  }
1367  }
1368  }
1369  }
1370  }
1371  }
1373  }
1374 }
1375 
1378 /* -------------------------------------------------------------------- */
1386 {
1387  for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
1388  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1389  LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1390  ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
1391  LISTBASE_FOREACH (ARegion *, region, regionbase) {
1392  wmGizmoMap *gzmap = region->gizmo_map;
1393  if ((gzmap != NULL) && (gzmap->is_init == false)) {
1394  WM_gizmomap_reinit(gzmap);
1395  }
1396  }
1397  }
1398  }
1399  }
1400 }
1401 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:985
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:973
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
#define BLI_assert_unreachable()
Definition: BLI_assert.h:96
#define BLI_assert(a)
Definition: BLI_assert.h:58
@ BLI_BUFFER_NOP
Definition: BLI_buffer.h:35
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_)
Definition: BLI_buffer.h:39
#define BLI_buffer_free(name_)
Definition: BLI_buffer.h:92
#define BLI_INLINE
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:150
unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:744
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_)
Definition: BLI_ghash.h:173
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:923
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE float int_as_float(int i)
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:1020
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size)
Definition: rct.c:508
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ OPERATOR_RUNNING_MODAL
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:706
@ SEL_SELECT
@ SEL_DESELECT
#define MAXPICKBUF
Definition: ED_view3d.h:511
void ED_view3d_draw_setup_view(const struct wmWindowManager *wm, struct wmWindow *win, struct Depsgraph *depsgraph, struct Scene *scene, struct ARegion *region, struct View3D *v3d, const float viewmat[4][4], const float winmat[4][4], const struct rcti *rect)
void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float out[3])
void view3d_operator_needs_opengl(const struct bContext *C)
void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc, const float win[3], float r_world[3])
Definition: gpu_matrix.cc:559
bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *unproj_precalc, const float model[4][4], const float proj[4][4], const int view[4])
Definition: gpu_matrix.cc:531
@ GPU_SELECT_NEAREST_SECOND_PASS
Definition: GPU_select.h:39
@ GPU_SELECT_NEAREST_FIRST_PASS
Definition: GPU_select.h:38
unsigned int GPU_select_end(void)
Definition: gpu_select.c:131
const uint * GPU_select_buffer_near(const uint *buffer, int hits)
Definition: gpu_select.c:200
void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const struct rcti *input, char mode, int oldhits)
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:85
void GPU_depth_mask(bool depth)
Definition: gpu_state.cc:117
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:81
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
void GPU_polygon_smooth(bool enable)
Definition: gpu_state.cc:90
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
#define C
Definition: RandGen.cpp:39
struct ARegion * UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz)
eWM_GizmoFlagMapDrawStep
@ WM_GIZMOMAP_DRAWSTEP_3D
@ WM_GIZMOMAP_DRAWSTEP_2D
@ WM_GIZMOMAPTYPE_UPDATE_REMOVE
@ WM_GIZMOMAPTYPE_KEYMAP_INIT
@ WM_GIZMOMAPTYPE_UPDATE_INIT
@ WM_GIZMOGROUP_INIT_REFRESH
@ WM_GIZMOGROUP_INIT_SETUP
eWM_GizmoFlag
@ WM_GIZMO_DRAW_NO_SCALE
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_MOVE_CURSOR
@ WM_GIZMO_SELECT_BACKGROUND
@ WM_GIZMO_HIDDEN_SELECT
@ WM_GIZMOGROUPTYPE_DEPTH_3D
@ WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMOGROUPTYPE_SELECT
@ WM_GIZMO_STATE_HIGHLIGHT
@ WM_GIZMO_STATE_MODAL
#define WM_GIZMOMAP_DRAWSTEP_MAX
@ WM_CURSOR_WRAP_XY
Definition: WM_types.h:188
unsigned int U
Definition: btGjkEpa3.h:78
const Depsgraph * depsgraph
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void area(int d1, int d2, int e1, int e2, float weights[2])
#define hash
Definition: noise.c:169
void * regiondata
struct ARegion * next
ListBase handlers
struct wmGizmoMap * gizmo_map
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase screens
Definition: BKE_main.h:161
ListBase areabase
wmEventHandler head
struct wmGizmoMap * gizmo_map
struct ScrArea * area
struct ARegion * region
struct wmEventHandler_Op::@1171 context
enum eWM_EventHandlerType type
int mval[2]
Definition: WM_types.h:583
wmTabletData tablet
Definition: WM_types.h:623
int x
Definition: WM_types.h:581
wmGizmoGroupFnInvokePrepare invoke_prepare
eWM_GizmoFlagGroupTypeFlag flag
eWM_GizmoFlagMapTypeUpdateFlag type_update_flag
union wmGizmoGroup::@1150 hide
struct wmGizmoGroupType * type
struct wmGizmo ** items
eWM_GizmoFlagMapTypeUpdateFlag type_update_flag
ListBase grouptype_refs
char update_flag[WM_GIZMOMAP_DRAWSTEP_MAX]
struct wmGizmoMapType * type
struct wmGizmoMap::@1146 gzmap_context
Gizmo map runtime context.
bool tag_remove_group
ListBase groups
struct wmGizmo * modal
short event_grabcursor
struct wmGizmo * highlight
struct wmGizmoMapSelectState select
struct wmOperatorType * type
wmGizmoFnDraw draw
wmGizmoFnModal modal
wmGizmoFnTestSelect test_select
wmGizmoFnExit exit
wmGizmoFnCursorGet cursor_get
wmGizmoFnInvoke invoke
wmGizmoFnDrawSelect draw_select
void * interaction_data
eWM_GizmoFlagState state
struct wmGizmoGroup * parent_gzgroup
int highlight_part
float matrix_basis[4][4]
float select_bias
struct wmGizmo * next
float scale_final
eWM_GizmoFlag flag
wmGizmoFnModal custom_modal
const struct wmGizmoType * type
struct wmOperatorType * type
char is_motion_absolute
Definition: WM_types.h:547
#define G(x, y, z)
uint len
uint len_alloc
void WM_cursor_set(wmWindow *win, int curs)
Definition: wm_cursors.c:142
void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
Definition: wm_cursors.c:246
void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2])
Definition: wm_cursors.c:283
int WM_event_modifier_flag(const wmEvent *event)
void WM_event_add_mousemove(wmWindow *win)
@ WM_HANDLER_TYPE_GIZMO
bool wm_gizmo_select_set_ex(wmGizmoMap *gzmap, wmGizmo *gz, bool select, bool use_array, bool use_callback)
Definition: wm_gizmo.c:397
bool WM_gizmo_context_check_drawstep(const struct bContext *C, eWM_GizmoFlagMapDrawStep step)
Definition: wm_gizmo.c:762
int WM_gizmo_operator_invoke(bContext *C, wmGizmo *gz, wmGizmoOpElem *gzop)
Definition: wm_gizmo.c:258
void wm_gizmo_update(wmGizmo *gz, const bContext *C, const bool refresh_map)
Definition: wm_gizmo.c:521
struct wmGizmoOpElem * WM_gizmo_operator_get(wmGizmo *gz, int part_index)
Definition: wm_gizmo.c:224
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select)
Definition: wm_gizmo.c:438
int wm_gizmo_is_visible(wmGizmo *gz)
Definition: wm_gizmo.c:529
int(* wmGizmoFnModal)(struct bContext *, struct wmGizmo *, const struct wmEvent *, eWM_GizmoFlagTweak)
Definition: wm_gizmo_fn.h:56
void WM_gizmo_group_refresh(const bContext *C, wmGizmoGroup *gzgroup)
void WM_gizmomaptype_group_init_runtime_keymap(const Main *bmain, wmGizmoGroupType *gzgt)
wmGizmoGroup * wm_gizmogroup_new_from_type(wmGizmoMap *gzmap, wmGizmoGroupType *gzgt)
void WM_gizmomaptype_group_init_runtime(const Main *bmain, wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
void wm_gizmogrouptype_setup_keymap(wmGizmoGroupType *gzgt, wmKeyConfig *keyconf)
void WM_gizmogroup_ensure_init(const bContext *C, wmGizmoGroup *gzgroup)
wmKeyMap * wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf)
bool wm_gizmogroup_is_visible_in_drawstep(const wmGizmoGroup *gzgroup, const eWM_GizmoFlagMapDrawStep drawstep)
void WM_gizmomaptype_group_free(wmGizmoGroupTypeRef *gzgt_ref)
void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm, const wmGizmoGroup *gzgroup, const int event_modifier, BLI_Buffer *visible_gizmos)
wmGizmo * wm_gizmogroup_find_intersected_gizmo(wmWindowManager *wm, const wmGizmoGroup *gzgroup, bContext *C, const int event_modifier, const int mval[2], int *r_part)
bool WM_gizmo_group_type_poll(const bContext *C, const wmGizmoGroupType *gzgt)
void WM_gizmomaptype_group_unlink(bContext *C, Main *bmain, wmGizmoMapType *gzmap_type, const wmGizmoGroupType *gzgt)
void wm_gizmogroup_free(bContext *C, wmGizmoGroup *gzgroup)
wmGizmoGroupType * WM_gizmogrouptype_find(const char *idname, bool quiet)
@ WM_GIZMO_IS_VISIBLE_DRAW
@ WM_GIZMO_IS_VISIBLE_UPDATE
wmGizmoMapType * WM_gizmomaptype_find(const struct wmGizmoMapType_Params *gzmap_params)
static wmGizmo * gizmo_find_intersected_3d(bContext *C, const int co[2], wmGizmo **visible_gizmos, const int visible_gizmos_len, int *r_part)
Definition: wm_gizmo_map.c:656
void wm_gizmomap_modal_set(wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event, bool enable)
eWM_GizmoFlagMapDrawStep WM_gizmomap_drawstep_from_gizmo_group(const wmGizmoGroup *gzgroup)
Definition: wm_gizmo_map.c:303
wmGizmoMapType * WM_gizmomaptype_ensure(const struct wmGizmoMapType_Params *gzmap_params)
static void wm_gizmomap_select_array_ensure_len_alloc(wmGizmoMap *gzmap, int len)
Definition: wm_gizmo_map.c:98
bool WM_gizmomap_is_any_selected(const wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:244
wmGizmo * wm_gizmomap_highlight_get(wmGizmoMap *gzmap)
void wm_gizmomaptypes_free(void)
void wm_gizmomaps_handled_modal_update(bContext *C, wmEvent *event, wmEventHandler_Op *handler)
Definition: wm_gizmo_map.c:810
@ GIZMOMAP_IS_PREPARE_DRAW
Definition: wm_gizmo_map.c:87
@ GIZMOMAP_IS_REFRESH_CALLBACK
Definition: wm_gizmo_map.c:88
bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part)
Definition: wm_gizmo_map.c:999
void WM_gizmomap_tag_refresh_drawstep(wmGizmoMap *gzmap, const eWM_GizmoFlagMapDrawStep drawstep)
Definition: wm_gizmo_map.c:315
void WM_reinit_gizmomap_all(Main *bmain)
struct ARegion * WM_gizmomap_tooltip_init(struct bContext *C, struct ARegion *region, int *UNUSED(r_pass), double *UNUSED(pass_delay), bool *r_exit_on_event)
static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, const int visible_gizmos_len, const bContext *C, const int co[2], const int hotspot)
Definition: wm_gizmo_map.c:569
void WM_gizmoconfig_update_tag_group_type_init(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
bool WM_gizmomap_minmax(const wmGizmoMap *gzmap, bool UNUSED(use_hidden), bool use_select, float r_min[3], float r_max[3])
Definition: wm_gizmo_map.c:252
bool WM_gizmomap_tag_delay_refresh_for_tweak_check(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:332
void wm_gizmomap_select_array_remove(wmGizmoMap *gzmap, wmGizmo *gz)
Definition: wm_gizmo_map.c:142
ListBase * wm_gizmomap_groups_get(wmGizmoMap *gzmap)
void WM_gizmomap_tag_refresh(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:323
bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, const int action)
Definition: wm_gizmo_map.c:923
static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBase *draw_gizmos)
Definition: wm_gizmo_map.c:441
static ListBase gizmomaptypes
Definition: wm_gizmo_map.c:64
void WM_gizmoconfig_update_tag_group_type_remove(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
wmGizmoGroup * WM_gizmomap_group_find_ptr(struct wmGizmoMap *gzmap, const struct wmGizmoGroupType *gzgt)
Definition: wm_gizmo_map.c:228
static void wm_gizmomap_free_data(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:190
void wm_gizmomap_remove(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:204
void WM_gizmomap_draw(wmGizmoMap *gzmap, const bContext *C, const eWM_GizmoFlagMapDrawStep drawstep)
Definition: wm_gizmo_map.c:498
void WM_gizmomap_reinit(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:211
static void gizmo_draw_select_3d_loop(const bContext *C, wmGizmo **visible_gizmos, const int visible_gizmos_len, bool *r_use_select_bias)
Definition: wm_gizmo_map.c:513
static bool wm_gizmomap_select_all_intern(bContext *C, wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:889
BLI_INLINE bool gizmo_selectable_poll(const wmGizmo *gz, void *UNUSED(data))
Definition: wm_gizmo_map.c:880
void wm_gizmomap_handler_context_op(bContext *C, wmEventHandler_Op *handler)
Definition: wm_gizmo_map.c:950
static eWM_GizmoFlagGroupTypeGlobalFlag wm_gzmap_type_update_flag
Definition: wm_gizmo_map.c:80
bool WM_gizmomap_cursor_set(const wmGizmoMap *gzmap, wmWindow *win)
Definition: wm_gizmo_map.c:988
static bool gizmo_prepare_drawing(wmGizmoMap *gzmap, wmGizmo *gz, const bContext *C, ListBase *draw_gizmos, const eWM_GizmoFlagMapDrawStep drawstep)
Definition: wm_gizmo_map.c:342
void wm_gizmomap_select_array_clear(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:108
void WM_gizmomap_add_handlers(ARegion *region, wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:792
wmGizmoGroup * WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
Definition: wm_gizmo_map.c:219
void WM_gizmoconfig_update_tag_group_remove(wmGizmoMap *gzmap)
static wmGizmoMap * wm_gizmomap_new_from_type_ex(struct wmGizmoMapType *gzmap_type, wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:163
wmGizmo * wm_gizmomap_highlight_find(wmGizmoMap *gzmap, bContext *C, const wmEvent *event, int *r_part)
Definition: wm_gizmo_map.c:724
void wm_gizmos_keymap(wmKeyConfig *keyconf)
void WM_gizmoconfig_update(struct Main *bmain)
eWM_GizmoFlagGroupTypeGlobalFlag
Definition: wm_gizmo_map.c:70
@ WM_GIZMOTYPE_GLOBAL_UPDATE_REMOVE
Definition: wm_gizmo_map.c:77
@ WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT
Definition: wm_gizmo_map.c:72
@ WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE
Definition: wm_gizmo_map.c:74
const ListBase * WM_gizmomap_group_list(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:239
wmGizmo * wm_gizmomap_modal_get(wmGizmoMap *gzmap)
void wm_gizmomap_select_array_push_back(wmGizmoMap *gzmap, wmGizmo *gz)
Definition: wm_gizmo_map.c:131
void wm_gizmomap_select_array_shrink(wmGizmoMap *gzmap, int len_subtract)
Definition: wm_gizmo_map.c:116
bool wm_gizmomap_deselect_all(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:861
void WM_gizmomap_message_subscribe(const bContext *C, wmGizmoMap *gzmap, ARegion *region, struct wmMsgBus *mbus)
void wm_gizmomap_handler_context_gizmo(bContext *UNUSED(C), wmEventHandler_Gizmo *UNUSED(handler))
Definition: wm_gizmo_map.c:983
static GHash * WM_gizmomap_gizmo_hash_new(const bContext *C, wmGizmoMap *gzmap, bool(*poll)(const wmGizmo *, void *), void *data, const eWM_GizmoFlag flag_exclude)
Definition: wm_gizmo_map.c:280
static void gizmomap_prepare_drawing(wmGizmoMap *gzmap, const bContext *C, ListBase *draw_gizmos, const eWM_GizmoFlagMapDrawStep drawstep)
Definition: wm_gizmo_map.c:371
wmGizmo ** wm_gizmomap_selected_get(wmGizmoMap *gzmap, int *r_selected_len)
wmGizmoMap * WM_gizmomap_new_from_type(const struct wmGizmoMapType_Params *gzmap_params)
Definition: wm_gizmo_map.c:182
void WM_gizmo_target_property_subscribe_all(wmGizmo *gz, struct wmMsgBus *mbus, ARegion *region)
void WM_tooltip_clear(bContext *C, wmWindow *win)
Definition: wm_tooltip.c:94
void WM_cursor_warp(wmWindow *win, int x, int y)
Definition: wm_window.c:2091