[Bf-blender-cvs] [5e42aff] strand_editmode: Basic undo support in the new strand edit mode.

Lukas Tönne noreply at git.blender.org
Mon Apr 20 14:24:24 CEST 2015


Commit: 5e42aff39795643490f0d3af9f9bd4ee1c730904
Author: Lukas Tönne
Date:   Thu Jan 29 20:53:12 2015 +0100
Branches: strand_editmode
https://developer.blender.org/rB5e42aff39795643490f0d3af9f9bd4ee1c730904

Basic undo support in the new strand edit mode.

This uses the generalized undo stack system which is also used for
object data edit. An extension is necessary to tell the undo functions
which object is specifically used for generating undo data and
identifying the stack, since strand editing does not edit the obdata
itself.

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

M	source/blender/editors/armature/armature_utils.c
M	source/blender/editors/curve/editcurve.c
M	source/blender/editors/curve/editfont.c
M	source/blender/editors/hair/CMakeLists.txt
A	source/blender/editors/hair/hair_undo.c
M	source/blender/editors/include/ED_physics.h
M	source/blender/editors/include/ED_util.h
M	source/blender/editors/mesh/editmesh_utils.c
M	source/blender/editors/metaball/mball_edit.c
M	source/blender/editors/object/object_lattice.c
M	source/blender/editors/util/editmode_undo.c
M	source/blender/editors/util/undo.c

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

diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 1835195..eebdd70 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -785,7 +785,7 @@ static void *get_armature_edit(bContext *C)
 void undo_push_armature(bContext *C, const char *name)
 {
 	// XXX solve getdata()
-	undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
+	undo_editmode_push(C, name, CTX_data_edit_object, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
 }
 
 /* *************************************************************** */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index cbbee2f..64d2bbf 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -7087,7 +7087,7 @@ static void *get_data(bContext *C)
 /* and this is all the undo system needs to know */
 void undo_push_curve(bContext *C, const char *name)
 {
-	undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
+	undo_editmode_push(C, name, CTX_data_edit_object, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
 }
 
 void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 303aa2c..4297344 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1879,7 +1879,7 @@ static void *get_undoFont(bContext *C)
 /* and this is all the undo system needs to know */
 void undo_push_font(bContext *C, const char *name)
 {
-	undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
+	undo_editmode_push(C, name, CTX_data_edit_object, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
 }
 
 /**
diff --git a/source/blender/editors/hair/CMakeLists.txt b/source/blender/editors/hair/CMakeLists.txt
index 570f46c..4430e10 100644
--- a/source/blender/editors/hair/CMakeLists.txt
+++ b/source/blender/editors/hair/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
 	hair_ops.c
 	hair_select.c
 	hair_stroke.c
+	hair_undo.c
 
 	hair_intern.h
 )
diff --git a/source/blender/editors/hair/hair_undo.c b/source/blender/editors/hair/hair_undo.c
new file mode 100644
index 0000000..1459768
--- /dev/null
+++ b/source/blender/editors/hair/hair_undo.c
@@ -0,0 +1,191 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/hair/hair_undo.c
+ *  \ingroup edhair
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_context.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_editstrands.h"
+#include "BKE_key.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_sample.h"
+
+#include "ED_physics.h"
+#include "ED_util.h"
+
+#include "bmesh.h"
+
+#include "hair_intern.h"
+
+static void *strands_get_edit(bContext *C)
+{
+	Object *obact = CTX_data_active_object(C);
+	const int mode_flag = OB_MODE_HAIR_EDIT;
+	const bool is_mode_set = ((obact->mode & mode_flag) != 0);
+
+	if (obact && is_mode_set) {
+		BMEditStrands *edit = BKE_editstrands_from_object(obact);
+		return edit;
+	}
+	return NULL;
+}
+
+typedef struct UndoStrands {
+	Mesh me; /* Mesh supports all the customdata we need, easiest way to implement undo storage */
+	int selectmode;
+
+	/** \note
+	 * this isn't a prefect solution, if you edit keys and change shapes this works well (fixing [#32442]),
+	 * but editing shape keys, going into object mode, removing or changing their order,
+	 * then go back into editmode and undo will give issues - where the old index will be out of sync
+	 * with the new object index.
+	 *
+	 * There are a few ways this could be made to work but for now its a known limitation with mixing
+	 * object and editmode operations - Campbell */
+	int shapenr;
+} UndoStrands;
+
+/* undo simply makes copies of a bmesh */
+static void *strands_edit_to_undo(void *editv, void *UNUSED(obdata))
+{
+	BMEditStrands *edit = editv;
+//	Mesh *obme = obdata;
+	
+	UndoStrands *undo = MEM_callocN(sizeof(UndoStrands), "undo Strands");
+	
+	/* make sure shape keys work */
+//	um->me.key = obme->key ? BKE_key_copy_nolib(obme->key) : NULL;
+
+	/* BM_mesh_validate(em->bm); */ /* for troubleshooting */
+
+	BM_mesh_bm_to_me(edit->bm, &undo->me, false);
+
+	undo->selectmode = edit->bm->selectmode;
+	undo->shapenr = edit->bm->shapenr;
+
+	return undo;
+}
+
+static void strands_undo_to_edit(void *undov, void *editv, void *UNUSED(obdata))
+{
+	UndoStrands *undo = undov;
+	BMEditStrands *edit = editv, *edit_tmp;
+	Object *ob = edit->ob;
+	DerivedMesh *dm = edit->root_dm;
+	BMesh *bm;
+//	Key *key = ((Mesh *) obdata)->key;
+	
+	const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&undo->me);
+	
+	edit->bm->shapenr = undo->shapenr;
+	
+	/* note: have to create the new edit before the old one,
+	 * since it owns the root_dm and we have to copy it before
+	 * it gets released when freeing the old edit.
+	 */
+	bm = BM_mesh_create(&allocsize);
+	edit_tmp = BKE_editstrands_create(bm, dm);
+	
+	BKE_editstrands_free(edit);
+	
+	BM_mesh_bm_from_me(bm, &undo->me, true, false, undo->shapenr);
+	
+	*edit = *edit_tmp;
+	
+	bm->selectmode = undo->selectmode;
+	edit->ob = ob;
+	
+#if 0
+	/* 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 != undo->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 = undo->me.totvert;
+			}
+			
+			BKE_keyblock_update_from_mesh(&undo->me, kb_act);
+		}
+	}
+#endif
+
+	ob->shapenr = undo->shapenr;
+	
+	MEM_freeN(edit_tmp);
+}
+
+static void strands_free_undo(void *undov)
+{
+	UndoStrands *undo = undov;
+	
+	if (undo->me.key) {
+		BKE_key_free(undo->me.key);
+		MEM_freeN(undo->me.key);
+	}
+
+	BKE_mesh_free(&undo->me, false);
+	MEM_freeN(undo);
+}
+
+/* and this is all the undo system needs to know */
+void undo_push_strands(bContext *C, const char *name)
+{
+	/* edit->ob gets out of date and crashes on mesh undo,
+	 * this is an easy way to ensure its OK
+	 * though we could investigate the matter further. */
+	Object *obact = CTX_data_active_object(C);
+	BMEditStrands *edit = BKE_editstrands_from_object(obact);
+	edit->ob = obact;
+	
+
+	undo_editmode_push(C, name, CTX_data_active_object, strands_get_edit, strands_free_undo, strands_undo_to_edit, strands_edit_to_undo, NULL);
+}
diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h
index aad2629..58baac7 100644
--- a/source/blender/editors/include/ED_physics.h
+++ b/source/blender/editors/include/ED_physics.h
@@ -59,6 +59,8 @@ void ED_operatortypes_physics(void);
 void ED_keymap_physics(struct wmKeyConfig *keyconf);
 
 /* hair edit */
+void undo_push_strands(struct bContext *C, const char *name);
+
 int ED_hair_mouse_select(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
 int ED_hair_border_select(struct bContext *C, struct rcti *rect, bool select, bool extend);
 int ED_hair_circle_select(struct bContext *C, bool select, const int mval[2], float radius);
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 9556c60..356c2f7 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -64,6 +64,7 @@ bool    ED_undo_is_valid(const struct bContext *C, const char *undoname);
 
 /* undo_editmode.c */
 void undo_editmode_push(struct bContext *C, const char *name, 
+                        struct Object *(*get_object)(const struct bContext * C),
                         void * (*getdata)(struct bContext *C),
                         void (*freedata)(void *),
                         void (*to_editmode)(void *, void *, void *),
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 4706f04..8e08ee8 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -608,7 +608,7 @@ void undo_push_mesh(bContext *C, const char *name)
 	BMEditMesh *em = BKE_editmesh_from_object(obe

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list