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:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh_convert.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.c21
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) {