diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-11-26 08:19:56 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-11-26 08:19:56 +0300 |
commit | 77829369771e1cb44bd85c5a4abdda02f6f42103 (patch) | |
tree | d3535b0c6a894ec82bf334d91a64a9706ea007b5 | |
parent | 0a3f0e64c9d226d1cee648a6411d0eb561d5c6e5 (diff) |
BMesh: support copying & freeing layers by type
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 70 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 96 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.h | 2 |
4 files changed, 99 insertions, 77 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index f5665707a0c..a4a36343ca3 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -258,6 +258,11 @@ void CustomData_bmesh_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block); +void CustomData_bmesh_copy_data_exclude_by_type(const struct CustomData *source, + struct CustomData *dest, + void *src_block, + void **dest_block, + const CustomDataMask mask_exclude); /* Copies data of a single layer of a given type. */ void CustomData_copy_layer_type_data(const struct CustomData *source, @@ -392,6 +397,9 @@ void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag); void CustomData_bmesh_set_default(struct CustomData *data, void **block); void CustomData_bmesh_free_block(struct CustomData *data, void **block); void CustomData_bmesh_free_block_data(struct CustomData *data, void *block); +void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data, + void *block, + const CustomDataMask mask_exclude); /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh * blocks of data. the CustomData's must not be compatible */ diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 8ac0f71cd7e..93db44ce60a 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -3415,24 +3415,18 @@ void CustomData_bmesh_free_block(CustomData *data, void **block) */ void CustomData_bmesh_free_block_data(CustomData *data, void *block) { - const LayerTypeInfo *typeInfo; - int i; - if (block == NULL) { return; } - - for (i = 0; i < data->totlayer; i++) { + for (int i = 0; i < data->totlayer; i++) { if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { - typeInfo = layerType_getInfo(data->layers[i].type); - + const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type); if (typeInfo->free) { const size_t offset = data->layers[i].offset; typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size); } } } - if (data->totsize) { memset(block, 0, data->totsize); } @@ -3453,6 +3447,30 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block) } } +/** + * A selective version of #CustomData_bmesh_free_block_data. + */ +void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data, + void *block, + const CustomDataMask mask_exclude) +{ + if (block == NULL) { + return; + } + for (int i = 0; i < data->totlayer; i++) { + if ((CD_TYPE_AS_MASK(data->layers[i].type) & mask_exclude) == 0) { + const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type); + const size_t offset = data->layers[i].offset; + if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { + if (typeInfo->free) { + typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size); + } + } + memset(POINTER_OFFSET(block, offset), 0, typeInfo->size); + } + } +} + static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n) { const LayerTypeInfo *typeInfo; @@ -3481,12 +3499,15 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) } } -void CustomData_bmesh_copy_data(const CustomData *source, - CustomData *dest, - void *src_block, - void **dest_block) +void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, + CustomData *dest, + void *src_block, + void **dest_block, + const CustomDataMask mask_exclude) { - const LayerTypeInfo *typeInfo; + /* Note that having a version of this function without a 'mask_exclude' + * would cause too much duplicate code, so add a check instead. */ + const bool no_mask = (mask_exclude == 0); int dest_i, src_i; if (*dest_block == NULL) { @@ -3519,13 +3540,14 @@ void CustomData_bmesh_copy_data(const CustomData *source, const void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset); void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset); - typeInfo = layerType_getInfo(source->layers[src_i].type); - - if (typeInfo->copy) { - typeInfo->copy(src_data, dest_data, 1); - } - else { - memcpy(dest_data, src_data, typeInfo->size); + if (no_mask || ((CD_TYPE_AS_MASK(dest->layers[dest_i].type) & mask_exclude) == 0)) { + const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); + if (typeInfo->copy) { + typeInfo->copy(src_data, dest_data, 1); + } + else { + memcpy(dest_data, src_data, typeInfo->size); + } } /* if there are multiple source & dest layers of the same type, @@ -3542,6 +3564,14 @@ void CustomData_bmesh_copy_data(const CustomData *source, } } +void CustomData_bmesh_copy_data(const CustomData *source, + CustomData *dest, + void *src_block, + void **dest_block) +{ + CustomData_bmesh_copy_data_exclude_by_type(source, dest, src_block, dest_block, 0); +} + /* BMesh Custom Data Functions. * Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */ diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index c8eab9c4b8c..592d8124b23 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -89,11 +89,8 @@ void BM_edges_from_verts_ensure(BMesh *bm, BMEdge **edge_arr, BMVert **vert_arr, } /* prototypes */ -static void bm_loop_attrs_copy(BMesh *source_mesh, - BMesh *target_mesh, - const BMLoop *source_loop, - BMLoop *target_loop, - uint64_t cd_mask); +static void bm_loop_attrs_copy( + BMesh *bm_src, BMesh *bm_dst, const BMLoop *l_src, BMLoop *l_dst, CustomDataMask mask_exclude); /** * \brief Make Quad/Triangle @@ -414,73 +411,59 @@ void BM_verts_sort_radial_plane(BMVert **vert_arr, int len) /*************************************************************/ -static void bm_vert_attrs_copy(BMesh *source_mesh, - BMesh *target_mesh, - const BMVert *source_vertex, - BMVert *target_vertex, - uint64_t cd_mask) +static void bm_vert_attrs_copy( + BMesh *bm_src, BMesh *bm_dst, const BMVert *v_src, BMVert *v_dst, CustomDataMask mask_exclude) { - if ((source_mesh == target_mesh) && (source_vertex == target_vertex)) { + if ((bm_src == bm_dst) && (v_src == v_dst)) { BLI_assert(!"BMVert: source and target match"); return; } - if ((cd_mask & CD_MASK_NORMAL) == 0) { - copy_v3_v3(target_vertex->no, source_vertex->no); + if ((mask_exclude & CD_MASK_NORMAL) == 0) { + copy_v3_v3(v_dst->no, v_src->no); } - CustomData_bmesh_free_block_data(&target_mesh->vdata, target_vertex->head.data); - CustomData_bmesh_copy_data(&source_mesh->vdata, - &target_mesh->vdata, - source_vertex->head.data, - &target_vertex->head.data); + CustomData_bmesh_free_block_data_exclude_by_type(&bm_dst->vdata, v_dst->head.data, mask_exclude); + CustomData_bmesh_copy_data_exclude_by_type( + &bm_src->vdata, &bm_dst->vdata, v_src->head.data, &v_dst->head.data, mask_exclude); } -static void bm_edge_attrs_copy(BMesh *source_mesh, - BMesh *target_mesh, - const BMEdge *source_edge, - BMEdge *target_edge, - uint64_t UNUSED(cd_mask)) +static void bm_edge_attrs_copy( + BMesh *bm_src, BMesh *bm_dst, const BMEdge *e_src, BMEdge *e_dst, CustomDataMask mask_exclude) { - if ((source_mesh == target_mesh) && (source_edge == target_edge)) { + if ((bm_src == bm_dst) && (e_src == e_dst)) { BLI_assert(!"BMEdge: source and target match"); return; } - CustomData_bmesh_free_block_data(&target_mesh->edata, target_edge->head.data); - CustomData_bmesh_copy_data( - &source_mesh->edata, &target_mesh->edata, source_edge->head.data, &target_edge->head.data); + CustomData_bmesh_free_block_data_exclude_by_type(&bm_dst->edata, e_dst->head.data, mask_exclude); + CustomData_bmesh_copy_data_exclude_by_type( + &bm_src->edata, &bm_dst->edata, e_src->head.data, &e_dst->head.data, mask_exclude); } -static void bm_loop_attrs_copy(BMesh *source_mesh, - BMesh *target_mesh, - const BMLoop *source_loop, - BMLoop *target_loop, - uint64_t UNUSED(cd_mask)) +static void bm_loop_attrs_copy( + BMesh *bm_src, BMesh *bm_dst, const BMLoop *l_src, BMLoop *l_dst, CustomDataMask mask_exclude) { - if ((source_mesh == target_mesh) && (source_loop == target_loop)) { + if ((bm_src == bm_dst) && (l_src == l_dst)) { BLI_assert(!"BMLoop: source and target match"); return; } - CustomData_bmesh_free_block_data(&target_mesh->ldata, target_loop->head.data); - CustomData_bmesh_copy_data( - &source_mesh->ldata, &target_mesh->ldata, source_loop->head.data, &target_loop->head.data); + CustomData_bmesh_free_block_data_exclude_by_type(&bm_dst->ldata, l_dst->head.data, mask_exclude); + CustomData_bmesh_copy_data_exclude_by_type( + &bm_src->ldata, &bm_dst->ldata, l_src->head.data, &l_dst->head.data, mask_exclude); } -static void bm_face_attrs_copy(BMesh *source_mesh, - BMesh *target_mesh, - const BMFace *source_face, - BMFace *target_face, - uint64_t cd_mask) +static void bm_face_attrs_copy( + BMesh *bm_src, BMesh *bm_dst, const BMFace *f_src, BMFace *f_dst, CustomDataMask mask_exclude) { - if ((source_mesh == target_mesh) && (source_face == target_face)) { + if ((bm_src == bm_dst) && (f_src == f_dst)) { BLI_assert(!"BMFace: source and target match"); return; } - if ((cd_mask & CD_MASK_NORMAL) == 0) { - copy_v3_v3(target_face->no, source_face->no); + if ((mask_exclude & CD_MASK_NORMAL) == 0) { + copy_v3_v3(f_dst->no, f_src->no); } - CustomData_bmesh_free_block_data(&target_mesh->pdata, target_face->head.data); - CustomData_bmesh_copy_data( - &source_mesh->pdata, &target_mesh->pdata, source_face->head.data, &target_face->head.data); - target_face->mat_nr = source_face->mat_nr; + CustomData_bmesh_free_block_data_exclude_by_type(&bm_dst->pdata, f_dst->head.data, mask_exclude); + CustomData_bmesh_copy_data_exclude_by_type( + &bm_src->pdata, &bm_dst->pdata, f_src->head.data, &f_dst->head.data, mask_exclude); + f_dst->mat_nr = f_src->mat_nr; } /* BMESH_TODO: Special handling for hide flags? */ @@ -495,7 +478,7 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, const void *ele_src_v, void *ele_dst_v, const char hflag_mask, - const uint64_t cd_mask) + const uint64_t cd_mask_exclude) { const BMHeader *ele_src = ele_src_v; BMHeader *ele_dst = ele_dst_v; @@ -503,9 +486,6 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BLI_assert(ele_src->htype == ele_dst->htype); BLI_assert(ele_src != ele_dst); - /* Only support normal layer at the moment. */ - BLI_assert((cd_mask & ~CD_MASK_NORMAL) == 0); - if ((hflag_mask & BM_ELEM_SELECT) == 0) { /* First we copy select */ if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) { @@ -527,16 +507,20 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, /* Copy specific attributes */ switch (ele_dst->htype) { case BM_VERT: - bm_vert_attrs_copy(bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst, cd_mask); + bm_vert_attrs_copy( + bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst, cd_mask_exclude); break; case BM_EDGE: - bm_edge_attrs_copy(bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst, cd_mask); + bm_edge_attrs_copy( + bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst, cd_mask_exclude); break; case BM_LOOP: - bm_loop_attrs_copy(bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst, cd_mask); + bm_loop_attrs_copy( + bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst, cd_mask_exclude); break; case BM_FACE: - bm_face_attrs_copy(bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst, cd_mask); + bm_face_attrs_copy( + bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst, cd_mask_exclude); break; default: BLI_assert(0); diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 0b285979369..a13392a88ba 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -61,7 +61,7 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, const void *ele_src_v, void *ele_dst_v, const char hflag_mask, - const uint64_t cd_mask); + const uint64_t cd_mask_exclude); void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v); void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v); |