workaround for loopselect-slide (with multicut enabled) changing from vertex-select...
[blender-staging.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                     * - Unitialized to -1 so we can easily tell its not set.
69                     * - Used for edge/vert/face, 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         struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
93
94         float co[3];
95         float no[3];
96         struct BMEdge *e;
97 } BMVert;
98
99 /* disk link structure, only used by edges */
100 typedef struct BMDiskLink {
101         struct BMEdge *next, *prev;
102 } BMDiskLink;
103
104 typedef struct BMEdge {
105         BMHeader head;
106         struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
107
108         struct BMVert *v1, *v2;
109         struct BMLoop *l;
110         
111         /* disk cycle pointers */
112         BMDiskLink v1_disk_link, v2_disk_link;
113 } BMEdge;
114
115 typedef struct BMLoop {
116         BMHeader head;
117         /* notice no flags layer */
118
119         struct BMVert *v;
120         struct BMEdge *e; /* edge, using verts (v, next->v) */
121         struct BMFace *f;
122
123         /* circular linked list of loops which all use the same edge as this one '->e',
124          * but not necessarily the same vertex (can be either v1 or v2 of our own '->e') */
125         struct BMLoop *radial_next, *radial_prev;
126
127         /* these were originally commented as private but are used all over the code */
128         /* can't use ListBase API, due to head */
129         struct BMLoop *next, *prev; /* next/prev verts around the face */
130 } BMLoop;
131
132 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
133 typedef struct BMElemF {
134         BMHeader head;
135
136         /* keep directly after header,
137          * optional array of flags, only used by the operator stack */
138         struct BMFlagLayer *oflags;
139 } BMElemF;
140
141 /* can cast anything to this, including BMLoop */
142 typedef struct BMElem {
143         BMHeader head;
144 } BMElem;
145
146 #ifdef USE_BMESH_HOLES
147 /* eventually, this structure will be used for supporting holes in faces */
148 typedef struct BMLoopList {
149         struct BMLoopList *next, *prev;
150         struct BMLoop *first, *last;
151 } BMLoopList;
152 #endif
153
154 typedef struct BMFace {
155         BMHeader head;
156         struct BMFlagLayer *oflags; /* an array of flags, mostly used by the operator stack */
157
158 #ifdef USE_BMESH_HOLES
159         int totbounds; /*total boundaries, is one plus the number of holes in the face*/
160         ListBase loops;
161 #else
162         BMLoop *l_first;
163 #endif
164         int   len;   /* includes all boundary loops */
165         float no[3]; /* yes, we do store this here */
166         short mat_nr;
167 //      short _pad[3];
168 } BMFace;
169
170 typedef struct BMFlagLayer {
171         short f; /* flags */
172 } BMFlagLayer;
173
174 // #pragma GCC diagnostic ignored "-Wpadded"
175
176 typedef struct BMesh {
177         int totvert, totedge, totloop, totface;
178         int totvertsel, totedgesel, totfacesel;
179
180         /* flag index arrays as being dirty so we can check if they are clean and
181          * avoid looping over the entire vert/edge/face array in those cases.
182          * valid flags are - BM_VERT | BM_EDGE | BM_FACE.
183          * BM_LOOP isn't handled so far. */
184         char elem_index_dirty;
185
186         /* element pools */
187         struct BLI_mempool *vpool, *epool, *lpool, *fpool;
188
189         /* operator api stuff (must be all NULL or all alloc'd) */
190         struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
191
192         int stackdepth;
193         struct BMOperator *currentop;
194         
195         CustomData vdata, edata, ldata, pdata;
196
197 #ifdef USE_BMESH_HOLES
198         struct BLI_mempool *looplistpool;
199 #endif
200
201         /* should be copy of scene select mode */
202         /* stored in BMEditMesh too, this is a bit confusing,
203          * make sure they're in sync!
204          * Only use when the edit mesh cant be accessed - campbell */
205         short selectmode;
206         
207         /* ID of the shape key this bmesh came from */
208         int shapenr;
209         
210         int walkers, totflags;
211         ListBase selected, error_stack;
212
213         BMFace *act_face;
214
215         ListBase errorstack;
216
217         void *py_handle;
218 } BMesh;
219
220 /* BMHeader->htype (char) */
221 enum {
222         BM_VERT = 1,
223         BM_EDGE = 2,
224         BM_LOOP = 4,
225         BM_FACE = 8
226 };
227
228 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
229 #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
230
231 /* BMHeader->hflag (char) */
232 enum {
233         BM_ELEM_SELECT  = (1 << 0),
234         BM_ELEM_HIDDEN  = (1 << 1),
235         BM_ELEM_SEAM    = (1 << 2),
236         BM_ELEM_SMOOTH  = (1 << 3), /* used for faces and edges, note from the user POV,
237                                  * this is a sharp edge when disabled */
238
239         BM_ELEM_TAG     = (1 << 4), /* internal flag, used for ensuring correct normals
240                                  * during multires interpolation, and any other time
241                                  * when temp tagging is handy.
242                                  * always assume dirty & clear before use. */
243
244         BM_ELEM_DRAW    = (1 << 5), /* edge display */
245
246         /* spare tag, assumed dirty, use define in each function to name based on use */
247         // _BM_ELEM_TAG_ALT = (1 << 6),  // UNUSED
248
249         BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging,
250                                      * since tools may want to tag verts and
251                                      * not have functions clobber them */
252 };
253
254 struct BPy_BMGeneric;
255 extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
256
257 /* defines */
258 #define BM_ELEM_CD_GET_VOID_P(ele, offset) \
259         (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
260
261 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
262         { assert(offset != -1); *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
263
264 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
265         (assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
266
267 #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
268         (assert(offset != -1), (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
269
270 /*forward declarations*/
271
272 #ifdef USE_BMESH_HOLES
273 #  define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
274 #else
275 #  define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
276 #endif
277
278 /**
279  * size to use for stack arrays when dealing with NGons,
280  * alloc after this limit is reached.
281  * this value is rather arbitrary */
282 #define BM_DEFAULT_NGON_STACK_SIZE 32
283 /**
284  * size to use for stack arrays dealing with connected mesh data
285  * verts of faces, edges of vert - etc.
286  * often used with #BM_iter_as_arrayN() */
287 #define BM_DEFAULT_ITER_STACK_SIZE 16
288
289 /* avoid inf loop, this value is arbitrary
290  * but should not error on valid cases */
291 #define BM_LOOP_RADIAL_MAX 10000
292 #define BM_NGON_MAX 100000
293 #define BM_OMP_LIMIT 10000  /* setting zero so we can catch bugs in OpenMP/BMesh */
294
295 #endif /* __BMESH_CLASS_H__ */