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:
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h10
-rw-r--r--source/blender/editors/include/ED_mesh.h1
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c7
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c1
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c8
-rw-r--r--source/blender/editors/object/object_edit.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c4
9 files changed, 40 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 9dcebbba56e..ab72b7d3b0d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1284,6 +1284,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
mesh,
(&(struct BMeshToMeshParams){
.calc_object_remap = true,
+ .update_shapekey_indices = true,
}));
DEG_id_tag_update(&mesh->id, 0);
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 9bcc9b9e84b..4e65ac40dd4 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -972,6 +972,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (ofs) {
MEM_freeN(ofs);
}
+
+ if (params->update_shapekey_indices) {
+ /* We have written a new shape key, if this mesh is _not_ going to be freed,
+ * update the shape key indices to match the newly updated. */
+ if (cd_shape_keyindex_offset != -1) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ BM_ELEM_CD_SET_INT(eve, cd_shape_keyindex_offset, i);
+ }
+ }
+ }
}
if (oldverts != NULL) {
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index f0302764a5f..65d5c6d5494 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -48,6 +48,16 @@ void BM_mesh_bm_from_me(BMesh *bm, const struct Mesh *me, const struct BMeshFrom
struct BMeshToMeshParams {
/** Update object hook indices & vertex parents. */
uint calc_object_remap : 1;
+ /**
+ * This re-assigns shape-key indices. Only do if the BMesh will have continued use
+ * to update the mesh & shape key in the future.
+ * In the case the BMesh is freed immediately, this can be left false.
+ *
+ * This is needed when flushing changes from edit-mode into object mode,
+ * so a second flush or edit-mode exit doesn't run with indices
+ * that have become invalid from updating the shape-key, see T71865.
+ */
+ uint update_shapekey_indices : 1;
struct CustomData_MeshMasks cd_mask_extra;
};
void BM_mesh_bm_to_me(struct Main *bmain,
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 835e1b4e26f..4bf43a2034a 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -83,6 +83,7 @@ void EDBM_mesh_clear(struct BMEditMesh *em);
void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct Object *ob, const int select_mode, const bool add_key_index);
void EDBM_mesh_free(struct BMEditMesh *em);
+void EDBM_mesh_load_ex(struct Main *bmain, struct Object *ob, bool free_data);
void EDBM_mesh_load(struct Main *bmain, struct Object *ob);
/* flushes based on the current select mode. if in vertex select mode,
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 8df392fb04b..59090acf433 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4197,7 +4197,12 @@ static bool mesh_separate_loose(
BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
if (clear_object_data) {
- BM_mesh_bm_to_me(NULL, bm_old, me_old, (&(struct BMeshToMeshParams){0}));
+ BM_mesh_bm_to_me(NULL,
+ bm_old,
+ me_old,
+ (&(struct BMeshToMeshParams){
+ .update_shapekey_indices = true,
+ }));
}
finally:
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 44984251243..d07ba05de20 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -521,6 +521,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
(&(struct BMeshToMeshParams){
/* Undo code should not be manipulating 'G_MAIN->object' hooks/vertex-parent. */
.calc_object_remap = false,
+ .update_shapekey_indices = false,
.cd_mask_extra = {.vmask = CD_MASK_SHAPE_KEYINDEX},
}));
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 522c2f32d27..42404554ed8 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -325,7 +325,7 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
* \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates).
* Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
*/
-void EDBM_mesh_load(Main *bmain, Object *ob)
+void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
{
Mesh *me = ob->data;
BMesh *bm = me->edit_mesh->bm;
@@ -341,6 +341,7 @@ void EDBM_mesh_load(Main *bmain, Object *ob)
me,
(&(struct BMeshToMeshParams){
.calc_object_remap = true,
+ .update_shapekey_indices = !free_data,
}));
/* Free derived mesh. usually this would happen through depsgraph but there
@@ -380,6 +381,11 @@ void EDBM_mesh_clear(BMEditMesh *em)
}
}
+void EDBM_mesh_load(Main *bmain, Object *ob)
+{
+ EDBM_mesh_load_ex(bmain, ob, true);
+}
+
/**
* Should only be called on the active editmesh, otherwise call #BKE_editmesh_free
*/
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index be815fb0d10..b7c9579e277 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -445,7 +445,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
return false;
}
- EDBM_mesh_load(bmain, obedit);
+ EDBM_mesh_load_ex(bmain, obedit, freedata);
if (freedata) {
EDBM_mesh_free(me->edit_mesh);
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index af595de2ee4..b601a35f7f2 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1091,7 +1091,9 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
bm = self->bm;
struct Main *bmain = NULL;
- struct BMeshToMeshParams params = {0};
+ struct BMeshToMeshParams params = {
+ .update_shapekey_indices = true,
+ };
if (me->id.tag & LIB_TAG_NO_MAIN) {
/* Mesh might be coming from a self-contained source like object.to_mesh(). No need to remap
* anything in this case. */