Merged changes in the trunk up to revision 54802.
[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 struct Object;
43
44 /* note: it is very important for BMHeader to start with two
45  * pointers. this is a requirement of mempool's method of
46  * iteration.
47  *
48  * hrm. it doesn't but still works ok, remove the comment above? - campbell.
49  */
50
51 // #pragma GCC diagnostic error "-Wpadded"
52
53 /**
54  * BMHeader
55  *
56  * All mesh elements begin with a BMHeader. This structure
57  * hold several types of data
58  *
59  * 1: The type of the element (vert, edge, loop or face)
60  * 2: Persistent "header" flags/markings (smooth, seam, select, hidden, etc)
61  *     note that this is different from the "tool" flags.
62  * 3: Unique ID in the bmesh.
63  * 4: some elements for internal record keeping.
64  */
65 typedef struct BMHeader {
66         void *data; /* customdata layers */
67         int index; /* notes:
68                     * - Use BM_elem_index_get/set macros for index
69                     * - Unitialized to -1 so we can easily tell its not set.
70                     * - Used for edge/vert/face, check BMesh.elem_index_dirty for valid index values,
71                     *   this is abused by various tools which set it dirty.
72                     * - For loops this is used for sorting during tessellation. */
73
74         char htype;    /* element geometric type (verts/edges/loops/faces) */
75         char hflag;    /* this would be a CD layer, see below */
76
77         /* internal use only!
78          * note,.we are very picky about not bloating this struct
79          * but in this case its padded up to 16 bytes anyway,
80          * so adding a flag here gives no increase in size */
81         char api_flag;
82 //      char _pad;
83 } BMHeader;
84
85 BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
86
87 /* note: need some way to specify custom locations for custom data layers.  so we can
88  * make them point directly into structs.  and some way to make it only happen to the
89  * active layer, and properly update when switching active layers.*/
90
91 typedef struct BMVert {
92         BMHeader head;
93         struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
94
95         float co[3];
96         float no[3];
97         struct BMEdge *e;
98 } BMVert;
99
100 /* disk link structure, only used by edges */
101 typedef struct BMDiskLink {
102         struct BMEdge *next, *prev;
103 } BMDiskLink;
104
105 typedef struct BMEdge {
106         BMHeader head;
107         struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
108
109         struct BMVert *v1, *v2;
110         struct BMLoop *l;
111         
112         /* disk cycle pointers */
113         BMDiskLink v1_disk_link, v2_disk_link;
114 } BMEdge;
115
116 typedef struct BMLoop {
117         BMHeader head;
118         /* notice no flags layer */
119
120         struct BMVert *v;
121         struct BMEdge *e; /* edge, using verts (v, next->v) */
122         struct BMFace *f;
123
124         /* circular linked list of loops which all use the same edge as this one '->e',
125          * but not necessarily the same vertex (can be either v1 or v2 of our own '->e') */
126         struct BMLoop *radial_next, *radial_prev;
127
128         /* these were originally commented as private but are used all over the code */
129         /* can't use ListBase API, due to head */
130         struct BMLoop *next, *prev; /* next/prev verts around the face */
131 } BMLoop;
132
133 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
134 typedef struct BMElemF {
135         BMHeader head;
136
137         /* keep directly after header,
138          * optional array of flags, only used by the operator stack */
139         struct BMFlagLayer *oflags;
140 } BMElemF;
141
142 /* can cast anything to this, including BMLoop */
143 typedef struct BMElem {
144         BMHeader head;
145 } BMElem;
146
147 #ifdef USE_BMESH_HOLES
148 /* eventually, this structure will be used for supporting holes in faces */
149 typedef struct BMLoopList {
150         struct BMLoopList *next, *prev;
151         struct BMLoop *first, *last;
152 } BMLoopList;
153 #endif
154
155 typedef struct BMFace {
156         BMHeader head;
157         struct BMFlagLayer *oflags; /* an array of flags, mostly used by the operator stack */
158
159 #ifdef USE_BMESH_HOLES
160         int totbounds; /*total boundaries, is one plus the number of holes in the face*/
161         ListBase loops;
162 #else
163         BMLoop *l_first;
164 #endif
165         int   len;   /* includes all boundary loops */
166         float no[3]; /* yes, we do store this here */
167         short mat_nr;
168 //      short _pad[3];
169 } BMFace;
170
171 typedef struct BMFlagLayer {
172         short f; /* flags */
173 } BMFlagLayer;
174
175 // #pragma GCC diagnostic ignored "-Wpadded"
176
177 typedef struct BMesh {
178         int totvert, totedge, totloop, totface;
179         int totvertsel, totedgesel, totfacesel;
180
181         /* flag index arrays as being dirty so we can check if they are clean and
182          * avoid looping over the entire vert/edge/face array in those cases.
183          * valid flags are - BM_VERT | BM_EDGE | BM_FACE.
184          * BM_LOOP isn't handled so far. */
185         char elem_index_dirty;
186
187         /* element pools */
188         struct BLI_mempool *vpool, *epool, *lpool, *fpool;
189
190         /* operator api stuff (must be all NULL or all alloc'd) */
191         struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
192
193         int stackdepth;
194         struct BMOperator *currentop;
195         
196         CustomData vdata, edata, ldata, pdata;
197
198 #ifdef USE_BMESH_HOLES
199         struct BLI_mempool *looplistpool;
200 #endif
201
202         /* should be copy of scene select mode */
203         /* stored in BMEditMesh too, this is a bit confusing,
204          * make sure they're in sync!
205          * Only use when the edit mesh cant be accessed - campbell */
206         short selectmode;
207         
208         /* ID of the shape key this bmesh came from */
209         int shapenr;
210         
211         int walkers, totflags;
212         ListBase selected, error_stack;
213
214         BMFace *act_face;
215
216         ListBase errorstack;
217
218         void *py_handle;
219 } BMesh;
220
221 /* BMHeader->htype (char) */
222 enum {
223         BM_VERT = 1,
224         BM_EDGE = 2,
225         BM_LOOP = 4,
226         BM_FACE = 8
227 };
228
229 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
230 #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
231
232 /* BMHeader->hflag (char) */
233 enum {
234         BM_ELEM_SELECT  = (1 << 0),
235         BM_ELEM_HIDDEN  = (1 << 1),
236         BM_ELEM_SEAM    = (1 << 2),
237         BM_ELEM_SMOOTH  = (1 << 3), /* used for faces and edges, note from the user POV,
238                                  * this is a sharp edge when disabled */
239
240         BM_ELEM_TAG     = (1 << 4), /* internal flag, used for ensuring correct normals
241                                  * during multires interpolation, and any other time
242                                  * when temp tagging is handy.
243                                  * always assume dirty & clear before use. */
244
245         BM_ELEM_DRAW    = (1 << 5), /* edge display */
246
247         /* spare tag, assumed dirty, use define in each function to name based on use */
248         // _BM_ELEM_TAG_ALT = (1 << 6),  // UNUSED
249 #ifdef WITH_FREESTYLE
250         BM_ELEM_FREESTYLE = (1 << 6), /* used for Freestyle faces and edges */
251 #endif
252
253         BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging,
254                                      * since tools may want to tag verts and
255                                      * not have functions clobber them */
256 };
257
258 /* defines */
259 #define BM_ELEM_CD_GET_VOID_P(ele, offset) \
260         (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
261
262 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
263         { assert(offset != -1); *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
264
265 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
266         (assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
267
268 #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
269         (assert(offset != -1), (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
270
271 /*forward declarations*/
272
273 #ifdef USE_BMESH_HOLES
274 #  define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
275 #else
276 #  define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
277 #endif
278
279 /**
280  * size to use for stack arrays when dealing with NGons,
281  * alloc after this limit is reached.
282  * this value is rather arbitrary */
283 #define BM_DEFAULT_NGON_STACK_SIZE 32
284 /**
285  * size to use for stack arrays dealing with connected mesh data
286  * verts of faces, edges of vert - etc.
287  * often used with #BM_iter_as_arrayN() */
288 #define BM_DEFAULT_ITER_STACK_SIZE 16
289
290 /* avoid inf loop, this value is arbitrary
291  * but should not error on valid cases */
292 #define BM_LOOP_RADIAL_MAX 10000
293 #define BM_NGON_MAX 100000
294 #define BM_OMP_LIMIT 10000  /* setting zero so we can catch bugs in OpenMP/BMesh */
295
296 #endif /* __BMESH_CLASS_H__ */