diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh_convert.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_convert.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c b/source/blender/bmesh/intern/bmesh_mesh_convert.c index 544a81f7020..d99fefbcd02 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.c +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c @@ -208,6 +208,14 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar return; /* Sanity check. */ } + /* Only copy normals to the new BMesh if they are not already dirty. This avoids unnecessary + * work, but also accessing normals on an incomplete mesh, for example when restoring undo steps + * in edit mode. */ + const float(*vert_normals)[3] = NULL; + if (!BKE_mesh_vertex_normals_are_dirty(me)) { + vert_normals = BKE_mesh_vertex_normals_ensure(me); + } + if (is_new) { CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0); CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0); @@ -334,7 +342,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar BM_vert_select_set(bm, v, true); } - normal_short_to_float_v3(v->no, mvert->no); + if (vert_normals) { + copy_v3_v3(v->no, vert_normals[i]); + } /* Copy Custom Data */ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); @@ -639,6 +649,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); + /* There is no way to tell if BMesh normals are dirty or not. Instead of calculating the normals + * on the BMesh possibly unnecessarily, just tag them dirty on the resulting mesh. */ + BKE_mesh_normals_tag_dirty(me); + me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); /* This is called again, 'dotess' arg is used there. */ @@ -647,7 +661,6 @@ 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); - normal_float_to_short_v3(mvert->no, v->no); mvert->flag = BM_vert_flag_to_mflag(v); @@ -1041,6 +1054,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + BKE_mesh_normals_tag_dirty(me); + me->runtime.deformed_only = true; /* Don't add origindex layer if one already exists. */ @@ -1055,8 +1070,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BM_elem_index_set(eve, i); /* set_inline */ - normal_float_to_short_v3(mv->no, eve->no); - mv->flag = BM_vert_flag_to_mflag(eve); if (cd_vert_bweight_offset != -1) { |