Blender  V2.93
bmesh_class.h
Go to the documentation of this file.
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 #pragma once
18 
26 /* disable holes for now,
27  * these are ifdef'd because they use more memory and cant be saved in DNA currently */
28 // #define USE_BMESH_HOLES
29 
30 struct BMEdge;
31 struct BMFace;
32 struct BMLoop;
33 struct BMVert;
34 struct BMesh;
35 
36 struct MLoopNorSpaceArray;
37 
38 struct BLI_mempool;
39 
40 /* note: it is very important for BMHeader to start with two
41  * pointers. this is a requirement of mempool's method of
42  * iteration.
43  *
44  * hrm. it doesn't but still works ok, remove the comment above? - campbell.
45  */
46 
47 // #pragma GCC diagnostic error "-Wpadded"
48 
61 typedef struct BMHeader {
63  void *data;
64 
73  int index;
74 
76  char htype;
78  char hflag;
79 
86  char api_flag;
87  // char _pad;
89 
90 BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
91 
92 /* note: need some way to specify custom locations for custom data layers. so we can
93  * make them point directly into structs. and some way to make it only happen to the
94  * active layer, and properly update when switching active layers.*/
95 
96 typedef struct BMVert {
98 
99  float co[3]; /* vertex coordinates */
100  float no[3]; /* vertex normal */
101 
109  struct BMEdge *e;
111 
112 typedef struct BMVert_OFlag {
116 
117 /* disk link structure, only used by edges */
118 typedef struct BMDiskLink {
119  struct BMEdge *next, *prev;
121 
122 typedef struct BMEdge {
124 
135 
140  struct BMLoop *l;
141 
150 
151 typedef struct BMEdge_OFlag {
155 
156 typedef struct BMLoop {
158  /* notice no flags layer */
159 
165  struct BMVert *v;
166 
176  struct BMEdge *e;
183  struct BMFace *f;
184 
217 
245  struct BMLoop *next, *prev;
247 
248 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
249 typedef struct BMElemF {
252 
253 /* can cast anything to this, including BMLoop */
254 typedef struct BMElem {
257 
258 #ifdef USE_BMESH_HOLES
259 /* eventually, this structure will be used for supporting holes in faces */
260 typedef struct BMLoopList {
261  struct BMLoopList *next, *prev;
262  struct BMLoop *first, *last;
263 } BMLoopList;
264 #endif
265 
266 typedef struct BMFace {
268 
269 #ifdef USE_BMESH_HOLES
270  int totbounds; /*total boundaries, is one plus the number of holes in the face*/
271  ListBase loops;
272 #else
274 #endif
279  int len;
280  float no[3]; /* face normal */
281  short mat_nr; /* material index */
282  // short _pad[3];
284 
285 typedef struct BMFace_OFlag {
289 
290 typedef struct BMFlagLayer {
291  short f; /* flags */
293 
294 // #pragma GCC diagnostic ignored "-Wpadded"
295 
296 typedef struct BMesh {
299 
306 
312 
313  /* element pools */
315 
316  /* mempool lookup tables (optional)
317  * index tables, to map indices to elements via
318  * BM_mesh_elem_table_ensure and associated functions. don't
319  * touch this or read it directly.\
320  * Use BM_mesh_elem_table_ensure(), BM_vert/edge/face_at_index() */
324 
325  /* size of allocated tables */
329 
330  /* operator api stuff (must be all NULL or all alloc'd) */
332 
334 
336 
338 
339 #ifdef USE_BMESH_HOLES
340  struct BLI_mempool *looplistpool;
341 #endif
342 
345 
346  /* Should be copy of scene select mode. */
347  /* Stored in #BMEditMesh too, this is a bit confusing,
348  * make sure they're in sync!
349  * Only use when the edit mesh cant be accessed - campbell */
350  short selectmode;
351 
352  /* ID of the shape key this bmesh came from */
353  int shapenr;
354 
355  int totflags;
357 
367 
370 
378  void *py_handle;
380 
382 enum {
383  BM_VERT = 1,
384  BM_EDGE = 2,
385  BM_LOOP = 4,
386  BM_FACE = 8,
387 };
388 
389 typedef struct BMLoopNorEditData {
392  float niloc[3];
393  float nloc[3];
394  float *loc;
395  short *clnors_data;
397 
398 typedef struct BMLoopNorEditDataArray {
405 
407  int totloop;
409 
410 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
411 #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
412 
414 enum {
418 };
419 
420 /* args for _Generic */
421 #define _BM_GENERIC_TYPE_ELEM_NONCONST \
422  void *, BMVert *, BMEdge *, BMLoop *, BMFace *, BMVert_OFlag *, BMEdge_OFlag *, BMFace_OFlag *, \
423  BMElem *, BMElemF *, BMHeader *
424 
425 #define _BM_GENERIC_TYPE_ELEM_CONST \
426  const void *, const BMVert *, const BMEdge *, const BMLoop *, const BMFace *, \
427  const BMVert_OFlag *, const BMEdge_OFlag *, const BMFace_OFlag *, const BMElem *, \
428  const BMElemF *, const BMHeader *, void *const, BMVert *const, BMEdge *const, \
429  BMLoop *const, BMFace *const, BMElem *const, BMElemF *const, BMHeader *const
430 
431 #define BM_CHECK_TYPE_ELEM_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPES_CONST)
432 
433 #define BM_CHECK_TYPE_ELEM_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
434 
435 #define BM_CHECK_TYPE_ELEM(ele) \
436  CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST, _BM_GENERIC_TYPE_ELEM_CONST)
437 
438 /* vert */
439 #define _BM_GENERIC_TYPE_VERT_NONCONST BMVert *, BMVert_OFlag *
440 #define _BM_GENERIC_TYPE_VERT_CONST const BMVert *, const BMVert_OFlag *
441 #define BM_CHECK_TYPE_VERT_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_VERT_CONST)
442 #define BM_CHECK_TYPE_VERT_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
443 #define BM_CHECK_TYPE_VERT(ele) \
444  CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_VERT_NONCONST, _BM_GENERIC_TYPE_VERT_CONST)
445 /* edge */
446 #define _BM_GENERIC_TYPE_EDGE_NONCONST BMEdge *, BMEdge_OFlag *
447 #define _BM_GENERIC_TYPE_EDGE_CONST const BMEdge *, const BMEdge_OFlag *
448 #define BM_CHECK_TYPE_EDGE_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_EDGE_CONST)
449 #define BM_CHECK_TYPE_EDGE_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
450 #define BM_CHECK_TYPE_EDGE(ele) \
451  CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_EDGE_NONCONST, _BM_GENERIC_TYPE_EDGE_CONST)
452 /* face */
453 #define _BM_GENERIC_TYPE_FACE_NONCONST BMFace *, BMFace_OFlag *
454 #define _BM_GENERIC_TYPE_FACE_CONST const BMFace *, const BMFace_OFlag *
455 #define BM_CHECK_TYPE_FACE_CONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_FACE_CONST)
456 #define BM_CHECK_TYPE_FACE_NONCONST(ele) CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_ELEM_NONCONST)
457 #define BM_CHECK_TYPE_FACE(ele) \
458  CHECK_TYPE_ANY(ele, _BM_GENERIC_TYPE_FACE_NONCONST, _BM_GENERIC_TYPE_FACE_CONST)
459 
460 /* Assignment from a void* to a typed pointer is not allowed in C++,
461  * casting the LHS to void works fine though.
462  */
463 #ifdef __cplusplus
464 # define BM_CHECK_TYPE_ELEM_ASSIGN(ele) (BM_CHECK_TYPE_ELEM(ele)), *((void **)&ele)
465 #else
466 # define BM_CHECK_TYPE_ELEM_ASSIGN(ele) (BM_CHECK_TYPE_ELEM(ele)), ele
467 #endif
468 
470 enum {
471  BM_ELEM_SELECT = (1 << 0),
472  BM_ELEM_HIDDEN = (1 << 1),
473  BM_ELEM_SEAM = (1 << 2),
477  BM_ELEM_SMOOTH = (1 << 3),
484  BM_ELEM_TAG = (1 << 4),
485 
486  BM_ELEM_DRAW = (1 << 5), /* edge display */
487 
489  BM_ELEM_TAG_ALT = (1 << 6),
490 
497 };
498 
499 struct BPy_BMGeneric;
500 extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
501 
502 typedef bool (*BMElemFilterFunc)(const BMElem *, void *user_data);
503 typedef bool (*BMVertFilterFunc)(const BMVert *, void *user_data);
504 typedef bool (*BMEdgeFilterFunc)(const BMEdge *, void *user_data);
505 typedef bool (*BMFaceFilterFunc)(const BMFace *, void *user_data);
506 typedef bool (*BMLoopFilterFunc)(const BMLoop *, void *user_data);
507 typedef bool (*BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_data);
508 
509 /* defines */
510 #define BM_ELEM_CD_SET_INT(ele, offset, f) \
511  { \
512  CHECK_TYPE_NONCONST(ele); \
513  BLI_assert(offset != -1); \
514  *((int *)((char *)(ele)->head.data + (offset))) = (f); \
515  } \
516  (void)0
517 
518 #define BM_ELEM_CD_GET_INT(ele, offset) \
519  (BLI_assert(offset != -1), *((int *)((char *)(ele)->head.data + (offset))))
520 
521 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
522 # define BM_ELEM_CD_GET_VOID_P(ele, offset) \
523  (BLI_assert(offset != -1), \
524  _Generic(ele, \
525  GENERIC_TYPE_ANY(POINTER_OFFSET((ele)->head.data, offset), \
526  _BM_GENERIC_TYPE_ELEM_NONCONST), \
527  GENERIC_TYPE_ANY((const void *)POINTER_OFFSET((ele)->head.data, offset), \
528  _BM_GENERIC_TYPE_ELEM_CONST)))
529 #else
530 # define BM_ELEM_CD_GET_VOID_P(ele, offset) \
531  (BLI_assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
532 #endif
533 
534 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
535  { \
536  CHECK_TYPE_NONCONST(ele); \
537  BLI_assert(offset != -1); \
538  *((float *)((char *)(ele)->head.data + (offset))) = (f); \
539  } \
540  (void)0
541 
542 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
543  (BLI_assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
544 
545 #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
546  (BLI_assert(offset != -1), (uchar)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
547 
548 /*forward declarations*/
549 
550 #ifdef USE_BMESH_HOLES
551 # define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
552 #else
553 # define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
554 #endif
555 
556 #define BM_DISK_EDGE_NEXT(e, v) \
557  (CHECK_TYPE_INLINE(e, BMEdge *), \
558  CHECK_TYPE_INLINE(v, BMVert *), \
559  BLI_assert(BM_vert_in_edge(e, v)), \
560  (((&e->v1_disk_link)[v == e->v2]).next))
561 #define BM_DISK_EDGE_PREV(e, v) \
562  (CHECK_TYPE_INLINE(e, BMEdge *), \
563  CHECK_TYPE_INLINE(v, BMVert *), \
564  BLI_assert(BM_vert_in_edge(e, v)), \
565  (((&e->v1_disk_link)[v == e->v2]).prev))
566 
571 #define BM_DEFAULT_NGON_STACK_SIZE 32
576 #define BM_DEFAULT_ITER_STACK_SIZE 16
577 
578 /* avoid inf loop, this value is arbitrary
579  * but should not error on valid cases */
580 #define BM_LOOP_RADIAL_MAX 10000
581 #define BM_NGON_MAX 100000
582 
583 /* setting zero so we can catch bugs in OpenMP/BMesh */
584 #ifdef DEBUG
585 # define BM_OMP_LIMIT 0
586 #else
587 # define BM_OMP_LIMIT 10000
588 #endif
unsigned int uint
Definition: BLI_sys_types.h:83
BLI_STATIC_ASSERT((sizeof(BMHeader)<=16), "BMHeader size has grown!")
struct BMDiskLink BMDiskLink
bool(* BMFaceFilterFunc)(const BMFace *, void *user_data)
Definition: bmesh_class.h:505
struct BMFace BMFace
@ BM_SPACEARR_BMO_SET
Definition: bmesh_class.h:417
@ BM_SPACEARR_DIRTY_ALL
Definition: bmesh_class.h:416
@ BM_SPACEARR_DIRTY
Definition: bmesh_class.h:415
struct BMFace_OFlag BMFace_OFlag
bool(* BMElemFilterFunc)(const BMElem *, void *user_data)
Definition: bmesh_class.h:502
bool(* BMVertFilterFunc)(const BMVert *, void *user_data)
Definition: bmesh_class.h:503
struct BMElemF BMElemF
bool(* BMLoopFilterFunc)(const BMLoop *, void *user_data)
Definition: bmesh_class.h:506
struct BMElem BMElem
struct BMHeader BMHeader
struct BMEdge BMEdge
struct BMVert_OFlag BMVert_OFlag
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
struct BMLoop BMLoop
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
@ BM_ELEM_SEAM
Definition: bmesh_class.h:473
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
@ BM_ELEM_SMOOTH
Definition: bmesh_class.h:477
@ BM_ELEM_INTERNAL_TAG
Definition: bmesh_class.h:496
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
@ BM_ELEM_DRAW
Definition: bmesh_class.h:486
@ BM_ELEM_TAG_ALT
Definition: bmesh_class.h:489
struct BMesh BMesh
struct BMLoopNorEditData BMLoopNorEditData
struct BMEdge_OFlag BMEdge_OFlag
struct BMVert BMVert
void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self)
bool(* BMEdgeFilterFunc)(const BMEdge *, void *user_data)
Definition: bmesh_class.h:504
bool(* BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_data)
Definition: bmesh_class.h:507
struct BMLoopNorEditDataArray BMLoopNorEditDataArray
struct BMFlagLayer BMFlagLayer
void * user_data
static ulong * next
struct BMFlagLayer * oflags
Definition: bmesh_class.h:153
BMHeader head
Definition: bmesh_class.h:123
BMVert * v1
Definition: bmesh_class.h:134
BMDiskLink v2_disk_link
Definition: bmesh_class.h:148
BMDiskLink v1_disk_link
Definition: bmesh_class.h:148
BMVert * v2
Definition: bmesh_class.h:134
struct BMLoop * l
Definition: bmesh_class.h:140
BMHeader head
Definition: bmesh_class.h:250
BMHeader head
Definition: bmesh_class.h:255
struct BMFlagLayer * oflags
Definition: bmesh_class.h:287
short mat_nr
Definition: bmesh_class.h:281
int len
Definition: bmesh_class.h:279
BMHeader head
Definition: bmesh_class.h:267
float no[3]
Definition: bmesh_class.h:280
BMLoop * l_first
Definition: bmesh_class.h:273
char htype
Definition: bmesh_class.h:76
int index
Definition: bmesh_class.h:73
char hflag
Definition: bmesh_class.h:78
void * data
Definition: bmesh_class.h:63
char api_flag
Definition: bmesh_class.h:86
BMLoopNorEditData ** lidx_to_lnor_editdata
Definition: bmesh_class.h:404
BMLoopNorEditData * lnor_editdata
Definition: bmesh_class.h:399
BMHeader head
Definition: bmesh_class.h:157
struct BMVert * v
Definition: bmesh_class.h:165
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMLoop * radial_prev
Definition: bmesh_class.h:216
struct BMLoop * radial_next
Definition: bmesh_class.h:216
struct BMLoop * prev
Definition: bmesh_class.h:245
struct BMFace * f
Definition: bmesh_class.h:183
struct BMLoop * next
Definition: bmesh_class.h:245
struct BMFlagLayer * oflags
Definition: bmesh_class.h:114
float co[3]
Definition: bmesh_class.h:99
struct BMEdge * e
Definition: bmesh_class.h:109
float no[3]
Definition: bmesh_class.h:100
BMHeader head
Definition: bmesh_class.h:97
int totvert
Definition: bmesh_class.h:297
BMEdge ** etable
Definition: bmesh_class.h:322
struct BLI_mempool * epool
Definition: bmesh_class.h:314
int totflags
Definition: bmesh_class.h:355
int totfacesel
Definition: bmesh_class.h:298
struct MLoopNorSpaceArray * lnor_spacearr
Definition: bmesh_class.h:343
int shapenr
Definition: bmesh_class.h:353
char elem_index_dirty
Definition: bmesh_class.h:305
CustomData vdata
Definition: bmesh_class.h:337
int totedge
Definition: bmesh_class.h:297
char elem_table_dirty
Definition: bmesh_class.h:311
struct BLI_mempool * vtoolflagpool
Definition: bmesh_class.h:331
ListBase selected
Definition: bmesh_class.h:356
CustomData edata
Definition: bmesh_class.h:337
uint use_toolflags
Definition: bmesh_class.h:333
int totvertsel
Definition: bmesh_class.h:298
int totloop
Definition: bmesh_class.h:297
int ftable_tot
Definition: bmesh_class.h:328
void * py_handle
Definition: bmesh_class.h:378
struct BLI_mempool * etoolflagpool
Definition: bmesh_class.h:331
BMFace * act_face
Definition: bmesh_class.h:366
short selectmode
Definition: bmesh_class.h:350
BMVert ** vtable
Definition: bmesh_class.h:321
struct BLI_mempool * ftoolflagpool
Definition: bmesh_class.h:331
int totedgesel
Definition: bmesh_class.h:298
char spacearr_dirty
Definition: bmesh_class.h:344
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
int vtable_tot
Definition: bmesh_class.h:326
BMFace ** ftable
Definition: bmesh_class.h:323
int totface
Definition: bmesh_class.h:297
int toolflag_index
Definition: bmesh_class.h:335
int etable_tot
Definition: bmesh_class.h:327
struct BLI_mempool * fpool
Definition: bmesh_class.h:314
struct BLI_mempool * vpool
Definition: bmesh_class.h:314
struct BLI_mempool * lpool
Definition: bmesh_class.h:314
ListBase errorstack
Definition: bmesh_class.h:369