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