Blender V5.0
bmesh_iterators.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
10
21
22#include "BLI_bit_span.hh"
23#include "BLI_compiler_attrs.h"
24#include "BLI_mempool.h"
25
26#include "bmesh_class.hh"
28
29/* these iterator over all elements of a specific
30 * type in the mesh.
31 *
32 * be sure to keep 'bm_iter_itype_htype_map' in sync with any changes
33 */
38 /* these are topological iterators. */
42 BM_VERTS_OF_EDGE = 7, /* just v1, v2: added so py can use generalized sequencer wrapper */
47 /* returns elements from all boundaries, and returns
48 * the first element at the end to flag that we're entering
49 * a different face hole boundary. */
50 // BM_ALL_LOOPS_OF_FACE = 12,
51 /* iterate through loops around this loop, which are fetched
52 * from the other faces in the radial cycle surrounding the
53 * input loop's edge. */
56};
57
58#define BM_ITYPE_MAX 14
59
60/* the iterator htype for each iterator */
61extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
62
63/* -------------------------------------------------------------------- */
68
69#define BM_ITER_MESH(ele, iter, bm, itype) \
70 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); ele; \
71 BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
72
73#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \
74 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; ele; \
75 BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
76
77/* a version of BM_ITER_MESH which keeps the next item in storage
78 * so we can delete the current item, see bug #36923. */
79#ifndef NDEBUG
80# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
81 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
82 ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \
83 (void)(BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), \
84 1) : \
85 0; \
86 BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next)
87#else
88# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
89 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
90 ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \
91 ele = ele_next)
92#endif
93
94#define BM_ITER_ELEM(ele, iter, data, itype) \
95 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); ele; \
96 BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
97
98#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \
99 for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; \
100 BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
101
103
104/* iterator type structs */
149
150using BMIter__begin_cb = void (*)(void *);
151using BMIter__step_cb = void *(*)(void *);
152
153/* Iterator Structure */
154/* NOTE: some of these vars are not used,
155 * so they have been commented to save stack space since this struct is used all over */
179
183void *BM_iter_at_index(BMesh *bm, char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
190int BM_iter_as_array(BMesh *bm, char itype, void *data, void **array, int len);
202 char itype,
203 void *data,
204 int *r_len,
205 void **stack_array,
206 int stack_array_size) ATTR_WARN_UNUSED_RESULT;
213 const char *slot_name,
214 char restrictmask,
215 void **array,
216 int len);
218 const char *slot_name,
219 char restrictmask,
220 int *r_len,
221 /* optional args to avoid an alloc (normally stack array) */
222 void **stack_array,
223 int stack_array_size);
224
226 BMesh *bm,
228 bool (*test_fn)(BMElem *, void *user_data),
229 void *user_data);
235 bool (*test_fn)(BMFace *, void *user_data),
236 void *user_data);
237
243int BM_iter_elem_count_flag(char itype, void *data, char hflag, bool value);
249int BMO_iter_elem_count_flag(BMesh *bm, char itype, void *data, short oflag, bool value);
253int BM_iter_mesh_count(char itype, BMesh *bm);
259int BM_iter_mesh_count_flag(char itype, BMesh *bm, char hflag, bool value);
260
261/* private for bmesh_iterators_inline.c */
262
263#define BMITER_CB_DEF(name) \
264 struct BMIter__##name; \
265 void bmiter__##name##_begin(struct BMIter__##name *iter); \
266 void *bmiter__##name##_step(struct BMIter__##name *iter)
267
268BMITER_CB_DEF(elem_of_mesh);
269BMITER_CB_DEF(edge_of_vert);
270BMITER_CB_DEF(face_of_vert);
271BMITER_CB_DEF(loop_of_vert);
272BMITER_CB_DEF(loop_of_edge);
273BMITER_CB_DEF(loop_of_loop);
274BMITER_CB_DEF(face_of_edge);
275BMITER_CB_DEF(vert_of_edge);
276BMITER_CB_DEF(vert_of_face);
277BMITER_CB_DEF(edge_of_face);
278BMITER_CB_DEF(loop_of_face);
279
280#undef BMITER_CB_DEF
281
282#include "intern/bmesh_iterators_inline.hh" /* IWYU pragma: export */
283
284#define BM_ITER_CHECK_TYPE_DATA(data) \
285 CHECK_TYPE_ANY(data, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *)
286
287#define BM_iter_new(iter, bm, itype, data) \
288 (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
289#define BM_iter_init(iter, bm, itype, data) \
290 (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
#define ATTR_WARN_UNUSED_RESULT
const char bm_iter_itype_htype_map[BM_ITYPE_MAX]
int BM_iter_mesh_count_flag(char itype, BMesh *bm, char hflag, bool value)
Mesh Iter Flag Count.
int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char restrictmask, void **array, int len)
Operator Iterator as Array.
int BMO_iter_elem_count_flag(BMesh *bm, char itype, void *data, short oflag, bool value)
Elem Iter Tool Flag Count.
int BM_iter_mesh_bitmap_from_filter(char itype, BMesh *bm, blender::MutableBitSpan bitmap, bool(*test_fn)(BMElem *, void *user_data), void *user_data)
void(*)(void *) BMIter__begin_cb
int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm, blender::MutableBitSpan bitmap, bool(*test_fn)(BMFace *, void *user_data), void *user_data)
BMIterType
BMesh Iterators.
@ BM_LOOPS_OF_LOOP
@ BM_FACES_OF_EDGE
@ BM_FACES_OF_VERT
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_VERTS_OF_EDGE
@ BM_VERTS_OF_FACE
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_VERT
@ BM_LOOPS_OF_EDGE
@ BM_EDGES_OF_VERT
@ BM_EDGES_OF_FACE
@ BM_LOOPS_OF_FACE
int BM_iter_mesh_count(char itype, BMesh *bm)
void * BM_iter_as_arrayN(BMesh *bm, char itype, void *data, int *r_len, void **stack_array, int stack_array_size) ATTR_WARN_UNUSED_RESULT
Iterator as Array.
int BM_iter_as_array(BMesh *bm, char itype, void *data, void **array, int len)
Iterator as Array.
void * BM_iter_at_index(BMesh *bm, char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT
#define BMITER_CB_DEF(name)
void *(*)(void *) BMIter__step_cb
void * BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char restrictmask, int *r_len, void **stack_array, int stack_array_size)
#define BM_ITYPE_MAX
int BM_iter_elem_count_flag(char itype, void *data, char hflag, bool value)
Elem Iter Flag Count.
BMesh const char void * data
BMesh * bm
BMesh const char itype
#define BMO_OP_MAX_SLOTS
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
BLI_mempool_iter pooliter
BMIter__vert_of_edge vert_of_edge
BMIter__loop_of_vert loop_of_vert
BMIter__edge_of_face edge_of_face
BMIter__loop_of_edge loop_of_edge
BMIter__face_of_vert face_of_vert
BMIter__begin_cb begin
BMIter__loop_of_loop loop_of_loop
BMIter__vert_of_face vert_of_face
BMIter__edge_of_vert edge_of_vert
BMIter__step_cb step
BMIter__face_of_edge face_of_edge
BMIter__loop_of_face loop_of_face
BMIter__elem_of_mesh elem_of_mesh
uint len