Blender  V3.3
view3d_gizmo_preselect_type.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
13 #include "MEM_guardedalloc.h"
14 
15 #include "BLI_math.h"
16 
17 #include "DNA_mesh_types.h"
18 #include "DNA_view3d_types.h"
19 
20 #include "BKE_context.h"
21 #include "BKE_editmesh.h"
22 #include "BKE_global.h"
23 #include "BKE_layer.h"
24 
25 #include "DEG_depsgraph.h"
26 #include "DEG_depsgraph_query.h"
27 
28 #include "RNA_access.h"
29 #include "RNA_define.h"
30 
31 #include "WM_api.h"
32 #include "WM_types.h"
33 
34 #include "bmesh.h"
35 
36 #include "ED_gizmo_library.h"
37 #include "ED_mesh.h"
38 #include "ED_screen.h"
39 #include "ED_view3d.h"
40 
41 /* -------------------------------------------------------------------- */
61 {
62  if (G.moving == false) {
64  if (!(rv3d && (rv3d->rflag & RV3D_NAVIGATING))) {
65  return true;
66  }
67  }
69  return false;
70 }
71 
74 /* -------------------------------------------------------------------- */
78 typedef struct MeshElemGizmo3D {
88 
89 static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz)
90 {
91  if (!gizmo_preselect_poll_for_draw(C, gz)) {
92  return;
93  }
94 
95  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
96  if (gz_ele->base_index != -1) {
97  Object *ob = gz_ele->bases[gz_ele->base_index]->object;
98  EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
99  }
100 }
101 
102 static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2])
103 {
104  wmEvent *event = CTX_wm_window(C)->eventstate;
105  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
106 
107  /* Hack: Switch action mode based on key input */
108  const bool is_ctrl_pressed = (event->modifier & KM_CTRL) != 0;
109  const bool is_shift_pressed = (event->modifier & KM_SHIFT) != 0;
111  if (is_ctrl_pressed && !is_shift_pressed) {
113  }
114  if (!is_ctrl_pressed && is_shift_pressed) {
116  }
117 
118  struct {
119  Object *ob;
120  BMElem *ele;
121  float dist;
122  int base_index;
123  } best = {
124  .dist = ED_view3d_select_dist_px(),
125  };
126 
127  {
128  ViewLayer *view_layer = CTX_data_view_layer(C);
129  View3D *v3d = CTX_wm_view3d(C);
130  if (((gz_ele->bases)) == NULL || (gz_ele->bases[0] != view_layer->basact)) {
131  MEM_SAFE_FREE(gz_ele->bases);
133  view_layer, v3d, &gz_ele->bases_len);
134  }
135  }
136 
137  ViewContext vc;
138  em_setup_viewcontext(C, &vc);
139  copy_v2_v2_int(vc.mval, mval);
140 
141  {
142  /* TODO: support faces. */
143  int base_index_vert = -1;
144  int base_index_edge = -1;
145  int base_index_face = -1;
146  BMVert *eve_test;
147  BMEdge *eed_test;
148  BMFace *efa_test;
149 
151  gz_ele->bases,
152  gz_ele->bases_len,
153  false,
154  true,
155  &base_index_vert,
156  &base_index_edge,
157  &base_index_face,
158  &eve_test,
159  &eed_test,
160  &efa_test)) {
162  /* Delete action */
163  if (efa_test) {
164  best.ele = (BMElem *)efa_test;
165  best.base_index = base_index_face;
166  }
167  }
168 
169  else {
170  /* Transform and create action */
171  if (eed_test) {
172  best.ele = (BMElem *)eed_test;
173  best.base_index = base_index_edge;
174  }
175  }
176 
177  /* All actions use same vertex pre-selection. */
178  /* Re-topology should always prioritize edge pre-selection.
179  * Only pre-select a vertex when the cursor is really close to it. */
180  if (eve_test) {
181  BMVert *vert = (BMVert *)eve_test;
182  float vert_p_co[2], vert_co[3];
183  const float mval_f[2] = {UNPACK2(vc.mval)};
184  mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co);
185  ED_view3d_project_v2(vc.region, vert_co, vert_p_co);
186  float len = len_v2v2(vert_p_co, mval_f);
187  if (len < 35) {
188  best.ele = (BMElem *)eve_test;
189  best.base_index = base_index_vert;
190  }
191  if (!BM_vert_is_boundary(vert) &&
193  best.ele = (BMElem *)eve_test;
194  best.base_index = base_index_vert;
195  }
196  }
197 
198  /* Check above should never fail, if it does it's an internal error. */
199  BLI_assert(best.base_index != -1);
200 
201  Base *base = gz_ele->bases[best.base_index];
202  best.ob = base->object;
203  }
204  }
205 
206  BMesh *bm = NULL;
207 
208  gz_ele->base_index = -1;
209  gz_ele->vert_index = -1;
210  gz_ele->edge_index = -1;
211  gz_ele->face_index = -1;
212 
213  if (best.ele) {
214  gz_ele->base_index = best.base_index;
215  bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm;
216  BM_mesh_elem_index_ensure(bm, best.ele->head.htype);
217 
218  if (best.ele->head.htype == BM_VERT) {
219  gz_ele->vert_index = BM_elem_index_get(best.ele);
220  }
221  else if (best.ele->head.htype == BM_EDGE) {
222  gz_ele->edge_index = BM_elem_index_get(best.ele);
223  }
224  else if (best.ele->head.htype == BM_FACE) {
225  gz_ele->face_index = BM_elem_index_get(best.ele);
226  }
227  }
228 
229  if (best.ele) {
230  const float(*coords)[3] = NULL;
231  {
232  Object *ob = gz_ele->bases[gz_ele->base_index]->object;
234  Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
235  if (me_eval->runtime.edit_data) {
236  coords = me_eval->runtime.edit_data->vertexCos;
237  }
238  }
239  EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
240  EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval);
241  }
242  else {
245  }
246 
247  RNA_int_set(gz->ptr, "object_index", gz_ele->base_index);
248  RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
249  RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
250  RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
251 
252  if (best.ele) {
253  ARegion *region = CTX_wm_region(C);
255  }
256 
257  // return best.eed ? 0 : -1;
258  return -1;
259 }
260 
262 {
263  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
264  if (gz_ele->psel == NULL) {
265  gz_ele->psel = EDBM_preselect_elem_create();
266  }
267  gz_ele->base_index = -1;
268 }
269 
271 {
272  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
274  gz_ele->psel = NULL;
275  MEM_SAFE_FREE(gz_ele->bases);
276 }
277 
279  wmGizmo *UNUSED(gz),
280  const wmEvent *UNUSED(event))
281 {
282  return OPERATOR_PASS_THROUGH;
283 }
284 
286 {
287  /* identifiers */
288  gzt->idname = "GIZMO_GT_mesh_preselect_elem_3d";
289 
290  /* api callbacks */
296 
297  gzt->struct_size = sizeof(MeshElemGizmo3D);
298 
299  RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
300  RNA_def_int(gzt->srna, "vert_index", -1, -1, INT_MAX, "Vert Index", "", -1, INT_MAX);
301  RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
302  RNA_def_int(gzt->srna, "face_index", -1, -1, INT_MAX, "Face Index", "", -1, INT_MAX);
303 }
304 
307 /* -------------------------------------------------------------------- */
311 typedef struct MeshEdgeRingGizmo3D {
319 
321 {
322  if (!gizmo_preselect_poll_for_draw(C, gz)) {
323  return;
324  }
325 
326  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
327  if (gz_ring->base_index != -1) {
328  Object *ob = gz_ring->bases[gz_ring->base_index]->object;
329  EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat);
330  }
331 }
332 
333 static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2])
334 {
335  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
336  struct {
337  Object *ob;
338  BMEdge *eed;
339  float dist;
340  int base_index;
341  } best = {
342  .dist = ED_view3d_select_dist_px(),
343  };
344 
345  struct {
346  int base_index;
347  int edge_index;
348  } prev = {
349  .base_index = gz_ring->base_index,
350  .edge_index = gz_ring->edge_index,
351  };
352 
353  {
354  ViewLayer *view_layer = CTX_data_view_layer(C);
355  View3D *v3d = CTX_wm_view3d(C);
356  if (((gz_ring->bases)) == NULL || (gz_ring->bases[0] != view_layer->basact)) {
357  MEM_SAFE_FREE(gz_ring->bases);
359  view_layer, v3d, &gz_ring->bases_len);
360  }
361  }
362 
363  ViewContext vc;
364  em_setup_viewcontext(C, &vc);
365  copy_v2_v2_int(vc.mval, mval);
366 
367  uint base_index;
368  BMEdge *eed_test = EDBM_edge_find_nearest_ex(
369  &vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index);
370 
371  if (eed_test) {
372  best.ob = gz_ring->bases[base_index]->object;
373  best.eed = eed_test;
374  best.base_index = base_index;
375  }
376 
377  BMesh *bm = NULL;
378  if (best.eed) {
379  gz_ring->base_index = best.base_index;
380  bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm;
382  gz_ring->edge_index = BM_elem_index_get(best.eed);
383  }
384  else {
385  gz_ring->base_index = -1;
386  gz_ring->edge_index = -1;
387  }
388 
389  if ((prev.base_index == gz_ring->base_index) && (prev.edge_index == gz_ring->edge_index)) {
390  /* pass (only recalculate on change) */
391  }
392  else {
393  if (best.eed) {
394  Object *ob = gz_ring->bases[gz_ring->base_index]->object;
395  Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc.depsgraph, &vc.scene->id);
396  Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob);
397  BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
398  /* Re-allocate coords each update isn't ideal, however we can't be sure
399  * the mesh hasn't been edited since last update. */
400  bool is_alloc = false;
401  const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed(
402  vc.depsgraph, em_eval, scene_eval, ob_eval, NULL, &is_alloc);
403  EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
404  if (is_alloc) {
405  MEM_freeN((void *)coords);
406  }
407  }
408  else {
410  }
411 
412  RNA_int_set(gz->ptr, "object_index", gz_ring->base_index);
413  RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index);
414 
415  ARegion *region = CTX_wm_region(C);
417  }
418 
419  // return best.eed ? 0 : -1;
420  return -1;
421 }
422 
424 {
425  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
426  if (gz_ring->psel == NULL) {
428  }
429  gz_ring->base_index = -1;
430 }
431 
433 {
434  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
436  gz_ring->psel = NULL;
437  MEM_SAFE_FREE(gz_ring->bases);
438 }
439 
441  wmGizmo *UNUSED(gz),
442  const wmEvent *UNUSED(event))
443 {
444  return OPERATOR_PASS_THROUGH;
445 }
446 
448 {
449  /* identifiers */
450  gzt->idname = "GIZMO_GT_mesh_preselect_edgering_3d";
451 
452  /* api callbacks */
458 
459  gzt->struct_size = sizeof(MeshEdgeRingGizmo3D);
460 
461  RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
462  RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
463 }
464 
467 /* -------------------------------------------------------------------- */
472 {
475 }
476 
479 /* -------------------------------------------------------------------- */
487  wmGizmo *gz,
488  Base **r_base,
489  BMElem **r_ele)
490 {
491  ViewLayer *view_layer = CTX_data_view_layer(C);
492 
493  const int object_index = RNA_int_get(gz->ptr, "object_index");
494 
495  /* weak, allocate an array just to access the index. */
496  Base *base = NULL;
497  Object *obedit = NULL;
498  {
499  uint bases_len;
501  view_layer, CTX_wm_view3d(C), &bases_len);
502  if (object_index < bases_len) {
503  base = bases[object_index];
504  obedit = base->object;
505  }
506  MEM_freeN(bases);
507  }
508 
509  *r_base = base;
510  *r_ele = NULL;
511 
512  if (obedit) {
513  BMEditMesh *em = BKE_editmesh_from_object(obedit);
514  BMesh *bm = em->bm;
515  PropertyRNA *prop;
516 
517  /* Ring select only defines edge, check properties exist first. */
518  prop = RNA_struct_find_property(gz->ptr, "vert_index");
519  const int vert_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
520  prop = RNA_struct_find_property(gz->ptr, "edge_index");
521  const int edge_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
522  prop = RNA_struct_find_property(gz->ptr, "face_index");
523  const int face_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
524 
525  if (vert_index != -1) {
526  *r_ele = (BMElem *)BM_vert_at_index_find(bm, vert_index);
527  }
528  else if (edge_index != -1) {
529  *r_ele = (BMElem *)BM_edge_at_index_find(bm, edge_index);
530  }
531  else if (face_index != -1) {
532  *r_ele = (BMElem *)BM_face_at_index_find(bm, face_index);
533  }
534  }
535 }
536 
538 {
539  if (STREQ(gz->type->idname, "GIZMO_GT_mesh_preselect_elem_3d")) {
540  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
541  gz_ele->base_index = -1;
542  gz_ele->vert_index = -1;
543  gz_ele->edge_index = -1;
544  gz_ele->face_index = -1;
545  }
546  else if (STREQ(gz->type->idname, "GIZMO_GT_mesh_preselect_edgering_3d")) {
548  gz_ele->base_index = -1;
549  gz_ele->edge_index = -1;
550  }
551  else {
553  }
554 
555  const char *prop_ids[] = {"object_index", "vert_index", "edge_index", "face_index"};
556  for (int i = 0; i < ARRAY_SIZE(prop_ids); i++) {
557  PropertyRNA *prop = RNA_struct_find_property(gz->ptr, prop_ids[i]);
558  if (prop == NULL) {
559  continue;
560  }
561  RNA_property_int_set(gz->ptr, prop, -1);
562  }
563 }
564 
typedef float(TangentPoint)[2]
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 RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
const float(* BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph, struct BMEditMesh *em, struct Scene *scene, struct Object *obedit, int *r_vert_len, bool *r_is_alloc))[3]
Definition: editmesh.c:241
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
#define BKE_view_layer_array_from_bases_in_edit_mode(view_layer, v3d, r_len)
Definition: BKE_layer.h:539
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNPACK2(a)
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
#define RV3D_NAVIGATING
@ OPERATOR_PASS_THROUGH
void EDBM_preselect_elem_update_preview(struct EditMesh_PreSelElem *psel, struct ViewContext *vc, struct BMesh *bm, struct BMElem *ele, const int mval[2])
void EDBM_preselect_elem_destroy(struct EditMesh_PreSelElem *psel)
bool EDBM_unified_findnearest_from_raycast(struct ViewContext *vc, struct Base **bases, uint bases_len, bool use_boundary_vertices, bool use_boundary_edges, int *r_base_index_vert, int *r_base_index_edge, int *r_base_index_face, struct BMVert **r_eve, struct BMEdge **r_eed, struct BMFace **r_efa)
void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matrix[4][4])
void EDBM_preselect_edgering_destroy(struct EditMesh_PreSelEdgeRing *psel)
@ PRESELECT_ACTION_CREATE
Definition: ED_mesh.h:354
@ PRESELECT_ACTION_DELETE
Definition: ED_mesh.h:355
@ PRESELECT_ACTION_TRANSFORM
Definition: ED_mesh.h:353
void EDBM_preselect_edgering_clear(struct EditMesh_PreSelEdgeRing *psel)
void EDBM_preselect_action_set(struct EditMesh_PreSelElem *psel, eEditMesh_PreSelPreviewAction action)
eEditMesh_PreSelPreviewAction EDBM_preselect_action_get(struct EditMesh_PreSelElem *psel)
void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc)
struct BMEdge * EDBM_edge_find_nearest_ex(struct ViewContext *vc, float *dist_px_manhattan, float *r_dist_center, bool use_select_bias, bool use_cycle, struct BMEdge **r_eed_zbuf, struct Base **bases, uint bases_len, uint *r_base_index)
void EDBM_preselect_elem_clear(struct EditMesh_PreSelElem *psel)
struct EditMesh_PreSelEdgeRing * EDBM_preselect_edgering_create(void)
void EDBM_preselect_elem_update_from_single(struct EditMesh_PreSelElem *psel, struct BMesh *bm, struct BMElem *ele, const float(*coords)[3])
void EDBM_preselect_preview_clear(struct EditMesh_PreSelElem *psel)
void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const float matrix[4][4])
struct EditMesh_PreSelElem * EDBM_preselect_elem_create(void)
void EDBM_preselect_edgering_update_from_edge(struct EditMesh_PreSelEdgeRing *psel, struct BMesh *bm, struct BMEdge *eed_start, int previewlines, const float(*coords)[3])
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:690
void ED_view3d_project_v2(const struct ARegion *region, const float world[3], float r_region_co[2])
float ED_view3d_select_dist_px(void)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
@ KM_CTRL
Definition: WM_types.h:239
@ KM_SHIFT
Definition: WM_types.h:238
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMFace * BM_face_at_index_find(BMesh *bm, const int index)
Definition: bmesh_mesh.cc:658
BMEdge * BM_edge_at_index_find(BMesh *bm, const int index)
Definition: bmesh_mesh.cc:653
BMVert * BM_vert_at_index_find(BMesh *bm, const int index)
Definition: bmesh_mesh.cc:648
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:446
bool BM_vert_is_boundary(const BMVert *v)
Definition: bmesh_query.c:916
const Depsgraph * depsgraph
int len
Definition: draw_manager.c:108
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
#define G(x, y, z)
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2449
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:4921
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
struct BMesh * bm
Definition: BKE_editmesh.h:40
float co[3]
Definition: bmesh_class.h:87
struct Object * object
const float(* vertexCos)[3]
struct EditMesh_PreSelEdgeRing * psel
struct EditMesh_PreSelElem * psel
struct EditMeshData * edit_data
Mesh_Runtime runtime
float obmat[4][4]
void * data
struct Depsgraph * depsgraph
Definition: ED_view3d.h:64
int mval[2]
Definition: ED_view3d.h:74
struct Scene * scene
Definition: ED_view3d.h:65
struct ARegion * region
Definition: ED_view3d.h:69
struct Base * basact
wmGizmoFnDraw draw
wmGizmoFnSetup setup
const char * idname
wmGizmoFnTestSelect test_select
struct StructRNA * srna
wmGizmoFnInvoke invoke
wmGizmoFnFree free
struct PointerRNA * ptr
const struct wmGizmoType * type
struct wmEvent * eventstate
static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz)
void ED_view3d_gizmo_mesh_preselect_clear(wmGizmo *gz)
static int gizmo_preselect_elem_invoke(bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
static void GIZMO_GT_mesh_preselect_elem_3d(wmGizmoType *gzt)
static bool gizmo_preselect_poll_for_draw(const bContext *C, wmGizmo *gz)
static void gizmo_preselect_elem_setup(wmGizmo *gz)
static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz)
static void gizmo_preselect_edgering_setup(wmGizmo *gz)
void ED_gizmotypes_preselect_3d(void)
static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2])
struct MeshElemGizmo3D MeshElemGizmo3D
static void gizmo_preselect_elem_free(wmGizmo *gz)
struct MeshEdgeRingGizmo3D MeshEdgeRingGizmo3D
void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C, wmGizmo *gz, Base **r_base, BMElem **r_ele)
static void GIZMO_GT_mesh_preselect_edgering_3d(wmGizmoType *gzt)
static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2])
static int gizmo_preselect_edgering_invoke(bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
static void gizmo_preselect_edgering_free(wmGizmo *gz)
void WM_gizmotype_append(void(*gtfunc)(struct wmGizmoType *))
Definition: wm_gizmo_type.c:93