From 67c7fe6ad62e18b78ef70428e8eead8fdba65100 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Oct 2020 13:50:02 +1100 Subject: Fix T80165: Separate by loose parts breaks custom normals - Add NULL check for BKE_lnor_spacearr_clear - Remove unnecessary 'use_toolflags' with BMesh creation. --- source/blender/blenkernel/intern/mesh_evaluate.c | 4 ++- source/blender/editors/mesh/editmesh_tools.c | 36 +++++++++++++++--------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 6b3a85cc364..eee1b763be5 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -541,7 +541,9 @@ void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) lnors_spacearr->num_spaces = 0; lnors_spacearr->lspacearr = NULL; lnors_spacearr->loops_pool = NULL; - BLI_memarena_clear(lnors_spacearr->mem); + if (lnors_spacearr->mem != NULL) { + BLI_memarena_clear(lnors_spacearr->mem); + } } void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 1ceeb3d1fed..47836d2e529 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4233,24 +4233,26 @@ static Base *mesh_separate_arrays(Main *bmain, BMFace **faces, uint faces_len) { + const BMAllocTemplate bm_new_allocsize = { + .totvert = verts_len, + .totedge = edges_len, + .totloop = faces_len * 3, + .totface = faces_len, + }; + const bool use_custom_normals = (bm_old->lnor_spacearr != NULL); + Base *base_new; Object *obedit = base_old->object; - BMesh *bm_new; - bm_new = BM_mesh_create(&bm_mesh_allocsize_default, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); - - CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); - CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); - CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); - CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + BMesh *bm_new = BM_mesh_create(&bm_new_allocsize, &((struct BMeshCreateParams){0})); - CustomData_bmesh_init_pool(&bm_new->vdata, verts_len, BM_VERT); - CustomData_bmesh_init_pool(&bm_new->edata, edges_len, BM_EDGE); - CustomData_bmesh_init_pool(&bm_new->ldata, faces_len * 3, BM_LOOP); - CustomData_bmesh_init_pool(&bm_new->pdata, faces_len, BM_FACE); + if (use_custom_normals) { + /* Needed so the temporary normal layer is copied too. */ + BM_mesh_copy_init_customdata_all_layers(bm_new, bm_old, BM_ALL, &bm_new_allocsize); + } + else { + BM_mesh_copy_init_customdata(bm_new, bm_old, &bm_new_allocsize); + } /* Take into account user preferences for duplicating actions. */ const eDupli_ID_Flags dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT); @@ -4270,6 +4272,10 @@ static Base *mesh_separate_arrays(Main *bmain, BM_mesh_copy_arrays(bm_old, bm_new, verts, verts_len, edges, edges_len, faces, faces_len); + if (use_custom_normals) { + BM_custom_loop_normals_from_vector_layer(bm_new, false); + } + for (uint i = 0; i < verts_len; i++) { BM_vert_kill(bm_old, verts[i]); } @@ -4432,6 +4438,8 @@ static bool mesh_separate_loose( ED_mesh_geometry_clear(base_old->object->data); } + BM_custom_loop_normals_to_vector_layer(bm_old); + /* Separate out all groups except the first. */ uint group_ofs[3] = {UNPACK3(groups[0])}; for (int i = 1; i < groups_len; i++) { -- cgit v1.2.3