Blender V4.3
bmesh_separate.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <climits>
13
14#include "MEM_guardedalloc.h"
15
16#include "BLI_buffer.h"
17#include "BLI_utildefines.h"
18
19#include "bmesh.hh"
20#include "bmesh_separate.hh" /* own include */
22
23void BM_mesh_separate_faces(BMesh *bm, BMFaceFilterFunc filter_fn, void *user_data)
24{
25 BMFace **faces_array_all = static_cast<BMFace **>(
26 MEM_mallocN(bm->totface * sizeof(BMFace *), __func__));
27 /*
28 * - Create an array of faces based on 'filter_fn'.
29 * First part of array for match, for non-match.
30 *
31 * - Enable all vertex tags, then clear all tagged vertices from 'faces_b'.
32 *
33 * - Loop over 'faces_a', checking each vertex,
34 * splitting out any which aren't tagged (and therefor shared), disabling tags as we go.
35 */
36
37 BMFace *f;
38 BMIter iter;
39
40 uint faces_a_len = 0;
41 uint faces_b_len = 0;
42 {
43 int i_a = 0;
44 int i_b = bm->totface;
45 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
46 faces_array_all[filter_fn(f, user_data) ? i_a++ : --i_b] = f;
47 }
48 faces_a_len = i_a;
49 faces_b_len = bm->totface - i_a;
50 }
51
52 BMFace **faces_a = faces_array_all;
53 BMFace **faces_b = faces_array_all + faces_a_len;
54
55 /* Enable for all. */
57
58 /* Disable vert tag on faces_b */
59 for (uint i = 0; i < faces_b_len; i++) {
60 BMLoop *l_iter, *l_first;
61 l_iter = l_first = BM_FACE_FIRST_LOOP(faces_b[i]);
62 do {
64 } while ((l_iter = l_iter->next) != l_first);
65 }
66
67 BLI_buffer_declare_static(BMLoop **, loop_split, 0, 128);
68
69 /* Check shared verts ('faces_a' tag and disable) */
70 for (uint i = 0; i < faces_a_len; i++) {
71 BMLoop *l_iter, *l_first;
72 l_iter = l_first = BM_FACE_FIRST_LOOP(faces_a[i]);
73 do {
74 if (!BM_elem_flag_test(l_iter->v, BM_ELEM_TAG)) {
75 BMVert *v = l_iter->v;
76 /* Enable, since we may visit this vertex again on other faces */
78
79 /* We know the vertex is shared, collect all vertices and split them off. */
80
81 /* Fill 'loop_split' */
82 {
83 BMEdge *e_first, *e_iter;
84 e_iter = e_first = l_iter->e;
85 do {
86 if (e_iter->l != nullptr) {
87 BMLoop *l_radial_first, *l_radial_iter;
88 l_radial_first = l_radial_iter = e_iter->l;
89 do {
90 if (l_radial_iter->v == v) {
91 if (filter_fn(l_radial_iter->f, user_data)) {
92 BLI_buffer_append(&loop_split, BMLoop *, l_radial_iter);
93 }
94 }
95 } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
96 }
97 } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
98 }
99
100 /* Perform the split */
101 BM_face_loop_separate_multi(bm, static_cast<BMLoop **>(loop_split.data), loop_split.count);
102
103 BLI_buffer_clear(&loop_split);
104 }
105 } while ((l_iter = l_iter->next) != l_first);
106 }
107
108 BLI_buffer_free(&loop_split);
109
110 MEM_freeN(faces_array_all);
111}
#define BLI_buffer_append(buffer_, type_, val_)
Definition BLI_buffer.h:52
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_)
Definition BLI_buffer.h:27
#define BLI_buffer_clear(buffer_)
Definition BLI_buffer.h:56
#define BLI_buffer_free(name_)
Definition BLI_buffer.h:96
unsigned int uint
Read Guarded memory(de)allocation.
bool(* BMFaceFilterFunc)(const BMFace *, void *user_data)
@ BM_ELEM_TAG
#define BM_FACE_FIRST_LOOP(p)
#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_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
BMVert * BM_face_loop_separate_multi(BMesh *bm, BMLoop **larr, int larr_len)
#define BM_VERT
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BM_mesh_separate_faces(BMesh *bm, BMFaceFilterFunc filter_fn, void *user_data)
BLI_INLINE BMEdge * bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
struct BMLoop * l
struct BMVert * v
struct BMEdge * e
struct BMLoop * radial_next
struct BMFace * f
struct BMLoop * next
int totface