doxygen: add newline after \file
[blender.git] / source / blender / bmesh / intern / bmesh_iterators.h
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
17 #ifndef __BMESH_ITERATORS_H__
18 #define __BMESH_ITERATORS_H__
19
20 /** \file
21  * \ingroup bmesh
22  */
23
24 /**
25  * \brief BMesh Iterators
26  *
27  * The functions and structures in this file
28  * provide a unified method for iterating over
29  * the elements of a mesh and answering simple
30  * adjacency queries. Tool authors should use
31  * the iterators provided in this file instead
32  * of inspecting the structure directly.
33  */
34
35 #include "BLI_compiler_attrs.h"
36 #include "BLI_mempool.h"
37
38 /* Defines for passing to BM_iter_new.
39  *
40  * "OF" can be substituted for "around"
41  * so BM_VERTS_OF_FACE means "vertices
42  * around a face."
43  */
44
45 /* these iterator over all elements of a specific
46  * type in the mesh.
47  *
48  * be sure to keep 'bm_iter_itype_htype_map' in sync with any changes
49  */
50 typedef enum BMIterType {
51         BM_VERTS_OF_MESH = 1,
52         BM_EDGES_OF_MESH = 2,
53         BM_FACES_OF_MESH = 3,
54         /* these are topological iterators. */
55         BM_EDGES_OF_VERT = 4,
56         BM_FACES_OF_VERT = 5,
57         BM_LOOPS_OF_VERT = 6,
58         BM_VERTS_OF_EDGE = 7, /* just v1, v2: added so py can use generalized sequencer wrapper */
59         BM_FACES_OF_EDGE = 8,
60         BM_VERTS_OF_FACE = 9,
61         BM_EDGES_OF_FACE = 10,
62         BM_LOOPS_OF_FACE = 11,
63         /* returns elements from all boundaries, and returns
64          * the first element at the end to flag that we're entering
65          * a different face hole boundary*/
66         // BM_ALL_LOOPS_OF_FACE = 12,
67         /* iterate through loops around this loop, which are fetched
68          * from the other faces in the radial cycle surrounding the
69          * input loop's edge.*/
70         BM_LOOPS_OF_LOOP = 12,
71         BM_LOOPS_OF_EDGE = 13,
72 } BMIterType;
73
74 #define BM_ITYPE_MAX 14
75
76 /* the iterator htype for each iterator */
77 extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
78
79 #define BM_ITER_MESH(ele, iter, bm, itype) \
80         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
81              ele; \
82              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
83
84 #define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \
85         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; \
86              ele; \
87              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
88
89 /* a version of BM_ITER_MESH which keeps the next item in storage
90  * so we can delete the current item, see bug [#36923] */
91 #ifdef DEBUG
92 #  define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
93         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
94              ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \
95                     (void)(ele_next = BM_iter_step(iter)), 1) : 0; \
96              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next)
97 #else
98 #  define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
99         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
100              ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \
101              ele = ele_next)
102 #endif
103
104
105 #define BM_ITER_ELEM(ele, iter, data, itype) \
106         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); \
107              ele; \
108              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
109
110 #define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \
111         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; \
112              ele; \
113              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
114
115 /* iterator type structs */
116 struct BMIter__elem_of_mesh {
117         BLI_mempool_iter pooliter;
118 };
119 struct BMIter__edge_of_vert {
120         BMVert *vdata;
121         BMEdge *e_first, *e_next;
122 };
123 struct BMIter__face_of_vert {
124         BMVert *vdata;
125         BMLoop *l_first, *l_next;
126         BMEdge *e_first, *e_next;
127 };
128 struct BMIter__loop_of_vert {
129         BMVert *vdata;
130         BMLoop *l_first, *l_next;
131         BMEdge *e_first, *e_next;
132 };
133 struct BMIter__loop_of_edge {
134         BMEdge *edata;
135         BMLoop *l_first, *l_next;
136 };
137 struct BMIter__loop_of_loop {
138         BMLoop *ldata;
139         BMLoop *l_first, *l_next;
140 };
141 struct BMIter__face_of_edge {
142         BMEdge *edata;
143         BMLoop *l_first, *l_next;
144 };
145 struct BMIter__vert_of_edge {
146         BMEdge *edata;
147 };
148 struct BMIter__vert_of_face {
149         BMFace *pdata;
150         BMLoop *l_first, *l_next;
151 };
152 struct BMIter__edge_of_face {
153         BMFace *pdata;
154         BMLoop *l_first, *l_next;
155 };
156 struct BMIter__loop_of_face {
157         BMFace *pdata;
158         BMLoop *l_first, *l_next;
159 };
160
161 typedef void  (*BMIter__begin_cb) (void *);
162 typedef void *(*BMIter__step_cb) (void *);
163
164 /* Iterator Structure */
165 /* note: some of these vars are not used,
166  * so they have been commented to save stack space since this struct is used all over */
167 typedef struct BMIter {
168         /* keep union first */
169         union {
170                 struct BMIter__elem_of_mesh elem_of_mesh;
171
172                 struct BMIter__edge_of_vert edge_of_vert;
173                 struct BMIter__face_of_vert face_of_vert;
174                 struct BMIter__loop_of_vert loop_of_vert;
175                 struct BMIter__loop_of_edge loop_of_edge;
176                 struct BMIter__loop_of_loop loop_of_loop;
177                 struct BMIter__face_of_edge face_of_edge;
178                 struct BMIter__vert_of_edge vert_of_edge;
179                 struct BMIter__vert_of_face vert_of_face;
180                 struct BMIter__edge_of_face edge_of_face;
181                 struct BMIter__loop_of_face loop_of_face;
182         } data;
183
184         BMIter__begin_cb begin;
185         BMIter__step_cb step;
186
187         int count;  /* note, only some iterators set this, don't rely on it */
188         char itype;
189 } BMIter;
190
191 void   *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
192 int     BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
193 void   *BM_iter_as_arrayN(
194         BMesh *bm, const char itype, void *data, int *r_len,
195         void **stack_array, int stack_array_size) ATTR_WARN_UNUSED_RESULT;
196 int     BMO_iter_as_array(
197         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
198         void **array, const int len);
199 void    *BMO_iter_as_arrayN(
200         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
201         int *r_len,
202         /* optional args to avoid an alloc (normally stack array) */
203         void **stack_array, int stack_array_size);
204
205 int BM_iter_mesh_bitmap_from_filter(
206         const char itype, BMesh *bm,
207         uint *bitmap,
208         bool (*test_fn)(BMElem *, void *user_data),
209         void *user_data);
210 int BM_iter_mesh_bitmap_from_filter_tessface(
211         BMesh *bm,
212         uint *bitmap,
213         bool (*test_fn)(BMFace *, void *user_data),
214         void *user_data);
215
216 int     BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
217 int     BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value);
218 int     BM_iter_mesh_count(const char itype, BMesh *bm);
219 int     BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
220
221 /* private for bmesh_iterators_inline.c */
222
223 #define BMITER_CB_DEF(name) \
224         struct BMIter__##name; \
225         void  bmiter__##name##_begin(struct BMIter__##name *iter); \
226         void *bmiter__##name##_step(struct BMIter__##name *iter)
227
228 BMITER_CB_DEF(elem_of_mesh);
229 BMITER_CB_DEF(edge_of_vert);
230 BMITER_CB_DEF(face_of_vert);
231 BMITER_CB_DEF(loop_of_vert);
232 BMITER_CB_DEF(loop_of_edge);
233 BMITER_CB_DEF(loop_of_loop);
234 BMITER_CB_DEF(face_of_edge);
235 BMITER_CB_DEF(vert_of_edge);
236 BMITER_CB_DEF(vert_of_face);
237 BMITER_CB_DEF(edge_of_face);
238 BMITER_CB_DEF(loop_of_face);
239
240 #undef BMITER_CB_DEF
241
242 #include "intern/bmesh_iterators_inline.h"
243
244 #define BM_ITER_CHECK_TYPE_DATA(data) \
245         CHECK_TYPE_ANY(data, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *)
246
247 #define BM_iter_new(iter, bm, itype, data) \
248         (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
249 #define BM_iter_init(iter, bm, itype, data) \
250         (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
251
252 #endif /* __BMESH_ITERATORS_H__ */