Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-06 22:25:48 +0300
committerHans Goudey <h.goudey@me.com>2022-09-06 22:25:48 +0300
commitf94130c94b24ac657805a632de1e456b002e8b63 (patch)
tree68e17b3f08302ed2ade67d17240bb2e085254858
parentced56dbc5396521e9fe51c0b59041f6577cd6135 (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.cc73
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);
}