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