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:
authorBastien Montagne <montagne29@wanadoo.fr>2014-11-17 10:13:22 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2014-11-17 13:19:54 +0300
commitdab0bd9de65a9be5e8ababba0e2799f994d5d12f (patch)
treec8766a347b72d7e048d2eaf8afb6615f0b3a4a28 /source/blender/editors/mesh/editmesh_utils.c
parentb7f5ab0cd33bc7632bd71af5f883745e340d6e18 (diff)
Fix T35170: Undoing edit op on a basis shapekey could generate extra offset on its 'children'.
Based on investigation by sergey (Sergey Sharybin) and revzin (Grigory Revzin). Based on patch D460 by revzin (Grigory Revzin). Differential Revision: https://developer.blender.org/D460
Diffstat (limited to 'source/blender/editors/mesh/editmesh_utils.c')
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 807f603b7bb..c6571058040 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -532,30 +532,56 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata)
return um;
}
-static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata))
+static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *obdata)
{
BMEditMesh *em = em_v, *em_tmp;
Object *ob = em->ob;
UndoMesh *um = umv;
BMesh *bm;
+ Key *key = ((Mesh *) obdata)->key;
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&um->me);
- ob->shapenr = em->bm->shapenr = um->shapenr;
+ em->bm->shapenr = um->shapenr;
EDBM_mesh_free(em);
bm = BM_mesh_create(&allocsize);
- BM_mesh_bm_from_me(bm, &um->me, true, false, ob->shapenr);
+ BM_mesh_bm_from_me(bm, &um->me, true, false, um->shapenr);
em_tmp = BKE_editmesh_create(bm, true);
*em = *em_tmp;
-
+
em->selectmode = um->selectmode;
bm->selectmode = um->selectmode;
em->ob = ob;
+ /* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens
+ * if the active is a basis for any other. */
+ if (key && (key->type == KEY_RELATIVE)) {
+ /* Since we can't add, remove or reorder keyblocks in editmode, it's safe to assume
+ * shapenr from restored bmesh and keyblock indices are in sync. */
+ const int kb_act_idx = ob->shapenr - 1;
+
+ /* If it is, let's patch the current mesh key block to its restored value.
+ * Else, the offsets won't be computed and it won't matter. */
+ if (BKE_keyblock_is_basis(key, kb_act_idx)) {
+ KeyBlock *kb_act = BLI_findlink(&key->block, kb_act_idx);
+
+ if (kb_act->totelem != um->me.totvert) {
+ /* The current mesh has some extra/missing verts compared to the undo, adjust. */
+ MEM_SAFE_FREE(kb_act->data);
+ kb_act->data = MEM_mallocN((size_t)(key->elemsize * bm->totvert), __func__);
+ kb_act->totelem = um->me.totvert;
+ }
+
+ BKE_keyblock_update_from_mesh(&um->me, kb_act);
+ }
+ }
+
+ ob->shapenr = um->shapenr;
+
MEM_freeN(em_tmp);
}