Blender V5.0
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
8
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
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
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. */
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 {
148 }
149
151 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
152 BisectData *opdata;
153
154 opdata = MEM_mallocN<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. */
177 status.item(IFACE_("Cancel"), ICON_EVENT_ESC);
178 status.item(IFACE_("Draw Cut Line"), ICON_MOUSE_LMB_DRAG);
179 }
180 return ret;
181}
182
183static void edbm_bisect_exit(BisectData *opdata)
184{
185 G.moving = 0;
186
187 for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
188 if (opdata->backup[ob_index].is_valid) {
189 EDBM_redo_state_free(&opdata->backup[ob_index].mesh_backup);
190 }
191 }
192 MEM_freeN(opdata->backup);
193}
194
196{
197 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
198 BisectData *opdata = static_cast<BisectData *>(gesture->user_data.data);
199 BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */
201
202 ret = WM_gesture_straightline_modal(C, op, event);
203
204 /* update or clear modal callout */
205 WorkSpace *workspace = CTX_wm_workspace(C);
206
207 if (workspace) {
209 }
210
212 edbm_bisect_exit(&opdata_back);
213
214#ifdef USE_GIZMO
215 /* Setup gizmos */
216 {
217 View3D *v3d = CTX_wm_view3d(C);
218 if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
219 WM_gizmo_group_type_ensure("MESH_GGT_bisect");
220 }
221 }
222#endif
223 }
224
225 return ret;
226}
227
228/* End Model Helpers */
229/* -------------------------------------------------------------------- */
230
232{
233 Scene *scene = CTX_data_scene(C);
234
235 /* both can be nullptr, fallbacks values are used */
237
239
240 float plane_co[3];
241 float plane_no[3];
242 float imat[4][4];
243
244 const float thresh = RNA_float_get(op->ptr, "threshold");
245 const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
246 const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
247 const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
248
249 PropertyRNA *prop_plane_co;
250 PropertyRNA *prop_plane_no;
251
252 prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
253 if (RNA_property_is_set(op->ptr, prop_plane_co)) {
254 RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
255 }
256 else {
257 copy_v3_v3(plane_co, scene->cursor.location);
258 RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
259 }
260
261 prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
262 if (RNA_property_is_set(op->ptr, prop_plane_no)) {
263 RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
264 }
265 else {
266 if (rv3d) {
267 copy_v3_v3(plane_no, rv3d->viewinv[1]);
268 }
269 else {
270 /* fallback... */
271 plane_no[0] = plane_no[1] = 0.0f;
272 plane_no[2] = 1.0f;
273 }
274 RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
275 }
276
277 wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
278 BisectData *opdata = static_cast<BisectData *>((gesture != nullptr) ? gesture->user_data.data :
279 nullptr);
280
281 /* -------------------------------------------------------------------- */
282 /* Modal support */
283 /* NOTE: keep this isolated, exec can work without this. */
284 if (opdata != nullptr) {
285 mesh_bisect_interactive_calc(C, op, plane_co, plane_no);
286 /* Write back to the props. */
287 RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
288 RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
289 }
290 /* End Modal */
291 /* -------------------------------------------------------------------- */
292
295
296 for (const int ob_index : objects.index_range()) {
297 Object *obedit = objects[ob_index];
299 BMesh *bm = em->bm;
300
301 if (opdata != nullptr) {
302 if (opdata->backup[ob_index].is_dirty) {
303 EDBM_redo_state_restore(&opdata->backup[ob_index].mesh_backup, em, false);
304 opdata->backup[ob_index].is_dirty = false;
305 }
306 }
307
308 if (bm->totedgesel == 0) {
309 continue;
310 }
311
312 if (opdata != nullptr) {
313 if (opdata->backup[ob_index].is_valid) {
314 opdata->backup[ob_index].is_dirty = true;
315 }
316 }
317
318 float plane_co_local[3];
319 float plane_no_local[3];
320 copy_v3_v3(plane_co_local, plane_co);
321 copy_v3_v3(plane_no_local, plane_no);
322
323 invert_m4_m4(imat, obedit->object_to_world().ptr());
324 mul_m4_v3(imat, plane_co_local);
325 mul_transposed_mat3_m4_v3(obedit->object_to_world().ptr(), plane_no_local);
326
327 BMOperator bmop;
329 em,
330 &bmop,
331 op,
332 "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
334 plane_co_local,
335 plane_no_local,
336 thresh,
337 clear_inner,
338 clear_outer);
339 BMO_op_exec(bm, &bmop);
340
342
343 if (use_fill) {
344 float normal_fill[3];
345 BMOperator bmop_fill;
346 BMOperator bmop_attr;
347
348 /* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
349 * The normal is passed so triangle fill won't have to calculate it. */
350 normalize_v3_v3(normal_fill, plane_no_local);
351
352 /* Fill */
354 &bmop_fill,
355 0,
356 "triangle_fill edges=%S normal=%v use_dissolve=%b",
357 &bmop,
358 "geom_cut.out",
359 normal_fill,
360 true);
361 BMO_op_exec(bm, &bmop_fill);
362
363 /* Copy Attributes */
365 &bmop_attr,
366 0,
367 "face_attribute_fill faces=%S use_normals=%b use_data=%b",
368 &bmop_fill,
369 "geom.out",
370 true,
371 true);
372 BMO_op_exec(bm, &bmop_attr);
373
375 bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
376
377 BMO_op_finish(bm, &bmop_attr);
378 BMO_op_finish(bm, &bmop_fill);
379 }
380
382 bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
383
384 if (EDBM_op_finish(em, &bmop, op, true)) {
386 params.calc_looptris = true;
387 params.calc_normals = false;
388 params.is_destructive = true;
389 EDBM_update(static_cast<Mesh *>(obedit->data), &params);
390
393
395 }
396 }
397 return ret;
398}
399
400#ifdef USE_GIZMO
401static void MESH_GGT_bisect(wmGizmoGroupType *gzgt);
402#endif
403
405{
406 PropertyRNA *prop;
407
408 /* identifiers */
409 ot->name = "Bisect";
410 ot->description = "Cut geometry along a plane (click-drag to define plane)";
411 ot->idname = "MESH_OT_bisect";
412
413 /* API callbacks. */
414 ot->exec = mesh_bisect_exec;
415 ot->invoke = mesh_bisect_invoke;
416 ot->modal = mesh_bisect_modal;
418 ot->poll = ED_operator_editmesh;
419
420 /* flags */
422
423 prop = RNA_def_float_vector_xyz(ot->srna,
424 "plane_co",
425 3,
426 nullptr,
427 -1e12f,
428 1e12f,
429 "Plane Point",
430 "A point on the plane",
431 -1e4f,
432 1e4f);
434 prop = RNA_def_float_vector(ot->srna,
435 "plane_no",
436 3,
437 nullptr,
438 -1.0f,
439 1.0f,
440 "Plane Normal",
441 "The direction the plane points",
442 -1.0f,
443 1.0f);
445
446 prop = RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill in the cut");
448
450 ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
452 ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
453
454 prop = RNA_def_float(ot->srna,
455 "threshold",
456 0.0001,
457 0.0,
458 10.0,
459 "Axis Threshold",
460 "Preserves the existing geometry along the cut plane",
461 0.00001,
462 0.1);
463 /* Without higher precision, the default value displays as zero. */
464 RNA_def_property_ui_range(prop, 0.0, 10.0, 0.01, 5);
465
467
468#ifdef USE_GIZMO
470#endif
471}
472
473#ifdef USE_GIZMO
474
475/* -------------------------------------------------------------------- */
478
480 /* Arrow to change plane depth. */
482 /* Translate XYZ */
484 /* For grabbing the gizmo and moving freely. */
486
487 /* We could store more vars here! */
488 struct {
493
494 float rotate_axis[3];
495 float rotate_up[3];
497};
498
505{
506 wmOperator *op = ggd->data.op;
507 if (op == WM_operator_last_redo(ggd->data.context)) {
509 }
510}
511
513{
514 wmOperator *op = ggd->data.op;
515
516 float plane_co[3], plane_no[3];
517
520
523 /* translate_c location comes from the property. */
524
526
528
530 if (rv3d) {
531 normalize_v3_v3(ggd->data.rotate_axis, rv3d->viewinv[2]);
532 normalize_v3_v3(ggd->data.rotate_up, rv3d->viewinv[1]);
533
534 /* ensure its orthogonal */
536 ggd->data.rotate_up, ggd->data.rotate_up, ggd->data.rotate_axis);
538
541 }
542}
543
544/* depth callbacks */
545static void gizmo_bisect_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
546{
547 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
548 wmOperator *op = ggd->data.op;
549 float *value = static_cast<float *>(value_p);
550
551 BLI_assert(gz_prop->type->array_length == 1);
552 UNUSED_VARS_NDEBUG(gz_prop);
553
554 float plane_co[3], plane_no[3];
557
558 value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
559}
560
562 wmGizmoProperty *gz_prop,
563 const void *value_p)
564{
565 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
566 wmOperator *op = ggd->data.op;
567 const float *value = static_cast<const float *>(value_p);
568
569 BLI_assert(gz_prop->type->array_length == 1);
570 UNUSED_VARS_NDEBUG(gz_prop);
571
572 float plane_co[3], plane[4];
575 normalize_v3(plane);
576
577 plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
578
579 /* Keep our location, may be offset simply to be inside the viewport. */
580 closest_to_plane_normalized_v3(plane_co, plane, plane_co);
581
583
585}
586
587/* translate callbacks */
589 wmGizmoProperty *gz_prop,
590 void *value_p)
591{
592 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
593 wmOperator *op = ggd->data.op;
594
595 BLI_assert(gz_prop->type->array_length == 3);
596 UNUSED_VARS_NDEBUG(gz_prop);
597
598 RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, static_cast<float *>(value_p));
599}
600
602 wmGizmoProperty *gz_prop,
603 const void *value_p)
604{
605 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
606 wmOperator *op = ggd->data.op;
607
608 BLI_assert(gz_prop->type->array_length == 3);
609 UNUSED_VARS_NDEBUG(gz_prop);
610
612 op->ptr, ggd->data.prop_plane_co, static_cast<const float *>(value_p));
613
615}
616
617/* angle callbacks */
618static void gizmo_bisect_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
619{
620 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
621 wmOperator *op = ggd->data.op;
622 float *value = static_cast<float *>(value_p);
623
624 BLI_assert(gz_prop->type->array_length == 1);
625 UNUSED_VARS_NDEBUG(gz_prop);
626
627 float plane_no[4];
629 normalize_v3(plane_no);
630
631 float plane_no_proj[3];
632 project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
633
634 if (!is_zero_v3(plane_no_proj)) {
635 const float angle = -angle_signed_on_axis_v3v3_v3(
636 plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
637 value[0] = angle;
638 }
639 else {
640 value[0] = 0.0f;
641 }
642}
643
645 wmGizmoProperty *gz_prop,
646 const void *value_p)
647{
648 GizmoGroup *ggd = static_cast<GizmoGroup *>(gz->parent_gzgroup->customdata);
649 wmOperator *op = ggd->data.op;
650 const float *value = static_cast<const float *>(value_p);
651
652 BLI_assert(gz_prop->type->array_length == 1);
653 UNUSED_VARS_NDEBUG(gz_prop);
654
655 float plane_no[4];
657 normalize_v3(plane_no);
658
659 float plane_no_proj[3];
660 project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
661
662 if (!is_zero_v3(plane_no_proj)) {
663 const float angle = -angle_signed_on_axis_v3v3_v3(
664 plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
665 const float angle_delta = angle - angle_compat_rad(value[0], angle);
666 if (angle_delta != 0.0f) {
667 float mat[3][3];
668 axis_angle_normalized_to_mat3(mat, ggd->data.rotate_axis, angle_delta);
669 mul_m3_v3(mat, plane_no);
670
671 /* re-normalize - seems acceptable */
673
675 }
676 }
677}
678
680{
681 return ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_bisect");
682}
683
684static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
685{
687
688 if (op == nullptr || !STREQ(op->type->idname, "MESH_OT_bisect")) {
689 return;
690 }
691
692 GizmoGroup *ggd = MEM_callocN<GizmoGroup>(__func__);
693 gzgroup->customdata = ggd;
694
695 const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
696 const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
697 const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
698
699 ggd->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
700 ggd->translate_c = WM_gizmo_new_ptr(gzt_move, gzgroup, nullptr);
701 ggd->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, nullptr);
702
706
709
712
713 {
714 ggd->data.context = (bContext *)C;
715 ggd->data.op = op;
716 ggd->data.prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
717 ggd->data.prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
718 }
719
721
722 /* Setup property callbacks */
723 {
724 {
726 params.value_get_fn = gizmo_bisect_prop_depth_get;
727 params.value_set_fn = gizmo_bisect_prop_depth_set;
728 params.range_get_fn = nullptr;
729 params.user_data = nullptr;
731 }
732
733 {
737 params.range_get_fn = nullptr;
738 params.user_data = nullptr;
740 }
741
742 {
744 params.value_get_fn = gizmo_bisect_prop_angle_get;
745 params.value_set_fn = gizmo_bisect_prop_angle_set;
746 params.range_get_fn = nullptr;
747 params.user_data = nullptr;
749 }
750 }
751}
752
753static void gizmo_mesh_bisect_draw_prepare(const bContext * /*C*/, wmGizmoGroup *gzgroup)
754{
755 GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
756 if (ggd->data.op->next) {
758 }
760}
761
763{
764 gzgt->name = "Mesh Bisect";
765 gzgt->idname = "MESH_GGT_bisect";
766
768
771
775}
776
778
779#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:61
@ 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)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
void BKE_workspace_status_clear(WorkSpace *workspace)
Definition workspace.cc:650
#define BLI_assert(a)
Definition BLI_assert.h:46
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition math_geom.cc:442
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_CANCELLED
@ OPERATOR_FINISHED
@ 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)
bool EDBM_uvselect_clear(BMEditMesh *em)
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
bool ED_operator_editmesh(bContext *C)
bool ED_undo_operator_repeat(bContext *C, wmOperator *op)
Definition ed_undo.cc:631
RegionView3D * ED_view3d_context_rv3d(bContext *C)
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3], bool precise=false)
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])
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:117
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
#define C
Definition RandGen.cpp:29
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:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
@ BM_ELEM_SELECT
BMesh const char void * data
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.
int64_t size() const
IndexRange index_range() const
nullptr float
static wmOperatorStatus mesh_bisect_exec(bContext *C, wmOperator *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 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 wmOperatorStatus mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
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 wmOperatorStatus mesh_bisect_modal(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)
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)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
const int status
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)
void * regiondata
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
int totedgesel
struct BisectData::BisectDataBackup * backup
PropertyRNA * prop_plane_no
wmOperator * op
float rotate_up[3]
struct GizmoGroup::@202235027223271307214350347166045063370065166121 data
float rotate_axis[3]
PropertyRNA * prop_plane_co
wmGizmo * rotate_c
wmGizmo * translate_c
bContext * context
wmGizmo * translate_z
float viewinv[4][4]
View3DCursor cursor
wmGenericUserData user_data
Definition WM_types.hh:666
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 * idname
Definition WM_types.hh:1035
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:4237
void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
wmOperatorStatus WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition wm_gizmo.cc:85
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition wm_gizmo.cc:317
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition wm_gizmo.cc:287
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition wm_gizmo.cc:307
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition wm_gizmo.cc:277
bool WM_gizmo_group_type_ensure(const StringRef 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 StringRef idname, bool quiet)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
wmOperator * WM_operator_last_redo(const bContext *C)