Blender V4.3
editmesh_polybuild.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <algorithm>
13
14#include "MEM_guardedalloc.h"
15
16#include "DNA_object_types.h"
17
18#include "BKE_context.hh"
19#include "BKE_editmesh.hh"
20#include "BKE_layer.hh"
21#include "BKE_object_types.hh"
22
23#include "BLI_math_geom.h"
24#include "BLI_math_matrix.h"
25#include "BLI_math_vector.h"
26
27#include "WM_types.hh"
28
29#include "ED_mesh.hh"
30#include "ED_object.hh"
31#include "ED_transform.hh"
32#include "ED_view3d.hh"
33
34#include "bmesh.hh"
35
36#include "mesh_intern.hh" /* own include */
37
38#include "RNA_access.hh"
39#include "RNA_define.hh"
40
41#include "WM_api.hh"
42
43#include "DEG_depsgraph.hh"
44
45using blender::Vector;
46
47/* -------------------------------------------------------------------- */
51static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmode)
52{
53 if ((scene->toolsettings->selectmode & selectmode) == 0) {
54 scene->toolsettings->selectmode |= selectmode;
55 em->selectmode = scene->toolsettings->selectmode;
57 }
58}
59
60/* Could make public, for now just keep here. */
61static void edbm_flag_disable_all_multi(const Scene *scene,
62 ViewLayer *view_layer,
63 View3D *v3d,
64 const char hflag)
65{
67 scene, view_layer, v3d);
68 for (Object *ob_iter : objects) {
69 BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
70 BMesh *bm_iter = em_iter->bm;
71 if (bm_iter->totvertsel) {
72 EDBM_flag_disable_all(em_iter, hflag);
73 DEG_id_tag_update(static_cast<ID *>(ob_iter->data), ID_RECALC_SELECT);
74 }
75 }
76}
77
79static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_base, BMElem **r_ele)
80{
81 ARegion *region = CTX_wm_region(C);
82 const bool show_gizmo = !(v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL));
83
84 wmGizmoMap *gzmap = show_gizmo ? region->gizmo_map : nullptr;
85 wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, "VIEW3D_GGT_mesh_preselect_elem") :
86 nullptr;
87 if (gzgroup != nullptr) {
88 wmGizmo *gz = static_cast<wmGizmo *>(gzgroup->gizmos.first);
90 }
91 else {
92 const Scene *scene = CTX_data_scene(C);
93 ViewLayer *view_layer = CTX_data_view_layer(C);
94 BKE_view_layer_synced_ensure(scene, view_layer);
95 Base *base = BKE_view_layer_active_base_get(view_layer);
96 Object *obedit = base->object;
98 BMesh *bm = em->bm;
99 *r_base = base;
100 *r_ele = BM_mesh_active_elem_get(bm);
101 }
102 return (*r_ele != nullptr);
103}
104
106 Base **r_base,
107 BMElem **r_ele)
108{
110 bool ok = edbm_preselect_or_active(C, vc.v3d, r_base, r_ele);
111 if (ok) {
112 ED_view3d_viewcontext_init_object(&vc, (*r_base)->object);
113 }
114 return vc;
115}
116
118 wmOperator * /*op*/,
119 const wmEvent * /*event*/)
120{
121 Base *basact = nullptr;
122 BMElem *ele_act = nullptr;
124 BMEditMesh *em = vc.em;
125 BMesh *bm = em->bm;
126
127 invert_m4_m4(vc.obedit->runtime->world_to_object.ptr(), vc.obedit->object_to_world().ptr());
129
130 if (!ele_act) {
131 return OPERATOR_CANCELLED;
132 }
133
135
137
138 if (ele_act->head.htype == BM_VERT) {
139 BM_vert_select_set(bm, (BMVert *)ele_act, true);
140 }
141 if (ele_act->head.htype == BM_EDGE) {
142 BM_edge_select_set(bm, (BMEdge *)ele_act, true);
143 }
144 if (ele_act->head.htype == BM_FACE) {
145 BM_face_select_set(bm, (BMFace *)ele_act, true);
146 }
147
149 params.calc_looptris = true;
150 params.calc_normals = true;
151 params.is_destructive = true;
152 EDBM_update(static_cast<Mesh *>(vc.obedit->data), &params);
153 if (basact != nullptr) {
155 if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
157 }
158 }
159 BM_select_history_store(bm, ele_act);
161 return OPERATOR_FINISHED;
162}
163
165{
166 /* identifiers */
167 ot->name = "Poly Build Transform at Cursor";
168 ot->idname = "MESH_OT_polybuild_transform_at_cursor";
169
170 /* api callbacks */
173
174 /* flags */
176
177 /* to give to transform */
179}
180
182 wmOperator *op,
183 const wmEvent * /*event*/)
184{
185 bool changed = false;
186 Base *basact = nullptr;
187 BMElem *ele_act = nullptr;
189 BMEditMesh *em = vc.em;
190 BMesh *bm = em->bm;
191
192 invert_m4_m4(vc.obedit->runtime->world_to_object.ptr(), vc.obedit->object_to_world().ptr());
194
195 if (!ele_act) {
196 return OPERATOR_CANCELLED;
197 }
198
200
201 if (ele_act->head.htype == BM_FACE) {
202 BMFace *f_act = (BMFace *)ele_act;
205 if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_TAG, DEL_FACES)) {
206 return OPERATOR_CANCELLED;
207 }
208 changed = true;
209 }
210 if (ele_act->head.htype == BM_VERT) {
211 BMVert *v_act = (BMVert *)ele_act;
212 if (BM_vert_is_edge_pair(v_act) && !BM_vert_is_wire(v_act)) {
213 BM_edge_collapse(bm, v_act->e, v_act, true, true);
214 changed = true;
215 }
216 else {
219
220 if (!EDBM_op_callf(em,
221 op,
222 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
224 false,
225 false))
226 {
227 return OPERATOR_CANCELLED;
228 }
229 changed = true;
230 }
231 }
232
233 if (changed) {
235 params.calc_looptris = true;
236 params.calc_normals = true;
237 params.is_destructive = true;
238 EDBM_update(static_cast<Mesh *>(vc.obedit->data), &params);
239 if (basact != nullptr) {
241 if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
243 }
244 }
246 return OPERATOR_FINISHED;
247 }
248 return OPERATOR_CANCELLED;
249}
250
252{
253 /* identifiers */
254 ot->name = "Poly Build Delete at Cursor";
255 ot->idname = "MESH_OT_polybuild_delete_at_cursor";
256
257 /* api callbacks */
260
261 /* flags */
263
264 /* to give to transform */
266}
267
270/* -------------------------------------------------------------------- */
275{
276 float center[3];
277 bool changed = false;
278
279 Base *basact = nullptr;
280 BMElem *ele_act = nullptr;
282 BMEditMesh *em = vc.em;
283 BMesh *bm = em->bm;
284
285 invert_m4_m4(vc.obedit->runtime->world_to_object.ptr(), vc.obedit->object_to_world().ptr());
287
289
290 if (ele_act == nullptr || ele_act->head.htype == BM_FACE) {
291 /* Just add vert */
292 copy_v3_v3(center, vc.scene->cursor.location);
293 mul_v3_m4v3(center, vc.obedit->object_to_world().ptr(), center);
294 ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
295 mul_m4_v3(vc.obedit->world_to_object().ptr(), center);
296
297 BMVert *v_new = BM_vert_create(bm, center, nullptr, BM_CREATE_NOP);
299 BM_vert_select_set(bm, v_new, true);
301 changed = true;
302 }
303 else if (ele_act->head.htype == BM_EDGE) {
304 BMEdge *e_act = (BMEdge *)ele_act;
305 BMFace *f_reference = e_act->l ? e_act->l->f : nullptr;
306
307 mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
308 mul_m4_v3(vc.obedit->object_to_world().ptr(), center);
309 ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
310 mul_m4_v3(vc.obedit->world_to_object().ptr(), center);
311 if (f_reference->len == 3 && RNA_boolean_get(op->ptr, "create_quads")) {
312 const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
313 BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, std::clamp(fac, 0.0f, 1.0f));
314 copy_v3_v3(v_new->co, center);
316 BM_vert_select_set(bm, v_new, true);
318 }
319 else {
320 BMVert *v_tri[3];
321 v_tri[0] = e_act->v1;
322 v_tri[1] = e_act->v2;
323 v_tri[2] = BM_vert_create(bm, center, nullptr, BM_CREATE_NOP);
324 if (e_act->l && e_act->l->v == v_tri[0]) {
325 std::swap(v_tri[0], v_tri[1]);
326 }
327 BM_face_create_verts(bm, v_tri, 3, f_reference, BM_CREATE_NOP, true);
329 BM_vert_select_set(bm, v_tri[2], true);
330 BM_select_history_store(bm, v_tri[2]);
331 }
332 changed = true;
333 }
334 else if (ele_act->head.htype == BM_VERT) {
335 BMVert *v_act = (BMVert *)ele_act;
336 BMEdge *e_pair[2] = {nullptr};
337
338 if (v_act->e != nullptr) {
339 for (uint allow_wire = 0; allow_wire < 2 && (e_pair[1] == nullptr); allow_wire++) {
340 int i = 0;
341 BMEdge *e_iter = v_act->e;
342 do {
343 if ((BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) &&
344 (allow_wire ? BM_edge_is_wire(e_iter) : BM_edge_is_boundary(e_iter)))
345 {
346 if (i == 2) {
347 e_pair[0] = e_pair[1] = nullptr;
348 break;
349 }
350 e_pair[i++] = e_iter;
351 }
352 } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_act)) != v_act->e);
353 }
354 }
355
356 if (e_pair[1] != nullptr) {
357 /* Quad from edge pair. */
358 if (BM_edge_calc_length_squared(e_pair[0]) < BM_edge_calc_length_squared(e_pair[1])) {
359 std::swap(e_pair[0], e_pair[1]);
360 }
361
362 BMFace *f_reference = e_pair[0]->l ? e_pair[0]->l->f : nullptr;
363
364 mul_v3_m4v3(center, vc.obedit->object_to_world().ptr(), v_act->co);
365 ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
366 mul_m4_v3(vc.obedit->world_to_object().ptr(), center);
367
368 BMVert *v_quad[4];
369 v_quad[0] = v_act;
370 v_quad[1] = BM_edge_other_vert(e_pair[0], v_act);
371 v_quad[2] = BM_vert_create(bm, center, nullptr, BM_CREATE_NOP);
372 v_quad[3] = BM_edge_other_vert(e_pair[1], v_act);
373 if (e_pair[0]->l && e_pair[0]->l->v == v_quad[0]) {
374 std::swap(v_quad[1], v_quad[3]);
375 }
376 // BMFace *f_new =
377 BM_face_create_verts(bm, v_quad, 4, f_reference, BM_CREATE_NOP, true);
378
380 BM_vert_select_set(bm, v_quad[2], true);
381 BM_select_history_store(bm, v_quad[2]);
382 changed = true;
383 }
384 else {
385 /* Just add edge */
386 mul_m4_v3(vc.obedit->object_to_world().ptr(), center);
387 ED_view3d_win_to_3d_int(vc.v3d, vc.region, v_act->co, event->mval, center);
388 mul_m4_v3(vc.obedit->world_to_object().ptr(), center);
389
390 BMVert *v_new = BM_vert_create(bm, center, nullptr, BM_CREATE_NOP);
391
392 BM_edge_create(bm, v_act, v_new, nullptr, BM_CREATE_NOP);
393
394 BM_vert_select_set(bm, v_new, true);
396 changed = true;
397 }
398 }
399
400 if (changed) {
402 params.calc_looptris = true;
403 params.calc_normals = true;
404 params.is_destructive = true;
405 EDBM_update(static_cast<Mesh *>(vc.obedit->data), &params);
406
407 if (basact != nullptr) {
409 if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
411 }
412 }
413
415
416 return OPERATOR_FINISHED;
417 }
418 return OPERATOR_CANCELLED;
419}
420
422{
423 /* identifiers */
424 ot->name = "Poly Build Face at Cursor";
425 ot->idname = "MESH_OT_polybuild_face_at_cursor";
426
427 /* api callbacks */
430
431 /* flags */
433
435 "create_quads",
436 true,
437 "Create Quads",
438 "Automatically split edges in triangles to maintain quad topology");
439 /* to give to transform */
441}
442
445/* -------------------------------------------------------------------- */
450 wmOperator * /*op*/,
451 const wmEvent *event)
452{
453 float center[3];
454 bool changed = false;
455
456 Base *basact = nullptr;
457 BMElem *ele_act = nullptr;
459 BMEditMesh *em = vc.em;
460 BMesh *bm = em->bm;
461
462 invert_m4_m4(vc.obedit->runtime->world_to_object.ptr(), vc.obedit->object_to_world().ptr());
464
466
467 if (ele_act == nullptr || ele_act->head.hflag == BM_FACE) {
469 }
470 if (ele_act->head.htype == BM_EDGE) {
471 BMEdge *e_act = (BMEdge *)ele_act;
472 mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
473 mul_m4_v3(vc.obedit->object_to_world().ptr(), center);
474 ED_view3d_win_to_3d_int(vc.v3d, vc.region, center, event->mval, center);
475 mul_m4_v3(vc.obedit->world_to_object().ptr(), center);
476
477 const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
478 BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, std::clamp(fac, 0.0f, 1.0f));
479 copy_v3_v3(v_new->co, center);
480
482 BM_vert_select_set(bm, v_new, true);
484 changed = true;
485 }
486 else if (ele_act->head.htype == BM_VERT) {
487 /* Just do nothing, allow dragging. */
488 return OPERATOR_FINISHED;
489 }
490
491 if (changed) {
493 params.calc_looptris = true;
494 params.calc_normals = true;
495 params.is_destructive = true;
496 EDBM_update(static_cast<Mesh *>(vc.obedit->data), &params);
497
499
501 if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
503 }
504
505 return OPERATOR_FINISHED;
506 }
507 return OPERATOR_CANCELLED;
508}
509
511{
512 /* identifiers */
513 ot->name = "Poly Build Split at Cursor";
514 ot->idname = "MESH_OT_polybuild_split_at_cursor";
515
516 /* api callbacks */
519
520 /* flags */
522
523 /* to give to transform */
525}
526
529/* -------------------------------------------------------------------- */
534 wmOperator *op,
535 const wmEvent * /*event*/)
536{
537 bool changed = false;
538
539 Base *basact = nullptr;
540 BMElem *ele_act = nullptr;
542 BMEditMesh *em = vc.em;
543 BMesh *bm = em->bm;
544
545 if (ele_act == nullptr) {
546 /* pass */
547 }
548 else if (ele_act->head.htype == BM_EDGE) {
549 BMEdge *e_act = (BMEdge *)ele_act;
550 BMLoop *l_a, *l_b;
551 if (BM_edge_loop_pair(e_act, &l_a, &l_b)) {
552 BMFace *f_new = BM_faces_join_pair(bm, l_a, l_b, true);
553 if (f_new) {
554 changed = true;
555 }
556 }
557 }
558 else if (ele_act->head.htype == BM_VERT) {
559 BMVert *v_act = (BMVert *)ele_act;
560 if (BM_vert_is_edge_pair(v_act)) {
561 BM_edge_collapse(bm, v_act->e, v_act, true, true);
562 }
563 else {
564 /* too involved to do inline */
565
566 /* Avoid using selection so failure won't leave modified state. */
569
570 if (!EDBM_op_callf(em,
571 op,
572 "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
574 false,
575 false))
576 {
577 return OPERATOR_CANCELLED;
578 }
579 }
580 changed = true;
581 }
582
583 if (changed) {
585
587 EDBM_update(static_cast<Mesh *>(vc.obedit->data), &params);
588
590 if (BKE_view_layer_active_base_get(vc.view_layer) != 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
Scene * CTX_data_scene(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:63
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
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])
unsigned int uint
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
Object is a sort of wrapper for general info.
@ SCE_SELECT_VERTEX
@ V3D_GIZMO_HIDE_TOOL
@ V3D_GIZMO_HIDE
@ OPERATOR_PASS_THROUGH
void EDBM_flag_disable_all(BMEditMesh *em, char hflag)
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
void EDBM_selectmode_set(BMEditMesh *em)
ViewContext em_setup_viewcontext(bContext *C)
#define P_PROPORTIONAL
void Transform_Properties(wmOperatorType *ot, int flags)
#define P_MIRROR_DUMMY
void ED_view3d_gizmo_mesh_preselect_get_active(const bContext *C, const wmGizmo *gz, Base **r_base, BMElem **r_ele)
void ED_view3d_win_to_3d_int(const View3D *v3d, const ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
Read Guarded memory(de)allocation.
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define BM_DISK_EDGE_NEXT(e, v)
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
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)
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.cc:43
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.
@ BM_CREATE_NOP
Definition bmesh_core.hh:24
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
Select Face.
BMElem * BM_mesh_active_elem_get(BMesh *bm)
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.
#define BM_select_history_store(bm, ele)
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
BMFace * BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_del)
Faces Join Pair.
BMVert * BM_edge_collapse(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
bool BM_vert_is_wire(const BMVert *v)
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
float BM_edge_calc_length_squared(const BMEdge *e)
bool BM_vert_is_edge_pair(const BMVert *v)
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
static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_base, BMElem **r_ele)
void MESH_OT_polybuild_transform_at_cursor(wmOperatorType *ot)
static void edbm_flag_disable_all_multi(const Scene *scene, ViewLayer *view_layer, View3D *v3d, const char hflag)
static int edbm_polybuild_split_at_cursor_invoke(bContext *C, wmOperator *, const wmEvent *event)
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 *)
static ViewContext edbm_preselect_or_active_init_viewcontext(bContext *C, Base **r_base, BMElem **r_ele)
void MESH_OT_polybuild_face_at_cursor(wmOperatorType *ot)
static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmode)
static int edbm_polybuild_transform_at_cursor_invoke(bContext *C, wmOperator *, const wmEvent *)
static int edbm_polybuild_delete_at_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *)
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)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void base_activate(bContext *C, Base *base)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
BMVert * v1
BMVert * v2
struct BMLoop * l
short selectmode
BMHeader head
struct BMVert * v
struct BMFace * f
float co[3]
struct BMEdge * e
int totvertsel
struct Object * object
Definition DNA_ID.h:413
void * first
ObjectRuntimeHandle * runtime
View3DCursor cursor
RegionView3D * rv3d
Definition ED_view3d.hh:76
ARegion * region
Definition ED_view3d.hh:73
Scene * scene
Definition ED_view3d.hh:69
BMEditMesh * em
Definition ED_view3d.hh:77
wmWindow * win
Definition ED_view3d.hh:75
ViewLayer * view_layer
Definition ED_view3d.hh:70
View3D * v3d
Definition ED_view3d.hh:74
Object * obedit
Definition ED_view3d.hh:72
int mval[2]
Definition WM_types.hh:728
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
StructRNA * srna
Definition WM_types.hh:1080
struct PointerRNA * ptr
void WM_event_add_mousemove(wmWindow *win)
wmOperatorType * ot
Definition wm_files.cc:4125
wmGizmoGroup * WM_gizmomap_group_find(wmGizmoMap *gzmap, const char *idname)