[Bf-blender-cvs] [dab0bd9] master: Fix T35170: Undoing edit op on a basis shapekey could generate extra offset on its 'children'.

Bastien Montagne noreply at git.blender.org
Mon Nov 17 11:21:22 CET 2014


Commit: dab0bd9de65a9be5e8ababba0e2799f994d5d12f
Author: Bastien Montagne
Date:   Mon Nov 17 08:13:22 2014 +0100
Branches: master
https://developer.blender.org/rBdab0bd9de65a9be5e8ababba0e2799f994d5d12f

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

===================================================================

M	source/blender/blenkernel/intern/key.c
M	source/blender/editors/mesh/editmesh_utils.c

===================================================================

diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index b982139..98fdac6 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -2210,7 +2210,7 @@ bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
 /**
  * Check if given keyblock (as index) is used as basis by others in given key.
  */
-bool BKE_keyblock_is_basis(struct Key *key, const int index)
+bool BKE_keyblock_is_basis(Key *key, const int index)
 {
 	KeyBlock *kb;
 	int i;
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 807f603..c657105 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);
 }




More information about the Bf-blender-cvs mailing list