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