Blender  V2.93
bmo_bisect_plane.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 
23 #include "MEM_guardedalloc.h"
24 
25 #include "BLI_math.h"
26 #include "BLI_utildefines.h"
27 #include "BLI_utildefines_stack.h"
28 
29 #include "bmesh.h"
30 #include "bmesh_tools.h"
31 
32 #include "intern/bmesh_operators_private.h" /* own include */
33 
34 #define ELE_NEW 1
35 #define ELE_CUT 2
36 #define ELE_INPUT 4
37 
39 {
40  const float dist = BMO_slot_float_get(op->slots_in, "dist");
41  const bool use_snap_center = BMO_slot_bool_get(op->slots_in, "use_snap_center");
42  const bool clear_outer = BMO_slot_bool_get(op->slots_in, "clear_outer");
43  const bool clear_inner = BMO_slot_bool_get(op->slots_in, "clear_inner");
44 
45  float plane_co[3];
46  float plane_no[3];
47  float plane[4];
48 
49  BMO_slot_vec_get(op->slots_in, "plane_co", plane_co);
50  BMO_slot_vec_get(op->slots_in, "plane_no", plane_no);
51 
52  if (is_zero_v3(plane_no)) {
53  BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Zero normal given");
54  return;
55  }
56 
57  plane_from_point_normal_v3(plane, plane_co, plane_no);
58 
59  /* tag geometry to bisect */
62 
64 
65  BM_mesh_bisect_plane(bm, plane, use_snap_center, true, ELE_CUT, ELE_NEW, dist);
66 
67  if (clear_outer || clear_inner) {
68  /* Use an array of vertices because 'geom' contains both verts and edges that may use them.
69  * Removing a vert may remove and edge which is later checked by #BMO_ITER.
70  * over-allocate the total possible vert count. */
71  const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_count(op->slots_in, "geom"));
72  BMVert **vert_arr = MEM_mallocN(sizeof(*vert_arr) * (size_t)vert_arr_max, __func__);
73  BMOIter siter;
74  BMVert *v;
75  float plane_inner[4];
76  float plane_outer[4];
77 
78  STACK_DECLARE(vert_arr);
79 
80  copy_v3_v3(plane_outer, plane);
81  copy_v3_v3(plane_inner, plane);
82  plane_outer[3] = plane[3] - dist;
83  plane_inner[3] = plane[3] + dist;
84 
85  STACK_INIT(vert_arr, vert_arr_max);
86 
87  BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
88  if ((clear_outer && plane_point_side_v3(plane_outer, v->co) > 0.0f) ||
89  (clear_inner && plane_point_side_v3(plane_inner, v->co) < 0.0f)) {
90  STACK_PUSH(vert_arr, v);
91  }
92  }
93 
94  while ((v = STACK_POP(vert_arr))) {
95  BM_vert_kill(bm, v);
96  }
97 
98  MEM_freeN(vert_arr);
99  }
100 
102  bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW | ELE_INPUT);
104  bm, op, op->slots_out, "geom_cut.out", BM_VERT | BM_EDGE, ELE_CUT);
105 }
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:243
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, tot)
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:1002
@ BMERR_MESH_ERROR
Definition: bmesh_error.h:61
void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
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_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_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const short oflag)
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)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
int BMO_slot_buffer_count(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, const char htype, const short oflag)
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:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:99
int totvert
Definition: bmesh_class.h:297