diff options
author | Germano Cavalcante <germano.costa@ig.com.br> | 2020-10-10 17:13:01 +0300 |
---|---|---|
committer | Germano Cavalcante <germano.costa@ig.com.br> | 2020-10-12 14:57:43 +0300 |
commit | aafd71a8a160bdf44ab3ccea37e88bb90b87a2ac (patch) | |
tree | d6782b5d8d26444b6af66e5fa9508b3d174877ab /source/blender | |
parent | ab65fe5a2dcca9cb5de14eaeabe5a441bc41f15a (diff) |
Fix T81060: CustomData Correction sometimes breaks UVs and Vertex Colors
`CustomData_bmesh_interp` use the same CustomData decryptor (in this case, `bm->ldata`) in both blocks.
So make sure that all CustomData layers match.
This commit also removes redundant `BM_elem_attrs_copy_ex` calls.
Maniphest Tasks: T81060
Differential Revision: https://developer.blender.org/D9159
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 41 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.h | 4 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert_mesh.c | 10 |
3 files changed, 48 insertions, 7 deletions
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 81494b03558..757ab735134 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -606,6 +606,47 @@ void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTem CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE); } +/** + * Similar to #BM_mesh_copy_init_customdata but copies all layers ignoring + * flags like #CD_FLAG_NOCOPY. + * + * \param bm_dst: BMesh whose custom-data layers will be added. + * \param bm_src: BMesh whose custom-data layers will be copied. + * \param htype: Specifies which custom-datas will be initiated. + * \param allocsize: Estimated number of elements to init the mempool. + */ +void BM_mesh_copy_init_customdata_all_layers(BMesh *bm_dst, + BMesh *bm_src, + const char htype, + const BMAllocTemplate *allocsize) +{ + if (allocsize == NULL) { + allocsize = &bm_mesh_allocsize_default; + } + + const char htypes[4] = {BM_VERT, BM_EDGE, BM_LOOP, BM_FACE}; + BLI_assert(((&bm_dst->vdata + 1) == &bm_dst->edata) && + ((&bm_dst->vdata + 2) == &bm_dst->ldata) && ((&bm_dst->vdata + 3) == &bm_dst->pdata)); + + BLI_assert(((&allocsize->totvert + 1) == &allocsize->totedge) && + ((&allocsize->totvert + 2) == &allocsize->totloop) && + ((&allocsize->totvert + 3) == &allocsize->totface)); + + for (int i = 0; i < 4; i++) { + if (!(htypes[i] & htype)) { + continue; + } + CustomData *dst = &bm_dst->vdata + i; + CustomData *src = &bm_src->vdata + i; + const int size = *(&allocsize->totvert + i); + + for (int l = 0; l < src->totlayer; l++) { + CustomData_add_layer(dst, src->layers[l].type, CD_CALLOC, NULL, 0); + } + CustomData_bmesh_init_pool(dst, size, htypes[i]); + } +} + BMesh *BM_mesh_copy(BMesh *bm_old) { BMesh *bm_new; diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 3523c4aec1a..f5102283ede 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -69,6 +69,10 @@ void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v); void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize); +void BM_mesh_copy_init_customdata_all_layers(BMesh *bm_dst, + BMesh *bm_src, + const char htype, + const struct BMAllocTemplate *allocsize); BMesh *BM_mesh_copy(BMesh *bm_old); char BM_face_flag_from_mflag(const char mflag); diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index d40a7168af1..f154c8d338e 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1176,8 +1176,9 @@ static void mesh_customdatacorrect_init_container_generic(TransDataContainer *UN .use_toolflags = false, })); - /* We need to have matching custom-data. */ - BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL); + /* We need to have matching loop custom-data. */ + BM_mesh_copy_init_customdata_all_layers(bm_origfaces, bm, BM_LOOP, NULL); + tcld->origfaces = origfaces; tcld->bm_origfaces = bm_origfaces; @@ -1359,9 +1360,6 @@ static void mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tcld, * and we do not want to mess up other shape keys */ BM_loop_interp_from_face(bm, l, f_copy, false, false); - /* make sure face-attributes are correct (e.g. #MLoopUV, #MLoopCol) */ - BM_elem_attrs_copy_ex(tcld->bm_origfaces, bm, f_copy, l->f, BM_ELEM_SELECT, CD_MASK_NORMAL); - /* weight the loop */ if (do_loop_weight) { const float eps = 1.0e-8f; @@ -1514,8 +1512,6 @@ static void mesh_customdatacorrect_restore(struct TransInfo *t) BM_elem_attrs_copy(bm_copy, bm, l_copy, l_iter); l_copy = l_copy->next; } while ((l_iter = l_iter->next) != l_first); - - BM_elem_attrs_copy_ex(bm_copy, bm, f_copy, f, BM_ELEM_SELECT, CD_MASK_NORMAL); } } } |