2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * Contributor(s): Geoffrey Bantle, Levi Schooley, Joseph Eagar.
20 * ***** END GPL LICENSE BLOCK *****
23 #ifndef __BMESH_CLASS_H__
24 #define __BMESH_CLASS_H__
26 /** \file blender/bmesh/bmesh_class.h
30 /* bmesh data structures */
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
44 /* note: it is very important for BMHeader to start with two
45 * pointers. this is a requirement of mempool's method of
48 * hrm. it doesn't but still works ok, remove the comment above? - campbell.
51 // #pragma GCC diagnostic error "-Wpadded"
56 * All mesh elements begin with a BMHeader. This structure
57 * hold several types of data
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.
65 typedef struct BMHeader {
66 void *data; /* customdata layers */
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. */
74 char htype; /* element geometric type (verts/edges/loops/faces) */
75 char hflag; /* this would be a CD layer, see below */
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 */
85 BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
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.*/
91 typedef struct BMVert {
93 struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
100 /* disk link structure, only used by edges */
101 typedef struct BMDiskLink {
102 struct BMEdge *next, *prev;
105 typedef struct BMEdge {
107 struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
109 struct BMVert *v1, *v2;
112 /* disk cycle pointers */
113 BMDiskLink v1_disk_link, v2_disk_link;
116 typedef struct BMLoop {
118 /* notice no flags layer */
121 struct BMEdge *e; /* edge, using verts (v, next->v) */
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;
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 */
133 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
134 typedef struct BMElemF {
137 /* keep directly after header,
138 * optional array of flags, only used by the operator stack */
139 struct BMFlagLayer *oflags;
142 /* can cast anything to this, including BMLoop */
143 typedef struct BMElem {
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;
155 typedef struct BMFace {
157 struct BMFlagLayer *oflags; /* an array of flags, mostly used by the operator stack */
159 #ifdef USE_BMESH_HOLES
160 int totbounds; /*total boundaries, is one plus the number of holes in the face*/
165 int len; /* includes all boundary loops */
166 float no[3]; /* yes, we do store this here */
171 typedef struct BMFlagLayer {
175 // #pragma GCC diagnostic ignored "-Wpadded"
177 typedef struct BMesh {
178 int totvert, totedge, totloop, totface;
179 int totvertsel, totedgesel, totfacesel;
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;
188 struct BLI_mempool *vpool, *epool, *lpool, *fpool;
190 /* operator api stuff (must be all NULL or all alloc'd) */
191 struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
194 struct BMOperator *currentop;
196 CustomData vdata, edata, ldata, pdata;
198 #ifdef USE_BMESH_HOLES
199 struct BLI_mempool *looplistpool;
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 */
208 /* ID of the shape key this bmesh came from */
211 int walkers, totflags;
212 ListBase selected, error_stack;
221 /* BMHeader->htype (char) */
229 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
230 #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
232 /* BMHeader->hflag (char) */
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 */
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. */
245 BM_ELEM_DRAW = (1 << 5), /* edge display */
247 /* spare tag, assumed dirty, use define in each function to name based on use */
248 // _BM_ELEM_TAG_ALT = (1 << 6), // UNUSED
250 BM_ELEM_INTERNAL_TAG = (1 << 7) /* for low level internal API tagging,
251 * since tools may want to tag verts and
252 * not have functions clobber them */
255 struct BPy_BMGeneric;
256 extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
259 #define BM_ELEM_CD_GET_VOID_P(ele, offset) \
260 (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
262 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
263 { assert(offset != -1); *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
265 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
266 (assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
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))
271 /*forward declarations*/
273 #ifdef USE_BMESH_HOLES
274 # define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
276 # define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
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
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
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 */
296 #endif /* __BMESH_CLASS_H__ */