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 26c48816b39..b6296fdffc3 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -86,6 +86,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 00a6fa6d178..79a1d8a88e4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -708,6 +708,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); @@ -1521,6 +1522,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); @@ -1559,6 +1566,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 09d9b19330a..61a02e10063 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1199,6 +1199,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 3b6e7b73b4f..71a753d8d30 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.c +++ b/source/blender/blenkernel/intern/mesh_wrapper.c @@ -129,6 +129,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 15197cdccc6..cfb5b35454f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1194,10 +1194,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); @@ -1225,7 +1221,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); @@ -1238,11 +1233,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]; @@ -1256,15 +1246,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]; @@ -1291,13 +1276,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; @@ -1324,10 +1305,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); |