[Bf-blender-cvs] [fbfe360cb13] master: Fix T60974: Dyntopo crash on undo after object deleted

Campbell Barton noreply at git.blender.org
Wed Jan 30 10:45:48 CET 2019


Commit: fbfe360cb13df5a6b47a86bf4cabd16e3bd92262
Author: Campbell Barton
Date:   Wed Jan 30 20:44:15 2019 +1100
Branches: master
https://developer.blender.org/rBfbfe360cb13df5a6b47a86bf4cabd16e3bd92262

Fix T60974: Dyntopo crash on undo after object deleted

Add the ability for undo steps to request memfile undo step added after
them, useful for mode switching, where we need the data to exist for
undo to enter the mode.

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

M	source/blender/blenkernel/BKE_undo_system.h
M	source/blender/blenkernel/intern/undo_system.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index dc8cabc52c7..2863642a3e0 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -73,6 +73,8 @@ typedef struct UndoStep {
 	size_t data_size;
 	/** Users should never see this step (only use for internal consistency). */
 	bool skip;
+	/** Some situations require the global state to be stored, edge cases when exiting modes. */
+	bool use_memfile_step;
 	/* Over alloc 'type->struct_size'. */
 } UndoStep;
 
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 7709b602179..d16f0569a57 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -512,7 +512,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char
 	if (ut->step_foreach_ID_ref != NULL) {
 		Main *bmain = G.main;
 		if (bmain->is_memfile_undo_written == false) {
-			const char *name_internal = "MemFile Internal";
+			const char *name_internal = "MemFile Internal (pre)";
 			/* Don't let 'step_init' cause issues when adding memfile undo step. */
 			void *step_init = ustack->step_init;
 			ustack->step_init = NULL;
@@ -531,25 +531,43 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char
 	}
 #endif
 
-	UndoStep *us = ustack->step_init ? ustack->step_init : MEM_callocN(ut->step_size, __func__);
-	ustack->step_init = NULL;
-	if (us->name[0] == '\0') {
-		BLI_strncpy(us->name, name, sizeof(us->name));
-	}
-	us->type = ut;
-	/* initialized, not added yet. */
+	bool use_memfile_step = false;
+	{
+		UndoStep *us = ustack->step_init ? ustack->step_init : MEM_callocN(ut->step_size, __func__);
+		ustack->step_init = NULL;
+		if (us->name[0] == '\0') {
+			BLI_strncpy(us->name, name, sizeof(us->name));
+		}
+		us->type = ut;
+		/* initialized, not added yet. */
 
-	if (undosys_step_encode(C, ustack, us)) {
+		if (!undosys_step_encode(C, ustack, us)) {
+			MEM_freeN(us);
+			undosys_stack_validate(ustack, true);
+			return false;
+		}
 		ustack->step_active = us;
 		BLI_addtail(&ustack->steps, us);
-		undosys_stack_validate(ustack, true);
-		return true;
+		use_memfile_step = us->use_memfile_step;
 	}
-	else {
-		MEM_freeN(us);
-		undosys_stack_validate(ustack, true);
-		return false;
+
+	if (use_memfile_step) {
+		Main *bmain = G.main;
+		const char *name_internal = "MemFile Internal (post)";
+		const bool ok = undosys_stack_push_main(ustack, name_internal, bmain);
+		if (ok) {
+			UndoStep *us = ustack->steps.last;
+			BLI_assert(STREQ(us->name, name_internal));
+			us->skip = true;
+#ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER
+			ustack->step_active_memfile = us;
+#endif
+			ustack->step_active = us;
+		}
 	}
+
+	undosys_stack_validate(ustack, true);
+	return true;
 }
 
 bool BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name)
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index d3bcee3dc2e..0355f8e933b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1055,6 +1055,11 @@ static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), UndoStep *us_
 	 * to the current 'SculptUndoStep' added by encode_init. */
 	SculptUndoStep *us = (SculptUndoStep *)us_p;
 	us->step.data_size = us->data.undo_size;
+
+	SculptUndoNode *unode = us->data.nodes.last;
+	if (unode && unode->type == SCULPT_UNDO_DYNTOPO_END) {
+		us->step.use_memfile_step = true;
+	}
 	return true;
 }



More information about the Bf-blender-cvs mailing list