33 const bool use_toolflags,
39 size_t vert_size, edge_size, loop_size, face_size;
41 if (use_toolflags ==
true) {
44 loop_size =
sizeof(
BMLoop);
48 vert_size =
sizeof(
BMVert);
49 edge_size =
sizeof(
BMEdge);
50 loop_size =
sizeof(
BMLoop);
51 face_size =
sizeof(
BMFace);
177 if (is_ldata_free || is_pdata_free) {
229#ifdef USE_BMESH_HOLES
288#ifdef BMOP_UNTAN_MULTIRES_ENABLED
292 bmesh_mdisps_space_set(
bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
295 bmesh_rationalize_normals(
bm, 0);
306#ifdef BMOP_UNTAN_MULTIRES_ENABLED
310 bmesh_rationalize_normals(
bm, 1);
311 bmesh_mdisps_space_set(
bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
313 else if (
flag & BMO_OP_FLAG_RATIONALIZE_NORMALS) {
314 bmesh_rationalize_normals(
bm, 1);
348 if (elem_offset ==
nullptr) {
351 if (htype_needed == 0) {
361 int index = elem_offset ? elem_offset[0] : 0;
377 int index = elem_offset ? elem_offset[1] : 0;
390 (elem_offset && (elem_offset[2] || elem_offset[3])))
398 int index_loop = elem_offset ? elem_offset[2] : 0;
399 int index = elem_offset ? elem_offset[3] : 0;
412 }
while ((l_iter = l_iter->
next) != l_first);
462 BMesh *
bm,
const char *location,
const char *func,
const char *msg_a,
const char *msg_b)
467 const char *type_names[3] = {
"vert",
"edge",
"face"};
472 bool is_any_error =
false;
474 for (i = 0; i < 3; i++) {
477 bool is_error =
false;
493 if ((is_error ==
true) && (is_dirty ==
false)) {
496 "Invalid Index: at %s, %s, %s[%d] invalid index %d, '%s', '%s'\n",
505 else if ((is_error ==
false) && (is_dirty ==
true)) {
511 "Invalid Dirty: at %s, %s (%s), dirty flag was set but all index values are "
512 "correct, '%s', '%s'\n",
524 if (is_any_error == 0) {
525 fprintf(stderr,
"Valid Index Success: at %s, %s, '%s', '%s'\n", location, func, msg_a, msg_b);
571 const char htype_needed =
582 if (htype_needed == 0) {
690 }
while ((l_iter = l_iter->
next) != l_first);
700 return (index < bm->totvert) ?
bm->
vtable[index] :
nullptr;
708 return (index < bm->totedge) ?
bm->
etable[index] :
nullptr;
716 return (index < bm->totface) ?
bm->
ftable[index] :
nullptr;
742 GHash *vptr_map =
nullptr, *eptr_map =
nullptr, *fptr_map =
nullptr;
749 if (!(vert_idx || edge_idx || face_idx)) {
758 BMVert **verts_pool, *verts_copy, **vep;
770 verts_copy =
static_cast<BMVert *
>(
772 void **pyptrs = (cd_vert_pyptr != -1) ?
773 static_cast<void **
>(
MEM_mallocN(
sizeof(
void *) * totvert, __func__)) :
775 for (i = totvert, ve = verts_copy + totvert - 1, vep = verts_pool + totvert - 1; i--;
780 if (cd_vert_pyptr != -1) {
787 new_idx = vert_idx + totvert - 1;
788 ve = verts_copy + totvert - 1;
789 vep = verts_pool + totvert - 1;
790 for (i = totvert; i--; new_idx--, ve--, vep--) {
791 BMVert *new_vep = verts_pool[*new_idx];
795 "mapping vert from %d to %d (%p/%p to %p)\n", i, *new_idx, *vep, verts_pool[i], new_vep);
798 if (cd_vert_pyptr != -1) {
799 void **pyptr =
static_cast<void **
>(
801 *pyptr = pyptrs[*new_idx];
815 BMEdge **edges_pool, *edges_copy, **edp;
827 edges_copy =
static_cast<BMEdge *
>(
829 void **pyptrs = (cd_edge_pyptr != -1) ?
830 static_cast<void **
>(
MEM_mallocN(
sizeof(
void *) * totedge, __func__)) :
832 for (i = totedge, ed = edges_copy + totedge - 1, edp = edges_pool + totedge - 1; i--;
836 if (cd_edge_pyptr != -1) {
843 new_idx = edge_idx + totedge - 1;
844 ed = edges_copy + totedge - 1;
845 edp = edges_pool + totedge - 1;
846 for (i = totedge; i--; new_idx--, ed--, edp--) {
847 BMEdge *new_edp = edges_pool[*new_idx];
852 "mapping edge from %d to %d (%p/%p to %p)\n", i, *new_idx, *edp, edges_pool[i], new_edp);
854 if (cd_edge_pyptr != -1) {
855 void **pyptr =
static_cast<void **
>(
857 *pyptr = pyptrs[*new_idx];
871 BMFace **faces_pool, *faces_copy, **fap;
883 faces_copy =
static_cast<BMFace *
>(
885 void **pyptrs = (cd_poly_pyptr != -1) ?
886 static_cast<void **
>(
MEM_mallocN(
sizeof(
void *) * totface, __func__)) :
888 for (i = totface, fa = faces_copy + totface - 1, fap = faces_pool + totface - 1; i--;
892 if (cd_poly_pyptr != -1) {
899 new_idx = face_idx + totface - 1;
900 fa = faces_copy + totface - 1;
901 fap = faces_pool + totface - 1;
902 for (i = totface; i--; new_idx--, fa--, fap--) {
903 BMFace *new_fap = faces_pool[*new_idx];
906 if (cd_poly_pyptr != -1) {
907 void **pyptr =
static_cast<void **
>(
909 *pyptr = pyptrs[*new_idx];
937 if (vptr_map || eptr_map) {
951 printf(
"Edge v1_disk_link prev: %p -> %p\n",
954 printf(
"Edge v1_disk_link next: %p -> %p\n",
957 printf(
"Edge v2_disk_link prev: %p -> %p\n",
960 printf(
"Edge v2_disk_link next: %p -> %p\n",
1004 switch (ese->htype) {
1052 const char remap = (vpool_dst ?
BM_VERT : 0) | (epool_dst ?
BM_EDGE : 0) |
1068 const bool use_toolflags =
params->use_toolflags;
1076 memcpy(v_dst, v_src,
sizeof(
BMVert));
1077 if (use_toolflags) {
1084 vtable_dst[index] = v_dst;
1095 memcpy(e_dst, e_src,
sizeof(
BMEdge));
1096 if (use_toolflags) {
1103 etable_dst[index] = e_dst;
1110 int index, index_loop = 0;
1116 memcpy(f_dst, f_src,
sizeof(
BMFace));
1117 if (use_toolflags) {
1124 ftable_dst[index] = f_dst;
1130 BMLoop *l_iter_src, *l_first_src;
1134 memcpy(l_dst, l_iter_src,
sizeof(
BMLoop));
1135 ltable_dst[index_loop] = l_dst;
1137 }
while ((l_iter_src = l_iter_src->
next) != l_first_src);
1142#define MAP_VERT(ele) vtable_dst[BM_elem_index_get(ele)]
1143#define MAP_EDGE(ele) etable_dst[BM_elem_index_get(ele)]
1144#define MAP_LOOP(ele) ltable_dst[BM_elem_index_get(ele)]
1145#define MAP_FACE(ele) ftable_dst[BM_elem_index_get(ele)]
1147#define REMAP_VERT(ele) \
1149 if (remap & BM_VERT) { \
1150 ele = MAP_VERT(ele); \
1154#define REMAP_EDGE(ele) \
1156 if (remap & BM_EDGE) { \
1157 ele = MAP_EDGE(ele); \
1161#define REMAP_LOOP(ele) \
1163 if (remap & BM_LOOP) { \
1164 ele = MAP_LOOP(ele); \
1168#define REMAP_FACE(ele) \
1170 if (remap & BM_FACE) { \
1171 ele = MAP_FACE(ele); \
1205 BMFace *f = ftable_dst[i];
1209 BMLoop *l_iter, *l_first;
1220 }
while ((l_iter = l_iter->
next) != l_first);
1226 switch (ese->htype) {
1315 bm_mempool_init_ex(&allocsize, use_toolflags, &vpool_dst, &epool_dst,
nullptr, &fpool_dst);
1317 if (use_toolflags ==
false) {
1327 params.use_toolflags = use_toolflags;
1344 positions[i] =
v->
co;
1376 const float (*vert_coords)[3],
1377 const float mat[4][4])
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
void CustomData_bmesh_free_block(CustomData *data, void **block)
void CustomData_reset(CustomData *data)
void CustomData_free(CustomData *data, int totelem)
bool CustomData_bmesh_has_free(const CustomData *data)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
GHash * BLI_ghash_ptr_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
void * BLI_mempool_findelem(BLI_mempool *pool, unsigned int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
These structs are the foundation for all linked lists in the library system.
Read Guarded memory(de)allocation.
struct BMFace_OFlag BMFace_OFlag
struct BMVert_OFlag BMVert_OFlag
#define BM_FACE_FIRST_LOOP(p)
struct BMEdge_OFlag BMEdge_OFlag
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
void BMO_error_clear(BMesh *bm)
#define BM_ELEM_INDEX_VALIDATE(_bm, _msg_a, _msg_b)
#define BM_elem_index_get(ele)
#define BM_elem_index_set(ele, index)
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len)
Iterator as Array.
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_select_mode_flush(BMesh *bm)
void BM_mesh_elem_toolflags_clear(BMesh *bm)
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm, const float(*vert_coords)[3], const float mat[4][4])
const BMAllocTemplate bm_mesh_allocsize_default
void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
void BM_mesh_data_free(BMesh *bm)
BMesh Free Mesh Data.
static void bm_mempool_init_ex(const BMAllocTemplate *allocsize, const bool use_toolflags, BLI_mempool **r_vpool, BLI_mempool **r_epool, BLI_mempool **r_lpool, BLI_mempool **r_fpool)
void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx)
void BM_mesh_vert_coords_apply(BMesh *bm, const float(*vert_coords)[3])
void BM_mesh_clear(BMesh *bm)
BMesh Clear Mesh.
void bmesh_edit_begin(BMesh *, BMOpTypeFlag)
BMesh Begin Edit.
const BMAllocTemplate bm_mesh_chunksize_default
static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize, const bool use_toolflags)
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
void BM_mesh_rebuild(BMesh *bm, const BMeshCreateParams *params, BLI_mempool *vpool_dst, BLI_mempool *epool_dst, BLI_mempool *lpool_dst, BLI_mempool *fpool_dst)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
BMLoop * BM_loop_at_index_find(BMesh *bm, const int index)
void BM_mesh_vert_coords_get(BMesh *bm, MutableSpan< float3 > positions)
Array< float3 > BM_mesh_vert_coords_alloc(BMesh *bm)
BMVert * BM_vert_at_index_find_or_table(BMesh *bm, const int index)
void BM_mesh_elem_table_free(BMesh *bm, const char htype)
void BM_mesh_vert_normals_get(BMesh *bm, MutableSpan< float3 > normals)
int BM_mesh_elem_count(BMesh *bm, const char htype)
BMEdge * BM_edge_at_index_find(BMesh *bm, const int index)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_table_init(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b)
BMEdge * BM_edge_at_index_find_or_table(BMesh *bm, const int index)
void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag)
BMesh End Edit.
bool BM_mesh_elem_table_check(BMesh *bm)
BMVert * BM_vert_at_index_find(BMesh *bm, const int index)
BMFace * BM_face_at_index_find(BMesh *bm, const int index)
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
BMFace * BM_face_at_index_find_or_table(BMesh *bm, const int index)
void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4])
#define BMALLOC_TEMPLATE_FROM_BM(bm)
void BM_mesh_normals_update(BMesh *bm)
@ BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL
@ BMO_OPTYPE_FLAG_SELECT_VALIDATE
@ BMO_OPTYPE_FLAG_UNTAN_MULTIRES
@ BMO_OPTYPE_FLAG_NORMALS_CALC
@ BMO_OPTYPE_FLAG_SELECT_FLUSH
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void bpy_bm_generic_invalidate(struct BPy_BMGeneric *)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
struct BMFlagLayer * oflags
struct BMFlagLayer * oflags
struct BMLoop * radial_prev
struct BMLoop * radial_next
struct BMFlagLayer * oflags
struct BLI_mempool * epool
struct MLoopNorSpaceArray * lnor_spacearr
struct BLI_mempool * vtoolflagpool
struct BLI_mempool * etoolflagpool
struct BLI_mempool * ftoolflagpool
struct BLI_mempool * fpool
struct BLI_mempool * vpool
struct BLI_mempool * lpool
struct BLI_mempool * pool