Blender  V3.3
bmo_bisect_plane.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_math.h"
12 #include "BLI_utildefines.h"
13 #include "BLI_utildefines_stack.h"
14 
15 #include "bmesh.h"
16 #include "bmesh_tools.h"
17 
18 #include "intern/bmesh_operators_private.h" /* own include */
19 
20 #define ELE_NEW 1
21 #define ELE_CUT 2
22 #define ELE_INPUT 4
23 
25 {
26  const float dist = BMO_slot_float_get(op->slots_in, "dist");
27  const bool use_snap_center = BMO_slot_bool_get(op->slots_in, "use_snap_center");
28  const bool clear_outer = BMO_slot_bool_get(op->slots_in, "clear_outer");
29  const bool clear_inner = BMO_slot_bool_get(op->slots_in, "clear_inner");
30 
31  float plane_co[3];
32  float plane_no[3];
33  float plane[4];
34 
35  BMO_slot_vec_get(op->slots_in, "plane_co", plane_co);
36  BMO_slot_vec_get(op->slots_in, "plane_no", plane_no);
37 
38  if (is_zero_v3(plane_no)) {
39  BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "Zero normal given");
40  return;
41  }
42 
43  plane_from_point_normal_v3(plane, plane_co, plane_no);
44 
45  /* tag geometry to bisect */
48 
50 
51  BM_mesh_bisect_plane(bm, plane, use_snap_center, true, ELE_CUT, ELE_NEW, dist);
52 
53  if (clear_outer || clear_inner) {
54  /* Use an array of vertices because 'geom' contains both verts and edges that may use them.
55  * Removing a vert may remove and edge which is later checked by #BMO_ITER.
56  * over-allocate the total possible vert count. */
57  const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_len(op->slots_in, "geom"));
58  BMVert **vert_arr = MEM_mallocN(sizeof(*vert_arr) * (size_t)vert_arr_max, __func__);
59  BMOIter siter;
60  BMVert *v;
61  float plane_inner[4];
62  float plane_outer[4];
63 
64  STACK_DECLARE(vert_arr);
65 
66  copy_v3_v3(plane_outer, plane);
67  copy_v3_v3(plane_inner, plane);
68  plane_outer[3] = plane[3] - dist;
69  plane_inner[3] = plane[3] + dist;
70 
71  STACK_INIT(vert_arr, vert_arr_max);
72 
73  BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
74  if ((clear_outer && plane_point_side_v3(plane_outer, v->co) > 0.0f) ||
75  (clear_inner && plane_point_side_v3(plane_inner, v->co) < 0.0f)) {
76  STACK_PUSH(vert_arr, v);
77  }
78  }
79 
80  while ((v = STACK_POP(vert_arr))) {
81  BM_vert_kill(bm, v);
82  }
83 
84  MEM_freeN(vert_arr);
85  }
86 
88  bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW | ELE_INPUT);
90  bm, op, op->slots_out, "geom_cut.out", BM_VERT | BM_EDGE, ELE_CUT);
91 }
MINLINE int min_ii(int a, int b)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
MINLINE float plane_point_side_v3(const float plane[4], const float co[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
#define STACK_POP(stack)
#define STACK_PUSH(stack, val)
#define STACK_DECLARE(stack)
#define STACK_INIT(stack, stack_num)
Read Guarded memory(de)allocation.
void BM_mesh_bisect_plane(BMesh *bm, const float plane[4], const bool use_snap_center, const bool use_tag, const short oflag_center, const short oflag_new, const float eps)
#define BM_ALL_NOLOOP
Definition: bmesh_class.h:411
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_vert_kill(BMesh *bm, BMVert *v)
Definition: bmesh_core.c:939
@ BMO_ERROR_CANCEL
Definition: bmesh_error.h:21
void BMO_error_raise(BMesh *bm, BMOperator *owner, eBMOpErrorLevel level, const char *msg) ATTR_NONNULL(1
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
BMO_FLAG_BUFFER.
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_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3])
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define ELE_NEW
#define ELE_CUT
#define ELE_INPUT
void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:87
int totvert
Definition: bmesh_class.h:297