Sculpt: Minor bmesh refactor, made tool flags a CD layer
The way toolflags reallocated the entire mesh just to add or remove one pointer from BMEdge/Vert/Face was highly broken. Now a CD layer is used instead.
This commit is contained in:
parent
99b9c1bcad
commit
1969510974
|
@ -1563,11 +1563,6 @@ static void layerDynTopoVert_interp(
|
|||
mv->origmask = origmask;
|
||||
}
|
||||
|
||||
static void layerCopy_noop(const void *UNUSED(source), void *UNUSED(dest), int UNUSED(count))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static void layerInterp_noop(const void **UNUSED(sources),
|
||||
const float *UNUSED(weights),
|
||||
const float *UNUSED(sub_weights),
|
||||
|
@ -1987,7 +1982,16 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
|||
NULL, // flag singleton layer
|
||||
layerDynTopoVert_copy,
|
||||
NULL,
|
||||
layerDynTopoVert_interp}};
|
||||
layerDynTopoVert_interp},
|
||||
/*54 CD_BMESH_TOOLFLAGS */
|
||||
{sizeof(MToolFlags),
|
||||
"MToolFlags",
|
||||
1,
|
||||
NULL, // flag singleton layer
|
||||
NULL,
|
||||
NULL,
|
||||
layerInterp_noop},
|
||||
};
|
||||
|
||||
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
||||
/* 0-4 */
|
||||
|
@ -3752,7 +3756,7 @@ void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, Custom
|
|||
|
||||
void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
|
||||
{
|
||||
return CustomData_bmesh_init_pool_ex(data, totelem, htype, __func__);
|
||||
CustomData_bmesh_init_pool_ex(data, totelem, htype, __func__);
|
||||
}
|
||||
|
||||
void CustomData_bmesh_init_pool_ex(CustomData *data,
|
||||
|
@ -3928,7 +3932,7 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
|
|||
}
|
||||
}
|
||||
|
||||
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
|
||||
ATTR_NO_OPT static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
|
||||
{
|
||||
if (*block) {
|
||||
CustomData_bmesh_free_block(data, block);
|
||||
|
@ -3936,6 +3940,18 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
|
|||
|
||||
if (data->totsize > 0) {
|
||||
*block = BLI_mempool_alloc(data->pool);
|
||||
|
||||
/*clear toolflags pointer when created for the first time*/
|
||||
int cd_tflags = data->typemap[CD_TOOLFLAGS];
|
||||
if (cd_tflags != -1) {
|
||||
cd_tflags = data->layers[cd_tflags].offset;
|
||||
|
||||
char *ptr = (char *)*block;
|
||||
ptr += cd_tflags;
|
||||
|
||||
MToolFlags *flags = (MToolFlags *)ptr;
|
||||
flags->flag = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*block = NULL;
|
||||
|
@ -3968,15 +3984,14 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
|
|||
|
||||
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
|
||||
{
|
||||
int offset = data->layers[n].offset;
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
|
||||
|
||||
/* can't allow this to be called on CD_MESH_ID */
|
||||
|
||||
if (data->layers[n].type == CD_MESH_ID) {
|
||||
if (ELEM(data->layers[n].type, CD_TOOLFLAGS, CD_MESH_ID)) {
|
||||
/* do not do toolflags or mesh ids */
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = data->layers[n].offset;
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
|
||||
|
||||
if (typeInfo->set_default) {
|
||||
typeInfo->set_default(POINTER_OFFSET(*block, offset), 1);
|
||||
}
|
||||
|
@ -3985,9 +4000,9 @@ static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n
|
|||
}
|
||||
}
|
||||
|
||||
void CustomData_bmesh_set_default(CustomData *data, void **block)
|
||||
ATTR_NO_OPT void CustomData_bmesh_set_default(CustomData *data, void **block)
|
||||
{
|
||||
if (*block == NULL) {
|
||||
if (!*block) {
|
||||
CustomData_bmesh_alloc_block(data, block);
|
||||
}
|
||||
|
||||
|
@ -4005,15 +4020,30 @@ void CustomData_bmesh_swap_data_simple(CustomData *data, void **block1, void **b
|
|||
*block1 = *block2;
|
||||
*block2 = tmp;
|
||||
|
||||
// unswap ids if they exist
|
||||
if (cd_id != -1 && *block1 && *block2) {
|
||||
int itmp;
|
||||
int *id1 = (int *)(((char *)*block1) + cd_id);
|
||||
int *id2 = (int *)(((char *)*block2) + cd_id);
|
||||
int cd_tflags = data->typemap[CD_TOOLFLAGS];
|
||||
cd_tflags = cd_tflags != -1 ? data->layers[cd_tflags].offset : -1;
|
||||
|
||||
itmp = *id1;
|
||||
*id1 = *id2;
|
||||
*id2 = itmp;
|
||||
// unswap ids if they exist
|
||||
if (*block1 && *block2) {
|
||||
if (cd_id != -1) {
|
||||
int itmp;
|
||||
int *id1 = (int *)(((char *)*block1) + cd_id);
|
||||
int *id2 = (int *)(((char *)*block2) + cd_id);
|
||||
|
||||
itmp = *id1;
|
||||
*id1 = *id2;
|
||||
*id2 = itmp;
|
||||
}
|
||||
|
||||
if (cd_tflags != -1) {
|
||||
MToolFlags tmp;
|
||||
MToolFlags *flags1 = (MToolFlags *)(((char *)*block1) + cd_tflags);
|
||||
MToolFlags *flags2 = (MToolFlags *)(((char *)*block2) + cd_tflags);
|
||||
|
||||
tmp = *flags1;
|
||||
*flags1 = *flags2;
|
||||
*flags2 = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4044,8 +4074,8 @@ void CustomData_bmesh_swap_data(CustomData *source,
|
|||
dest_i_start++;
|
||||
}
|
||||
|
||||
if (source->layers[src_i].type == CD_MESH_ID) {
|
||||
// do not swap ids
|
||||
if (ELEM(source->layers[src_i].type, CD_MESH_ID, CD_TOOLFLAGS)) {
|
||||
// do not swap ids or toolflags
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4096,6 +4126,14 @@ void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source,
|
|||
* would cause too much duplicate code, so add a check instead. */
|
||||
const bool no_mask = (mask_exclude == 0);
|
||||
|
||||
/*
|
||||
Note that we don't handle id/toolflag layers specially here,
|
||||
instead relying on CD_ELEM_NO_COPY semantics.
|
||||
|
||||
This is so BM_data_layer_add can reallocate customdata blocks without
|
||||
zeroing those two layers.
|
||||
*/
|
||||
|
||||
if (*dest_block == NULL) {
|
||||
CustomData_bmesh_alloc_block(dest, dest_block);
|
||||
if (*dest_block) {
|
||||
|
@ -4135,6 +4173,9 @@ void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source,
|
|||
/* if we found a matching layer, copy the data */
|
||||
if (STREQ(dest->layers[dest_i].name, source->layers[src_i].name)) {
|
||||
if (no_mask || ((CD_TYPE_AS_MASK(dest->layers[dest_i].type) & mask_exclude) == 0)) {
|
||||
/* CD_FLAG_ELEM_NOCOPY is used to forcibly exclude copying CD_MESH_ID and CD_TOOLFLAGS
|
||||
layers */
|
||||
|
||||
if (dest->layers[dest_i].flag & CD_FLAG_ELEM_NOCOPY) {
|
||||
break;
|
||||
}
|
||||
|
@ -4463,6 +4504,12 @@ void CustomData_bmesh_interp(CustomData *data,
|
|||
for (int i = 0; i < data->totlayer; i++) {
|
||||
CustomDataLayer *layer = &data->layers[i];
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
|
||||
|
||||
// ignore id and toolflag layers
|
||||
if (ELEM(layer->type, CD_MESH_ID, CD_TOOLFLAGS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeInfo->interp) {
|
||||
for (int j = 0; j < count; j++) {
|
||||
sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset);
|
||||
|
|
|
@ -5348,13 +5348,40 @@ ATTR_NO_OPT void BKE_pbvh_bmesh_from_saved_indices(PBVH *pbvh)
|
|||
BLI_array_free(ltable);
|
||||
}
|
||||
|
||||
extern char dyntopop_node_idx_layer_id[];
|
||||
extern char dyntopop_faces_areas_layer_id[];
|
||||
|
||||
static void pbvh_bmesh_fetch_cdrefs(PBVH *pbvh)
|
||||
{
|
||||
BMesh *bm = pbvh->bm;
|
||||
|
||||
int idx = CustomData_get_named_layer_index(
|
||||
&bm->vdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
pbvh->cd_vert_node_offset = bm->vdata.layers[idx].offset;
|
||||
|
||||
idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
pbvh->cd_face_node_offset = bm->pdata.layers[idx].offset;
|
||||
|
||||
idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
|
||||
pbvh->cd_face_area = bm->pdata.layers[idx].offset;
|
||||
|
||||
pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
|
||||
pbvh->cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR);
|
||||
pbvh->cd_faceset_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
pbvh->cd_dyn_vert = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_VERT);
|
||||
}
|
||||
|
||||
void BKE_pbvh_bmesh_set_toolflags(PBVH *pbvh, bool use_toolflags)
|
||||
{
|
||||
if (use_toolflags == pbvh->bm->use_toolflags) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_pbvh_bmesh_save_indices(pbvh);
|
||||
// BKE_pbvh_bmesh_save_indices(pbvh);
|
||||
BM_mesh_toolflags_set(pbvh->bm, use_toolflags);
|
||||
BKE_pbvh_bmesh_from_saved_indices(pbvh);
|
||||
|
||||
// customdata layout might've changed
|
||||
pbvh_bmesh_fetch_cdrefs(pbvh);
|
||||
|
||||
// BKE_pbvh_bmesh_from_saved_indices(pbvh);
|
||||
}
|
||||
|
|
|
@ -114,10 +114,9 @@ typedef struct BMVert {
|
|||
struct BMEdge *e;
|
||||
} BMVert;
|
||||
|
||||
typedef struct BMVert_OFlag {
|
||||
BMVert base;
|
||||
struct BMFlagLayer *oflags;
|
||||
} BMVert_OFlag;
|
||||
#define BMVert_OFlag BMVert
|
||||
#define BMEdge_OFlag BMEdge
|
||||
#define BMFace_OFlag BMFace
|
||||
|
||||
/* disk link structure, only used by edges */
|
||||
typedef struct BMDiskLink {
|
||||
|
@ -153,11 +152,6 @@ typedef struct BMEdge {
|
|||
BMDiskLink v1_disk_link, v2_disk_link;
|
||||
} BMEdge;
|
||||
|
||||
typedef struct BMEdge_OFlag {
|
||||
BMEdge base;
|
||||
struct BMFlagLayer *oflags;
|
||||
} BMEdge_OFlag;
|
||||
|
||||
typedef struct BMLoop {
|
||||
BMHeader head;
|
||||
/* notice no flags layer */
|
||||
|
@ -287,11 +281,6 @@ typedef struct BMFace {
|
|||
// short _pad[3];
|
||||
} BMFace;
|
||||
|
||||
typedef struct BMFace_OFlag {
|
||||
BMFace base;
|
||||
struct BMFlagLayer *oflags;
|
||||
} BMFace_OFlag;
|
||||
|
||||
typedef struct BMFlagLayer {
|
||||
short f; /* flags */
|
||||
} BMFlagLayer;
|
||||
|
|
|
@ -795,28 +795,28 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src,
|
|||
bm_dst,
|
||||
(const BMVert *)ele_src,
|
||||
(BMVert *)ele_dst,
|
||||
cd_mask_exclude | CD_MASK_MESH_ID);
|
||||
cd_mask_exclude | CD_MASK_MESH_ID | CD_MASK_TOOLFLAGS);
|
||||
break;
|
||||
case BM_EDGE:
|
||||
bm_edge_attrs_copy(bm_src,
|
||||
bm_dst,
|
||||
(const BMEdge *)ele_src,
|
||||
(BMEdge *)ele_dst,
|
||||
cd_mask_exclude | CD_MASK_MESH_ID);
|
||||
cd_mask_exclude | CD_MASK_MESH_ID | CD_MASK_TOOLFLAGS);
|
||||
break;
|
||||
case BM_LOOP:
|
||||
bm_loop_attrs_copy(bm_src,
|
||||
bm_dst,
|
||||
(const BMLoop *)ele_src,
|
||||
(BMLoop *)ele_dst,
|
||||
cd_mask_exclude | CD_MASK_MESH_ID);
|
||||
cd_mask_exclude | CD_MASK_MESH_ID | CD_MASK_TOOLFLAGS);
|
||||
break;
|
||||
case BM_FACE:
|
||||
bm_face_attrs_copy(bm_src,
|
||||
bm_dst,
|
||||
(const BMFace *)ele_src,
|
||||
(BMFace *)ele_dst,
|
||||
cd_mask_exclude | CD_MASK_MESH_ID);
|
||||
cd_mask_exclude | CD_MASK_MESH_ID | CD_MASK_TOOLFLAGS);
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
|
@ -876,6 +876,8 @@ static BMFace *bm_mesh_copy_new_face(
|
|||
BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff, 0x0);
|
||||
f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */
|
||||
|
||||
bm_elem_check_toolflags(bm_new, (BMElem *)f);
|
||||
|
||||
j = 0;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
|
||||
do {
|
||||
|
@ -1047,7 +1049,9 @@ BMesh *BM_mesh_copy_ex(BMesh *bm_old, struct BMeshCreateParams *params)
|
|||
v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD | BM_CREATE_SKIP_ID);
|
||||
|
||||
BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff, 0x0);
|
||||
|
||||
bm_alloc_id(bm_new, (BMElem *)v_new);
|
||||
bm_elem_check_toolflags(bm_new, (BMElem *)v_new);
|
||||
|
||||
v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */
|
||||
vtable[i] = v_new;
|
||||
|
@ -1069,6 +1073,7 @@ BMesh *BM_mesh_copy_ex(BMesh *bm_old, struct BMeshCreateParams *params)
|
|||
|
||||
BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff, 0x0);
|
||||
bm_alloc_id(bm_new, (BMElem *)e_new);
|
||||
bm_elem_check_toolflags(bm_new, (BMElem *)e_new);
|
||||
|
||||
e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */
|
||||
etable[i] = e_new;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_array.h"
|
||||
#include "BLI_asan.h"
|
||||
#include "BLI_linklist_stack.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_utildefines_stack.h"
|
||||
|
@ -53,6 +54,40 @@
|
|||
|
||||
#endif
|
||||
|
||||
ATTR_NO_OPT void bm_elem_check_toolflags(BMesh *bm, BMElem *elem)
|
||||
{
|
||||
int cd_off = -1;
|
||||
MToolFlags *flags;
|
||||
BLI_mempool *flagpool;
|
||||
|
||||
switch (elem->head.htype) {
|
||||
case BM_VERT:
|
||||
cd_off = bm->vdata.typemap[CD_TOOLFLAGS];
|
||||
cd_off = cd_off != -1 ? bm->vdata.layers[cd_off].offset : -1;
|
||||
flagpool = bm->vtoolflagpool;
|
||||
break;
|
||||
case BM_EDGE:
|
||||
cd_off = bm->edata.typemap[CD_TOOLFLAGS];
|
||||
cd_off = cd_off != -1 ? bm->edata.layers[cd_off].offset : -1;
|
||||
flagpool = bm->etoolflagpool;
|
||||
break;
|
||||
case BM_FACE:
|
||||
cd_off = bm->pdata.typemap[CD_TOOLFLAGS];
|
||||
cd_off = cd_off != -1 ? bm->pdata.layers[cd_off].offset : -1;
|
||||
flagpool = bm->ftoolflagpool;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cd_off == -1 || !flagpool) {
|
||||
return;
|
||||
}
|
||||
|
||||
flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(elem, cd_off);
|
||||
if (!flags->flag) {
|
||||
flags->flag = BLI_mempool_calloc(flagpool);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Main function for creating a new vertex.
|
||||
*/
|
||||
|
@ -79,11 +114,6 @@ BMVert *BM_vert_create(BMesh *bm,
|
|||
v->head.hflag = 0;
|
||||
v->head.api_flag = 0;
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags) {
|
||||
((BMVert_OFlag *)v)->oflags = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
/* 'v->no' is handled by BM_elem_attrs_copy */
|
||||
if (co) {
|
||||
copy_v3_v3(v->co, co);
|
||||
|
@ -137,6 +167,13 @@ BMVert *BM_vert_create(BMesh *bm,
|
|||
}
|
||||
}
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags && v->head.data) {
|
||||
int cd_tflags = bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(v, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->vtoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(v);
|
||||
|
||||
return v;
|
||||
|
@ -178,11 +215,6 @@ BMEdge *BM_edge_create(
|
|||
e->head.hflag = BM_ELEM_SMOOTH | BM_ELEM_DRAW;
|
||||
e->head.api_flag = 0;
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags) {
|
||||
((BMEdge_OFlag *)e)->oflags = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
e->v1 = v1;
|
||||
e->v2 = v2;
|
||||
e->l = NULL;
|
||||
|
@ -213,6 +245,13 @@ BMEdge *BM_edge_create(
|
|||
}
|
||||
}
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags && e->head.data) {
|
||||
int cd_tflags = bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(e, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->etoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(e);
|
||||
|
||||
return e;
|
||||
|
@ -366,6 +405,7 @@ BMFace *BM_face_copy(
|
|||
|
||||
BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
|
||||
bm_alloc_id(bm_dst, (BMElem *)f_copy);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)f_copy);
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
l_copy = BM_FACE_FIRST_LOOP(f_copy);
|
||||
|
@ -403,11 +443,6 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
|
|||
f->head.hflag = 0;
|
||||
f->head.api_flag = 0;
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags) {
|
||||
((BMFace_OFlag *)f)->oflags = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BLI_listbase_clear(&f->loops);
|
||||
#else
|
||||
|
@ -510,6 +545,13 @@ BMFace *BM_face_create(BMesh *bm,
|
|||
}
|
||||
}
|
||||
|
||||
/* allocate flags */
|
||||
if (bm->use_toolflags && f->head.data) {
|
||||
int cd_tflags = bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(f, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->ftoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(f);
|
||||
|
||||
return f;
|
||||
|
@ -779,13 +821,17 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
|
|||
|
||||
BM_select_history_remove(bm, v);
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
v, bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->vtoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
if (v->head.data) {
|
||||
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
|
||||
}
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
BLI_mempool_free(bm->vtoolflagpool, ((BMVert_OFlag *)v)->oflags);
|
||||
}
|
||||
BLI_mempool_free(bm->vpool, v);
|
||||
}
|
||||
|
||||
|
@ -880,13 +926,17 @@ void bm_kill_only_edge(BMesh *bm, BMEdge *e)
|
|||
|
||||
BM_select_history_remove(bm, (BMElem *)e);
|
||||
|
||||
if (bm->etoolflagpool) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
e, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
if (e->head.data) {
|
||||
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
|
||||
}
|
||||
|
||||
if (bm->etoolflagpool) {
|
||||
BLI_mempool_free(bm->etoolflagpool, ((BMEdge_OFlag *)e)->oflags);
|
||||
}
|
||||
BLI_mempool_free(bm->epool, e);
|
||||
}
|
||||
|
||||
|
@ -909,13 +959,17 @@ void bm_kill_only_face(BMesh *bm, BMFace *f)
|
|||
|
||||
BM_select_history_remove(bm, (BMElem *)f);
|
||||
|
||||
if (bm->ftoolflagpool) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
f, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->vtoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
if (f->head.data) {
|
||||
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
|
||||
}
|
||||
|
||||
if (bm->ftoolflagpool) {
|
||||
BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f)->oflags);
|
||||
}
|
||||
BLI_mempool_free(bm->fpool, f);
|
||||
}
|
||||
|
||||
|
@ -1525,6 +1579,12 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
|
|||
BM_elem_attrs_copy(bm, bm, f_example, f);
|
||||
bm_alloc_id(bm, (BMElem *)f);
|
||||
|
||||
if (bm->use_toolflags && f->head.data) {
|
||||
int cd_tflags = bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(f, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->ftoolflagpool);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -1723,7 +1783,10 @@ BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
|
|||
*
|
||||
* \return The newly created BMVert pointer.
|
||||
*/
|
||||
BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
|
||||
ATTR_NO_OPT BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm,
|
||||
BMVert *tv,
|
||||
BMEdge *e,
|
||||
BMEdge **r_e)
|
||||
{
|
||||
BMLoop *l_next;
|
||||
BMEdge *e_new;
|
||||
|
@ -2303,7 +2366,10 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
|
|||
|
||||
/* deallocate edge and its two loops as well as f2 */
|
||||
if (bm->etoolflagpool) {
|
||||
BLI_mempool_free(bm->etoolflagpool, ((BMEdge_OFlag *)l_f1->e)->oflags);
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
l_f1->e, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
}
|
||||
BLI_mempool_free(bm->epool, l_f1->e);
|
||||
bm->totedge--;
|
||||
|
@ -2311,9 +2377,14 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
|
|||
bm->totloop--;
|
||||
BLI_mempool_free(bm->lpool, l_f2);
|
||||
bm->totloop--;
|
||||
|
||||
if (bm->ftoolflagpool) {
|
||||
BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f2)->oflags);
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f2, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->ftoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->fpool, f2);
|
||||
bm->totface--;
|
||||
/* account for both above */
|
||||
|
|
|
@ -30,10 +30,14 @@ typedef enum eBMCreateFlag {
|
|||
/* Skip CustomData - for all element types data,
|
||||
* use if we immediately write customdata into the element so this skips copying from 'example'
|
||||
* args or setting defaults, speeds up conversion when data is converted all at once. */
|
||||
BM_CREATE_SKIP_CD = (1 << 2),
|
||||
BM_CREATE_SKIP_CD = (1 << 2), /* if true, you must call bm_elem_check_toolflags(bm, elem) later
|
||||
if toolflags are on */
|
||||
BM_CREATE_SKIP_ID = (1 << 3)
|
||||
} eBMCreateFlag;
|
||||
|
||||
/* if toolflags are enabled, checks that internal pointer to toolflags it not null */
|
||||
void bm_elem_check_toolflags(BMesh *bm, BMElem *elem);
|
||||
|
||||
BMVert *BM_vert_create(BMesh *bm,
|
||||
const float co[3],
|
||||
const BMVert *v_example,
|
||||
|
|
|
@ -66,6 +66,28 @@ void bm_restore_id(BMesh *bm, BMElem *elem, int id)
|
|||
}
|
||||
}
|
||||
|
||||
static void copy_cdata_simple(BMesh *bm,
|
||||
CustomData *data_layer,
|
||||
BMElem *ele_dst,
|
||||
const BMElem *ele_src)
|
||||
{
|
||||
int id = bm_save_id(bm, ele_dst);
|
||||
int cd_tflags;
|
||||
MToolFlags saved_tflags;
|
||||
|
||||
if ((cd_tflags = CustomData_get_offset(data_layer, CD_TOOLFLAGS)) != -1) {
|
||||
saved_tflags = *(MToolFlags *)BM_ELEM_CD_GET_VOID_P(ele_dst, cd_tflags);
|
||||
}
|
||||
|
||||
CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
|
||||
CustomData_bmesh_copy_data(data_layer, data_layer, ele_src->head.data, &ele_dst->head.data);
|
||||
|
||||
if (cd_tflags != -1) {
|
||||
*(MToolFlags *)BM_ELEM_CD_GET_VOID_P(ele_dst, cd_tflags) = saved_tflags;
|
||||
}
|
||||
bm_restore_id(bm, ele_dst, id);
|
||||
}
|
||||
|
||||
/* edge and vertex share, currently there's no need to have different logic */
|
||||
static void bm_data_interp_from_elem(BMesh *bm,
|
||||
CustomData *data_layer,
|
||||
|
@ -81,13 +103,7 @@ static void bm_data_interp_from_elem(BMesh *bm,
|
|||
/* do nothing */
|
||||
}
|
||||
else {
|
||||
int id = bm_save_id(bm, ele_dst);
|
||||
|
||||
CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
|
||||
CustomData_bmesh_copy_data(
|
||||
data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data);
|
||||
|
||||
bm_restore_id(bm, ele_dst, id);
|
||||
copy_cdata_simple(bm, data_layer, ele_dst, ele_src_1);
|
||||
}
|
||||
}
|
||||
else if (fac >= 1.0f) {
|
||||
|
@ -95,13 +111,7 @@ static void bm_data_interp_from_elem(BMesh *bm,
|
|||
/* do nothing */
|
||||
}
|
||||
else {
|
||||
int id = bm_save_id(bm, ele_dst);
|
||||
|
||||
CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
|
||||
CustomData_bmesh_copy_data(
|
||||
data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data);
|
||||
|
||||
bm_restore_id(bm, ele_dst, id);
|
||||
copy_cdata_simple(bm, data_layer, ele_dst, ele_src_2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "BKE_customdata.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh_private.h"
|
||||
#include "range_tree.h"
|
||||
|
@ -43,6 +45,8 @@
|
|||
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
|
||||
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
|
||||
|
||||
static void bm_alloc_toolflags(BMesh *bm);
|
||||
|
||||
static void bm_mempool_init_ex(const BMAllocTemplate *allocsize,
|
||||
const bool use_toolflags,
|
||||
BLI_mempool **r_vpool,
|
||||
|
@ -104,30 +108,15 @@ void BM_mesh_elem_toolflags_ensure(BMesh *bm)
|
|||
bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
BMIter iter;
|
||||
BMVert_OFlag *v_olfag;
|
||||
BLI_mempool *toolflagpool = bm->vtoolflagpool;
|
||||
BM_ITER_MESH (v_olfag, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
v_olfag->oflags = BLI_mempool_calloc(toolflagpool);
|
||||
}
|
||||
|
||||
BMEdge_OFlag *e_olfag;
|
||||
toolflagpool = bm->etoolflagpool;
|
||||
BM_ITER_MESH (e_olfag, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
e_olfag->oflags = BLI_mempool_calloc(toolflagpool);
|
||||
}
|
||||
|
||||
BMFace_OFlag *f_olfag;
|
||||
toolflagpool = bm->ftoolflagpool;
|
||||
BM_ITER_MESH (f_olfag, &iter, bm, BM_FACES_OF_MESH) {
|
||||
f_olfag->oflags = BLI_mempool_calloc(toolflagpool);
|
||||
}
|
||||
bm_alloc_toolflags(bm);
|
||||
|
||||
bm->totflags = 1;
|
||||
}
|
||||
|
||||
void BM_mesh_elem_toolflags_clear(BMesh *bm)
|
||||
ATTR_NO_OPT void BM_mesh_elem_toolflags_clear(BMesh *bm)
|
||||
{
|
||||
bool haveflags = bm->vtoolflagpool || bm->etoolflagpool || bm->ftoolflagpool;
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
bm->vtoolflagpool = NULL;
|
||||
|
@ -140,6 +129,12 @@ void BM_mesh_elem_toolflags_clear(BMesh *bm)
|
|||
BLI_mempool_destroy(bm->ftoolflagpool);
|
||||
bm->ftoolflagpool = NULL;
|
||||
}
|
||||
|
||||
if (haveflags) {
|
||||
BM_data_layer_free(bm, &bm->vdata, CD_TOOLFLAGS);
|
||||
BM_data_layer_free(bm, &bm->edata, CD_TOOLFLAGS);
|
||||
BM_data_layer_free(bm, &bm->pdata, CD_TOOLFLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
// int cdmap[8] = {0, 1, -1, -1, 2, -1, -1, -1, 3};
|
||||
|
@ -225,9 +220,19 @@ BMesh *BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreate
|
|||
CustomData_reset(&bm->ldata);
|
||||
CustomData_reset(&bm->pdata);
|
||||
|
||||
bool init_cdata_pools = false;
|
||||
|
||||
if (bm->use_toolflags) {
|
||||
init_cdata_pools = true;
|
||||
bm_alloc_toolflags_cdlayers(bm, false);
|
||||
}
|
||||
|
||||
if (params->create_unique_ids) {
|
||||
bm_init_idmap_cdlayers(bm);
|
||||
init_cdata_pools = true;
|
||||
}
|
||||
|
||||
if (init_cdata_pools) {
|
||||
if (bm->vdata.totlayer) {
|
||||
CustomData_bmesh_init_pool_ex(&bm->vdata, 0, BM_VERT, __func__);
|
||||
}
|
||||
|
@ -343,8 +348,20 @@ void BM_mesh_data_free(BMesh *bm)
|
|||
MEM_freeN(bm->ftable);
|
||||
}
|
||||
|
||||
/* destroy flag pool */
|
||||
BM_mesh_elem_toolflags_clear(bm);
|
||||
/* destroy flag pools */
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
bm->vtoolflagpool = NULL;
|
||||
}
|
||||
if (bm->etoolflagpool) {
|
||||
BLI_mempool_destroy(bm->etoolflagpool);
|
||||
bm->etoolflagpool = NULL;
|
||||
}
|
||||
if (bm->ftoolflagpool) {
|
||||
BLI_mempool_destroy(bm->ftoolflagpool);
|
||||
bm->ftoolflagpool = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BLI_mempool_destroy(bm->looplistpool);
|
||||
|
@ -1422,9 +1439,10 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
BMVert *v_dst = BLI_mempool_alloc(vpool_dst);
|
||||
memcpy(v_dst, v_src, sizeof(BMVert));
|
||||
if (use_toolflags) {
|
||||
((BMVert_OFlag *)v_dst)->oflags = bm->vtoolflagpool ?
|
||||
BLI_mempool_calloc(bm->vtoolflagpool) :
|
||||
NULL;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
v_dst, bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
vtable_dst[index] = v_dst;
|
||||
|
@ -1440,9 +1458,10 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
BMEdge *e_dst = BLI_mempool_alloc(epool_dst);
|
||||
memcpy(e_dst, e_src, sizeof(BMEdge));
|
||||
if (use_toolflags) {
|
||||
((BMEdge_OFlag *)e_dst)->oflags = bm->etoolflagpool ?
|
||||
BLI_mempool_calloc(bm->etoolflagpool) :
|
||||
NULL;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
e_dst, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
etable_dst[index] = e_dst;
|
||||
|
@ -1459,10 +1478,12 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
if (remap & BM_FACE) {
|
||||
BMFace *f_dst = BLI_mempool_alloc(fpool_dst);
|
||||
memcpy(f_dst, f_src, sizeof(BMFace));
|
||||
|
||||
if (use_toolflags) {
|
||||
((BMFace_OFlag *)f_dst)->oflags = bm->ftoolflagpool ?
|
||||
BLI_mempool_calloc(bm->ftoolflagpool) :
|
||||
NULL;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f_dst, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
ftable_dst[index] = f_dst;
|
||||
|
@ -1646,6 +1667,66 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
bm_rebuild_idmap(bm);
|
||||
}
|
||||
|
||||
void bm_alloc_toolflags_cdlayers(BMesh *bm, bool set_elems)
|
||||
{
|
||||
CustomData *cdatas[3] = {&bm->vdata, &bm->edata, &bm->pdata};
|
||||
int iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CustomData *cdata = cdatas[i];
|
||||
int cd_tflags = CustomData_get_offset(cdata, CD_TOOLFLAGS);
|
||||
|
||||
if (cd_tflags == -1) {
|
||||
if (set_elems) {
|
||||
BM_data_layer_add(bm, cdata, CD_TOOLFLAGS);
|
||||
}
|
||||
else {
|
||||
CustomData_add_layer(cdata, CD_TOOLFLAGS, CD_ASSIGN, NULL, 0);
|
||||
}
|
||||
|
||||
int idx = CustomData_get_layer_index(cdata, CD_TOOLFLAGS);
|
||||
|
||||
cdata->layers[idx].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY | CD_FLAG_ELEM_NOCOPY;
|
||||
cd_tflags = cdata->layers[idx].offset;
|
||||
|
||||
if (set_elems) {
|
||||
BMIter iter;
|
||||
BMElem *elem;
|
||||
|
||||
BM_ITER_MESH (elem, &iter, bm, iters[i]) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
|
||||
flags->flag = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bm_alloc_toolflags(BMesh *bm)
|
||||
{
|
||||
bm_alloc_toolflags_cdlayers(bm, true);
|
||||
|
||||
CustomData *cdatas[3] = {&bm->vdata, &bm->edata, &bm->pdata};
|
||||
BLI_mempool *flagpools[3] = {bm->vtoolflagpool, bm->etoolflagpool, bm->ftoolflagpool};
|
||||
BLI_mempool *elempools[3] = { bm->vpool, bm->epool, bm->fpool };
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CustomData *cdata = cdatas[i];
|
||||
int cd_tflags = CustomData_get_offset(cdata, CD_TOOLFLAGS);
|
||||
|
||||
BLI_mempool_iter iter;
|
||||
BLI_mempool_iternew(elempools[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
|
||||
flags->flag = BLI_mempool_calloc(flagpools[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-allocates mesh data with/without toolflags.
|
||||
*/
|
||||
|
@ -1655,14 +1736,6 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
|
|||
return;
|
||||
}
|
||||
|
||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm);
|
||||
|
||||
BLI_mempool *vpool_dst = NULL;
|
||||
BLI_mempool *epool_dst = NULL;
|
||||
BLI_mempool *fpool_dst = NULL;
|
||||
|
||||
bm_mempool_init_ex(&allocsize, use_toolflags, &vpool_dst, &epool_dst, NULL, &fpool_dst);
|
||||
|
||||
if (use_toolflags == false) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
BLI_mempool_destroy(bm->etoolflagpool);
|
||||
|
@ -1671,18 +1744,20 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
|
|||
bm->vtoolflagpool = NULL;
|
||||
bm->etoolflagpool = NULL;
|
||||
bm->ftoolflagpool = NULL;
|
||||
|
||||
BM_data_layer_free(bm, &bm->vdata, CD_TOOLFLAGS);
|
||||
BM_data_layer_free(bm, &bm->edata, CD_TOOLFLAGS);
|
||||
BM_data_layer_free(bm, &bm->pdata, CD_TOOLFLAGS);
|
||||
}
|
||||
else {
|
||||
bm_alloc_toolflags_cdlayers(bm, true);
|
||||
}
|
||||
|
||||
BM_mesh_rebuild(bm,
|
||||
&((struct BMeshCreateParams){
|
||||
.use_toolflags = use_toolflags,
|
||||
}),
|
||||
vpool_dst,
|
||||
epool_dst,
|
||||
NULL,
|
||||
fpool_dst);
|
||||
|
||||
bm->use_toolflags = use_toolflags;
|
||||
|
||||
if (use_toolflags) {
|
||||
BM_mesh_elem_toolflags_ensure(bm);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -472,6 +472,21 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
}
|
||||
}
|
||||
|
||||
if (bm->use_toolflags) {
|
||||
bm_alloc_toolflags_cdlayers(bm, !is_new);
|
||||
|
||||
if (!bm->vtoolflagpool) {
|
||||
bm->vtoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
bm->totflags = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_new) {
|
||||
CustomData_bmesh_init_pool_ex(&bm->vdata, me->totvert, BM_VERT, __func__);
|
||||
CustomData_bmesh_init_pool_ex(&bm->edata, me->totedge, BM_EDGE, __func__);
|
||||
|
@ -532,6 +547,8 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
/* Copy Custom Data */
|
||||
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
|
||||
|
||||
bm_elem_check_toolflags(bm, (BMElem *)v);
|
||||
|
||||
if (has_ids & BM_VERT) {
|
||||
if (use_exist_ids & BM_VERT) {
|
||||
bm_assign_id(bm, (BMElem *)v, existing_id_layers[0][i], false);
|
||||
|
@ -581,6 +598,8 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
/* Copy Custom Data */
|
||||
CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
|
||||
|
||||
bm_elem_check_toolflags(bm, (BMElem *)e);
|
||||
|
||||
if (has_ids & BM_EDGE) {
|
||||
if (use_exist_ids & BM_EDGE) {
|
||||
bm_assign_id(bm, (BMElem *)e, existing_id_layers[1][i], false);
|
||||
|
@ -665,6 +684,8 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
/* Copy Custom Data */
|
||||
CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
|
||||
|
||||
bm_elem_check_toolflags(bm, (BMElem *)f);
|
||||
|
||||
if (has_ids & BM_FACE) {
|
||||
if (use_exist_ids & BM_FACE) {
|
||||
bm_assign_id(bm, (BMElem *)f, existing_id_layers[3][i], false);
|
||||
|
|
|
@ -34,7 +34,9 @@ static BMVert *bm_vert_copy(BMesh *bm_src, BMesh *bm_dst, BMVert *v_src)
|
|||
{
|
||||
BMVert *v_dst = BM_vert_create(bm_dst, v_src->co, NULL, BM_CREATE_SKIP_CD);
|
||||
BM_elem_attrs_copy(bm_src, bm_dst, v_src, v_dst);
|
||||
|
||||
bm_alloc_id(bm_dst, (BMElem *)v_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)v_dst);
|
||||
|
||||
return v_dst;
|
||||
}
|
||||
|
@ -47,8 +49,11 @@ static BMEdge *bm_edge_copy_with_arrays(BMesh *bm_src,
|
|||
BMVert *e_dst_v1 = verts_dst[BM_elem_index_get(e_src->v1)];
|
||||
BMVert *e_dst_v2 = verts_dst[BM_elem_index_get(e_src->v2)];
|
||||
BMEdge *e_dst = BM_edge_create(bm_dst, e_dst_v1, e_dst_v2, NULL, BM_CREATE_SKIP_CD);
|
||||
|
||||
BM_elem_attrs_copy(bm_src, bm_dst, e_src, e_dst);
|
||||
|
||||
bm_alloc_id(bm_dst, (BMElem *)e_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)e_dst);
|
||||
|
||||
return e_dst;
|
||||
}
|
||||
|
@ -78,7 +83,9 @@ static BMFace *bm_face_copy_with_arrays(
|
|||
|
||||
/* Copy attributes. */
|
||||
BM_elem_attrs_copy(bm_src, bm_dst, f_src, f_dst);
|
||||
|
||||
bm_alloc_id(bm_dst, (BMElem *)f_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)f_dst);
|
||||
|
||||
/* Copy per-loop custom data. */
|
||||
l_iter_src = l_first_src;
|
||||
|
|
|
@ -593,7 +593,7 @@ BMVert *BM_edge_collapse(BMesh *bm,
|
|||
* \param r_e: The newly created edge.
|
||||
* \return The new vertex.
|
||||
*/
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
|
||||
ATTR_NO_OPT BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
|
||||
{
|
||||
BMVert *v_new, *v_other;
|
||||
BMEdge *e_new;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -68,122 +69,142 @@ extern "C" {
|
|||
|
||||
struct GHashIterator;
|
||||
|
||||
BLI_INLINE BMFlagLayer *BMO_elem_flag_from_header(BMHeader *ele_head)
|
||||
ATTR_NO_OPT static BMFlagLayer *BMO_elem_flag_from_header(BMesh *bm, BMElem *ele)
|
||||
{
|
||||
switch (ele_head->htype) {
|
||||
int cd_tflags;
|
||||
|
||||
switch (ele->head.htype) {
|
||||
case BM_VERT:
|
||||
return ((BMVert_OFlag *)ele_head)->oflags;
|
||||
cd_tflags = bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
break;
|
||||
case BM_EDGE:
|
||||
return ((BMEdge_OFlag *)ele_head)->oflags;
|
||||
cd_tflags = bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset;
|
||||
break;
|
||||
case BM_FACE:
|
||||
cd_tflags = bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
break;
|
||||
default:
|
||||
return ((BMFace_OFlag *)ele_head)->oflags;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(ele, cd_tflags);
|
||||
|
||||
return (BMFlagLayer *)flags->flag;
|
||||
}
|
||||
|
||||
#define BMO_elem_flag_test(bm, ele, oflag) \
|
||||
_bmo_elem_flag_test(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
|
||||
_bmo_elem_flag_test(bm, BMO_elem_flag_from_header(bm, (BMElem *)(ele)), oflag)
|
||||
#define BMO_elem_flag_test_bool(bm, ele, oflag) \
|
||||
_bmo_elem_flag_test_bool(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
|
||||
_bmo_elem_flag_test_bool(bm, BMO_elem_flag_from_header(bm, (BMElem *)(ele)), oflag)
|
||||
#define BMO_elem_flag_enable(bm, ele, oflag) \
|
||||
_bmo_elem_flag_enable( \
|
||||
bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
|
||||
bm, \
|
||||
(BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(bm, (BMElem *)(ele))), \
|
||||
oflag)
|
||||
#define BMO_elem_flag_disable(bm, ele, oflag) \
|
||||
_bmo_elem_flag_disable( \
|
||||
bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
|
||||
bm, \
|
||||
(BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(bm, (BMElem *)(ele))), \
|
||||
oflag)
|
||||
#define BMO_elem_flag_set(bm, ele, oflag, val) \
|
||||
_bmo_elem_flag_set(bm, \
|
||||
(BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), \
|
||||
oflag, \
|
||||
val)
|
||||
_bmo_elem_flag_set( \
|
||||
bm, \
|
||||
(BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(bm, (BMElem *)(ele))), \
|
||||
oflag, \
|
||||
val)
|
||||
#define BMO_elem_flag_toggle(bm, ele, oflag) \
|
||||
_bmo_elem_flag_toggle( \
|
||||
bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
|
||||
bm, \
|
||||
(BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(bm, (BMElem *)(ele))), \
|
||||
oflag)
|
||||
|
||||
/* take care not to instantiate args multiple times */
|
||||
#ifdef __GNUC___
|
||||
# define _BMO_CAST_V_CONST(e) \
|
||||
({ \
|
||||
#ifdef __GNUC__
|
||||
/* clang-format off */
|
||||
#define _BMO_CAST_V_CONST(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_VERT(_e), \
|
||||
(const BMFlagLayer*) BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_VERT), \
|
||||
(const BMVert_OFlag *)_e); \
|
||||
})
|
||||
# define _BMO_CAST_E_CONST(e) \
|
||||
({ \
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_EDGE(_e), \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), \
|
||||
(const BMEdge_OFlag *)_e); \
|
||||
})
|
||||
# define _BMO_CAST_F_CONST(e) \
|
||||
({ \
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_FACE(_e), \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), \
|
||||
(const BMFace_OFlag *)_e); \
|
||||
})
|
||||
# define _BMO_CAST_V(e) \
|
||||
({ \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
#define _BMO_CAST_V(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_VERT_NONCONST(_e), \
|
||||
BLI_assert(((BMHeader *)_e)->htype == BM_VERT), \
|
||||
(BMVert_OFlag *)_e); \
|
||||
})
|
||||
# define _BMO_CAST_E(e) \
|
||||
({ \
|
||||
BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_VERT), \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
|
||||
#define _BMO_CAST_E_CONST(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_EDGE_NONCONST(_e), \
|
||||
BLI_assert(((BMHeader *)_e)->htype == BM_EDGE), \
|
||||
(BMEdge_OFlag *)_e); \
|
||||
})
|
||||
# define _BMO_CAST_F(e) \
|
||||
({ \
|
||||
(BM_CHECK_TYPE_VERT(_e), \
|
||||
(const BMFlagLayer*) BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
#define _BMO_CAST_E(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_FACE_NONCONST(_e), \
|
||||
BLI_assert(((BMHeader *)_e)->htype == BM_FACE), \
|
||||
(BMFace_OFlag *)_e); \
|
||||
})
|
||||
(BM_CHECK_TYPE_VERT_NONCONST(_e), \
|
||||
BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
|
||||
#define _BMO_CAST_F_CONST(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_VERT(_e), \
|
||||
(const BMFlagLayer*) BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
#define _BMO_CAST_F(bm, e) ({\
|
||||
typeof(e) _e = e; \
|
||||
(BM_CHECK_TYPE_VERT_NONCONST(_e), \
|
||||
BMO_elem_flag_from_header(bm, \
|
||||
BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), \
|
||||
(BMElem*)_e)); \
|
||||
})
|
||||
|
||||
/* clang-format on */
|
||||
#else
|
||||
# define _BMO_CAST_V_CONST(e) (BM_CHECK_TYPE_VERT(e), (const BMVert_OFlag *)e)
|
||||
# define _BMO_CAST_E_CONST(e) (BM_CHECK_TYPE_EDGE(e), (const BMEdge_OFlag *)e)
|
||||
# define _BMO_CAST_F_CONST(e) (BM_CHECK_TYPE_FACE(e), (const BMFace_OFlag *)e)
|
||||
# define _BMO_CAST_V(e) (BM_CHECK_TYPE_VERT_NONCONST(e), (BMVert_OFlag *)e)
|
||||
# define _BMO_CAST_E(e) (BM_CHECK_TYPE_EDGE_NONCONST(e), (BMEdge_OFlag *)e)
|
||||
# define _BMO_CAST_F(e) (BM_CHECK_TYPE_FACE_NONCONST(e), (BMFace_OFlag *)e)
|
||||
# define _BMO_CAST_V_CONST(bm, e) \
|
||||
(BM_CHECK_TYPE_VERT(e), (const BMFlagLayer *)BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
# define _BMO_CAST_E_CONST(bm, e) \
|
||||
(BM_CHECK_TYPE_EDGE(e), (const BMFlagLayer *)BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
# define _BMO_CAST_F_CONST(bm, e) \
|
||||
(BM_CHECK_TYPE_FACE(e), (const BMFlagLayer *)BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
# define _BMO_CAST_V(bm, e) \
|
||||
(BM_CHECK_TYPE_VERT_NONCONST(e), BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
# define _BMO_CAST_E(bm, e) \
|
||||
(BM_CHECK_TYPE_EDGE_NONCONST(e), BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
# define _BMO_CAST_F(bm, e) \
|
||||
(BM_CHECK_TYPE_FACE_NONCONST(e), BMO_elem_flag_from_header(bm, (BMElem *)(e)))
|
||||
#endif
|
||||
|
||||
#define BMO_vert_flag_test(bm, e, oflag) \
|
||||
_bmo_elem_flag_test(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
|
||||
#define BMO_vert_flag_test(bm, e, oflag) _bmo_elem_flag_test(bm, _BMO_CAST_V_CONST(bm, e), oflag)
|
||||
#define BMO_vert_flag_test_bool(bm, e, oflag) \
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
|
||||
#define BMO_vert_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_V(e)->oflags, oflag)
|
||||
#define BMO_vert_flag_disable(bm, e, oflag) \
|
||||
_bmo_elem_flag_disable(bm, _BMO_CAST_V(e)->oflags, oflag)
|
||||
#define BMO_vert_flag_set(bm, e, oflag, val) \
|
||||
_bmo_elem_flag_set(bm, _BMO_CAST_V(e)->oflags, oflag, val)
|
||||
#define BMO_vert_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_V(e)->oflags, oflag)
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_V_CONST(bm, e), oflag)
|
||||
#define BMO_vert_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_V(bm, e), oflag)
|
||||
#define BMO_vert_flag_disable(bm, e, oflag) _bmo_elem_flag_disable(bm, _BMO_CAST_V(bm, e), oflag)
|
||||
#define BMO_vert_flag_set(bm, e, oflag, val) _bmo_elem_flag_set(bm, _BMO_CAST_V(bm, e), oflag, val)
|
||||
#define BMO_vert_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_V(bm, e), oflag)
|
||||
|
||||
#define BMO_edge_flag_test(bm, e, oflag) \
|
||||
_bmo_elem_flag_test(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
|
||||
#define BMO_edge_flag_test(bm, e, oflag) _bmo_elem_flag_test(bm, _BMO_CAST_E_CONST(bm, e), oflag)
|
||||
#define BMO_edge_flag_test_bool(bm, e, oflag) \
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
|
||||
#define BMO_edge_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_E(e)->oflags, oflag)
|
||||
#define BMO_edge_flag_disable(bm, e, oflag) \
|
||||
_bmo_elem_flag_disable(bm, _BMO_CAST_E(e)->oflags, oflag)
|
||||
#define BMO_edge_flag_set(bm, e, oflag, val) \
|
||||
_bmo_elem_flag_set(bm, _BMO_CAST_E(e)->oflags, oflag, val)
|
||||
#define BMO_edge_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_E(e)->oflags, oflag)
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_E_CONST(bm, e), oflag)
|
||||
#define BMO_edge_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_E(bm, e), oflag)
|
||||
#define BMO_edge_flag_disable(bm, e, oflag) _bmo_elem_flag_disable(bm, _BMO_CAST_E(bm, e), oflag)
|
||||
#define BMO_edge_flag_set(bm, e, oflag, val) _bmo_elem_flag_set(bm, _BMO_CAST_E(bm, e), oflag, val)
|
||||
#define BMO_edge_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_E(bm, e), oflag)
|
||||
|
||||
#define BMO_face_flag_test(bm, e, oflag) \
|
||||
_bmo_elem_flag_test(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
|
||||
#define BMO_face_flag_test(bm, e, oflag) _bmo_elem_flag_test(bm, _BMO_CAST_F_CONST(bm, e), oflag)
|
||||
#define BMO_face_flag_test_bool(bm, e, oflag) \
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
|
||||
#define BMO_face_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_F(e)->oflags, oflag)
|
||||
#define BMO_face_flag_disable(bm, e, oflag) \
|
||||
_bmo_elem_flag_disable(bm, _BMO_CAST_F(e)->oflags, oflag)
|
||||
#define BMO_face_flag_set(bm, e, oflag, val) \
|
||||
_bmo_elem_flag_set(bm, _BMO_CAST_F(e)->oflags, oflag, val)
|
||||
#define BMO_face_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_F(e)->oflags, oflag)
|
||||
_bmo_elem_flag_test_bool(bm, _BMO_CAST_F_CONST(bm, e), oflag)
|
||||
#define BMO_face_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_F(bm, e), oflag)
|
||||
#define BMO_face_flag_disable(bm, e, oflag) _bmo_elem_flag_disable(bm, _BMO_CAST_F(bm, e), oflag)
|
||||
#define BMO_face_flag_set(bm, e, oflag, val) _bmo_elem_flag_set(bm, _BMO_CAST_F(bm, e), oflag, val)
|
||||
#define BMO_face_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_F(bm, e), oflag)
|
||||
|
||||
BLI_INLINE short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
|
||||
BLI_INLINE bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
|
||||
|
|
|
@ -30,6 +30,7 @@ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
|
|||
short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
|
||||
{
|
||||
BLI_assert(bm->use_toolflags);
|
||||
|
||||
return oflags[bm->toolflag_index].f & oflag;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,13 @@
|
|||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "intern/bmesh_private.h"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
/* forward declarations */
|
||||
static void bmo_flag_layer_alloc(BMesh *bm);
|
||||
static void bmo_flag_layer_free(BMesh *bm);
|
||||
|
@ -1248,6 +1252,68 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
|
|||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void bmo_flag_layer_do(BMesh *bm,
|
||||
int new_totflags,
|
||||
void (*callback)(BMesh *bm,
|
||||
int cd_tflags,
|
||||
int itertype,
|
||||
int htype,
|
||||
int totelem,
|
||||
int new_totflags,
|
||||
BLI_mempool **pool_ptr))
|
||||
{
|
||||
int iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
|
||||
int types[3] = {BM_VERT, BM_EDGE, BM_FACE};
|
||||
int tots[3] = {bm->totvert, bm->totedge, bm->totface};
|
||||
|
||||
BLI_mempool **pools[3] = {&bm->vtoolflagpool, &bm->etoolflagpool, &bm->ftoolflagpool};
|
||||
CustomData *cdatas[3] = {&bm->vdata, &bm->edata, &bm->pdata};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int cd_tflags = CustomData_get_offset(cdatas[i], CD_TOOLFLAGS);
|
||||
|
||||
if (cd_tflags == -1) {
|
||||
printf("eek!\n");
|
||||
}
|
||||
|
||||
callback(bm, cd_tflags, iters[i], types[i], tots[i], new_totflags, pools[i]);
|
||||
}
|
||||
|
||||
bm->totflags = new_totflags;
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void bmo_flag_layer_alloc_do(BMesh *bm,
|
||||
int cd_tflags,
|
||||
int itertype,
|
||||
int htype,
|
||||
int totelem,
|
||||
int new_totflags,
|
||||
BLI_mempool **pool_ptr)
|
||||
{
|
||||
BMIter iter;
|
||||
BMElem *elem;
|
||||
int i;
|
||||
|
||||
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
|
||||
BLI_mempool *oldpool = *pool_ptr;
|
||||
BLI_mempool *newpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer) * new_totflags, totelem, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
BM_ITER_MESH_INDEX (elem, &iter, bm, itertype, i) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
|
||||
short *oldflags = flags->flag;
|
||||
flags->flag = BLI_mempool_calloc(newpool);
|
||||
|
||||
memcpy(flags->flag, oldflags, old_totflags_size);
|
||||
BM_elem_index_set(elem, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)elem);
|
||||
}
|
||||
|
||||
*pool_ptr = newpool;
|
||||
BLI_mempool_destroy(oldpool);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief ALLOC/FREE FLAG LAYER
|
||||
*
|
||||
|
@ -1261,165 +1327,42 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
|
|||
* all operators have been executed. This would
|
||||
* save a lot of realloc potentially.
|
||||
*/
|
||||
static void bmo_flag_layer_alloc(BMesh *bm)
|
||||
ATTR_NO_OPT static void bmo_flag_layer_alloc(BMesh *bm)
|
||||
{
|
||||
/* set the index values since we are looping over all data anyway,
|
||||
* may save time later on */
|
||||
|
||||
BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */
|
||||
BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */
|
||||
BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */
|
||||
|
||||
/* store memcpy size for reuse */
|
||||
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
|
||||
|
||||
bm->totflags++;
|
||||
|
||||
bm->vtoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer) * bm->totflags, bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer) * bm->totflags, bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(
|
||||
sizeof(BMFlagLayer) * bm->totflags, bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
/* now go through and memcpy all the flags. Loops don't get a flag layer at this time. */
|
||||
BMIter iter;
|
||||
int i;
|
||||
|
||||
BMVert_OFlag *v_oflag;
|
||||
BLI_mempool *newpool = bm->vtoolflagpool;
|
||||
BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
void *oldflags = v_oflag->oflags;
|
||||
v_oflag->oflags = BLI_mempool_calloc(newpool);
|
||||
memcpy(v_oflag->oflags, oldflags, old_totflags_size);
|
||||
BM_elem_index_set(&v_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
|
||||
}
|
||||
|
||||
BMEdge_OFlag *e_oflag;
|
||||
newpool = bm->etoolflagpool;
|
||||
BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
void *oldflags = e_oflag->oflags;
|
||||
e_oflag->oflags = BLI_mempool_calloc(newpool);
|
||||
memcpy(e_oflag->oflags, oldflags, old_totflags_size);
|
||||
BM_elem_index_set(&e_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
|
||||
}
|
||||
|
||||
BMFace_OFlag *f_oflag;
|
||||
newpool = bm->ftoolflagpool;
|
||||
BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
void *oldflags = f_oflag->oflags;
|
||||
f_oflag->oflags = BLI_mempool_calloc(newpool);
|
||||
memcpy(f_oflag->oflags, oldflags, old_totflags_size);
|
||||
BM_elem_index_set(&f_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
|
||||
}
|
||||
|
||||
BLI_mempool_destroy(voldpool);
|
||||
BLI_mempool_destroy(eoldpool);
|
||||
BLI_mempool_destroy(foldpool);
|
||||
|
||||
bmo_flag_layer_do(bm, bm->totflags + 1, bmo_flag_layer_alloc_do);
|
||||
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
|
||||
}
|
||||
|
||||
static void bmo_flag_layer_free(BMesh *bm)
|
||||
ATTR_NO_OPT static void bmo_flag_layer_free(BMesh *bm)
|
||||
{
|
||||
/* set the index values since we are looping over all data anyway,
|
||||
* may save time later on */
|
||||
|
||||
BLI_mempool *voldpool = bm->vtoolflagpool;
|
||||
BLI_mempool *eoldpool = bm->etoolflagpool;
|
||||
BLI_mempool *foldpool = bm->ftoolflagpool;
|
||||
bmo_flag_layer_do(bm, bm->totflags - 1, bmo_flag_layer_alloc_do);
|
||||
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
|
||||
}
|
||||
|
||||
/* store memcpy size for reuse */
|
||||
const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer));
|
||||
|
||||
/* de-increment the totflags first. */
|
||||
bm->totflags--;
|
||||
|
||||
bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
/* now go through and memcpy all the flag */
|
||||
ATTR_NO_OPT static void bmo_flag_layer_clear_do(BMesh *bm,
|
||||
int cd_tflags,
|
||||
int itertype,
|
||||
int htype,
|
||||
int totelem,
|
||||
int totflag,
|
||||
BLI_mempool **pool_ptr)
|
||||
{
|
||||
BMIter iter;
|
||||
BMElem *elem;
|
||||
int i;
|
||||
|
||||
BMVert_OFlag *v_oflag;
|
||||
BLI_mempool *newpool = bm->vtoolflagpool;
|
||||
BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
void *oldflags = v_oflag->oflags;
|
||||
v_oflag->oflags = BLI_mempool_alloc(newpool);
|
||||
memcpy(v_oflag->oflags, oldflags, new_totflags_size);
|
||||
BM_elem_index_set(&v_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
|
||||
BM_ITER_MESH_INDEX (elem, &iter, bm, itertype, i) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
flags->flag[totflag - 1] = 0;
|
||||
|
||||
BM_elem_index_set(elem, i); /* set_inline */
|
||||
}
|
||||
|
||||
BMEdge_OFlag *e_oflag;
|
||||
newpool = bm->etoolflagpool;
|
||||
BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
void *oldflags = e_oflag->oflags;
|
||||
e_oflag->oflags = BLI_mempool_alloc(newpool);
|
||||
memcpy(e_oflag->oflags, oldflags, new_totflags_size);
|
||||
BM_elem_index_set(&e_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
|
||||
}
|
||||
|
||||
BMFace_OFlag *f_oflag;
|
||||
newpool = bm->ftoolflagpool;
|
||||
BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
void *oldflags = f_oflag->oflags;
|
||||
f_oflag->oflags = BLI_mempool_alloc(newpool);
|
||||
memcpy(f_oflag->oflags, oldflags, new_totflags_size);
|
||||
BM_elem_index_set(&f_oflag->base, i); /* set_inline */
|
||||
BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
|
||||
}
|
||||
|
||||
BLI_mempool_destroy(voldpool);
|
||||
BLI_mempool_destroy(eoldpool);
|
||||
BLI_mempool_destroy(foldpool);
|
||||
|
||||
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
|
||||
}
|
||||
|
||||
static void bmo_flag_layer_clear(BMesh *bm)
|
||||
{
|
||||
/* set the index values since we are looping over all data anyway,
|
||||
* may save time later on */
|
||||
const BMFlagLayer zero_flag = {0};
|
||||
|
||||
const int totflags_offset = bm->totflags - 1;
|
||||
|
||||
/* now go through and memcpy all the flag */
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert_OFlag *ele;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
ele->oflags[totflags_offset] = zero_flag;
|
||||
BM_elem_index_set(&ele->base, i); /* set_inline */
|
||||
}
|
||||
}
|
||||
{
|
||||
BMIter iter;
|
||||
BMEdge_OFlag *ele;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
ele->oflags[totflags_offset] = zero_flag;
|
||||
BM_elem_index_set(&ele->base, i); /* set_inline */
|
||||
}
|
||||
}
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace_OFlag *ele;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
ele->oflags[totflags_offset] = zero_flag;
|
||||
BM_elem_index_set(&ele->base, i); /* set_inline */
|
||||
}
|
||||
}
|
||||
|
||||
bmo_flag_layer_do(bm, bm->totflags, bmo_flag_layer_clear_do);
|
||||
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,9 @@ int bmesh_radial_length(const BMLoop *l);
|
|||
int bmesh_disk_count_at_most(const BMVert *v, const int count_max);
|
||||
int bmesh_disk_count(const BMVert *v);
|
||||
void bm_rebuild_idmap(BMesh *bm);
|
||||
void bm_alloc_toolflags_cdlayers(BMesh *bm, bool set_elems);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Internal BMHeader.api_flag
|
||||
* \note Ensure different parts of the API do not conflict
|
||||
* on using these internal flags!
|
||||
|
|
|
@ -63,6 +63,7 @@ static BMVert *bmo_vert_copy(BMOperator *op,
|
|||
|
||||
/* Handle Ids */
|
||||
bm_alloc_id(bm_dst, (BMElem *)v_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)v_dst);
|
||||
|
||||
/* Mark the vert for output */
|
||||
BMO_vert_flag_enable(bm_dst, v_dst, DUPE_NEW);
|
||||
|
@ -128,6 +129,7 @@ static BMEdge *bmo_edge_copy(BMOperator *op,
|
|||
|
||||
/* Handle Ids */
|
||||
bm_alloc_id(bm_dst, (BMElem *)e_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)e_dst);
|
||||
|
||||
/* Mark the edge for output */
|
||||
BMO_edge_flag_enable(bm_dst, e_dst, DUPE_NEW);
|
||||
|
@ -181,8 +183,9 @@ static BMFace *bmo_face_copy(BMOperator *op,
|
|||
/* Copy attributes */
|
||||
BM_elem_attrs_copy(bm_src, bm_dst, f_src, f_dst);
|
||||
|
||||
/* Handle Ids */
|
||||
/* Handle Ids and toolflags */
|
||||
bm_alloc_id(bm_dst, (BMElem *)f_dst);
|
||||
bm_elem_check_toolflags(bm_dst, (BMElem *)f_dst);
|
||||
|
||||
/* copy per-loop custom data */
|
||||
l_iter_src = l_first_src;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_stack.h"
|
||||
#include "BLI_utildefines_stack.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
|
@ -290,7 +291,12 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
|
|||
bmesh_face_swap_data(f_new, f);
|
||||
|
||||
if (bm->use_toolflags) {
|
||||
SWAP(BMFlagLayer *, ((BMFace_OFlag *)f)->oflags, ((BMFace_OFlag *)f_new)->oflags);
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
MToolFlags *flags_new = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f_new, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
SWAP(short *, flags->flag, flags_new->flag);
|
||||
}
|
||||
|
||||
BMO_face_flag_disable(bm, f, ELE_DEL);
|
||||
|
|
|
@ -2451,6 +2451,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
BMesh *bm = sculpt_faceset_bm_begin(ss, mesh);
|
||||
if (ss->bm) {
|
||||
BKE_pbvh_bmesh_set_toolflags(ss->pbvh, true);
|
||||
SCULPT_update_customdata_refs(ss);
|
||||
}
|
||||
|
||||
BM_mesh_elem_table_init(bm, BM_FACE);
|
||||
|
@ -2653,7 +2654,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
case BM_EDGE: {
|
||||
BMEdge *e = (BMEdge *)ele;
|
||||
BM_log_edge_added(ss->bm_log, e);
|
||||
|
||||
#if 0
|
||||
if (!BM_elem_flag_test(e->v1, tag1)) {
|
||||
BM_elem_flag_enable(e->v1, tag1);
|
||||
BM_log_vert_added(ss->bm_log, e->v1, ss->cd_vert_mask_offset);
|
||||
|
@ -2680,7 +2681,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
} while ((l = l->radial_next) != e->l);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case BM_FACE: {
|
||||
|
@ -2689,7 +2690,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
if (dot_v3v3(f->no, f->no) > 0.0f) {
|
||||
add_v3_v3(no, f->no);
|
||||
}
|
||||
|
||||
#if 0
|
||||
BMLoop *l = f->l_first;
|
||||
do {
|
||||
if (!(l->v->head.hflag & tag1)) {
|
||||
|
@ -2702,7 +2703,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
BM_log_edge_added(ss->bm_log, l->e);
|
||||
}
|
||||
} while ((l = l->next) != f->l_first);
|
||||
|
||||
#endif
|
||||
BKE_pbvh_bmesh_add_face(ss->pbvh, f, false, false);
|
||||
BM_log_face_added(ss->bm_log, f);
|
||||
break;
|
||||
|
@ -2757,7 +2758,8 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
if (cd_dyn_vert >= 0) {
|
||||
do {
|
||||
MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(l->v, cd_dyn_vert);
|
||||
mv->flag |= DYNVERT_NEED_BOUNDARY|DYNVERT_NEED_DISK_SORT|DYNVERT_NEED_TRIANGULATE|DYNVERT_NEED_VALENCE;
|
||||
mv->flag |= DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_DISK_SORT | DYNVERT_NEED_TRIANGULATE |
|
||||
DYNVERT_NEED_VALENCE;
|
||||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
|
@ -2841,6 +2843,7 @@ ATTR_NO_OPT static void sculpt_face_set_extrude_id(
|
|||
sculpt_faceset_bm_end(ss, bm);
|
||||
if (ss->bm) {
|
||||
BKE_pbvh_bmesh_set_toolflags(ss->pbvh, false);
|
||||
SCULPT_update_customdata_refs(ss);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,8 +84,7 @@ typedef struct CustomData {
|
|||
* MUST be >= CD_NUMTYPES, but we can't use a define here.
|
||||
* Correct size is ensured in CustomData_update_typemap assert().
|
||||
*/
|
||||
int typemap[54];
|
||||
char _pad[4];
|
||||
int typemap[55];
|
||||
|
||||
/** Number of layers, size of layers array. */
|
||||
int totlayer, maxlayer;
|
||||
|
@ -171,7 +170,8 @@ typedef enum CustomDataType {
|
|||
CD_HAIRLENGTH = 51,
|
||||
CD_MESH_ID = 52,
|
||||
CD_DYNTOPO_VERT = 53,
|
||||
CD_NUMTYPES = 54,
|
||||
CD_TOOLFLAGS = 54,
|
||||
CD_NUMTYPES = 55,
|
||||
} CustomDataType;
|
||||
|
||||
/* Bits for CustomDataMask */
|
||||
|
@ -228,6 +228,7 @@ typedef enum CustomDataType {
|
|||
#define CD_MASK_DYNTOPO_VERT (1ULL << CD_DYNTOPO_VERT)
|
||||
#define CD_MASK_MESH_ID (1ULL << CD_MESH_ID)
|
||||
#define CD_MASK_HAIRLENGTH (1ULL << CD_HAIRLENGTH)
|
||||
#define CD_MASK_TOOLFLAGS (1ULL << CD_TOOLFLAGS)
|
||||
|
||||
/** Multires loop data. */
|
||||
#define CD_MASK_MULTIRES_GRIDS (CD_MASK_MDISPS | CD_GRID_PAINT_MASK)
|
||||
|
|
|
@ -542,7 +542,7 @@ typedef struct MDynTopoVert {
|
|||
int stroke_id;
|
||||
} MDynTopoVert;
|
||||
|
||||
/*MDynTopoVert->flag*/
|
||||
/* MDynTopoVert->flag */
|
||||
enum {
|
||||
DYNVERT_BOUNDARY = (1 << 0),
|
||||
DYNVERT_VERT_FSET_HIDDEN = (1 << 1),
|
||||
|
@ -561,6 +561,11 @@ enum {
|
|||
DYNVERT_PBVH_BOUNDARY = (1 << 14)
|
||||
};
|
||||
|
||||
/* for internal bmesh toolflags api */
|
||||
typedef struct MToolFlags {
|
||||
short *flag;
|
||||
} MToolFlags;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue