Cleanup: commas at the end of enums
[blender.git] / source / blender / bmesh / bmesh_class.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Geoffrey Bantle, Levi Schooley, Joseph Eagar.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #ifndef __BMESH_CLASS_H__
24 #define __BMESH_CLASS_H__
25
26 /** \file blender/bmesh/bmesh_class.h
27  *  \ingroup bmesh
28  */
29
30 /* bmesh data structures */
31
32 /* dissable holes for now, these are ifdef'd because they use more memory and cant be saved in DNA currently */
33 // #define USE_BMESH_HOLES
34
35 struct BMesh;
36 struct BMVert;
37 struct BMEdge;
38 struct BMLoop;
39 struct BMFace;
40
41 struct BLI_mempool;
42
43 /* note: it is very important for BMHeader to start with two
44  * pointers. this is a requirement of mempool's method of
45  * iteration.
46  *
47  * hrm. it doesn't but still works ok, remove the comment above? - campbell.
48  */
49
50 // #pragma GCC diagnostic error "-Wpadded"
51
52 /**
53  * BMHeader
54  *
55  * All mesh elements begin with a BMHeader. This structure
56  * hold several types of data
57  *
58  * 1: The type of the element (vert, edge, loop or face)
59  * 2: Persistent "header" flags/markings (smooth, seam, select, hidden, etc)
60  *     note that this is different from the "tool" flags.
61  * 3: Unique ID in the bmesh.
62  * 4: some elements for internal record keeping.
63  */
64 typedef struct BMHeader {
65         void *data; /* customdata layers */
66         int index; /* notes:
67                     * - Use BM_elem_index_get/set macros for index
68                     * - Uninitialized to -1 so we can easily tell its not set.
69                     * - Used for edge/vert/face/loop, check BMesh.elem_index_dirty for valid index values,
70                     *   this is abused by various tools which set it dirty.
71                     * - For loops this is used for sorting during tessellation. */
72
73         char htype;    /* element geometric type (verts/edges/loops/faces) */
74         char hflag;    /* this would be a CD layer, see below */
75
76         /* internal use only!
77          * note,.we are very picky about not bloating this struct
78          * but in this case its padded up to 16 bytes anyway,
79          * so adding a flag here gives no increase in size */
80         char api_flag;
81 //      char _pad;
82 } BMHeader;
83
84 BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
85
86 /* note: need some way to specify custom locations for custom data layers.  so we can
87  * make them point directly into structs.  and some way to make it only happen to the
88  * active layer, and properly update when switching active layers.*/
89
90 typedef struct BMVert {
91         BMHeader head;
92
93         float co[3];  /* vertex coordinates */
94         float no[3];  /* vertex normal */
95
96         /* pointer to (any) edge using this vertex (for disk cycles)
97          *
98          * note: some higher level functions set this to different edges that use this vertex,
99          *       which is a bit of an abuse of internal bmesh data but also works OK for now (use with care!).
100          */
101         struct BMEdge *e;
102 } BMVert;
103
104 typedef struct BMVert_OFlag {
105         BMVert base;
106         struct BMFlagLayer *oflags;
107 } BMVert_OFlag;
108
109 /* disk link structure, only used by edges */
110 typedef struct BMDiskLink {
111         struct BMEdge *next, *prev;
112 } BMDiskLink;
113
114 typedef struct BMEdge {
115         BMHeader head;
116
117         struct BMVert *v1, *v2;  /* vertices (unordered) */
118
119         /* the list of loops around the edge (use l->radial_prev/next)
120          * to access the other loops using the edge */
121         struct BMLoop *l;
122
123         /* disk cycle pointers
124          * relative data: d1 indicates indicates the next/prev edge around vertex v1 and d2 does the same for v2 */
125         BMDiskLink v1_disk_link, v2_disk_link;
126 } BMEdge;
127
128 typedef struct BMEdge_OFlag {
129         BMEdge base;
130         struct BMFlagLayer *oflags;
131 } BMEdge_OFlag;
132
133 typedef struct BMLoop {
134         BMHeader head;
135         /* notice no flags layer */
136
137         struct BMVert *v;
138         struct BMEdge *e; /* edge, using verts (v, next->v) */
139         struct BMFace *f;
140
141         /* circular linked list of loops which all use the same edge as this one '->e',
142          * but not necessarily the same vertex (can be either v1 or v2 of our own '->e') */
143         struct BMLoop *radial_next, *radial_prev;
144
145         /* these were originally commented as private but are used all over the code */
146         /* can't use ListBase API, due to head */
147         struct BMLoop *next, *prev; /* next/prev verts around the face */
148 } BMLoop;
149
150 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
151 typedef struct BMElemF {
152         BMHeader head;
153 } BMElemF;
154
155 /* can cast anything to this, including BMLoop */
156 typedef struct BMElem {
157         BMHeader head;
158 } BMElem;
159
160 #ifdef USE_BMESH_HOLES
161 /* eventually, this structure will be used for supporting holes in faces */
162 typedef struct BMLoopList {
163         struct BMLoopList *next, *prev;
164         struct BMLoop *first, *last;
165 } BMLoopList;
166 #endif
167
168 typedef struct BMFace {
169         BMHeader head;
170
171 #ifdef USE_BMESH_HOLES
172         int totbounds; /*total boundaries, is one plus the number of holes in the face*/
173         ListBase loops;
174 #else
175         BMLoop *l_first;
176 #endif
177         int   len;   /* number of vertices in the face */
178         float no[3];  /* face normal */
179         short mat_nr;  /* material index */
180 //      short _pad[3];
181 } BMFace;
182
183 typedef struct BMFace_OFlag {
184         BMFace base;
185         struct BMFlagLayer *oflags;
186 } BMFace_OFlag;
187
188 typedef struct BMFlagLayer {
189         short f; /* flags */
190 } BMFlagLayer;
191
192 // #pragma GCC diagnostic ignored "-Wpadded"
193
194 typedef struct BMesh {
195         int totvert, totedge, totloop, totface;
196         int totvertsel, totedgesel, totfacesel;
197
198         /* flag index arrays as being dirty so we can check if they are clean and
199          * avoid looping over the entire vert/edge/face/loop array in those cases.
200          * valid flags are - BM_VERT | BM_EDGE | BM_FACE | BM_LOOP. */
201         char elem_index_dirty;
202
203         /* flag array table as being dirty so we know when its safe to use it,
204          * or when it needs to be re-created */
205         char elem_table_dirty;
206
207
208         /* element pools */
209         struct BLI_mempool *vpool, *epool, *lpool, *fpool;
210
211         /* mempool lookup tables (optional)
212          * index tables, to map indices to elements via
213          * BM_mesh_elem_table_ensure and associated functions.  don't
214          * touch this or read it directly.\
215          * Use BM_mesh_elem_table_ensure(), BM_vert/edge/face_at_index() */
216         BMVert **vtable;
217         BMEdge **etable;
218         BMFace **ftable;
219
220         /* size of allocated tables */
221         int vtable_tot;
222         int etable_tot;
223         int ftable_tot;
224
225         /* operator api stuff (must be all NULL or all alloc'd) */
226         struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
227
228         uint use_toolflags : 1;
229
230         int toolflag_index;
231         struct BMOperator *currentop;
232
233         CustomData vdata, edata, ldata, pdata;
234
235 #ifdef USE_BMESH_HOLES
236         struct BLI_mempool *looplistpool;
237 #endif
238
239         /* should be copy of scene select mode */
240         /* stored in BMEditMesh too, this is a bit confusing,
241          * make sure they're in sync!
242          * Only use when the edit mesh cant be accessed - campbell */
243         short selectmode;
244
245         /* ID of the shape key this bmesh came from */
246         int shapenr;
247
248         int totflags;
249         ListBase selected;
250
251         BMFace *act_face;
252
253         ListBase errorstack;
254
255         void *py_handle;
256 } BMesh;
257
258 /* BMHeader->htype (char) */
259 enum {
260         BM_VERT = 1,
261         BM_EDGE = 2,
262         BM_LOOP = 4,
263         BM_FACE = 8,
264 };
265
266 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
267 #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
268
269 /* args for _Generic */
270 #define _BM_GENERIC_TYPE_ELEM_NONCONST \
271         void *, BMVert *, BMEdge *, BMLoop *, BMFace *, \
272         BMVert_OFlag *, BMEdge_OFlag *, BMFace_OFlag *, \
273         BMElem *, BMElemF *, BMHeader *
274
275 #define _BM_GENERIC_TYPE_ELEM_CONST \
276         const void *, const BMVert *, const BMEdge *, const BMLoop *, const BMFace *, \
277         const BMVert_OFlag *, const BMEdge_OFlag *, const BMFace_OFlag *, \
278         const BMElem *, const BMElemF *, const BMHeader *, \
279         void * const, BMVert * const, BMEdge * const, BMLoop * const, BMFace * const, \
280         BMElem * const, BMElemF * const, BMHeader * const
281
282 #define BM_CHECK_TYPE_ELEM_CONST(ele) \
283         CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPES_CONST)
284
285 #define BM_CHECK_TYPE_ELEM_NONCONST(ele) \
286         CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
287
288 #define BM_CHECK_TYPE_ELEM(ele) \
289         CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST, _BM_GENERIC_TYPE_ELEM_CONST)
290
291 /* vert */
292 #define _BM_GENERIC_TYPE_VERT_NONCONST BMVert *, BMVert_OFlag *
293 #define _BM_GENERIC_TYPE_VERT_CONST const BMVert *, const BMVert_OFlag *
294 #define BM_CHECK_TYPE_VERT_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_VERT_CONST)
295 #define BM_CHECK_TYPE_VERT_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
296 #define BM_CHECK_TYPE_VERT(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_VERT_NONCONST, _BM_GENERIC_TYPE_VERT_CONST)
297 /* edge */
298 #define _BM_GENERIC_TYPE_EDGE_NONCONST BMEdge *, BMEdge_OFlag *
299 #define _BM_GENERIC_TYPE_EDGE_CONST const BMEdge *, const BMEdge_OFlag *
300 #define BM_CHECK_TYPE_EDGE_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_EDGE_CONST)
301 #define BM_CHECK_TYPE_EDGE_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
302 #define BM_CHECK_TYPE_EDGE(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_EDGE_NONCONST, _BM_GENERIC_TYPE_EDGE_CONST)
303 /* face */
304 #define _BM_GENERIC_TYPE_FACE_NONCONST BMFace *, BMFace_OFlag *
305 #define _BM_GENERIC_TYPE_FACE_CONST const BMFace *, const BMFace_OFlag *
306 #define BM_CHECK_TYPE_FACE_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_FACE_CONST)
307 #define BM_CHECK_TYPE_FACE_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
308 #define BM_CHECK_TYPE_FACE(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_FACE_NONCONST, _BM_GENERIC_TYPE_FACE_CONST)
309
310
311
312 /* Assignment from a void* to a typed pointer is not allowed in C++,
313  * casting the LHS to void works fine though.
314  */
315 #ifdef __cplusplus
316 #define BM_CHECK_TYPE_ELEM_ASSIGN(ele) \
317         (BM_CHECK_TYPE_ELEM(ele)), *((void **)&ele)
318 #else
319 #define BM_CHECK_TYPE_ELEM_ASSIGN(ele) \
320         (BM_CHECK_TYPE_ELEM(ele)), ele
321 #endif
322
323 /* BMHeader->hflag (char) */
324 enum {
325         BM_ELEM_SELECT  = (1 << 0),
326         BM_ELEM_HIDDEN  = (1 << 1),
327         BM_ELEM_SEAM    = (1 << 2),
328         /**
329          * used for faces and edges, note from the user POV,
330          * this is a sharp edge when disabled */
331         BM_ELEM_SMOOTH  = (1 << 3),
332         /**
333          * internal flag, used for ensuring correct normals
334          * during multires interpolation, and any other time
335          * when temp tagging is handy.
336          * always assume dirty & clear before use. */
337         BM_ELEM_TAG     = (1 << 4),
338
339         BM_ELEM_DRAW    = (1 << 5), /* edge display */
340
341         /* spare tag, assumed dirty, use define in each function to name based on use */
342         // _BM_ELEM_TAG_ALT = (1 << 6),  // UNUSED
343         /**
344          * For low level internal API tagging,
345          * since tools may want to tag verts and not have functions clobber them.
346          * Leave cleared! */
347         BM_ELEM_INTERNAL_TAG = (1 << 7),
348 };
349
350 struct BPy_BMGeneric;
351 extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
352
353 typedef bool (*BMElemFilterFunc)(const BMElem *, void *user_data);
354 typedef bool (*BMVertFilterFunc)(const BMVert *, void *user_data);
355 typedef bool (*BMEdgeFilterFunc)(const BMEdge *, void *user_data);
356 typedef bool (*BMFaceFilterFunc)(const BMFace *, void *user_data);
357 typedef bool (*BMLoopFilterFunc)(const BMLoop *, void *user_data);
358
359 /* defines */
360 #define BM_ELEM_CD_SET_INT(ele, offset, f) { CHECK_TYPE_NONCONST(ele); \
361         assert(offset != -1); *((int *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
362
363 #define BM_ELEM_CD_GET_INT(ele, offset) \
364         (assert(offset != -1), *((int *)((char *)(ele)->head.data + (offset))))
365
366 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
367 #define BM_ELEM_CD_GET_VOID_P(ele, offset) \
368         (assert(offset != -1), \
369         _Generic(ele, \
370                 GENERIC_TYPE_ANY(              POINTER_OFFSET((ele)->head.data, offset), _BM_GENERIC_TYPE_ELEM_NONCONST), \
371                 GENERIC_TYPE_ANY((const void *)POINTER_OFFSET((ele)->head.data, offset), _BM_GENERIC_TYPE_ELEM_CONST)) \
372         )
373 #else
374 #define BM_ELEM_CD_GET_VOID_P(ele, offset) \
375         (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
376 #endif
377
378 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) { CHECK_TYPE_NONCONST(ele); \
379         assert(offset != -1); *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
380
381 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
382         (assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
383
384 #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
385         (assert(offset != -1), (uchar)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
386
387 /*forward declarations*/
388
389 #ifdef USE_BMESH_HOLES
390 #  define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
391 #else
392 #  define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
393 #endif
394
395 #define BM_DISK_EDGE_NEXT(e, v)  ( \
396         CHECK_TYPE_INLINE(e, BMEdge *), CHECK_TYPE_INLINE(v, BMVert *), \
397         BLI_assert(BM_vert_in_edge(e, v)), \
398         (((&e->v1_disk_link)[v == e->v2]).next))
399 #define BM_DISK_EDGE_PREV(e, v)  ( \
400         CHECK_TYPE_INLINE(e, BMEdge *), CHECK_TYPE_INLINE(v, BMVert *), \
401         BLI_assert(BM_vert_in_edge(e, v)), \
402         (((&e->v1_disk_link)[v == e->v2]).prev))
403
404 /**
405  * size to use for stack arrays when dealing with NGons,
406  * alloc after this limit is reached.
407  * this value is rather arbitrary */
408 #define BM_DEFAULT_NGON_STACK_SIZE 32
409 /**
410  * size to use for stack arrays dealing with connected mesh data
411  * verts of faces, edges of vert - etc.
412  * often used with #BM_iter_as_arrayN() */
413 #define BM_DEFAULT_ITER_STACK_SIZE 16
414
415 /* avoid inf loop, this value is arbitrary
416  * but should not error on valid cases */
417 #define BM_LOOP_RADIAL_MAX 10000
418 #define BM_NGON_MAX 100000
419
420 /* setting zero so we can catch bugs in OpenMP/BMesh */
421 #ifdef DEBUG
422 #  define BM_OMP_LIMIT 0
423 #else
424 #  define BM_OMP_LIMIT 10000
425 #endif
426
427 #endif /* __BMESH_CLASS_H__ */