Blender V4.3
editmesh_bisect.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "DNA_object_types.h"
12
13#include "BLT_translation.hh"
14
15#include "BKE_context.hh"
16#include "BKE_editmesh.hh"
17#include "BKE_global.hh"
18#include "BKE_layer.hh"
19#include "BKE_report.hh"
20#include "BKE_workspace.hh"
21
22#include "BLI_math_geom.h"
23#include "BLI_math_matrix.h"
24#include "BLI_math_rotation.h"
25#include "BLI_math_vector.h"
26
27#include "RNA_access.hh"
28#include "RNA_define.hh"
29
30#include "WM_api.hh"
31#include "WM_types.hh"
32
33#include "ED_gizmo_utils.hh"
34#include "ED_mesh.hh"
35#include "ED_screen.hh"
36#include "ED_view3d.hh"
37
38#include "UI_resources.hh"
39
40#include "mesh_intern.hh" /* own include */
41
42#define USE_GIZMO
43
44#ifdef USE_GIZMO
45# include "ED_gizmo_library.hh"
46# include "ED_undo.hh"
47#endif
48
49using blender::Vector;
50
51static int mesh_bisect_exec(bContext *C, wmOperator *op);
52
53/* -------------------------------------------------------------------- */
54/* Model Helpers */
55
56struct BisectData {
57 /* modal only */
58
59 /* Aligned with objects array. */
66};
67
69 wmOperator *op,
70 float plane_co[3],
71 float plane_no[3])
72{
73 View3D *v3d = CTX_wm_view3d(C);
74 ARegion *region = CTX_wm_region(C);
75 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
76
77 int x_start = RNA_int_get(op->ptr, "xstart");
78 int y_start = RNA_int_get(op->ptr, "ystart");
79 int x_end = RNA_int_get(op->ptr, "xend");
80 int y_end = RNA_int_get(op->ptr, "yend");
81 const bool use_flip = RNA_boolean_get(op->ptr, "flip");
82
83 /* reference location (some point in front of the view) for finding a point on a plane */
84 const float *co_ref = rv3d->ofs;
85 float co_a_ss[2] = {float(x_start), float(y_start)};
86 float co_b_ss[2] = {float(x_end), float(y_end)};
87 float co_delta_ss[2];
88 float co_a[3], co_b[3];
89 const float zfac = ED_view3d_calc_zfac(rv3d, co_ref);
90
91 /* view vector */
92 ED_view3d_win_to_vector(region, co_a_ss, co_a);
93
94 /* view delta */
95 sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
96 ED_view3d_win_to_delta(region, co_delta_ss, zfac, co_b);
97
98 /* cross both to get a normal */
99 cross_v3_v3v3(plane_no, co_a, co_b);
100 normalize_v3(plane_no); /* not needed but nicer for user */
101 if (use_flip) {
102 negate_v3(plane_no);
103 }
104
105 /* point on plane, can use either start or endpoint */
106 ED_view3d_win_to_3d(v3d, region, co_ref, co_a_ss, plane_co);
107}
108
109static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
110{
111 const Scene *scene = CTX_data_scene(C);
112 ViewLayer *view_layer = CTX_data_view_layer(C);
113 int valid_objects = 0;
114
115 /* If the properties are set or there is no rv3d,
116 * skip modal and exec immediately. */
117 if ((CTX_wm_region_view3d(C) == nullptr) || (RNA_struct_property_is_set(op->ptr, "plane_co") &&
118 RNA_struct_property_is_set(op->ptr, "plane_no")))
119 {
120 return mesh_bisect_exec(C, op);
121 }
122
124 scene, view_layer, CTX_wm_view3d(C));
125 for (Object *obedit : objects) {
127
128 if (em->bm->totedgesel != 0) {
129 valid_objects++;
130 }
131 }
132
133 if (valid_objects == 0) {
134 BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required");
135 return OPERATOR_CANCELLED;
136 }
137
138 /* Support flipping if side matters. */
139 int ret;
140 const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
141 const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
142 const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
143 if ((clear_inner != clear_outer) || use_fill) {
145 }
146 else {
147 ret = WM_gesture_straightline_invoke(C, op, event);
148 }
149
151 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
152 BisectData *opdata;
153
154 opdata = static_cast<BisectData *>(MEM_mallocN(sizeof(BisectData), "inset_operator_data"));
155 gesture->user_data.data = opdata;
156
157 opdata->backup_len = objects.size();
158 opdata->backup = static_cast<BisectData::BisectDataBackup *>(
159 MEM_callocN(sizeof(*opdata->backup) * objects.size(), __func__));
160
161 /* Store the mesh backups. */
162 for (const int ob_index : objects.index_range()) {
163 Object *obedit = objects[ob_index];
165
166 if (em->bm->totedgesel != 0) {
167 opdata->backup[ob_index].is_valid = true;
168 opdata->backup[ob_index].mesh_backup = EDBM_redo_state_store(em);
169 }
170 }
171
172 /* Misc other vars. */
173 G.moving = G_TRANSFORM_EDIT;
174
175 /* Initialize modal callout. */
176 ED_workspace_status_text(C, IFACE_("LMB: Click and drag to draw cut line"));
177 }
178 return ret;
179}
180
181static void edbm_bisect_exit(BisectData *opdata)
182{
183 G.moving = 0;
184
185 for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
186 if (opdata->backup[ob_index].is_valid) {
187 EDBM_redo_state_free(&opdata->backup[ob_index].mesh_backup);
188 }
189 }
190 MEM_freeN(opdata->backup);
191}
192
193static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
194{
195 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
196 BisectData *opdata = static_cast<BisectData *>(gesture->user_data.data);
197 BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */
198 int ret;
199
200 ret = WM_gesture_straightline_modal(C, op, event);
201
202 /* update or clear modal callout */
203 WorkSpace *workspace = CTX_wm_workspace(C);
204
205 if (workspace) {
207 }
208
210 edbm_bisect_exit(&opdata_back);
211
212#ifdef USE_GIZMO
213 /* Setup gizmos */
214 {
215 View3D *v3d = CTX_wm_view3d(C);
216 if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
217 WM_gizmo_group_type_ensure("MESH_GGT_bisect");
218 }
219 }
220#endif
221 }
222
223 return ret;
224}
225
226/* End Model Helpers */
227/* -------------------------------------------------------------------- */
228
230{
231 Scene *scene = CTX_data_scene(C);
232
233 /* both can be nullptr, fallbacks values are used */
235
237
238 float plane_co[3];
239 float plane_no[3];
240 float imat[4][4];
241
242 const float thresh = RNA_float_get(op->ptr, "threshold");
243 const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
244 const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
245 const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
246
247 PropertyRNA *prop_plane_co;
248 PropertyRNA *prop_plane_no;
249
250 prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
251 if (RNA_property_is_set(op->ptr, prop_plane_co)) {
252 RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
253 }
254 else {
255 copy_v3_v3(plane_co, scene->cursor.location);
256 RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
257 }
258
259 prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
260 if (RNA_property_is_set(op->ptr, prop_plane_no)) {
261 RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
262 }
263 else {
264 if (rv3d) {
265 copy_v3_v3(plane_no, rv3d->viewinv[1]);
266 }
267 else {
268 /* fallback... */
269 plane_no[0] = plane_no[1] = 0.0f;
270 plane_no[2] = 1.0f;
271 }
272 RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
273 }
274
275 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
276 BisectData *opdata = static_cast<BisectData *>((gesture != nullptr) ? gesture->user_data.data :
277 nullptr);
278
279 /* -------------------------------------------------------------------- */
280 /* Modal support */
281 /* NOTE: keep this isolated, exec can work without this. */
282 if (opdata != nullptr) {
283 mesh_bisect_interactive_calc(C, op, plane_co, plane_no);
284 /* Write back to the props. */
285 RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
286 RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
287 }
288 /* End Modal */
289 /* -------------------------------------------------------------------- */
290
293
294 for (const int ob_index : objects.index_range()) {
295 Object *obedit = objects[ob_index];
297 BMesh *bm = em->bm;
298
299 if (opdata != nullptr) {
300 if (opdata->backup[ob_index].is_dirty) {
301 EDBM_redo_state_restore(&opdata->backup[ob_index].mesh_backup, em, false);
302 opdata->backup[ob_index].is_dirty = false;
303 }
304 }
305
306 if (bm->totedgesel == 0) {
307 continue;
308 }
309
310 if (opdata != nullptr) {
311 if (opdata->backup[ob_index].is_valid) {
312 opdata->backup[ob_index].is_dirty = true;
313 }
314 }
315
316 float plane_co_local[3];
317 float plane_no_local[3];
318 copy_v3_v3(plane_co_local, plane_co);
319 copy_v3_v3(plane_no_local, plane_no);
320
321 invert_m4_m4(imat, obedit->object_to_world().ptr());
322 mul_m4_v3(imat, plane_co_local);
323 mul_transposed_mat3_m4_v3(obedit->object_to_world().ptr(), plane_no_local);
324
325 BMOperator bmop;
327 em,
328 &bmop,
329 op,
330 "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
332 plane_co_local,
333 plane_no_local,
334 thresh,
335 clear_inner,
336 clear_outer);
337 BMO_op_exec(bm, &bmop);
338
340
341 if (use_fill) {
342 float normal_fill[3];
343 BMOperator bmop_fill;
344 BMOperator bmop_attr;
345
346 /* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
347 * The normal is passed so triangle fill won't have to calculate it. */
348 normalize_v3_v3(normal_fill, plane_no_local);
349
350 /* Fill */
352 &bmop_fill,
353 0,
354 "triangle_fill edges=%S normal=%v use_dissolve=%b",
355 &bmop,
356 "geom_cut.out",
357 normal_fill,
358 true);
359 BMO_op_exec(bm, &bmop_fill);
360
361 /* Copy Attributes */
363 &bmop_attr,
364 0,
365 "face_attribute_fill faces=%S use_normals=%b use_data=%b",
366 &bmop_fill,
367 "geom.out",
368 true,
369 true);
370 BMO_op_exec(bm, &bmop_attr);
371
373 bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
374
375 BMO_op_finish(bm, &bmop_attr);
376 BMO_op_finish(bm, &bmop_fill);
377 }
378
380 bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
381
382 if (EDBM_op_finish(em, &bmop, op, true)) {
384 params.calc_looptris = true;
385 params.calc_normals = false;
386 params.is_destructive = true;
387 EDBM_update(static_cast<Mesh *>(obedit->data), &params);
390 }
391 }
392 return ret;
393}
394
395#ifdef USE_GIZMO
396static void MESH_GGT_bisect(wmGizmoGroupType *gzgt);
397#endif
398
400{
401 PropertyRNA *prop;
402
403 /* identifiers */
404 ot->name = "Bisect";
405 ot->description = "Cut geometry along a plane (click-drag to define plane)";
406 ot->idname = "MESH_OT_bisect";
407
408 /* api callbacks */
414
415 /* flags */
417
419 "plane_co",
420 3,
421 nullptr,
422 -1e12f,
423 1e12f,
424 "Plane Point",
425 "A point on the plane",
426 -1e4f,
427 1e4f);
430 "plane_no",
431 3,
432 nullptr,
433 -1.0f,
434 1.0f,
435 "Plane Normal",
436 "The direction the plane points",
437 -1.0f,
438 1.0f);
440
441 prop = RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill in the cut");
443
445 ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
447 ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
448
449 prop = RNA_def_float(ot->srna,
450 "threshold",
451 0.0001,
452 0.0,
453 10.0,
454 "Axis Threshold",
455 "Preserves the existing geometry along the cut plane",
456 0.00001,
457 0.1);
458 /* Without higher precision, the default value displays as zero. */
459 RNA_def_property_ui_range(prop, 0.0, 10.0, 0.01, 5);
460
462
463#ifdef USE_GIZMO
465#endif
466}
467
468#ifdef USE_GIZMO
469
470/* -------------------------------------------------------------------- */
475 /* Arrow to change plane depth. */
477 /* Translate XYZ */
479 /* For grabbing the gizmo and moving freely. */
481
482 /* We could store more vars here! */
483 struct {
488
489 float rotate_axis[3];
490 float rotate_up[3];
492};
493
500{
501 wmOperator *op = ggd->data.op;
502 if (op == WM_operator_last_redo((bContext *)ggd->data.context)) {
504 }
505}
506
508{
509 wmOperator *op = ggd->data.op;
510
511 float plane_co[3], plane_no[3];
512
515
518 /* translate_c location comes from the property. */
519
521
523
525 if (rv3d) {
526 normalize_v3_v3(ggd->data.rotate_axis, rv3d->viewinv[2]);
527 normalize_v3_v3(ggd->data.rotate_up, rv3d->viewinv[1]);
528
529 /* ensure its orthogonal */
531 ggd->data.rotate_up, ggd->data.rotate_up, ggd->data.rotate_axis);
533
536 }
537}
538
539/* depth callbacks */
540static void gizmo_bisect_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
541{
542 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
543 wmOperator *op = ggd->data.op;
544 float *value = static_cast<float *>(value_p);
545
546 BLI_assert(gz_prop->type->array_length == 1);
547 UNUSED_VARS_NDEBUG(gz_prop);
548
549 float plane_co[3], plane_no[3];
552
553 value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
554}
555
557 wmGizmoProperty *gz_prop,
558 const void *value_p)
559{
560 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
561 wmOperator *op = ggd->data.op;
562 const float *value = static_cast<const float *>(value_p);
563
564 BLI_assert(gz_prop->type->array_length == 1);
565 UNUSED_VARS_NDEBUG(gz_prop);
566
567 float plane_co[3], plane[4];
570 normalize_v3(plane);
571
572 plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
573
574 /* Keep our location, may be offset simply to be inside the viewport. */
575 closest_to_plane_normalized_v3(plane_co, plane, plane_co);
576
578
580}
581
582/* translate callbacks */
584 wmGizmoProperty *gz_prop,
585 void *value_p)
586{
587 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
588 wmOperator *op = ggd->data.op;
589
590 BLI_assert(gz_prop->type->array_length == 3);
591 UNUSED_VARS_NDEBUG(gz_prop);
592
593 RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, static_cast<float *>(value_p));
594}
595
597 wmGizmoProperty *gz_prop,
598 const void *value_p)
599{
600 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
601 wmOperator *op = ggd->data.op;
602
603 BLI_assert(gz_prop->type->array_length == 3);
604 UNUSED_VARS_NDEBUG(gz_prop);
605
607 op->ptr, ggd->data.prop_plane_co, static_cast<const float *>(value_p));
608
610}
611
612/* angle callbacks */
613static void gizmo_bisect_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
614{
615 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
616 wmOperator *op = ggd->data.op;
617 float *value = static_cast<float *>(value_p);
618
619 BLI_assert(gz_prop->type->array_length == 1);
620 UNUSED_VARS_NDEBUG(gz_prop);
621
622 float plane_no[4];
624 normalize_v3(plane_no);
625
626 float plane_no_proj[3];
627 project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
628
629 if (!is_zero_v3(plane_no_proj)) {
630 const float angle = -angle_signed_on_axis_v3v3_v3(
631 plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
632 value[0] = angle;
633 }
634 else {
635 value[0] = 0.0f;
636 }
637}
638
640 wmGizmoProperty *gz_prop,
641 const void *value_p)
642{
643 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
644 wmOperator *op = ggd->data.op;
645 const float *value = static_cast<const float *>(value_p);
646
647 BLI_assert(gz_prop->type->array_length == 1);
648 UNUSED_VARS_NDEBUG(gz_prop);
649
650 float plane_no[4];
652 normalize_v3(plane_no);
653
654 float plane_no_proj[3];
655 project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
656
657 if (!is_zero_v3(plane_no_proj)) {
658 const float angle = -angle_signed_on_axis_v3v3_v3(
659 plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
660 const float angle_delta = angle - angle_compat_rad(value[0], angle);
661 if (angle_delta != 0.0f) {
662 float mat[3][3];
663 axis_angle_normalized_to_mat3(mat, ggd->data.rotate_axis, angle_delta);
664 mul_m3_v3(mat, plane_no);
665
666 /* re-normalize - seems acceptable */
668
670 }
671 }
672}
673
675{
676 return ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_bisect");
677}
678
679static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
680{
682
683 if (op == nullptr || !STREQ(op->type->idname, "MESH_OT_bisect")) {
684 return;
685 }
686
687 GizmoGroup *ggd = static_cast<GizmoGroup *>(MEM_callocN(sizeof(GizmoGroup), __func__));
688 gzgroup->customdata = ggd;
689
690 const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
691 const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
692 const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
693
694 ggd->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
695 ggd->translate_c = WM_gizmo_new_ptr(gzt_move, gzgroup, nullptr);
696 ggd->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, nullptr);
697
701
704
707
708 {
709 ggd->data.context = (bContext *)C;
710 ggd->data.op = op;
711 ggd->data.prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
712 ggd->data.prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
713 }
714
716
717 /* Setup property callbacks */
718 {
719 {
721 params.value_get_fn = gizmo_bisect_prop_depth_get;
722 params.value_set_fn = gizmo_bisect_prop_depth_set;
723 params.range_get_fn = nullptr;
724 params.user_data = nullptr;
726 }
727
728 {
732 params.range_get_fn = nullptr;
733 params.user_data = nullptr;
735 }
736
737 {
739 params.value_get_fn = gizmo_bisect_prop_angle_get;
740 params.value_set_fn = gizmo_bisect_prop_angle_set;
741 params.range_get_fn = nullptr;
742 params.user_data = nullptr;
744 }
745 }
746}
747
748static void gizmo_mesh_bisect_draw_prepare(const bContext * /*C*/, wmGizmoGroup *gzgroup)
749{
750 GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
751 if (ggd->data.op->next) {
753 }
755}
756
758{
759 gzgt->name = "Mesh Bisect";
760 gzgt->idname = "MESH_GGT_bisect";
761
763
766
770}
771
774#endif /* USE_GIZMO */
WorkSpace * CTX_wm_workspace(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(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
@ G_TRANSFORM_EDIT
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
void BKE_workspace_status_clear(WorkSpace *workspace)
Definition workspace.cc:649
#define BLI_assert(a)
Definition BLI_assert.h:50
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition math_geom.cc:440
void mul_m3_v3(const float M[3][3], float r[3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
float angle_compat_rad(float angle, float angle_compat)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float n[3])
#define UNUSED_VARS_NDEBUG(...)
#define STREQ(a, b)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_ID_MASK
Object is a sort of wrapper for general info.
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ V3D_GIZMO_HIDE
@ OPERATOR_RUNNING_MODAL
@ ED_GIZMO_ARROW_STYLE_NORMAL
@ ED_GIZMO_MOVE_STYLE_RING_2D
bool ED_gizmo_poll_or_unlink_delayed_from_operator(const bContext *C, wmGizmoGroupType *gzgt, const char *idname)
void EDBM_flag_disable_all(BMEditMesh *em, char hflag)
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
void void void EDBM_redo_state_free(BMBackup *backup) ATTR_NONNULL(1)
void EDBM_selectmode_flush(BMEditMesh *em)
BMBackup EDBM_redo_state_store(BMEditMesh *em)
void EDBM_redo_state_restore(BMBackup *backup, BMEditMesh *em, bool recalc_looptris) ATTR_NONNULL(1
void ED_workspace_status_text(bContext *C, const char *str)
Definition area.cc:966
bool ED_operator_editmesh(bContext *C)
int ED_undo_operator_repeat(bContext *C, wmOperator *op)
Definition ed_undo.cc:644
RegionView3D * ED_view3d_context_rv3d(bContext *C)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float r_out[3])
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
void UI_GetThemeColor3fv(int colorid, float col[3])
@ TH_GIZMO_PRIMARY
@ TH_GIZMO_SECONDARY
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE
@ WM_GIZMOGROUPTYPE_3D
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
@ BM_ELEM_SELECT
ATTR_WARN_UNUSED_RESULT BMesh * bm
#define BM_FACE
#define BM_EDGE
#define BM_VERT
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
bool BMO_op_initf(BMesh *bm, BMOperator *op, int flag, const char *fmt,...)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
static void gizmo_mesh_bisect_draw_prepare(const bContext *, wmGizmoGroup *gzgroup)
static void mesh_bisect_interactive_calc(bContext *C, wmOperator *op, float plane_co[3], float plane_no[3])
static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
static void gizmo_bisect_prop_depth_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
static void edbm_bisect_exit(BisectData *opdata)
static void gizmo_bisect_exec(GizmoGroup *ggd)
static void gizmo_bisect_prop_translate_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void gizmo_mesh_bisect_update_from_op(GizmoGroup *ggd)
static void gizmo_bisect_prop_translate_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
static bool gizmo_mesh_bisect_poll(const bContext *C, wmGizmoGroupType *gzgt)
static void MESH_GGT_bisect(wmGizmoGroupType *gzgt)
static void gizmo_bisect_prop_angle_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p)
static void gizmo_bisect_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
void MESH_OT_bisect(wmOperatorType *ot)
static void gizmo_bisect_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
static int mesh_bisect_exec(bContext *C, wmOperator *op)
bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt,...)
bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report)
draw_view in_light_buf[] float
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
#define G(x, y, z)
return ret
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
int totedgesel
struct BisectData::BisectDataBackup * backup
struct GizmoGroup::@412 data
PropertyRNA * prop_plane_no
wmOperator * op
float rotate_up[3]
float rotate_axis[3]
PropertyRNA * prop_plane_co
wmGizmo * rotate_c
wmGizmo * translate_c
bContext * context
wmGizmo * translate_z
float viewinv[4][4]
wmGenericUserData user_data
Definition WM_types.hh:632
wmGizmoGroupFnInit setup
const char * idname
wmGizmoMapType_Params gzmap_params
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupFnPoll poll
wmGizmoGroupFnDrawPrepare draw_prepare
const wmGizmoPropertyType * type
wmGizmoGroup * parent_gzgroup
float matrix_basis[4][4]
float color[4]
PointerRNA * ptr
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(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1028
struct ReportList * reports
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
@ WM_CURSOR_EDIT
Definition wm_cursors.hh:19
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition wm_gizmo.cc:81
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition wm_gizmo.cc:313
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition wm_gizmo.cc:283
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition wm_gizmo.cc:303
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition wm_gizmo.cc:273
bool WM_gizmo_group_type_ensure(const char *idname)
wmGizmoGroupType * WM_gizmogrouptype_append(void(*wtfunc)(wmGizmoGroupType *))
void WM_gizmo_target_property_def_func(wmGizmo *gz, const char *idname, const wmGizmoPropertyFnParams *params)
const wmGizmoType * WM_gizmotype_find(const char *idname, bool quiet)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
wmOperator * WM_operator_last_redo(const bContext *C)