Blender  V2.93
editmesh_bisect.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 by Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_object_types.h"
27 
28 #include "BLI_math.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "BKE_context.h"
33 #include "BKE_editmesh.h"
34 #include "BKE_global.h"
35 #include "BKE_layer.h"
36 #include "BKE_report.h"
37 
38 #include "RNA_access.h"
39 #include "RNA_define.h"
40 
41 #include "WM_api.h"
42 #include "WM_types.h"
43 
44 #include "ED_gizmo_utils.h"
45 #include "ED_mesh.h"
46 #include "ED_screen.h"
47 #include "ED_view3d.h"
48 
49 #include "UI_resources.h"
50 
51 #include "mesh_intern.h" /* own include */
52 
53 #define USE_GIZMO
54 
55 #ifdef USE_GIZMO
56 # include "ED_gizmo_library.h"
57 # include "ED_undo.h"
58 #endif
59 
60 static int mesh_bisect_exec(bContext *C, wmOperator *op);
61 
62 /* -------------------------------------------------------------------- */
63 /* Model Helpers */
64 
65 typedef struct {
66  /* modal only */
67 
68  /* Aligned with objects array. */
69  struct {
71  bool is_valid;
72  bool is_dirty;
73  } * backup;
75  short gizmo_flag;
76 } BisectData;
77 
79  wmOperator *op,
80  float plane_co[3],
81  float plane_no[3])
82 {
83  View3D *v3d = CTX_wm_view3d(C);
84  ARegion *region = CTX_wm_region(C);
85  RegionView3D *rv3d = region->regiondata;
86 
87  int x_start = RNA_int_get(op->ptr, "xstart");
88  int y_start = RNA_int_get(op->ptr, "ystart");
89  int x_end = RNA_int_get(op->ptr, "xend");
90  int y_end = RNA_int_get(op->ptr, "yend");
91 
92  /* reference location (some point in front of the view) for finding a point on a plane */
93  const float *co_ref = rv3d->ofs;
94  float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
95  float co_a[3], co_b[3];
96  const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
97 
98  /* view vector */
99  ED_view3d_win_to_vector(region, co_a_ss, co_a);
100 
101  /* view delta */
102  sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
103  ED_view3d_win_to_delta(region, co_delta_ss, co_b, zfac);
104 
105  /* cross both to get a normal */
106  cross_v3_v3v3(plane_no, co_a, co_b);
107  normalize_v3(plane_no); /* not needed but nicer for user */
108 
109  /* point on plane, can use either start or endpoint */
110  ED_view3d_win_to_3d(v3d, region, co_ref, co_a_ss, plane_co);
111 }
112 
113 static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
114 {
115  ViewLayer *view_layer = CTX_data_view_layer(C);
116  int valid_objects = 0;
117 
118  /* If the properties are set or there is no rv3d,
119  * skip model and exec immediately. */
120  if ((CTX_wm_region_view3d(C) == NULL) || (RNA_struct_property_is_set(op->ptr, "plane_co") &&
121  RNA_struct_property_is_set(op->ptr, "plane_no"))) {
122  return mesh_bisect_exec(C, op);
123  }
124 
125  uint objects_len = 0;
127  view_layer, CTX_wm_view3d(C), &objects_len);
128  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
129  Object *obedit = objects[ob_index];
130  BMEditMesh *em = BKE_editmesh_from_object(obedit);
131 
132  if (em->bm->totedgesel != 0) {
133  valid_objects++;
134  }
135  }
136 
137  if (valid_objects == 0) {
138  BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required");
139  MEM_freeN(objects);
140  return OPERATOR_CANCELLED;
141  }
142 
143  int ret = WM_gesture_straightline_invoke(C, op, event);
144  if (ret & OPERATOR_RUNNING_MODAL) {
145  View3D *v3d = CTX_wm_view3d(C);
146 
147  wmGesture *gesture = op->customdata;
148  BisectData *opdata;
149 
150  opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data");
151  gesture->user_data.data = opdata;
152 
153  opdata->backup_len = objects_len;
154  opdata->backup = MEM_callocN(sizeof(*opdata->backup) * objects_len, __func__);
155 
156  /* Store the mesh backups. */
157  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
158  Object *obedit = objects[ob_index];
159  BMEditMesh *em = BKE_editmesh_from_object(obedit);
160 
161  if (em->bm->totedgesel != 0) {
162  opdata->backup[ob_index].is_valid = true;
163  opdata->backup[ob_index].mesh = EDBM_redo_state_store(em);
164  }
165  }
166 
167  /* Misc other vars. */
168  G.moving = G_TRANSFORM_EDIT;
169  opdata->gizmo_flag = v3d->gizmo_flag;
170  v3d->gizmo_flag = V3D_GIZMO_HIDE;
171 
172  /* Initialize modal callout. */
173  ED_workspace_status_text(C, TIP_("LMB: Click and drag to draw cut line"));
174  }
175  MEM_freeN(objects);
176  return ret;
177 }
178 
179 static void edbm_bisect_exit(bContext *C, BisectData *opdata)
180 {
181  View3D *v3d = CTX_wm_view3d(C);
182  v3d->gizmo_flag = opdata->gizmo_flag;
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, NULL, false);
188  }
189  }
190  MEM_freeN(opdata->backup);
191 }
192 
193 static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
194 {
195  wmGesture *gesture = op->customdata;
196  BisectData *opdata = 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  if (event->type == EVT_MODAL_MAP) {
204  if (event->val == GESTURE_MODAL_BEGIN) {
205  ED_workspace_status_text(C, TIP_("LMB: Release to confirm cut line"));
206  }
207  else {
209  }
210  }
211 
213  edbm_bisect_exit(C, &opdata_back);
214 
215 #ifdef USE_GIZMO
216  /* Setup gizmos */
217  {
218  View3D *v3d = CTX_wm_view3d(C);
219  if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
220  WM_gizmo_group_type_ensure("MESH_GGT_bisect");
221  }
222  }
223 #endif
224  }
225 
226  return ret;
227 }
228 
229 /* End Model Helpers */
230 /* -------------------------------------------------------------------- */
231 
233 {
235 
236  /* both can be NULL, fallbacks values are used */
238 
239  int ret = OPERATOR_CANCELLED;
240 
241  float plane_co[3];
242  float plane_no[3];
243  float imat[4][4];
244 
245  const float thresh = RNA_float_get(op->ptr, "threshold");
246  const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
247  const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
248  const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
249 
250  PropertyRNA *prop_plane_co;
251  PropertyRNA *prop_plane_no;
252 
253  prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
254  if (RNA_property_is_set(op->ptr, prop_plane_co)) {
255  RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
256  }
257  else {
258  copy_v3_v3(plane_co, scene->cursor.location);
259  RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
260  }
261 
262  prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
263  if (RNA_property_is_set(op->ptr, prop_plane_no)) {
264  RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
265  }
266  else {
267  if (rv3d) {
268  copy_v3_v3(plane_no, rv3d->viewinv[1]);
269  }
270  else {
271  /* fallback... */
272  plane_no[0] = plane_no[1] = 0.0f;
273  plane_no[2] = 1.0f;
274  }
275  RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
276  }
277 
278  wmGesture *gesture = op->customdata;
279  BisectData *opdata = (gesture != NULL) ? gesture->user_data.data : NULL;
280 
281  /* -------------------------------------------------------------------- */
282  /* Modal support */
283  /* Note: keep this isolated, exec can work without this */
284  if (opdata != NULL) {
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 
293  uint objects_len = 0;
295  CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
296 
297  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
298  Object *obedit = objects[ob_index];
299  BMEditMesh *em = BKE_editmesh_from_object(obedit);
300  BMesh *bm = em->bm;
301 
302  if (opdata != NULL) {
303  if (opdata->backup[ob_index].is_dirty) {
304  EDBM_redo_state_restore(opdata->backup[ob_index].mesh, em, false);
305  opdata->backup[ob_index].is_dirty = false;
306  }
307  }
308 
309  if (bm->totedgesel == 0) {
310  continue;
311  }
312 
313  if (opdata != NULL) {
314  if (opdata->backup[ob_index].is_valid) {
315  opdata->backup[ob_index].is_dirty = true;
316  }
317  }
318 
319  float plane_co_local[3];
320  float plane_no_local[3];
321  copy_v3_v3(plane_co_local, plane_co);
322  copy_v3_v3(plane_no_local, plane_no);
323 
324  invert_m4_m4(imat, obedit->obmat);
325  mul_m4_v3(imat, plane_co_local);
326  mul_transposed_mat3_m4_v3(obedit->obmat, plane_no_local);
327 
328  BMOperator bmop;
329  EDBM_op_init(
330  em,
331  &bmop,
332  op,
333  "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
335  plane_co_local,
336  plane_no_local,
337  thresh,
338  clear_inner,
339  clear_outer);
340  BMO_op_exec(bm, &bmop);
341 
343 
344  if (use_fill) {
345  float normal_fill[3];
346  BMOperator bmop_fill;
347  BMOperator bmop_attr;
348 
349  /* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
350  * The normal is passed so triangle fill wont have to calculate it. */
351  normalize_v3_v3(normal_fill, plane_no_local);
352 
353  /* Fill */
355  &bmop_fill,
356  0,
357  "triangle_fill edges=%S normal=%v use_dissolve=%b",
358  &bmop,
359  "geom_cut.out",
360  normal_fill,
361  true);
362  BMO_op_exec(bm, &bmop_fill);
363 
364  /* Copy Attributes */
366  &bmop_attr,
367  0,
368  "face_attribute_fill faces=%S use_normals=%b use_data=%b",
369  &bmop_fill,
370  "geom.out",
371  true,
372  true);
373  BMO_op_exec(bm, &bmop_attr);
374 
376  bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
377 
378  BMO_op_finish(bm, &bmop_attr);
379  BMO_op_finish(bm, &bmop_fill);
380  }
381 
383  bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
384 
385  if (EDBM_op_finish(em, &bmop, op, true)) {
386  EDBM_update_generic(obedit->data, true, true);
389  }
390  }
391  MEM_freeN(objects);
392  return ret;
393 }
394 
395 #ifdef USE_GIZMO
396 static void MESH_GGT_bisect(struct 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  NULL,
422  -1e12f,
423  1e12f,
424  "Plane Point",
425  "A point on the plane",
426  -1e4f,
427  1e4f);
429  prop = RNA_def_float_vector(ot->srna,
430  "plane_no",
431  3,
432  NULL,
433  -1.0f,
434  1.0f,
435  "Plane Normal",
436  "The direction the plane points",
437  -1.0f,
438  1.0f);
440 
441  RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill in the cut");
443  ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
445  ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
446 
447  prop = RNA_def_float(ot->srna,
448  "threshold",
449  0.0001,
450  0.0,
451  10.0,
452  "Axis Threshold",
453  "Preserves the existing geometry along the cut plane",
454  0.00001,
455  0.1);
456  /* Without higher precision, the default value displays as zero. */
457  RNA_def_property_ui_range(prop, 0.0, 10.0, 0.01, 5);
458 
460 
461 #ifdef USE_GIZMO
463 #endif
464 }
465 
466 #ifdef USE_GIZMO
467 
468 /* -------------------------------------------------------------------- */
472 typedef struct GizmoGroup {
473  /* Arrow to change plane depth. */
475  /* Translate XYZ */
477  /* For grabbing the gizmo and moving freely. */
478  struct wmGizmo *rotate_c;
479 
480  /* We could store more vars here! */
481  struct {
486 
487  float rotate_axis[3];
488  float rotate_up[3];
489  } data;
491 
497 static void gizmo_bisect_exec(GizmoGroup *ggd)
498 {
499  wmOperator *op = ggd->data.op;
500  if (op == WM_operator_last_redo((bContext *)ggd->data.context)) {
502  }
503 }
504 
506 {
507  wmOperator *op = ggd->data.op;
508 
509  float plane_co[3], plane_no[3];
510 
511  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
512  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
513 
515  WM_gizmo_set_matrix_location(ggd->rotate_c, plane_co);
516  /* translate_c location comes from the property. */
517 
519 
520  WM_gizmo_set_scale(ggd->translate_c, 0.2);
521 
523  if (rv3d) {
524  normalize_v3_v3(ggd->data.rotate_axis, rv3d->viewinv[2]);
525  normalize_v3_v3(ggd->data.rotate_up, rv3d->viewinv[1]);
526 
527  /* ensure its orthogonal */
529  ggd->data.rotate_up, ggd->data.rotate_up, ggd->data.rotate_axis);
531 
533 
534  float plane_no_cross[3];
535  cross_v3_v3v3(plane_no_cross, plane_no, ggd->data.rotate_axis);
536 
538  ggd->rotate_c, plane_no_cross, ggd->data.rotate_axis);
539  RNA_enum_set(ggd->rotate_c->ptr,
540  "draw_options",
542  }
543 }
544 
545 /* depth callbacks */
546 static void gizmo_bisect_prop_depth_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
547 {
549  wmOperator *op = ggd->data.op;
550  float *value = value_p;
551 
552  BLI_assert(gz_prop->type->array_length == 1);
553  UNUSED_VARS_NDEBUG(gz_prop);
554 
555  float plane_co[3], plane_no[3];
556  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
557  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
558 
559  value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]);
560 }
561 
562 static void gizmo_bisect_prop_depth_set(const wmGizmo *gz,
563  wmGizmoProperty *gz_prop,
564  const void *value_p)
565 {
567  wmOperator *op = ggd->data.op;
568  const float *value = value_p;
569 
570  BLI_assert(gz_prop->type->array_length == 1);
571  UNUSED_VARS_NDEBUG(gz_prop);
572 
573  float plane_co[3], plane[4];
574  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_co, plane_co);
576  normalize_v3(plane);
577 
578  plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]);
579 
580  /* Keep our location, may be offset simply to be inside the viewport. */
581  closest_to_plane_normalized_v3(plane_co, plane, plane_co);
582 
583  RNA_property_float_set_array(op->ptr, ggd->data.prop_plane_co, plane_co);
584 
585  gizmo_bisect_exec(ggd);
586 }
587 
588 /* translate callbacks */
590  wmGizmoProperty *gz_prop,
591  void *value_p)
592 {
594  wmOperator *op = ggd->data.op;
595 
596  BLI_assert(gz_prop->type->array_length == 3);
597  UNUSED_VARS_NDEBUG(gz_prop);
598 
600 }
601 
603  wmGizmoProperty *gz_prop,
604  const void *value_p)
605 {
607  wmOperator *op = ggd->data.op;
608 
609  BLI_assert(gz_prop->type->array_length == 3);
610  UNUSED_VARS_NDEBUG(gz_prop);
611 
613 
614  gizmo_bisect_exec(ggd);
615 }
616 
617 /* angle callbacks */
618 static void gizmo_bisect_prop_angle_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p)
619 {
621  wmOperator *op = ggd->data.op;
622  float *value = value_p;
623 
624  BLI_assert(gz_prop->type->array_length == 1);
625  UNUSED_VARS_NDEBUG(gz_prop);
626 
627  float plane_no[4];
628  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
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 
644 static void gizmo_bisect_prop_angle_set(const wmGizmo *gz,
645  wmGizmoProperty *gz_prop,
646  const void *value_p)
647 {
649  wmOperator *op = ggd->data.op;
650  const float *value = value_p;
651 
652  BLI_assert(gz_prop->type->array_length == 1);
653  UNUSED_VARS_NDEBUG(gz_prop);
654 
655  float plane_no[4];
656  RNA_property_float_get_array(op->ptr, ggd->data.prop_plane_no, plane_no);
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 */
672  RNA_property_float_set_array(op->ptr, ggd->data.prop_plane_no, plane_no);
673 
674  gizmo_bisect_exec(ggd);
675  }
676  }
677 }
678 
680 {
681  return ED_gizmo_poll_or_unlink_delayed_from_operator(C, gzgt, "MESH_OT_bisect");
682 }
683 
684 static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup)
685 {
687 
688  if (op == NULL || !STREQ(op->type->idname, "MESH_OT_bisect")) {
689  return;
690  }
691 
692  struct GizmoGroup *ggd = MEM_callocN(sizeof(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, NULL);
700  ggd->translate_c = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
701  ggd->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL);
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  {
725  "offset",
726  &(const struct wmGizmoPropertyFnParams){
727  .value_get_fn = gizmo_bisect_prop_depth_get,
728  .value_set_fn = gizmo_bisect_prop_depth_set,
729  .range_get_fn = NULL,
730  .user_data = NULL,
731  });
732 
734  "offset",
735  &(const struct wmGizmoPropertyFnParams){
736  .value_get_fn = gizmo_bisect_prop_translate_get,
737  .value_set_fn = gizmo_bisect_prop_translate_set,
738  .range_get_fn = NULL,
739  .user_data = NULL,
740  });
741 
743  "offset",
744  &(const struct wmGizmoPropertyFnParams){
745  .value_get_fn = gizmo_bisect_prop_angle_get,
746  .value_set_fn = gizmo_bisect_prop_angle_set,
747  .range_get_fn = NULL,
748  .user_data = NULL,
749  });
750  }
751 }
752 
754 {
755  GizmoGroup *ggd = gzgroup->customdata;
756  if (ggd->data.op->next) {
758  }
760 }
761 
762 static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt)
763 {
764  gzgt->name = "Mesh Bisect";
765  gzgt->idname = "MESH_GGT_bisect";
766 
767  gzgt->flag = WM_GIZMOGROUPTYPE_3D;
768 
771 
775 }
776 
779 #endif /* USE_GIZMO */
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:219
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:426
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define BLI_assert(a)
Definition: BLI_assert.h:58
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:412
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:950
float angle_compat_rad(float angle, float angle_compat)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const 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:757
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:551
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:83
#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_ARROW_STYLE_NORMAL
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y
bool ED_gizmo_poll_or_unlink_delayed_from_operator(const struct bContext *C, struct wmGizmoGroupType *gzgt, const char *idname)
void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess)
struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em)
void EDBM_update_generic(struct Mesh *me, const bool do_tessellation, const bool is_destructive)
void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag)
void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalctess)
void EDBM_selectmode_flush(struct BMEditMesh *em)
bool ED_operator_editmesh(struct bContext *C)
Definition: screen_ops.c:404
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:840
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op)
Definition: ed_undo.c:678
void ED_view3d_win_to_delta(const struct ARegion *region, const float mval[2], float out[3], const float zfac)
void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float out[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:89
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip)
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1191
@ TH_GIZMO_PRIMARY
Definition: UI_resources.h:321
@ TH_GIZMO_SECONDARY
Definition: UI_resources.h:322
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMOGROUPTYPE_3D
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
@ 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, const char htype, const char hflag, const 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, const 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 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 edbm_bisect_exit(bContext *C, BisectData *opdata)
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:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
return ret
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:3033
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:3132
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
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:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
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:3851
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:3883
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
Definition: rna_define.c:1706
void * regiondata
struct BMesh * bm
Definition: BKE_editmesh.h:52
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
int totedgesel
Definition: bmesh_class.h:298
short gizmo_flag
struct BisectData::@430 * backup
BMBackup mesh
struct wmGizmo * translate_z
PropertyRNA * prop_plane_no
wmOperator * op
struct wmGizmo * rotate_c
struct GizmoGroup::@431 data
struct wmGizmo * translate_c
float rotate_up[3]
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:579
short type
Definition: WM_types.h:577
wmGenericUserData user_data
Definition: WM_types.h:532
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:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct wmOperator * next
struct wmOperatorType * type
struct PointerRNA * ptr
#define G(x, y, z)
@ WM_CURSOR_EDIT
Definition: wm_cursors.h:38
@ EVT_MODAL_MAP
@ GESTURE_MODAL_BEGIN
wmOperatorType * ot
Definition: wm_files.c:3156
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)
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:328
wmGizmo * WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
Definition: wm_gizmo.c:96
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
Definition: wm_gizmo.c:349
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
Definition: wm_gizmo.c:316
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
Definition: wm_gizmo.c:339
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
Definition: wm_gizmo.c:306
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:58
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
wmOperator * WM_operator_last_redo(const bContext *C)