Blender  V3.3
editmesh_bisect.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_object_types.h"
11 
12 #include "BLI_math.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_editmesh.h"
18 #include "BKE_global.h"
19 #include "BKE_layer.h"
20 #include "BKE_report.h"
21 
22 #include "RNA_access.h"
23 #include "RNA_define.h"
24 
25 #include "WM_api.h"
26 #include "WM_types.h"
27 
28 #include "ED_gizmo_utils.h"
29 #include "ED_mesh.h"
30 #include "ED_screen.h"
31 #include "ED_view3d.h"
32 
33 #include "UI_resources.h"
34 
35 #include "mesh_intern.h" /* own include */
36 
37 #define USE_GIZMO
38 
39 #ifdef USE_GIZMO
40 # include "ED_gizmo_library.h"
41 # include "ED_undo.h"
42 #endif
43 
44 static int mesh_bisect_exec(bContext *C, wmOperator *op);
45 
46 /* -------------------------------------------------------------------- */
47 /* Model Helpers */
48 
49 typedef struct {
50  /* modal only */
51 
52  /* Aligned with objects array. */
53  struct {
55  bool is_valid;
56  bool is_dirty;
57  } * backup;
59 } BisectData;
60 
62  wmOperator *op,
63  float plane_co[3],
64  float plane_no[3])
65 {
66  View3D *v3d = CTX_wm_view3d(C);
67  ARegion *region = CTX_wm_region(C);
68  RegionView3D *rv3d = region->regiondata;
69 
70  int x_start = RNA_int_get(op->ptr, "xstart");
71  int y_start = RNA_int_get(op->ptr, "ystart");
72  int x_end = RNA_int_get(op->ptr, "xend");
73  int y_end = RNA_int_get(op->ptr, "yend");
74  const bool use_flip = RNA_boolean_get(op->ptr, "flip");
75 
76  /* reference location (some point in front of the view) for finding a point on a plane */
77  const float *co_ref = rv3d->ofs;
78  float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
79  float co_a[3], co_b[3];
80  const float zfac = ED_view3d_calc_zfac(rv3d, co_ref);
81 
82  /* view vector */
83  ED_view3d_win_to_vector(region, co_a_ss, co_a);
84 
85  /* view delta */
86  sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
87  ED_view3d_win_to_delta(region, co_delta_ss, zfac, co_b);
88 
89  /* cross both to get a normal */
90  cross_v3_v3v3(plane_no, co_a, co_b);
91  normalize_v3(plane_no); /* not needed but nicer for user */
92  if (use_flip) {
93  negate_v3(plane_no);
94  }
95 
96  /* point on plane, can use either start or endpoint */
97  ED_view3d_win_to_3d(v3d, region, co_ref, co_a_ss, plane_co);
98 }
99 
100 static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
101 {
102  ViewLayer *view_layer = CTX_data_view_layer(C);
103  int valid_objects = 0;
104 
105  /* If the properties are set or there is no rv3d,
106  * skip modal and exec immediately. */
107  if ((CTX_wm_region_view3d(C) == NULL) || (RNA_struct_property_is_set(op->ptr, "plane_co") &&
108  RNA_struct_property_is_set(op->ptr, "plane_no"))) {
109  return mesh_bisect_exec(C, op);
110  }
111 
112  uint objects_len = 0;
114  view_layer, CTX_wm_view3d(C), &objects_len);
115  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
116  Object *obedit = objects[ob_index];
117  BMEditMesh *em = BKE_editmesh_from_object(obedit);
118 
119  if (em->bm->totedgesel != 0) {
120  valid_objects++;
121  }
122  }
123 
124  if (valid_objects == 0) {
125  BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required");
126  MEM_freeN(objects);
127  return OPERATOR_CANCELLED;
128  }
129 
130  /* Support flipping if side matters. */
131  int ret;
132  const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
133  const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
134  const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
135  if ((clear_inner != clear_outer) || use_fill) {
137  }
138  else {
139  ret = WM_gesture_straightline_invoke(C, op, event);
140  }
141 
142  if (ret & OPERATOR_RUNNING_MODAL) {
143  wmGesture *gesture = op->customdata;
144  BisectData *opdata;
145 
146  opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data");
147  gesture->user_data.data = opdata;
148 
149  opdata->backup_len = objects_len;
150  opdata->backup = MEM_callocN(sizeof(*opdata->backup) * objects_len, __func__);
151 
152  /* Store the mesh backups. */
153  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
154  Object *obedit = objects[ob_index];
155  BMEditMesh *em = BKE_editmesh_from_object(obedit);
156 
157  if (em->bm->totedgesel != 0) {
158  opdata->backup[ob_index].is_valid = true;
159  opdata->backup[ob_index].mesh_backup = EDBM_redo_state_store(em);
160  }
161  }
162 
163  /* Misc other vars. */
164  G.moving = G_TRANSFORM_EDIT;
165 
166  /* Initialize modal callout. */
167  ED_workspace_status_text(C, TIP_("LMB: Click and drag to draw cut line"));
168  }
169  MEM_freeN(objects);
170  return ret;
171 }
172 
173 static void edbm_bisect_exit(BisectData *opdata)
174 {
175  G.moving = 0;
176 
177  for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
178  if (opdata->backup[ob_index].is_valid) {
179  EDBM_redo_state_free(&opdata->backup[ob_index].mesh_backup);
180  }
181  }
182  MEM_freeN(opdata->backup);
183 }
184 
185 static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
186 {
187  wmGesture *gesture = op->customdata;
188  BisectData *opdata = gesture->user_data.data;
189  BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */
190  int ret;
191 
192  ret = WM_gesture_straightline_modal(C, op, event);
193 
194  /* update or clear modal callout */
195  if (event->type == EVT_MODAL_MAP) {
196  if (event->val == GESTURE_MODAL_BEGIN) {
197  ED_workspace_status_text(C, TIP_("LMB: Release to confirm cut line"));
198  }
199  else {
201  }
202  }
203 
205  edbm_bisect_exit(&opdata_back);
206 
207 #ifdef USE_GIZMO
208  /* Setup gizmos */
209  {
210  View3D *v3d = CTX_wm_view3d(C);
211  if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
212  WM_gizmo_group_type_ensure("MESH_GGT_bisect");
213  }
214  }
215 #endif
216  }
217 
218  return ret;
219 }
220 
221 /* End Model Helpers */
222 /* -------------------------------------------------------------------- */
223 
225 {
227 
228  /* both can be NULL, fallbacks values are used */
230 
231  int ret = OPERATOR_CANCELLED;
232 
233  float plane_co[3];
234  float plane_no[3];
235  float imat[4][4];
236 
237  const float thresh = RNA_float_get(op->ptr, "threshold");
238  const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
239  const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
240  const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
241 
242  PropertyRNA *prop_plane_co;
243  PropertyRNA *prop_plane_no;
244 
245  prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
246  if (RNA_property_is_set(op->ptr, prop_plane_co)) {
247  RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
248  }
249  else {
250  copy_v3_v3(plane_co, scene->cursor.location);
251  RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
252  }
253 
254  prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
255  if (RNA_property_is_set(op->ptr, prop_plane_no)) {
256  RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
257  }
258  else {
259  if (rv3d) {
260  copy_v3_v3(plane_no, rv3d->viewinv[1]);
261  }
262  else {
263  /* fallback... */
264  plane_no[0] = plane_no[1] = 0.0f;
265  plane_no[2] = 1.0f;
266  }
267  RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
268  }
269 
270  wmGesture *gesture = op->customdata;
271  BisectData *opdata = (gesture != NULL) ? gesture->user_data.data : NULL;
272 
273  /* -------------------------------------------------------------------- */
274  /* Modal support */
275  /* NOTE: keep this isolated, exec can work without this. */
276  if (opdata != NULL) {
277  mesh_bisect_interactive_calc(C, op, plane_co, plane_no);
278  /* Write back to the props. */
279  RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
280  RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
281  }
282  /* End Modal */
283  /* -------------------------------------------------------------------- */
284 
285  uint objects_len = 0;
287  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
288 
289  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
290  Object *obedit = objects[ob_index];
291  BMEditMesh *em = BKE_editmesh_from_object(obedit);
292  BMesh *bm = em->bm;
293 
294  if (opdata != NULL) {
295  if (opdata->backup[ob_index].is_dirty) {
296  EDBM_redo_state_restore(&opdata->backup[ob_index].mesh_backup, em, false);
297  opdata->backup[ob_index].is_dirty = false;
298  }
299  }
300 
301  if (bm->totedgesel == 0) {
302  continue;
303  }
304 
305  if (opdata != NULL) {
306  if (opdata->backup[ob_index].is_valid) {
307  opdata->backup[ob_index].is_dirty = true;
308  }
309  }
310 
311  float plane_co_local[3];
312  float plane_no_local[3];
313  copy_v3_v3(plane_co_local, plane_co);
314  copy_v3_v3(plane_no_local, plane_no);
315 
316  invert_m4_m4(imat, obedit->obmat);
317  mul_m4_v3(imat, plane_co_local);
318  mul_transposed_mat3_m4_v3(obedit->obmat, plane_no_local);
319 
320  BMOperator bmop;
321  EDBM_op_init(
322  em,
323  &bmop,
324  op,
325  "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
327  plane_co_local,
328  plane_no_local,
329  thresh,
330  clear_inner,
331  clear_outer);
332  BMO_op_exec(bm, &bmop);
333 
335 
336  if (use_fill) {
337  float normal_fill[3];
338  BMOperator bmop_fill;
339  BMOperator bmop_attr;
340 
341  /* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
342  * The normal is passed so triangle fill won't have to calculate it. */
343  normalize_v3_v3(normal_fill, plane_no_local);
344 
345  /* Fill */
347  &bmop_fill,
348  0,
349  "triangle_fill edges=%S normal=%v use_dissolve=%b",
350  &bmop,
351  "geom_cut.out",
352  normal_fill,
353  true);
354  BMO_op_exec(bm, &bmop_fill);
355 
356  /* Copy Attributes */
358  &bmop_attr,
359  0,
360  "face_attribute_fill faces=%S use_normals=%b use_data=%b",
361  &bmop_fill,
362  "geom.out",
363  true,
364  true);
365  BMO_op_exec(bm, &bmop_attr);
366 
368  bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
369 
370  BMO_op_finish(bm, &bmop_attr);
371  BMO_op_finish(bm, &bmop_fill);
372  }
373 
375  bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
376 
377  if (EDBM_op_finish(em, &bmop, op, true)) {
378  EDBM_update(obedit->data,
379  &(const struct EDBMUpdate_Params){
380  .calc_looptri = true,
381  .calc_normals = false,
382  .is_destructive = true,
383  });
386  }
387  }
388  MEM_freeN(objects);
389  return ret;
390 }
391 
392 #ifdef USE_GIZMO
393 static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt);
394 #endif
395 
397 {
398  PropertyRNA *prop;
399 
400  /* identifiers */
401  ot->name = "Bisect";
402  ot->description = "Cut geometry along a plane (click-drag to define plane)";
403  ot->idname = "MESH_OT_bisect";
404 
405  /* api callbacks */
411 
412  /* flags */
414 
416  "plane_co",
417  3,
418  NULL,
419  -1e12f,
420  1e12f,
421  "Plane Point",
422  "A point on the plane",
423  -1e4f,
424  1e4f);
426  prop = RNA_def_float_vector(ot->srna,
427  "plane_no",
428  3,
429  NULL,
430  -1.0f,
431  1.0f,
432  "Plane Normal",
433  "The direction the plane points",
434  -1.0f,
435  1.0f);
437 
438  RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill in the cut");
440  ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
442  ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
443 
444  prop = RNA_def_float(ot->srna,
445  "threshold",
446  0.0001,
447  0.0,
448  10.0,
449  "Axis Threshold",
450  "Preserves the existing geometry along the cut plane",
451  0.00001,
452  0.1);
453  /* Without higher precision, the default value displays as zero. */
454  RNA_def_property_ui_range(prop, 0.0, 10.0, 0.01, 5);
455 
457 
458 #ifdef USE_GIZMO
460 #endif
461 }
462 
463 #ifdef USE_GIZMO
464 
465 /* -------------------------------------------------------------------- */
469 typedef struct GizmoGroup {
470  /* Arrow to change plane depth. */
472  /* Translate XYZ */
474  /* For grabbing the gizmo and moving freely. */
475  struct wmGizmo *rotate_c;
476 
477  /* We could store more vars here! */
478  struct {
483 
484  float rotate_axis[3];
485  float rotate_up[3];
486  } data;
488 
494 static void gizmo_bisect_exec(GizmoGroup *ggd)
495 {
496  wmOperator *op = ggd->data.op;
497  if (op == WM_operator_last_redo((bContext *)ggd->data.context)) {
499  }
500 }
501 
503 {
504  wmOperator *op = ggd->data.op;
505 
506  float plane_co[3], plane_no[3];
507 
508  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
509  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
510 
512  WM_gizmo_set_matrix_location(ggd->rotate_c, plane_co);
513  /* translate_c location comes from the property. */
514 
516 
517  WM_gizmo_set_scale(ggd->translate_c, 0.2);
518 
520  if (rv3d) {
521  normalize_v3_v3(ggd->data.rotate_axis, rv3d->viewinv[2]);
522  normalize_v3_v3(ggd->data.rotate_up, rv3d->viewinv[1]);
523 
524  /* ensure its orthogonal */
526  ggd->data.rotate_up, ggd->data.rotate_up, ggd->data.rotate_axis);
528 
530 
531  float plane_no_cross[3];
532  cross_v3_v3v3(plane_no_cross, plane_no, ggd->data.rotate_axis);
533 
535  ggd->rotate_c, plane_no_cross, ggd->data.rotate_axis);
536  RNA_enum_set(ggd->rotate_c->ptr,
537  "draw_options",
539  }
540 }
541 
542 /* depth callbacks */
543 static void gizmo_bisect_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
544 {
546  wmOperator *op = ggd->data.op;
547  float *value = value_p;
548 
549  BLI_assert(gz_prop->type->array_length == 1);
550  UNUSED_VARS_NDEBUG(gz_prop);
551 
552  float plane_co[3], plane_no[3];
553  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
554  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
555 
556  value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
557 }
558 
559 static void gizmo_bisect_prop_depth_set(const wmGizmo *gz,
560  wmGizmoProperty *gz_prop,
561  const void *value_p)
562 {
564  wmOperator *op = ggd->data.op;
565  const float *value = value_p;
566 
567  BLI_assert(gz_prop->type->array_length == 1);
568  UNUSED_VARS_NDEBUG(gz_prop);
569 
570  float plane_co[3], plane[4];
571  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
573  normalize_v3(plane);
574 
575  plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
576 
577  /* Keep our location, may be offset simply to be inside the viewport. */
578  closest_to_plane_normalized_v3(plane_co, plane, plane_co);
579 
580  RNA_property_float_set_array(op->ptr, ggd->data.prop_plane_co, plane_co);
581 
582  gizmo_bisect_exec(ggd);
583 }
584 
585 /* translate callbacks */
587  wmGizmoProperty *gz_prop,
588  void *value_p)
589 {
591  wmOperator *op = ggd->data.op;
592 
593  BLI_assert(gz_prop->type->array_length == 3);
594  UNUSED_VARS_NDEBUG(gz_prop);
595 
597 }
598 
600  wmGizmoProperty *gz_prop,
601  const void *value_p)
602 {
604  wmOperator *op = ggd->data.op;
605 
606  BLI_assert(gz_prop->type->array_length == 3);
607  UNUSED_VARS_NDEBUG(gz_prop);
608 
610 
611  gizmo_bisect_exec(ggd);
612 }
613 
614 /* angle callbacks */
615 static void gizmo_bisect_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
616 {
618  wmOperator *op = ggd->data.op;
619  float *value = value_p;
620 
621  BLI_assert(gz_prop->type->array_length == 1);
622  UNUSED_VARS_NDEBUG(gz_prop);
623 
624  float plane_no[4];
625  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
626  normalize_v3(plane_no);
627 
628  float plane_no_proj[3];
629  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
630 
631  if (!is_zero_v3(plane_no_proj)) {
632  const float angle = -angle_signed_on_axis_v3v3_v3(
633  plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
634  value[0] = angle;
635  }
636  else {
637  value[0] = 0.0f;
638  }
639 }
640 
641 static void gizmo_bisect_prop_angle_set(const wmGizmo *gz,
642  wmGizmoProperty *gz_prop,
643  const void *value_p)
644 {
646  wmOperator *op = ggd->data.op;
647  const float *value = value_p;
648 
649  BLI_assert(gz_prop->type->array_length == 1);
650  UNUSED_VARS_NDEBUG(gz_prop);
651 
652  float plane_no[4];
653  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
654  normalize_v3(plane_no);
655 
656  float plane_no_proj[3];
657  project_plane_normalized_v3_v3v3(plane_no_proj, plane_no, ggd->data.rotate_axis);
658 
659  if (!is_zero_v3(plane_no_proj)) {
660  const float angle = -angle_signed_on_axis_v3v3_v3(
661  plane_no_proj, ggd->data.rotate_up, ggd->data.rotate_axis);
662  const float angle_delta = angle - angle_compat_rad(value[0], angle);
663  if (angle_delta != 0.0f) {
664  float mat[3][3];
665  axis_angle_normalized_to_mat3(mat, ggd->data.rotate_axis, angle_delta);
666  mul_m3_v3(mat, plane_no);
667 
668  /* re-normalize - seems acceptable */
669  RNA_property_float_set_array(op->ptr, ggd->data.prop_plane_no, plane_no);
670 
671  gizmo_bisect_exec(ggd);
672  }
673  }
674 }
675 
677 {
678  return ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_bisect");
679 }
680 
681 static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
682 {
684 
685  if (op == NULL || !STREQ(op->type->idname, "MESH_OT_bisect")) {
686  return;
687  }
688 
689  struct GizmoGroup *ggd = MEM_callocN(sizeof(GizmoGroup), __func__);
690  gzgroup->customdata = ggd;
691 
692  const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
693  const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
694  const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
695 
696  ggd->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
697  ggd->translate_c = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
698  ggd->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
699 
703 
706 
709 
710  {
711  ggd->data.context = (bContext *)C;
712  ggd->data.op = op;
713  ggd->data.prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
714  ggd->data.prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
715  }
716 
718 
719  /* Setup property callbacks */
720  {
722  "offset",
723  &(const struct wmGizmoPropertyFnParams){
724  .value_get_fn = gizmo_bisect_prop_depth_get,
725  .value_set_fn = gizmo_bisect_prop_depth_set,
726  .range_get_fn = NULL,
727  .user_data = NULL,
728  });
729 
731  "offset",
732  &(const struct wmGizmoPropertyFnParams){
733  .value_get_fn = gizmo_bisect_prop_translate_get,
734  .value_set_fn = gizmo_bisect_prop_translate_set,
735  .range_get_fn = NULL,
736  .user_data = NULL,
737  });
738 
740  "offset",
741  &(const struct wmGizmoPropertyFnParams){
742  .value_get_fn = gizmo_bisect_prop_angle_get,
743  .value_set_fn = gizmo_bisect_prop_angle_set,
744  .range_get_fn = NULL,
745  .user_data = NULL,
746  });
747  }
748 }
749 
751 {
752  GizmoGroup *ggd = gzgroup->customdata;
753  if (ggd->data.op->next) {
755  }
757 }
758 
759 static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt)
760 {
761  gzgt->name = "Mesh Bisect";
762  gzgt->idname = "MESH_GGT_bisect";
763 
765 
768 
772 }
773 
776 #endif /* USE_GIZMO */
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:248
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:542
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
#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.c:408
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
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_transposed_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:946
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 float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
Definition: math_vector.c:652
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
Definition: math_vector.c:488
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])
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define STREQ(a, b)
#define TIP_(msgid)
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_MOVE_STYLE_RING_2D
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y
@ ED_GIZMO_ARROW_STYLE_NORMAL
bool ED_gizmo_poll_or_unlink_delayed_from_operator(const struct bContext *C, struct wmGizmoGroupType *gzgt, const char *idname)
void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params)
void EDBM_redo_state_restore(struct BMBackup *backup, struct BMEditMesh *em, bool recalc_looptri) ATTR_NONNULL(1
struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em)
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag)
void void void EDBM_redo_state_free(struct BMBackup *backup) ATTR_NONNULL(1)
void EDBM_selectmode_flush(struct BMEditMesh *em)
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:433
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:816
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op)
Definition: ed_undo.c:662
void ED_view3d_win_to_delta(const struct ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float r_out[3])
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3])
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
struct RegionView3D * ED_view3d_context_rv3d(struct bContext *C)
Definition: space_view3d.c:82
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
#define C
Definition: RandGen.cpp:25
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1165
@ TH_GIZMO_PRIMARY
Definition: UI_resources.h:305
@ TH_GIZMO_SECONDARY
Definition: UI_resources.h:306
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE
@ WM_GIZMOGROUPTYPE_3D
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
ATTR_WARN_UNUSED_RESULT BMesh * bm
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.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
AnimationBackup * backup
void MESH_OT_bisect(struct wmOperatorType *ot)
static void gizmo_mesh_bisect_draw_prepare(const bContext *UNUSED(C), 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)
struct GizmoGroup GizmoGroup
static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void gizmo_mesh_bisect_update_from_op(GizmoGroup *ggd)
static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt)
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 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)
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)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define G(x, y, z)
return ret
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:5301
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
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
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3862
PropertyRNA * RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3894
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
Definition: rna_define.c:1664
void * regiondata
struct BMesh * bm
Definition: BKE_editmesh.h:40
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
int totedgesel
Definition: bmesh_class.h:298
struct BisectData::@450 * backup
BMBackup mesh_backup
struct wmGizmo * translate_z
PropertyRNA * prop_plane_no
wmOperator * op
struct wmGizmo * rotate_c
struct wmGizmo * translate_c
float rotate_up[3]
struct GizmoGroup::@451 data
float rotate_axis[3]
PropertyRNA * prop_plane_co
bContext * context
float obmat[4][4]
void * data
float viewinv[4][4]
View3DCursor cursor
char gizmo_flag
short val
Definition: WM_types.h:680
short type
Definition: WM_types.h:678
wmGenericUserData user_data
Definition: WM_types.h:595
wmGizmoGroupFnInit setup
const char * idname
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupFnPoll poll
struct wmGizmoMapType_Params gzmap_params
const char * name
wmGizmoGroupFnDrawPrepare draw_prepare
const struct wmGizmoPropertyType * type
struct wmGizmoGroup * parent_gzgroup
float matrix_basis[4][4]
float color[4]
struct PointerRNA * ptr
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
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
@ WM_CURSOR_EDIT
Definition: wm_cursors.h:22
@ EVT_MODAL_MAP
@ GESTURE_MODAL_BEGIN
wmOperatorType * ot
Definition: wm_files.c:3479
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)
void WM_gizmo_set_matrix_offset_rotation_from_yz_axis(wmGizmo *gz, const float y_axis[3], const float z_axis[3])
Definition: wm_gizmo.c:293
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition: wm_gizmo.c:81
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition: wm_gizmo.c:314
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition: wm_gizmo.c:284
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition: wm_gizmo.c:304
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition: wm_gizmo.c:274
bool WM_gizmo_group_type_ensure(const char *idname)
wmGizmoGroupType * WM_gizmogrouptype_append(void(*wtfunc)(struct 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)
Definition: wm_gizmo_type.c:45
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
wmOperator * WM_operator_last_redo(const bContext *C)