Blender  V3.3
editmesh_polybuild.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
10 #include "MEM_guardedalloc.h"
11 
12 #include "DNA_object_types.h"
13 
14 #include "BLI_math.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_editmesh.h"
18 #include "BKE_layer.h"
19 #include "BKE_mesh.h"
20 #include "BKE_report.h"
21 
22 #include "WM_types.h"
23 
24 #include "ED_mesh.h"
25 #include "ED_object.h"
26 #include "ED_scene.h"
27 #include "ED_screen.h"
28 #include "ED_transform.h"
29 #include "ED_view3d.h"
30 
31 #include "bmesh.h"
32 
33 #include "mesh_intern.h" /* own include */
34 
35 #include "RNA_access.h"
36 #include "RNA_define.h"
37 
38 #include "WM_api.h"
39 
40 #include "DEG_depsgraph.h"
41 
42 /* -------------------------------------------------------------------- */
46 static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmode)
47 {
48  if ((scene->toolsettings->selectmode & selectmode) == 0) {
49  scene->toolsettings->selectmode |= selectmode;
52  }
53 }
54 
55 /* Could make public, for now just keep here. */
56 static void edbm_flag_disable_all_multi(ViewLayer *view_layer, View3D *v3d, const char hflag)
57 {
58  uint objects_len = 0;
60  view_layer, v3d, &objects_len);
61  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
62  Object *ob_iter = objects[ob_index];
63  BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
64  BMesh *bm_iter = em_iter->bm;
65  if (bm_iter->totvertsel) {
66  EDBM_flag_disable_all(em_iter, hflag);
68  }
69  }
70  MEM_freeN(objects);
71 }
72 
73 /* When accessed as a tool, get the active edge from the preselection gizmo. */
74 static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_base, BMElem **r_ele)
75 {
76  ARegion *region = CTX_wm_region(C);
77  const bool show_gizmo = !((v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)));
78 
79  wmGizmoMap *gzmap = show_gizmo ? region->gizmo_map : NULL;
80  wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, "VIEW3D_GGT_mesh_preselect_elem") :
81  NULL;
82  if (gzgroup != NULL) {
83  wmGizmo *gz = gzgroup->gizmos.first;
84  ED_view3d_gizmo_mesh_preselect_get_active(C, gz, r_base, r_ele);
85  }
86  else {
87  ViewLayer *view_layer = CTX_data_view_layer(C);
88  Base *base = view_layer->basact;
89  Object *obedit = base->object;
91  BMesh *bm = em->bm;
92  *r_base = base;
93  *r_ele = BM_mesh_active_elem_get(bm);
94  }
95  return (*r_ele != NULL);
96 }
97 
99  ViewContext *vc,
100  Base **r_base,
101  BMElem **r_ele)
102 {
103  em_setup_viewcontext(C, vc);
104  bool ok = edbm_preselect_or_active(C, vc->v3d, r_base, r_ele);
105  if (ok) {
106  ED_view3d_viewcontext_init_object(vc, (*r_base)->object);
107  }
108  return ok;
109 }
110 
112  wmOperator *UNUSED(op),
113  const wmEvent *UNUSED(event))
114 {
115  ViewContext vc;
116  Base *basact = NULL;
117  BMElem *ele_act = NULL;
118  edbm_preselect_or_active_init_viewcontext(C, &vc, &basact, &ele_act);
119  BMEditMesh *em = vc.em;
120  BMesh *bm = em->bm;
121 
122  invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
124 
125  if (!ele_act) {
126  return OPERATOR_CANCELLED;
127  }
128 
130 
132 
133  if (ele_act->head.htype == BM_VERT) {
134  BM_vert_select_set(bm, (BMVert *)ele_act, true);
135  }
136  if (ele_act->head.htype == BM_EDGE) {
137  BM_edge_select_set(bm, (BMEdge *)ele_act, true);
138  }
139  if (ele_act->head.htype == BM_FACE) {
140  BM_face_select_set(bm, (BMFace *)ele_act, true);
141  }
142 
143  EDBM_update(vc.obedit->data,
144  &(const struct EDBMUpdate_Params){
145  .calc_looptri = true,
146  .calc_normals = true,
147  .is_destructive = true,
148  });
149  if (basact != NULL) {
150  if (vc.view_layer->basact != basact) {
151  ED_object_base_activate(C, basact);
152  }
153  }
154  BM_select_history_store(bm, ele_act);
156  return OPERATOR_FINISHED;
157 }
158 
160 {
161  /* identifiers */
162  ot->name = "Poly Build Transform at Cursor";
163  ot->idname = "MESH_OT_polybuild_transform_at_cursor";
164 
165  /* api callbacks */
168 
169  /* flags */
171 
172  /* to give to transform */
174 }
175 
177  wmOperator *op,
178  const wmEvent *UNUSED(event))
179 {
180  bool changed = false;
181 
182  ViewContext vc;
183  Base *basact = NULL;
184  BMElem *ele_act = NULL;
185  edbm_preselect_or_active_init_viewcontext(C, &vc, &basact, &ele_act);
186  BMEditMesh *em = vc.em;
187  BMesh *bm = em->bm;
188 
189  invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
191 
192  if (!ele_act) {
193  return OPERATOR_CANCELLED;
194  }
195 
197 
198  if (ele_act->head.htype == BM_FACE) {
199  BMFace *f_act = (BMFace *)ele_act;
202  if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_TAG, DEL_FACES)) {
203  return OPERATOR_CANCELLED;
204  }
205  changed = true;
206  }
207  if (ele_act->head.htype == BM_VERT) {
208  BMVert *v_act = (BMVert *)ele_act;
209  if (BM_vert_is_edge_pair(v_act) && !BM_vert_is_wire(v_act)) {
210  BM_edge_collapse(bm, v_act->e, v_act, true, true);
211  changed = true;
212  }
213  else {
216 
217  if (!EDBM_op_callf(em,
218  op,
219  "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
220  BM_ELEM_TAG,
221  false,
222  false)) {
223  return OPERATOR_CANCELLED;
224  }
225  changed = true;
226  }
227  }
228 
229  if (changed) {
230  EDBM_update(vc.obedit->data,
231  &(const struct EDBMUpdate_Params){
232  .calc_looptri = true,
233  .calc_normals = true,
234  .is_destructive = true,
235  });
236  if (basact != NULL) {
237  if (vc.view_layer->basact != basact) {
238  ED_object_base_activate(C, basact);
239  }
240  }
242  return OPERATOR_FINISHED;
243  }
244  return OPERATOR_CANCELLED;
245 }
246 
248 {
249  /* identifiers */
250  ot->name = "Poly Build Delete at Cursor";
251  ot->idname = "MESH_OT_polybuild_delete_at_cursor";
252 
253  /* api callbacks */
256 
257  /* flags */
259 
260  /* to give to transform */
262 }
263 
266 /* -------------------------------------------------------------------- */
271 {
272  float center[3];
273  bool changed = false;
274 
275  ViewContext vc;
276  Base *basact = NULL;
277  BMElem *ele_act = NULL;
278  edbm_preselect_or_active_init_viewcontext(C, &vc, &basact, &ele_act);
279  BMEditMesh *em = vc.em;
280  BMesh *bm = em->bm;
281 
282  invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
284 
286 
287  if (ele_act == NULL || ele_act->head.htype == BM_FACE) {
288  /* Just add vert */
292  mul_m4_v3(vc.obedit->imat, center);
293 
296  BM_vert_select_set(bm, v_new, true);
297  BM_select_history_store(bm, v_new);
298  changed = true;
299  }
300  else if (ele_act->head.htype == BM_EDGE) {
301  BMEdge *e_act = (BMEdge *)ele_act;
302  BMFace *f_reference = e_act->l ? e_act->l->f : NULL;
303 
304  mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
307  mul_m4_v3(vc.obedit->imat, center);
308  if (f_reference->len == 3 && RNA_boolean_get(op->ptr, "create_quads")) {
309  const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
310  BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, NULL, CLAMPIS(fac, 0.0f, 1.0f));
311  copy_v3_v3(v_new->co, center);
313  BM_vert_select_set(bm, v_new, true);
314  BM_select_history_store(bm, v_new);
315  }
316  else {
317  BMVert *v_tri[3];
318  v_tri[0] = e_act->v1;
319  v_tri[1] = e_act->v2;
320  v_tri[2] = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
321  if (e_act->l && e_act->l->v == v_tri[0]) {
322  SWAP(BMVert *, v_tri[0], v_tri[1]);
323  }
324  BM_face_create_verts(bm, v_tri, 3, f_reference, BM_CREATE_NOP, true);
326  BM_vert_select_set(bm, v_tri[2], true);
327  BM_select_history_store(bm, v_tri[2]);
328  }
329  changed = true;
330  }
331  else if (ele_act->head.htype == BM_VERT) {
332  BMVert *v_act = (BMVert *)ele_act;
333  BMEdge *e_pair[2] = {NULL};
334 
335  if (v_act->e != NULL) {
336  for (uint allow_wire = 0; allow_wire < 2 && (e_pair[1] == NULL); allow_wire++) {
337  int i = 0;
338  BMEdge *e_iter = v_act->e;
339  do {
340  if ((BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) &&
341  (allow_wire ? BM_edge_is_wire(e_iter) : BM_edge_is_boundary(e_iter))) {
342  if (i == 2) {
343  e_pair[0] = e_pair[1] = NULL;
344  break;
345  }
346  e_pair[i++] = e_iter;
347  }
348  } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_act)) != v_act->e);
349  }
350  }
351 
352  if (e_pair[1] != NULL) {
353  /* Quad from edge pair. */
354  if (BM_edge_calc_length_squared(e_pair[0]) < BM_edge_calc_length_squared(e_pair[1])) {
355  SWAP(BMEdge *, e_pair[0], e_pair[1]);
356  }
357 
358  BMFace *f_reference = e_pair[0]->l ? e_pair[0]->l->f : NULL;
359 
360  mul_v3_m4v3(center, vc.obedit->obmat, v_act->co);
362  mul_m4_v3(vc.obedit->imat, center);
363 
364  BMVert *v_quad[4];
365  v_quad[0] = v_act;
366  v_quad[1] = BM_edge_other_vert(e_pair[0], v_act);
367  v_quad[2] = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
368  v_quad[3] = BM_edge_other_vert(e_pair[1], v_act);
369  if (e_pair[0]->l && e_pair[0]->l->v == v_quad[0]) {
370  SWAP(BMVert *, v_quad[1], v_quad[3]);
371  }
372  // BMFace *f_new =
373  BM_face_create_verts(bm, v_quad, 4, f_reference, BM_CREATE_NOP, true);
374 
376  BM_vert_select_set(bm, v_quad[2], true);
377  BM_select_history_store(bm, v_quad[2]);
378  changed = true;
379  }
380  else {
381  /* Just add edge */
383  ED_view3d_win_to_3d_int(vc.v3d, vc.region, v_act->co, event->mval, center);
384  mul_m4_v3(vc.obedit->imat, center);
385 
387 
388  BM_edge_create(bm, v_act, v_new, NULL, BM_CREATE_NOP);
389 
390  BM_vert_select_set(bm, v_new, true);
391  BM_select_history_store(bm, v_new);
392  changed = true;
393  }
394  }
395 
396  if (changed) {
397  EDBM_update(vc.obedit->data,
398  &(const struct EDBMUpdate_Params){
399  .calc_looptri = true,
400  .calc_normals = true,
401  .is_destructive = true,
402  });
403 
404  if (basact != NULL) {
405  if (vc.view_layer->basact != basact) {
406  ED_object_base_activate(C, basact);
407  }
408  }
409 
411 
412  return OPERATOR_FINISHED;
413  }
414  return OPERATOR_CANCELLED;
415 }
416 
418 {
419  /* identifiers */
420  ot->name = "Poly Build Face at Cursor";
421  ot->idname = "MESH_OT_polybuild_face_at_cursor";
422 
423  /* api callbacks */
426 
427  /* flags */
429 
431  "create_quads",
432  true,
433  "Create Quads",
434  "Automatically split edges in triangles to maintain quad topology");
435  /* to give to transform */
437 }
438 
441 /* -------------------------------------------------------------------- */
446  wmOperator *UNUSED(op),
447  const wmEvent *event)
448 {
449  float center[3];
450  bool changed = false;
451 
452  ViewContext vc;
453  Base *basact = NULL;
454  BMElem *ele_act = NULL;
455  edbm_preselect_or_active_init_viewcontext(C, &vc, &basact, &ele_act);
456  BMEditMesh *em = vc.em;
457  BMesh *bm = em->bm;
458 
459  invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
461 
463 
464  if (ele_act == NULL || ele_act->head.hflag == BM_FACE) {
465  return OPERATOR_PASS_THROUGH;
466  }
467  if (ele_act->head.htype == BM_EDGE) {
468  BMEdge *e_act = (BMEdge *)ele_act;
469  mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
472  mul_m4_v3(vc.obedit->imat, center);
473 
474  const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
475  BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, NULL, CLAMPIS(fac, 0.0f, 1.0f));
476  copy_v3_v3(v_new->co, center);
477 
479  BM_vert_select_set(bm, v_new, true);
480  BM_select_history_store(bm, v_new);
481  changed = true;
482  }
483  else if (ele_act->head.htype == BM_VERT) {
484  /* Just do nothing, allow dragging. */
485  return OPERATOR_FINISHED;
486  }
487 
488  if (changed) {
489  EDBM_update(vc.obedit->data,
490  &(const struct EDBMUpdate_Params){
491  .calc_looptri = true,
492  .calc_normals = true,
493  .is_destructive = true,
494  });
495 
497 
498  if (vc.view_layer->basact != basact) {
499  ED_object_base_activate(C, basact);
500  }
501 
502  return OPERATOR_FINISHED;
503  }
504  return OPERATOR_CANCELLED;
505 }
506 
508 {
509  /* identifiers */
510  ot->name = "Poly Build Split at Cursor";
511  ot->idname = "MESH_OT_polybuild_split_at_cursor";
512 
513  /* api callbacks */
516 
517  /* flags */
519 
520  /* to give to transform */
522 }
523 
526 /* -------------------------------------------------------------------- */
531  wmOperator *op,
532  const wmEvent *UNUSED(event))
533 {
534  bool changed = false;
535 
536  ViewContext vc;
537  Base *basact = NULL;
538  BMElem *ele_act = NULL;
539  edbm_preselect_or_active_init_viewcontext(C, &vc, &basact, &ele_act);
540  BMEditMesh *em = vc.em;
541  BMesh *bm = em->bm;
542 
543  if (ele_act == NULL) {
544  /* pass */
545  }
546  else if (ele_act->head.htype == BM_EDGE) {
547  BMEdge *e_act = (BMEdge *)ele_act;
548  BMLoop *l_a, *l_b;
549  if (BM_edge_loop_pair(e_act, &l_a, &l_b)) {
550  BMFace *f_new = BM_faces_join_pair(bm, l_a, l_b, true);
551  if (f_new) {
552  changed = true;
553  }
554  }
555  }
556  else if (ele_act->head.htype == BM_VERT) {
557  BMVert *v_act = (BMVert *)ele_act;
558  if (BM_vert_is_edge_pair(v_act)) {
559  BM_edge_collapse(bm, v_act->e, v_act, true, true);
560  }
561  else {
562  /* too involved to do inline */
563 
564  /* Avoid using selection so failure won't leave modified state. */
567 
568  if (!EDBM_op_callf(em,
569  op,
570  "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
571  BM_ELEM_TAG,
572  false,
573  false)) {
574  return OPERATOR_CANCELLED;
575  }
576  }
577  changed = true;
578  }
579 
580  if (changed) {
582 
583  EDBM_update(vc.obedit->data,
584  &(const struct EDBMUpdate_Params){
585  .calc_looptri = true,
586  .calc_normals = true,
587  .is_destructive = true,
588  });
589 
590  if (vc.view_layer->basact != basact) {
591  ED_object_base_activate(C, basact);
592  }
593 
595 
596  return OPERATOR_FINISHED;
597  }
598  return OPERATOR_CANCELLED;
599 }
600 
602 {
603  /* identifiers */
604  ot->name = "Poly Build Dissolve at Cursor";
605  ot->idname = "MESH_OT_polybuild_dissolve_at_cursor";
606 
607  /* api callbacks */
610 
611  /* flags */
613 }
614 
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
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_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:542
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:3254
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
unsigned int uint
Definition: BLI_sys_types.h:67
#define CLAMPIS(a, b, c)
#define SWAP(type, a, b)
#define UNUSED(x)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
Object is a sort of wrapper for general info.
#define SCE_SELECT_VERTEX
@ V3D_GIZMO_HIDE_TOOL
@ V3D_GIZMO_HIDE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params)
void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc)
void EDBM_selectmode_set(struct BMEditMesh *em)
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag)
void ED_object_base_activate(struct bContext *C, struct Base *base)
#define P_PROPORTIONAL
Definition: ED_transform.h:110
void Transform_Properties(struct wmOperatorType *ot, int flags)
#define P_MIRROR_DUMMY
Definition: ED_transform.h:109
void ED_view3d_win_to_3d_int(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact)
void ED_view3d_gizmo_mesh_preselect_get_active(struct bContext *C, struct wmGizmo *gz, struct Base **r_base, struct BMElem **r_ele)
void ED_view3d_init_mats_rv3d(const struct Object *ob, struct RegionView3D *rv3d)
Definition: space_view3d.c:166
NSNotificationCenter * center
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define BM_DISK_EDGE_NEXT(e, v)
Definition: bmesh_class.h:625
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
Definition: bmesh_core.c:41
BMFace * BM_face_create_verts(BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
Definition: bmesh_core.c:464
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
Definition: bmesh_core.c:123
@ BM_CREATE_NOP
Definition: bmesh_core.h:12
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:14
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
Select Face.
void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
Select Vert.
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
Select Edge.
BMElem * BM_mesh_active_elem_get(BMesh *bm)
#define BM_select_history_store(bm, ele)
BMFace * BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_del)
Faces Join Pair.
Definition: bmesh_mods.c:166
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
Definition: bmesh_mods.c:448
BMVert * BM_edge_collapse(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
Definition: bmesh_mods.c:442
@ DEL_FACES
bool BM_vert_is_wire(const BMVert *v)
Definition: bmesh_query.c:688
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
Definition: bmesh_query.c:553
float BM_edge_calc_length_squared(const BMEdge *e)
Definition: bmesh_query.c:533
bool BM_vert_is_edge_pair(const BMVert *v)
Definition: bmesh_query.c:568
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
Scene scene
static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_base, BMElem **r_ele)
static void edbm_flag_disable_all_multi(ViewLayer *view_layer, View3D *v3d, const char hflag)
void MESH_OT_polybuild_transform_at_cursor(wmOperatorType *ot)
static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int edbm_polybuild_delete_at_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int edbm_polybuild_transform_at_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
void MESH_OT_polybuild_face_at_cursor(wmOperatorType *ot)
static int edbm_polybuild_split_at_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmode)
static bool edbm_preselect_or_active_init_viewcontext(bContext *C, ViewContext *vc, Base **r_base, BMElem **r_ele)
void MESH_OT_polybuild_delete_at_cursor(wmOperatorType *ot)
void MESH_OT_polybuild_dissolve_at_cursor(wmOperatorType *ot)
void MESH_OT_polybuild_split_at_cursor(wmOperatorType *ot)
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt,...)
bool EDBM_view3d_poll(bContext *C)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
struct wmGizmoMap * gizmo_map
BMVert * v1
Definition: bmesh_class.h:122
BMVert * v2
Definition: bmesh_class.h:122
struct BMLoop * l
Definition: bmesh_class.h:128
short selectmode
Definition: BKE_editmesh.h:52
struct BMesh * bm
Definition: BKE_editmesh.h:40
BMHeader head
Definition: bmesh_class.h:243
int len
Definition: bmesh_class.h:267
char htype
Definition: bmesh_class.h:64
char hflag
Definition: bmesh_class.h:66
struct BMVert * v
Definition: bmesh_class.h:153
struct BMFace * f
Definition: bmesh_class.h:171
float co[3]
Definition: bmesh_class.h:87
struct BMEdge * e
Definition: bmesh_class.h:97
int totvertsel
Definition: bmesh_class.h:298
struct Object * object
void * first
Definition: DNA_listBase.h:31
float imat[4][4]
float obmat[4][4]
void * data
struct ToolSettings * toolsettings
View3DCursor cursor
char gizmo_flag
struct Scene * scene
Definition: ED_view3d.h:65
struct ARegion * region
Definition: ED_view3d.h:69
struct ViewLayer * view_layer
Definition: ED_view3d.h:66
struct BMEditMesh * em
Definition: ED_view3d.h:73
struct Object * obedit
Definition: ED_view3d.h:68
struct wmWindow * win
Definition: ED_view3d.h:71
struct View3D * v3d
Definition: ED_view3d.h:70
struct RegionView3D * rv3d
Definition: ED_view3d.h:72
struct Base * basact
int mval[2]
Definition: WM_types.h:684
ListBase gizmos
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
struct PointerRNA * ptr
void WM_event_add_mousemove(wmWindow *win)
wmOperatorType * ot
Definition: wm_files.c:3479
wmGizmoGroup * WM_gizmomap_group_find(struct wmGizmoMap *gzmap, const char *idname)
Definition: wm_gizmo_map.c:202