diff options
author | Hans Goudey <h.goudey@me.com> | 2022-09-06 22:25:48 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-06 22:25:48 +0300 |
commit | f94130c94b24ac657805a632de1e456b002e8b63 (patch) | |
tree | 68e17b3f08302ed2ade67d17240bb2e085254858 | |
parent | ced56dbc5396521e9fe51c0b59041f6577cd6135 (diff) |
Fix T100854, T100856: Invalid shape keys when exiting edit mode
The `mvert` pointer was passed to `bm_to_mesh_shape` and was never
reset to the beginning of the vertex array. Use spans instead to
eliminate this error completely. This also has the benefit of letting
the CustomData system handle allocation of mesh layers.
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_convert.cc | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0190f91250b..257134e7661 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -705,7 +705,7 @@ static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey) */ static void bm_to_mesh_shape(BMesh *bm, Key *key, - MVert *mvert, + MutableSpan<MVert> mvert, const bool active_shapekey_to_mvert) { KeyBlock *actkey = static_cast<KeyBlock *>(BLI_findlink(&key->block, bm->shapenr - 1)); @@ -984,7 +984,6 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm, void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params) { - MEdge *med; BMVert *v, *eve; BMEdge *e; BMFace *f; @@ -1024,19 +1023,30 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); } - MVert *mvert = bm->totvert ? (MVert *)MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") : - nullptr; - MEdge *medge = bm->totedge ? (MEdge *)MEM_callocN(sizeof(MEdge) * bm->totedge, "bm_to_me.edge") : - nullptr; - MLoop *mloop = bm->totloop ? (MLoop *)MEM_callocN(sizeof(MLoop) * bm->totloop, "bm_to_me.loop") : - nullptr; - MPoly *mpoly = bm->totface ? (MPoly *)MEM_callocN(sizeof(MPoly) * bm->totface, "bm_to_me.poly") : - nullptr; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge); - CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); - CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); + MutableSpan<MVert> mvert; + MutableSpan<MEdge> medge; + MutableSpan<MPoly> mpoly; + MutableSpan<MLoop> mloop; + if (me->totvert > 0) { + mvert = {static_cast<MVert *>( + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert)), + me->totvert}; + } + if (me->totedge > 0) { + medge = {static_cast<MEdge *>( + CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge)), + me->totedge}; + } + if (me->totpoly > 0) { + mpoly = {static_cast<MPoly *>( + CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly)), + me->totpoly}; + } + if (me->totloop > 0) { + mloop = {static_cast<MLoop *>( + CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop)), + me->totloop}; + } bool need_hide_vert = false; bool need_hide_edge = false; @@ -1051,9 +1061,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - copy_v3_v3(mvert->co, v->co); + copy_v3_v3(mvert[i].co, v->co); - mvert->flag = BM_vert_flag_to_mflag(v); + mvert[i].flag = BM_vert_flag_to_mflag(v); if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { need_hide_vert = true; } @@ -1064,23 +1074,21 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); if (cd_vert_bweight_offset != -1) { - mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); + mvert[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); } i++; - mvert++; BM_CHECK_ELEMENT(v); } bm->elem_index_dirty &= ~BM_VERT; - med = medge; i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - med->v1 = BM_elem_index_get(e->v1); - med->v2 = BM_elem_index_get(e->v2); + medge[i].v1 = BM_elem_index_get(e->v1); + medge[i].v2 = BM_elem_index_get(e->v2); - med->flag = BM_edge_flag_to_mflag(e); + medge[i].flag = BM_edge_flag_to_mflag(e); if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { need_hide_edge = true; } @@ -1090,17 +1098,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh /* Copy over custom-data. */ CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i); - bmesh_quick_edgedraw_flag(med, e); + bmesh_quick_edgedraw_flag(&medge[i], e); if (cd_edge_crease_offset != -1) { - med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); + medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); } if (cd_edge_bweight_offset != -1) { - med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); + medge[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); } i++; - med++; BM_CHECK_ELEMENT(e); } bm->elem_index_dirty &= ~BM_EDGE; @@ -1109,26 +1116,25 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh j = 0; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { BMLoop *l_iter, *l_first; - mpoly->loopstart = j; - mpoly->totloop = f->len; + mpoly[i].loopstart = j; + mpoly[i].totloop = f->len; if (f->mat_nr != 0) { need_material_index = true; } - mpoly->flag = BM_face_flag_to_mflag(f); + mpoly[i].flag = BM_face_flag_to_mflag(f); if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { need_hide_poly = true; } l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - mloop->e = BM_elem_index_get(l_iter->e); - mloop->v = BM_elem_index_get(l_iter->v); + mloop[j].e = BM_elem_index_get(l_iter->e); + mloop[j].v = BM_elem_index_get(l_iter->v); /* Copy over custom-data. */ CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); j++; - mloop++; BM_CHECK_ELEMENT(l_iter); BM_CHECK_ELEMENT(l_iter->e); BM_CHECK_ELEMENT(l_iter->v); @@ -1142,7 +1148,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i); i++; - mpoly++; BM_CHECK_ELEMENT(f); } |