Blender V5.0
bmesh_delete.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2007 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "bmesh.hh"
12
13/* BMO functions */
14
15/* -------------------------------------------------------------------- */
18
23static void bmo_remove_tagged_faces(BMesh *bm, const short oflag)
24{
25 BMFace *f, *f_next;
26 BMIter iter;
27
28 BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
29 if (BMO_face_flag_test(bm, f, oflag)) {
30 BM_face_kill(bm, f);
31 }
32 }
33}
34
35static void bmo_remove_tagged_edges(BMesh *bm, const short oflag)
36{
37 BMEdge *e, *e_next;
38 BMIter iter;
39
40 BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
43 }
44 }
45}
46
47static void bmo_remove_tagged_verts(BMesh *bm, const short oflag)
48{
49 BMVert *v, *v_next;
50 BMIter iter;
51
52 BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
55 }
56 }
57}
58
59static void bmo_remove_tagged_verts_loose(BMesh *bm, const short oflag)
60{
61 BMVert *v, *v_next;
62 BMIter iter;
63
64 BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
65 if (BMO_vert_flag_test(bm, v, oflag) && (v->e == nullptr)) {
67 }
68 }
69}
70
71void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype)
72{
73 if (htype & BM_FACE) {
75 }
76 if (htype & BM_EDGE) {
78 }
79 if (htype & BM_VERT) {
81 }
82}
83
85 const short oflag,
86 const int type,
87 blender::FunctionRef<void()> prepare_fn)
88{
89 BMEdge *e;
90
91 BMIter eiter;
92 BMIter fiter;
93
94 switch (type) {
95 case DEL_VERTS: {
96 if (prepare_fn) {
97 prepare_fn();
98 }
100 break;
101 }
102 case DEL_EDGES: {
103 /* flush down to vert */
104 BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
105 if (BMO_edge_flag_test(bm, e, oflag)) {
108 }
109 }
110 if (prepare_fn) {
111 prepare_fn();
112 }
115 break;
116 }
117 case DEL_EDGESFACES: {
118 if (prepare_fn) {
119 prepare_fn();
120 }
122 break;
123 }
124 case DEL_ONLYFACES: {
125 if (prepare_fn) {
126 prepare_fn();
127 }
129 break;
130 }
131 case DEL_ONLYTAGGED: {
132 if (prepare_fn) {
133 prepare_fn();
134 }
136 break;
137 }
138 case DEL_FACES:
140 /* go through and mark all edges and all verts of all faces for delete */
141 BMFace *f;
142 BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
143 if (BMO_face_flag_test(bm, f, oflag)) {
144 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
145 BMLoop *l_iter;
146
147 l_iter = l_first;
148 do {
149 BMO_vert_flag_enable(bm, l_iter->v, oflag);
150 BMO_edge_flag_enable(bm, l_iter->e, oflag);
151 } while ((l_iter = l_iter->next) != l_first);
152 }
153 }
154 /* now go through and mark all remaining faces all edges for keeping */
155 BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
156 if (!BMO_face_flag_test(bm, f, oflag)) {
157 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
158 BMLoop *l_iter;
159
160 l_iter = l_first;
161 do {
162 BMO_vert_flag_disable(bm, l_iter->v, oflag);
163 BMO_edge_flag_disable(bm, l_iter->e, oflag);
164 } while ((l_iter = l_iter->next) != l_first);
165 }
166 }
167 /* also mark all the vertices of remaining edges for keeping */
168 BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
169
170 /* Only exception to normal 'DEL_FACES' logic. */
171 if (type == DEL_FACES_KEEP_BOUNDARY) {
172 if (BM_edge_is_boundary(e)) {
174 }
175 }
176
177 if (!BMO_edge_flag_test(bm, e, oflag)) {
180 }
181 }
182 if (prepare_fn) {
183 prepare_fn();
184 }
185
186 /* now delete marked face */
188 /* delete marked edge */
190 /* remove loose vertices */
192
193 break;
194 }
195 }
196}
197
199
200/* BM functions
201 *
202 * NOTE: this is just a duplicate of the code above (bad!)
203 * but for now keep in sync, its less hassle than having to create bmesh operator flags,
204 * each time we need to remove some geometry.
205 */
206
207/* -------------------------------------------------------------------- */
210
211static void bm_remove_tagged_faces(BMesh *bm, const char hflag)
212{
213 BMFace *f, *f_next;
214 BMIter iter;
215
216 BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
217 if (BM_elem_flag_test(f, hflag)) {
218 BM_face_kill(bm, f);
219 }
220 }
221}
222
223static void bm_remove_tagged_edges(BMesh *bm, const char hflag)
224{
225 BMEdge *e, *e_next;
226 BMIter iter;
227
228 BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
229 if (BM_elem_flag_test(e, hflag)) {
230 BM_edge_kill(bm, e);
231 }
232 }
233}
234
235static void bm_remove_tagged_verts(BMesh *bm, const char hflag)
236{
237 BMVert *v, *v_next;
238 BMIter iter;
239
240 BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
241 if (BM_elem_flag_test(v, hflag)) {
242 BM_vert_kill(bm, v);
243 }
244 }
245}
246
247static void bm_remove_tagged_verts_loose(BMesh *bm, const char hflag)
248{
249 BMVert *v, *v_next;
250 BMIter iter;
251
252 BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
253 if (BM_elem_flag_test(v, hflag) && (v->e == nullptr)) {
254 BM_vert_kill(bm, v);
255 }
256 }
257}
258
259void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype)
260{
261 if (htype & BM_FACE) {
263 }
264 if (htype & BM_EDGE) {
266 }
267 if (htype & BM_VERT) {
269 }
270}
271
272void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
273{
274
275 BMIter eiter;
276 BMIter fiter;
277
278 switch (type) {
279 case DEL_VERTS: {
281
282 break;
283 }
284 case DEL_EDGES: {
285 /* flush down to vert */
286 BMEdge *e;
287 BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
288 if (BM_elem_flag_test(e, hflag)) {
289 BM_elem_flag_enable(e->v1, hflag);
290 BM_elem_flag_enable(e->v2, hflag);
291 }
292 }
295
296 break;
297 }
298 case DEL_EDGESFACES: {
300
301 break;
302 }
303 case DEL_ONLYFACES: {
305
306 break;
307 }
308 case DEL_ONLYTAGGED: {
310
311 break;
312 }
313 case DEL_FACES: {
314 /* go through and mark all edges and all verts of all faces for delete */
315 BMFace *f;
316 BMEdge *e;
317 BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
318 if (BM_elem_flag_test(f, hflag)) {
319 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
320 BMLoop *l_iter;
321
322 l_iter = l_first;
323 do {
324 BM_elem_flag_enable(l_iter->v, hflag);
325 BM_elem_flag_enable(l_iter->e, hflag);
326 } while ((l_iter = l_iter->next) != l_first);
327 }
328 }
329 /* now go through and mark all remaining faces all edges for keeping */
330 BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
331 if (!BM_elem_flag_test(f, hflag)) {
332 BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
333 BMLoop *l_iter;
334
335 l_iter = l_first;
336 do {
337 BM_elem_flag_disable(l_iter->v, hflag);
338 BM_elem_flag_disable(l_iter->e, hflag);
339 } while ((l_iter = l_iter->next) != l_first);
340 }
341 }
342 /* also mark all the vertices of remaining edges for keeping */
343 BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
344 if (!BM_elem_flag_test(e, hflag)) {
345 BM_elem_flag_disable(e->v1, hflag);
346 BM_elem_flag_disable(e->v2, hflag);
347 }
348 }
349 /* now delete marked face */
351 /* delete marked edge */
353 /* remove loose vertices */
355
356 break;
357 }
358 }
359}
360
#define BM_ALL_NOLOOP
#define BM_FACE_FIRST_LOOP(p)
void BM_vert_kill(BMesh *bm, BMVert *v)
void BM_face_kill(BMesh *bm, BMFace *f)
void BM_edge_kill(BMesh *bm, BMEdge *e)
static void bm_remove_tagged_verts(BMesh *bm, const char hflag)
static void bmo_remove_tagged_edges(BMesh *bm, const short oflag)
static void bm_remove_tagged_edges(BMesh *bm, const char hflag)
void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype)
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype)
void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type, blender::FunctionRef< void()> prepare_fn)
static void bm_remove_tagged_verts_loose(BMesh *bm, const char hflag)
static void bmo_remove_tagged_faces(BMesh *bm, const short oflag)
static void bmo_remove_tagged_verts(BMesh *bm, const short oflag)
static void bm_remove_tagged_faces(BMesh *bm, const char hflag)
static void bmo_remove_tagged_verts_loose(BMesh *bm, const short oflag)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
#define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype)
BMesh * bm
#define BM_FACE
#define BM_EDGE
#define BM_VERT
@ DEL_ONLYTAGGED
@ DEL_FACES_KEEP_BOUNDARY
@ DEL_EDGESFACES
@ DEL_ONLYFACES
#define BMO_vert_flag_disable(bm, e, oflag)
#define BMO_edge_flag_test(bm, e, oflag)
#define BMO_edge_flag_enable(bm, e, oflag)
#define BMO_vert_flag_enable(bm, e, oflag)
#define BMO_vert_flag_test(bm, e, oflag)
#define BMO_edge_flag_disable(bm, e, oflag)
#define BMO_face_flag_test(bm, e, oflag)
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
struct BMVert * v
struct BMEdge * e
struct BMLoop * next