diff options
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.cc | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.cc | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_wrapper.c | 10 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_convert.cc | 23 |
5 files changed, 42 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index a84f6058d67..2335ff7ad28 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -70,6 +70,13 @@ struct Mesh *BKE_mesh_from_bmesh_for_eval_nomain(struct BMesh *bm, const struct Mesh *me_settings); /** + * Add original index (#CD_ORIGINDEX) layers if they don't already exist. This is meant to be used + * when creating an evaluated mesh from an original edit mode mesh, to allow mapping from the + * evaluated vertices to the originals. + */ +void BKE_mesh_ensure_default_orig_index_customdata(struct Mesh *mesh); + +/** * Find the index of the loop in 'poly' which references vertex, * returns -1 if not found */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 542be4027bc..633873adf33 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -546,6 +546,7 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer) if (em) { mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, me); + BKE_mesh_ensure_default_orig_index_customdata(mesh); } else { mesh = BKE_mesh_copy_for_eval(me, true); @@ -1364,6 +1365,12 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, em_input, &final_datamask, nullptr, mesh_input); } + /* The mesh from edit mode should not have any original index layers already, since those + * are added during evaluation when necessary and are redundant on an original mesh. */ + BLI_assert(CustomData_get_layer(&em_input->bm->pdata, CD_ORIGINDEX) == nullptr && + CustomData_get_layer(&em_input->bm->edata, CD_ORIGINDEX) == nullptr && + CustomData_get_layer(&em_input->bm->pdata, CD_ORIGINDEX) == nullptr); + /* Clear errors before evaluation. */ BKE_modifiers_clear_errors(ob); @@ -1402,6 +1409,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { if (mesh_final == nullptr) { mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, nullptr, mesh_input); + BKE_mesh_ensure_default_orig_index_customdata(mesh_final); ASSERT_IS_VALID_MESH(mesh_final); } BLI_assert(deformed_verts != nullptr); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 6ca5babbf13..9893a9d298d 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1204,6 +1204,23 @@ Mesh *BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, return mesh; } +static void ensure_orig_index_layer(CustomData &data, const int size) +{ + if (CustomData_has_layer(&data, CD_ORIGINDEX)) { + return; + } + int *indices = (int *)CustomData_add_layer(&data, CD_ORIGINDEX, CD_DEFAULT, nullptr, size); + range_vn_i(indices, size, 0); +} + +void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh) +{ + BLI_assert(mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA); + ensure_orig_index_layer(mesh->vdata, mesh->totvert); + ensure_orig_index_layer(mesh->edata, mesh->totedge); + ensure_orig_index_layer(mesh->pdata, mesh->totpoly); +} + BoundBox *BKE_mesh_boundbox_get(Object *ob) { /* This is Object-level data access, diff --git a/source/blender/blenkernel/intern/mesh_wrapper.c b/source/blender/blenkernel/intern/mesh_wrapper.c index 267020fb675..f9fcaa0dceb 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.c +++ b/source/blender/blenkernel/intern/mesh_wrapper.c @@ -115,6 +115,16 @@ static void mesh_wrapper_ensure_mdata_isolated(void *userdata) BMEditMesh *em = me->edit_mesh; BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime.cd_mask_extra); + /* Adding original index layers assumes that all BMesh mesh wrappers are created from + * original edit mode meshes (the only case where adding original indices makes sense). + * If that assumption is broken, the layers might be incorrect in that they might not + * actually be "original". + * + * There is also a performance aspect, where this also assumes that original indices are + * always needed when converting an edit mesh to a mesh. That might be wrong, but it's not + * harmful. */ + BKE_mesh_ensure_default_orig_index_customdata(me); + EditMeshData *edit_data = me->runtime.edit_data; if (edit_data->vertexCos) { BKE_mesh_vert_coords_apply(me, edit_data->vertexCos); diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index ae6b4da6003..40a82fdd96f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1028,10 +1028,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * me->totloop = bm->totloop; me->totpoly = bm->totface; - CustomData_add_layer(&me->vdata, CD_ORIGINDEX, CD_CALLOC, nullptr, bm->totvert); - CustomData_add_layer(&me->edata, CD_ORIGINDEX, CD_CALLOC, nullptr, bm->totedge); - CustomData_add_layer(&me->pdata, CD_ORIGINDEX, CD_CALLOC, nullptr, bm->totface); - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, bm->totvert); CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, nullptr, bm->totedge); CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, nullptr, bm->totloop); @@ -1059,7 +1055,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * MEdge *medge = me->medge; MLoop *mloop = me->mloop; MPoly *mpoly = me->mpoly; - int *index, add_orig; unsigned int i, j; const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); @@ -1070,11 +1065,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * me->runtime.deformed_only = true; - /* Don't add origindex layer if one already exists. */ - add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX); - - index = (int *)CustomData_get_layer(&me->vdata, CD_ORIGINDEX); - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { MVert *mv = &mvert[i]; @@ -1088,15 +1078,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); } - if (add_orig) { - *index++ = i; - } - CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; - index = (int *)CustomData_get_layer(&me->edata, CD_ORIGINDEX); BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; @@ -1123,13 +1108,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i); - if (add_orig) { - *index++ = i; - } } bm->elem_index_dirty &= ~BM_EDGE; - index = (int *)CustomData_get_layer(&me->pdata, CD_ORIGINDEX); j = 0; BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { BMLoop *l_iter; @@ -1156,10 +1137,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } while ((l_iter = l_iter->next) != l_first); CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i); - - if (add_orig) { - *index++ = i; - } } bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); |