Blender  V3.3
bmesh_class.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
12 #include "BLI_assert.h"
13 
14 /* disable holes for now,
15  * these are ifdef'd because they use more memory and can't be saved in DNA currently */
16 // #define USE_BMESH_HOLES
17 
18 struct BMEdge;
19 struct BMFace;
20 struct BMLoop;
21 struct BMVert;
22 struct BMesh;
23 
24 struct MLoopNorSpaceArray;
25 
26 struct BLI_mempool;
27 
28 /* NOTE: it is very important for BMHeader to start with two
29  * pointers. this is a requirement of mempool's method of
30  * iteration.
31  *
32  * hrm. it doesn't but still works ok, remove the comment above? - campbell.
33  */
34 
35 // #pragma GCC diagnostic error "-Wpadded"
36 
49 typedef struct BMHeader {
51  void *data;
52 
61  int index;
62 
64  char htype;
66  char hflag;
67 
74  char api_flag;
75  // char _pad;
77 
78 BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
79 
80 /* NOTE: need some way to specify custom locations for custom data layers. so we can
81  * make them point directly into structs. and some way to make it only happen to the
82  * active layer, and properly update when switching active layers. */
83 
84 typedef struct BMVert {
86 
87  float co[3]; /* vertex coordinates */
88  float no[3]; /* vertex normal */
89 
97  struct BMEdge *e;
99 
100 typedef struct BMVert_OFlag {
104 
105 /* disk link structure, only used by edges */
106 typedef struct BMDiskLink {
107  struct BMEdge *next, *prev;
109 
110 typedef struct BMEdge {
112 
123 
128  struct BMLoop *l;
129 
138 
139 typedef struct BMEdge_OFlag {
143 
144 typedef struct BMLoop {
146  /* notice no flags layer */
147 
153  struct BMVert *v;
154 
164  struct BMEdge *e;
171  struct BMFace *f;
172 
205 
233  struct BMLoop *next, *prev;
235 
236 /* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
237 typedef struct BMElemF {
240 
241 /* can cast anything to this, including BMLoop */
242 typedef struct BMElem {
245 
246 #ifdef USE_BMESH_HOLES
247 /* eventually, this structure will be used for supporting holes in faces */
248 typedef struct BMLoopList {
249  struct BMLoopList *next, *prev;
250  struct BMLoop *first, *last;
251 } BMLoopList;
252 #endif
253 
254 typedef struct BMFace {
256 
257 #ifdef USE_BMESH_HOLES
258  int totbounds; /* Total boundaries, is one plus the number of holes in the face. */
259  ListBase loops;
260 #else
262 #endif
267  int len;
271  float no[3];
281  short mat_nr;
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 can't 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 #define BM_ELEM_CD_SET_BOOL(ele, offset, f) \
522  { \
523  CHECK_TYPE_NONCONST(ele); \
524  BLI_assert(offset != -1); \
525  *((bool *)((char *)(ele)->head.data + (offset))) = (f); \
526  } \
527  (void)0
528 
529 #define BM_ELEM_CD_GET_BOOL(ele, offset) \
530  (BLI_assert(offset != -1), *((bool *)((char *)(ele)->head.data + (offset))))
531 
532 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
533 # define BM_ELEM_CD_GET_VOID_P(ele, offset) \
534  (BLI_assert(offset != -1), \
535  _Generic(ele, \
536  GENERIC_TYPE_ANY(POINTER_OFFSET((ele)->head.data, offset), \
537  _BM_GENERIC_TYPE_ELEM_NONCONST), \
538  GENERIC_TYPE_ANY((const void *)POINTER_OFFSET((ele)->head.data, offset), \
539  _BM_GENERIC_TYPE_ELEM_CONST)))
540 #else
541 # define BM_ELEM_CD_GET_VOID_P(ele, offset) \
542  (BLI_assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
543 #endif
544 
545 #define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
546  { \
547  CHECK_TYPE_NONCONST(ele); \
548  BLI_assert(offset != -1); \
549  *((float *)((char *)(ele)->head.data + (offset))) = (f); \
550  } \
551  (void)0
552 
553 #define BM_ELEM_CD_GET_FLOAT(ele, offset) \
554  (BLI_assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
555 
556 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
557 
558 # define BM_ELEM_CD_GET_FLOAT_P(ele, offset) \
559  (BLI_assert(offset != -1), \
560  _Generic(ele, \
561  GENERIC_TYPE_ANY((float *)POINTER_OFFSET((ele)->head.data, offset), \
562  _BM_GENERIC_TYPE_ELEM_NONCONST), \
563  GENERIC_TYPE_ANY((const float *)POINTER_OFFSET((ele)->head.data, offset), \
564  _BM_GENERIC_TYPE_ELEM_CONST)))
565 
566 # define BM_ELEM_CD_GET_FLOAT2_P(ele, offset) \
567  (BLI_assert(offset != -1), \
568  _Generic(ele, \
569  GENERIC_TYPE_ANY((float(*)[2])POINTER_OFFSET((ele)->head.data, offset), \
570  _BM_GENERIC_TYPE_ELEM_NONCONST), \
571  GENERIC_TYPE_ANY((const float(*)[2])POINTER_OFFSET((ele)->head.data, offset), \
572  _BM_GENERIC_TYPE_ELEM_CONST)))
573 
574 # define BM_ELEM_CD_GET_FLOAT3_P(ele, offset) \
575  (BLI_assert(offset != -1), \
576  _Generic(ele, \
577  GENERIC_TYPE_ANY((float(*)[3])POINTER_OFFSET((ele)->head.data, offset), \
578  _BM_GENERIC_TYPE_ELEM_NONCONST), \
579  GENERIC_TYPE_ANY((const float(*)[3])POINTER_OFFSET((ele)->head.data, offset), \
580  _BM_GENERIC_TYPE_ELEM_CONST)))
581 
582 #else
583 
584 # define BM_ELEM_CD_GET_FLOAT_P(ele, offset) \
585  (BLI_assert(offset != -1), (float *)((char *)(ele)->head.data + (offset)))
586 
587 # define BM_ELEM_CD_GET_FLOAT2_P(ele, offset) \
588  (BLI_assert(offset != -1), (float(*)[2])((char *)(ele)->head.data + (offset)))
589 
590 # define BM_ELEM_CD_GET_FLOAT3_P(ele, offset) \
591  (BLI_assert(offset != -1), (float(*)[3])((char *)(ele)->head.data + (offset)))
592 
593 #endif
594 
595 #define BM_ELEM_CD_SET_FLOAT2(ele, offset, f) \
596  { \
597  CHECK_TYPE_NONCONST(ele); \
598  BLI_assert(offset != -1); \
599  ((float *)((char *)(ele)->head.data + (offset)))[0] = (f)[0]; \
600  ((float *)((char *)(ele)->head.data + (offset)))[1] = (f)[1]; \
601  } \
602  (void)0
603 
604 #define BM_ELEM_CD_SET_FLOAT3(ele, offset, f) \
605  { \
606  CHECK_TYPE_NONCONST(ele); \
607  BLI_assert(offset != -1); \
608  ((float *)((char *)(ele)->head.data + (offset)))[0] = (f)[0]; \
609  ((float *)((char *)(ele)->head.data + (offset)))[1] = (f)[1]; \
610  ((float *)((char *)(ele)->head.data + (offset)))[2] = (f)[2]; \
611  } \
612  (void)0
613 
614 #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
615  (BLI_assert(offset != -1), (uchar)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
616 
617 /* Forward declarations. */
618 
619 #ifdef USE_BMESH_HOLES
620 # define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
621 #else
622 # define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
623 #endif
624 
625 #define BM_DISK_EDGE_NEXT(e, v) \
626  (CHECK_TYPE_INLINE(e, BMEdge *), \
627  CHECK_TYPE_INLINE(v, BMVert *), \
628  BLI_assert(BM_vert_in_edge(e, v)), \
629  (((&e->v1_disk_link)[v == e->v2]).next))
630 #define BM_DISK_EDGE_PREV(e, v) \
631  (CHECK_TYPE_INLINE(e, BMEdge *), \
632  CHECK_TYPE_INLINE(v, BMVert *), \
633  BLI_assert(BM_vert_in_edge(e, v)), \
634  (((&e->v1_disk_link)[v == e->v2]).prev))
635 
640 #define BM_DEFAULT_NGON_STACK_SIZE 32
645 #define BM_DEFAULT_ITER_STACK_SIZE 16
646 
647 /* avoid inf loop, this value is arbitrary
648  * but should not error on valid cases */
649 #define BM_LOOP_RADIAL_MAX 10000
650 #define BM_NGON_MAX 100000
651 
652 /* setting zero so we can catch bugs in OpenMP/BMesh */
653 #ifdef DEBUG
654 # define BM_OMP_LIMIT 0
655 #else
656 # define BM_OMP_LIMIT 10000
657 #endif
unsigned int uint
Definition: BLI_sys_types.h:67
BLI_STATIC_ASSERT((sizeof(BMHeader)<=16), "BMHeader size has grown!")
struct BMDiskLink BMDiskLink
@ 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
bool(* BMFaceFilterFunc)(const BMFace *, void *user_data)
Definition: bmesh_class.h:505
struct BMFace BMFace
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
struct BMLoop BMLoop
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
@ 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
@ 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 BMFlagLayer BMFlagLayer
void * user_data
static ulong * next
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
struct BMFlagLayer * oflags
Definition: bmesh_class.h:141
BMHeader head
Definition: bmesh_class.h:111
BMVert * v1
Definition: bmesh_class.h:122
BMDiskLink v2_disk_link
Definition: bmesh_class.h:136
BMDiskLink v1_disk_link
Definition: bmesh_class.h:136
BMVert * v2
Definition: bmesh_class.h:122
struct BMLoop * l
Definition: bmesh_class.h:128
BMHeader head
Definition: bmesh_class.h:238
BMHeader head
Definition: bmesh_class.h:243
struct BMFlagLayer * oflags
Definition: bmesh_class.h:287
short mat_nr
Definition: bmesh_class.h:281
int len
Definition: bmesh_class.h:267
BMHeader head
Definition: bmesh_class.h:255
float no[3]
Definition: bmesh_class.h:271
BMLoop * l_first
Definition: bmesh_class.h:261
char htype
Definition: bmesh_class.h:64
int index
Definition: bmesh_class.h:61
char hflag
Definition: bmesh_class.h:66
void * data
Definition: bmesh_class.h:51
char api_flag
Definition: bmesh_class.h:74
BMLoopNorEditData ** lidx_to_lnor_editdata
Definition: bmesh_class.h:404
BMLoopNorEditData * lnor_editdata
Definition: bmesh_class.h:399
BMHeader head
Definition: bmesh_class.h:145
struct BMVert * v
Definition: bmesh_class.h:153
struct BMEdge * e
Definition: bmesh_class.h:164
struct BMLoop * radial_prev
Definition: bmesh_class.h:204
struct BMLoop * radial_next
Definition: bmesh_class.h:204
struct BMLoop * prev
Definition: bmesh_class.h:233
struct BMFace * f
Definition: bmesh_class.h:171
struct BMLoop * next
Definition: bmesh_class.h:233
struct BMFlagLayer * oflags
Definition: bmesh_class.h:102
float co[3]
Definition: bmesh_class.h:87
struct BMEdge * e
Definition: bmesh_class.h:97
float no[3]
Definition: bmesh_class.h:88
BMHeader head
Definition: bmesh_class.h:85
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