doxygen: add newline after \file
[blender.git] / source / blender / bmesh / intern / bmesh_iterators_inline.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 /** \file
18  * \ingroup bmesh
19  *
20  * BMesh inline iterator functions.
21  */
22
23 #ifndef __BMESH_ITERATORS_INLINE_H__
24 #define __BMESH_ITERATORS_INLINE_H__
25
26 /* inline here optimizes out the switch statement when called with
27  * constant values (which is very common), nicer for loop-in-loop situations */
28
29 /**
30  * \brief Iterator Step
31  *
32  * Calls an iterators step function to return the next element.
33  */
34 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
35 BLI_INLINE void *BM_iter_step(BMIter *iter)
36 {
37         return iter->step(iter);
38 }
39
40
41 /**
42  * \brief Iterator Init
43  *
44  * Takes a bmesh iterator structure and fills
45  * it with the appropriate function pointers based
46  * upon its type.
47  */
48 ATTR_NONNULL(1)
49 BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
50 {
51         /* int argtype; */
52         iter->itype = itype;
53
54         /* inlining optimizes out this switch when called with the defined type */
55         switch ((BMIterType)itype) {
56                 case BM_VERTS_OF_MESH:
57                         BLI_assert(bm != NULL);
58                         BLI_assert(data == NULL);
59                         iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
60                         iter->step  = (BMIter__step_cb)bmiter__elem_of_mesh_step;
61                         iter->data.elem_of_mesh.pooliter.pool = bm->vpool;
62                         break;
63                 case BM_EDGES_OF_MESH:
64                         BLI_assert(bm != NULL);
65                         BLI_assert(data == NULL);
66                         iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
67                         iter->step  = (BMIter__step_cb)bmiter__elem_of_mesh_step;
68                         iter->data.elem_of_mesh.pooliter.pool = bm->epool;
69                         break;
70                 case BM_FACES_OF_MESH:
71                         BLI_assert(bm != NULL);
72                         BLI_assert(data == NULL);
73                         iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
74                         iter->step  = (BMIter__step_cb)bmiter__elem_of_mesh_step;
75                         iter->data.elem_of_mesh.pooliter.pool = bm->fpool;
76                         break;
77                 case BM_EDGES_OF_VERT:
78                         BLI_assert(data != NULL);
79                         BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
80                         iter->begin = (BMIter__begin_cb)bmiter__edge_of_vert_begin;
81                         iter->step  = (BMIter__step_cb)bmiter__edge_of_vert_step;
82                         iter->data.edge_of_vert.vdata = (BMVert *)data;
83                         break;
84                 case BM_FACES_OF_VERT:
85                         BLI_assert(data != NULL);
86                         BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
87                         iter->begin = (BMIter__begin_cb)bmiter__face_of_vert_begin;
88                         iter->step  = (BMIter__step_cb)bmiter__face_of_vert_step;
89                         iter->data.face_of_vert.vdata = (BMVert *)data;
90                         break;
91                 case BM_LOOPS_OF_VERT:
92                         BLI_assert(data != NULL);
93                         BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
94                         iter->begin = (BMIter__begin_cb)bmiter__loop_of_vert_begin;
95                         iter->step  = (BMIter__step_cb)bmiter__loop_of_vert_step;
96                         iter->data.loop_of_vert.vdata = (BMVert *)data;
97                         break;
98                 case BM_VERTS_OF_EDGE:
99                         BLI_assert(data != NULL);
100                         BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
101                         iter->begin = (BMIter__begin_cb)bmiter__vert_of_edge_begin;
102                         iter->step  = (BMIter__step_cb)bmiter__vert_of_edge_step;
103                         iter->data.vert_of_edge.edata = (BMEdge *)data;
104                         break;
105                 case BM_FACES_OF_EDGE:
106                         BLI_assert(data != NULL);
107                         BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
108                         iter->begin = (BMIter__begin_cb)bmiter__face_of_edge_begin;
109                         iter->step  = (BMIter__step_cb)bmiter__face_of_edge_step;
110                         iter->data.face_of_edge.edata = (BMEdge *)data;
111                         break;
112                 case BM_VERTS_OF_FACE:
113                         BLI_assert(data != NULL);
114                         BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
115                         iter->begin = (BMIter__begin_cb)bmiter__vert_of_face_begin;
116                         iter->step  = (BMIter__step_cb)bmiter__vert_of_face_step;
117                         iter->data.vert_of_face.pdata = (BMFace *)data;
118                         break;
119                 case BM_EDGES_OF_FACE:
120                         BLI_assert(data != NULL);
121                         BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
122                         iter->begin = (BMIter__begin_cb)bmiter__edge_of_face_begin;
123                         iter->step  = (BMIter__step_cb)bmiter__edge_of_face_step;
124                         iter->data.edge_of_face.pdata = (BMFace *)data;
125                         break;
126                 case BM_LOOPS_OF_FACE:
127                         BLI_assert(data != NULL);
128                         BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
129                         iter->begin = (BMIter__begin_cb)bmiter__loop_of_face_begin;
130                         iter->step  = (BMIter__step_cb)bmiter__loop_of_face_step;
131                         iter->data.loop_of_face.pdata = (BMFace *)data;
132                         break;
133                 case BM_LOOPS_OF_LOOP:
134                         BLI_assert(data != NULL);
135                         BLI_assert(((BMElem *)data)->head.htype == BM_LOOP);
136                         iter->begin = (BMIter__begin_cb)bmiter__loop_of_loop_begin;
137                         iter->step  = (BMIter__step_cb)bmiter__loop_of_loop_step;
138                         iter->data.loop_of_loop.ldata = (BMLoop *)data;
139                         break;
140                 case BM_LOOPS_OF_EDGE:
141                         BLI_assert(data != NULL);
142                         BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
143                         iter->begin = (BMIter__begin_cb)bmiter__loop_of_edge_begin;
144                         iter->step  = (BMIter__step_cb)bmiter__loop_of_edge_step;
145                         iter->data.loop_of_edge.edata = (BMEdge *)data;
146                         break;
147                 default:
148                         /* should never happen */
149                         BLI_assert(0);
150                         return false;
151                         break;
152         }
153
154         iter->begin(iter);
155
156         return true;
157 }
158
159 /**
160  * \brief Iterator New
161  *
162  * Takes a bmesh iterator structure and fills
163  * it with the appropriate function pointers based
164  * upon its type and then calls BMeshIter_step()
165  * to return the first element of the iterator.
166  */
167 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
168 BLI_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data)
169 {
170         if (LIKELY(BM_iter_init(iter, bm, itype, data))) {
171                 return BM_iter_step(iter);
172         }
173         else {
174                 return NULL;
175         }
176 }
177
178 /**
179  * \brief Parallel (threaded) iterator, only available for most basic itertypes (verts/edges/faces of mesh).
180  *
181  * Uses BLI_task_parallel_mempool to iterate over all items of underlying matching mempool.
182  *
183  * \note You have to include BLI_task.h before BMesh includes to be able to use this function!
184  */
185
186 #ifdef __BLI_TASK_H__
187
188 ATTR_NONNULL(1)
189 BLI_INLINE void BM_iter_parallel(
190         BMesh *bm, const char itype, TaskParallelMempoolFunc func, void *userdata, const bool use_threading)
191 {
192         /* inlining optimizes out this switch when called with the defined type */
193         switch ((BMIterType)itype) {
194                 case BM_VERTS_OF_MESH:
195                         BLI_task_parallel_mempool(bm->vpool, userdata, func, use_threading);
196                         break;
197                 case BM_EDGES_OF_MESH:
198                         BLI_task_parallel_mempool(bm->epool, userdata, func, use_threading);
199                         break;
200                 case BM_FACES_OF_MESH:
201                         BLI_task_parallel_mempool(bm->fpool, userdata, func, use_threading);
202                         break;
203                 default:
204                         /* should never happen */
205                         BLI_assert(0);
206                         break;
207         }
208 }
209
210 #endif  /* __BLI_TASK_H__ */
211
212 #endif /* __BMESH_ITERATORS_INLINE_H__ */