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:
authorCampbell Barton <ideasman42@gmail.com>2019-11-07 08:52:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-11-07 08:56:21 +0300
commit79b703bb635ea719bbe31c1ece9884d2d298eaef (patch)
tree7ee7e896e8e66233f85dd425708a595f66607f48 /source/blender
parent85637311c28f49b55286d3287d4c7cefbcbca18a (diff)
Fix T69822: Switching sculpt objects breaks undo
This introduces object mode tagging for data which hasn't yet been written back to the ID data. Now when selecting other sculpt objects, the original objects data is flushed back to the ID before writing a memfile undo step.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h7
-rw-r--r--source/blender/blenkernel/BKE_font.h6
-rw-r--r--source/blender/blenkernel/BKE_main.h5
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h7
-rw-r--r--source/blender/blenkernel/intern/object.c49
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/editors/armature/editarmature_undo.c19
-rw-r--r--source/blender/editors/curve/editcurve_undo.c12
-rw-r--r--source/blender/editors/curve/editfont_undo.c17
-rw-r--r--source/blender/editors/include/ED_mball.h1
-rw-r--r--source/blender/editors/include/ED_util.h2
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c19
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c20
-rw-r--r--source/blender/editors/metaball/editmball_undo.c19
-rw-r--r--source/blender/editors/object/object_edit.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c27
-rw-r--r--source/blender/editors/undo/ed_undo.c2
-rw-r--r--source/blender/editors/undo/memfile_undo.c5
-rw-r--r--source/blender/editors/util/ed_util.c27
-rw-r--r--source/blender/makesdna/DNA_armature_types.h4
-rw-r--r--source/blender/makesdna/DNA_curve_types.h7
-rw-r--r--source/blender/makesdna/DNA_lattice_types.h6
-rw-r--r--source/blender/makesdna/DNA_meta_types.h8
24 files changed, 227 insertions, 62 deletions
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 47c8f31ead3..1b9e318146e 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -79,6 +79,13 @@ typedef struct BMEditMesh {
/*temp variables for x-mirror editing*/
int mirror_cdlayer; /* -1 is invalid */
+
+ /**
+ * ID data is older than edit-mode data.
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
+
} BMEditMesh;
/* editmesh.c */
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index e440d617f7a..3dd2a551a93 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -61,6 +61,12 @@ typedef struct EditFont {
int len, pos;
int selstart, selend;
+ /**
+ * ID data is older than edit-mode data.
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
+
} EditFont;
bool BKE_vfont_is_builtin(struct VFont *vfont);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 1b2e8bcbf42..c48a9cad443 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -80,6 +80,11 @@ typedef struct Main {
char recovered; /* indicate the main->name (file) is the recovered one */
/** All current ID's exist in the last memfile undo step. */
char is_memfile_undo_written;
+ /**
+ * An ID needs it's data to be flushed back.
+ * use "needs_flush_to_id" in edit data to flag data which needs updating.
+ */
+ char is_memfile_undo_flush_needed;
BlendThumbnail *blen_thumb;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index ffdcb9cd2c0..d76c55f0815 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -99,6 +99,8 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
bool BKE_object_data_is_in_editmode(const struct ID *id);
+char *BKE_object_data_editmode_flush_ptr_get(struct ID *id);
+
void BKE_object_update_select_id(struct Main *bmain);
typedef enum eObjectVisibilityResult {
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 4413ad2a70f..48f9e1fd95e 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -306,6 +306,13 @@ typedef struct SculptSession {
/* This flag prevents PBVH from being freed when creating the vp_handle for texture paint. */
bool building_vp_handle;
+
+ /**
+ * ID data is older than sculpt-mode data.
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
+
} SculptSession;
void BKE_sculptsession_free(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 773e2d19b22..b50e152527e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -81,6 +81,7 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
+#include "BKE_font.h"
#include "BKE_fcurve.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_icons.h"
@@ -629,6 +630,54 @@ bool BKE_object_data_is_in_editmode(const ID *id)
}
}
+char *BKE_object_data_editmode_flush_ptr_get(struct ID *id)
+{
+ const short type = GS(id->name);
+ switch (type) {
+ case ID_ME: {
+ BMEditMesh *em = ((Mesh *)id)->edit_mesh;
+ if (em != NULL) {
+ return &em->needs_flush_to_id;
+ }
+ break;
+ }
+ case ID_CU: {
+ if (((Curve *)id)->vfont != NULL) {
+ EditFont *ef = ((Curve *)id)->editfont;
+ if (ef != NULL) {
+ return &ef->needs_flush_to_id;
+ }
+ }
+ else {
+ EditNurb *editnurb = ((Curve *)id)->editnurb;
+ if (editnurb) {
+ return &editnurb->needs_flush_to_id;
+ }
+ }
+ break;
+ }
+ case ID_MB: {
+ MetaBall *mb = (MetaBall *)id;
+ return &mb->needs_flush_to_id;
+ }
+ case ID_LT: {
+ EditLatt *editlatt = ((Lattice *)id)->editlatt;
+ if (editlatt) {
+ return &editlatt->needs_flush_to_id;
+ }
+ break;
+ }
+ case ID_AR: {
+ bArmature *arm = (bArmature *)id;
+ return &arm->needs_flush_to_id;
+ }
+ default:
+ BLI_assert(0);
+ return NULL;
+ }
+ return NULL;
+}
+
bool BKE_object_is_in_wpaint_select_vert(const Object *ob)
{
if (ob->type == OB_MESH) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3866878b12a..452e75081d6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3862,6 +3862,8 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
link_list(fd, &arm->bonebase);
arm->bonehash = NULL;
arm->edbo = NULL;
+ /* Must always be cleared (armatures don't have their own edit-data). */
+ arm->needs_flush_to_id = 0;
arm->adt = newdataadr(fd, arm->adt);
direct_link_animdata(fd, arm->adt);
@@ -4079,6 +4081,8 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
BLI_listbase_clear(&mb->disp);
mb->editelems = NULL;
+ /* Must always be cleared (meta's don't have their own edit-data). */
+ mb->needs_flush_to_id = 0;
/* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
mb->lastelem = NULL;
mb->batch_cache = NULL;
diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c
index 4a82a8fccee..4e3ab11a9f7 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -32,6 +32,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
+#include "BKE_main.h"
#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
@@ -142,9 +143,7 @@ static bool armature_undosys_poll(bContext *C)
return editarm_object_from_context(C) != NULL;
}
-static bool armature_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
@@ -165,17 +164,18 @@ static bool armature_undosys_step_encode(struct bContext *C,
elem->obedit_ref.ptr = ob;
bArmature *arm = elem->obedit_ref.ptr->data;
undoarm_from_editarm(&elem->data, arm);
+ arm->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
}
MEM_freeN(objects);
+
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
-static void armature_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void armature_undosys_step_decode(
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
{
ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
@@ -198,6 +198,7 @@ static void armature_undosys_step_decode(struct bContext *C,
continue;
}
undoarm_to_editarm(&elem->data, arm);
+ arm->needs_flush_to_id = 1;
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
@@ -205,6 +206,8 @@ static void armature_undosys_step_decode(struct bContext *C,
ED_undo_object_set_active_or_warn(
CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
+ bmain->is_memfile_undo_flush_needed = true;
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index f21b4f06246..ff3a1386fd9 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -208,9 +208,7 @@ static bool curve_undosys_poll(bContext *C)
return (obedit != NULL);
}
-static bool curve_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
CurveUndoStep *us = (CurveUndoStep *)us_p;
@@ -226,13 +224,18 @@ static bool curve_undosys_step_encode(struct bContext *C,
for (uint i = 0; i < objects_len; i++) {
Object *ob = objects[i];
+ Curve *cu = ob->data;
CurveUndoStep_Elem *elem = &us->elems[i];
elem->obedit_ref.ptr = ob;
undocurve_from_editcurve(&elem->data, ob->data, ob->shapenr);
+ cu->editnurb->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
}
MEM_freeN(objects);
+
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
@@ -260,6 +263,7 @@ static void curve_undosys_step_decode(
continue;
}
undocurve_to_editcurve(bmain, &elem->data, obedit->data, &obedit->shapenr);
+ cu->editnurb->needs_flush_to_id = 1;
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
@@ -267,6 +271,8 @@ static void curve_undosys_step_decode(
ED_undo_object_set_active_or_warn(
CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
+ bmain->is_memfile_undo_flush_needed = true;
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index ae858ec4c24..26c0e5cf6c9 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -32,6 +32,7 @@
#include "BKE_context.h"
#include "BKE_font.h"
+#include "BKE_main.h"
#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
@@ -341,23 +342,21 @@ static bool font_undosys_poll(bContext *C)
return editfont_object_from_context(C) != NULL;
}
-static bool font_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool font_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
FontUndoStep *us = (FontUndoStep *)us_p;
us->obedit_ref.ptr = editfont_object_from_context(C);
Curve *cu = us->obedit_ref.ptr->data;
undofont_from_editfont(&us->data, cu);
us->step.data_size = us->data.undo_size;
+ cu->editfont->needs_flush_to_id = 1;
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
-static void font_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void font_undosys_step_decode(
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
{
/* TODO(campbell): undo_system: use low-level API to set mode. */
ED_object_mode_set(C, OB_MODE_EDIT);
@@ -368,6 +367,8 @@ static void font_undosys_step_decode(struct bContext *C,
Curve *cu = obedit->data;
undofont_to_editfont(&us->data, cu);
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ cu->editfont->needs_flush_to_id = 1;
+ bmain->is_memfile_undo_flush_needed = true;
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h
index 8ffae0f2b66..5afb645d9e7 100644
--- a/source/blender/editors/include/ED_mball.h
+++ b/source/blender/editors/include/ED_mball.h
@@ -25,6 +25,7 @@
#define __ED_MBALL_H__
struct Base;
+struct MetaBall;
struct Object;
struct UndoType;
struct bContext;
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 87f57b4e144..003e84bbf05 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -34,6 +34,8 @@ struct wmOperatorType;
void ED_editors_init_for_undo(struct Main *bmain);
void ED_editors_init(struct bContext *C);
void ED_editors_exit(struct Main *bmain, bool do_undo_system);
+
+bool ED_editors_flush_edits_ex(struct Main *bmain, bool for_render, bool check_needs_flush);
bool ED_editors_flush_edits(struct Main *bmain, bool for_render);
void ED_spacedata_id_remap(struct ScrArea *sa,
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index abc5224c4d6..2790e6b5558 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -39,6 +39,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
+#include "BKE_main.h"
#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
@@ -154,9 +155,7 @@ static bool lattice_undosys_poll(bContext *C)
return editlatt_object_from_context(C) != NULL;
}
-static bool lattice_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool lattice_undosys_step_encode(struct bContext *C, Main *bmain, UndoStep *us_p)
{
LatticeUndoStep *us = (LatticeUndoStep *)us_p;
@@ -177,17 +176,18 @@ static bool lattice_undosys_step_encode(struct bContext *C,
elem->obedit_ref.ptr = ob;
Lattice *lt = ob->data;
undolatt_from_editlatt(&elem->data, lt->editlatt);
+ lt->editlatt->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
}
MEM_freeN(objects);
+
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
-static void lattice_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void lattice_undosys_step_decode(
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
{
LatticeUndoStep *us = (LatticeUndoStep *)us_p;
@@ -210,6 +210,7 @@ static void lattice_undosys_step_decode(struct bContext *C,
continue;
}
undolatt_to_editlatt(&elem->data, lt->editlatt);
+ lt->editlatt->needs_flush_to_id = 1;
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
@@ -217,6 +218,8 @@ static void lattice_undosys_step_decode(struct bContext *C,
ED_undo_object_set_active_or_warn(
CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
+ bmain->is_memfile_undo_flush_needed = true;
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 7071258d8cf..44984251243 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -34,6 +34,7 @@
#include "BKE_context.h"
#include "BKE_key.h"
#include "BKE_layer.h"
+#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_editmesh.h"
#include "BKE_undo_system.h"
@@ -708,9 +709,7 @@ static bool mesh_undosys_poll(bContext *C)
return editmesh_object_from_context(C) != NULL;
}
-static bool mesh_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
@@ -730,18 +729,20 @@ static bool mesh_undosys_step_encode(struct bContext *C,
elem->obedit_ref.ptr = ob;
Mesh *me = elem->obedit_ref.ptr->data;
+ BMEditMesh *em = me->edit_mesh;
undomesh_from_editmesh(&elem->data, me->edit_mesh, me->key);
+ em->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
}
MEM_freeN(objects);
+
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
-static void mesh_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void mesh_undosys_step_decode(
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
@@ -765,6 +766,7 @@ static void mesh_undosys_step_decode(struct bContext *C,
}
BMEditMesh *em = me->edit_mesh;
undomesh_to_editmesh(&elem->data, em, obedit->data);
+ em->needs_flush_to_id = 1;
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
@@ -775,6 +777,8 @@ static void mesh_undosys_step_decode(struct bContext *C,
Scene *scene = CTX_data_scene(C);
scene->toolsettings->selectmode = us->elems[0].data.selectmode;
+ bmain->is_memfile_undo_flush_needed = true;
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c
index 9a95560ccdd..e8700e94e91 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -35,6 +35,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
+#include "BKE_main.h"
#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
@@ -153,9 +154,7 @@ static bool mball_undosys_poll(bContext *C)
return editmball_object_from_context(C) != NULL;
}
-static bool mball_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
+static bool mball_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p)
{
MBallUndoStep *us = (MBallUndoStep *)us_p;
@@ -176,17 +175,18 @@ static bool mball_undosys_step_encode(struct bContext *C,
elem->obedit_ref.ptr = ob;
MetaBall *mb = ob->data;
editmball_from_undomball(&elem->data, mb);
+ mb->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
}
MEM_freeN(objects);
+
+ bmain->is_memfile_undo_flush_needed = true;
+
return true;
}
-static void mball_undosys_step_decode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p,
- int UNUSED(dir),
- bool UNUSED(is_final))
+static void mball_undosys_step_decode(
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
{
MBallUndoStep *us = (MBallUndoStep *)us_p;
@@ -209,6 +209,7 @@ static void mball_undosys_step_decode(struct bContext *C,
continue;
}
undomball_to_editmball(&elem->data, mb);
+ mb->needs_flush_to_id = 1;
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
@@ -216,6 +217,8 @@ static void mball_undosys_step_decode(struct bContext *C,
ED_undo_object_set_active_or_warn(
CTX_data_view_layer(C), us->elems[0].obedit_ref.ptr, us_p->name, &LOG);
+ bmain->is_memfile_undo_flush_needed = true;
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 70d024c7902..be815fb0d10 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -514,6 +514,11 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
}
}
+ char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(obedit->data);
+ if (needs_flush_ptr) {
+ *needs_flush_ptr = false;
+ }
+
return true;
}
@@ -616,10 +621,13 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MESH, NULL);
}
else if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
ok = 1;
- ED_armature_to_edit(ob->data);
+ ED_armature_to_edit(arm);
/* to ensure all goes in restposition and without striding */
+ arm->needs_flush_to_id = 0;
+
/* XXX: should this be ID_RECALC_GEOMETRY? */
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
@@ -632,9 +640,13 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_TEXT, scene);
}
else if (ob->type == OB_MBALL) {
+ MetaBall *mb = ob->data;
+
ok = 1;
ED_mball_editmball_make(ob);
+ mb->needs_flush_to_id = 0;
+
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MBALL, scene);
}
else if (ob->type == OB_LATTICE) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index fc990c01bfb..052f2bd03a4 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1027,6 +1027,8 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
/* list is manipulated by multiple threads, so we lock */
BLI_thread_lock(LOCK_CUSTOM1);
+ ss->needs_flush_to_id = 1;
+
if (ss->bm || ELEM(type, SCULPT_UNDO_DYNTOPO_BEGIN, SCULPT_UNDO_DYNTOPO_END)) {
/* Dynamic topology stores only one undo node per stroke,
* regardless of the number of PBVH nodes modified */
@@ -1142,17 +1144,6 @@ typedef struct SculptUndoStep {
UndoSculpt data;
} SculptUndoStep;
-static bool sculpt_undosys_poll(bContext *C)
-{
- Object *obact = CTX_data_active_object(C);
- if (obact && obact->type == OB_MESH) {
- if (obact && (obact->mode & OB_MODE_SCULPT)) {
- return true;
- }
- }
- return false;
-}
-
static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
{
SculptUndoStep *us = (SculptUndoStep *)us_p;
@@ -1161,7 +1152,7 @@ static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep
}
static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C),
- struct Main *UNUSED(bmain),
+ struct Main *bmain,
UndoStep *us_p)
{
/* dummy, encoding is done along the way by adding tiles
@@ -1174,6 +1165,11 @@ static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C),
us->step.use_memfile_step = true;
}
us->step.is_applied = true;
+
+ if (!BLI_listbase_is_empty(&us->data.nodes)) {
+ bmain->is_memfile_undo_flush_needed = true;
+ }
+
return true;
}
@@ -1256,7 +1252,11 @@ static void sculpt_undosys_step_decode(
me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, true, NULL);
}
- BLI_assert(sculpt_undosys_poll(C));
+
+ if (ob->sculpt) {
+ ob->sculpt->needs_flush_to_id = 1;
+ }
+ bmain->is_memfile_undo_flush_needed = true;
}
else {
BLI_assert(0);
@@ -1295,7 +1295,6 @@ void ED_sculpt_undo_geometry_end(struct Object *ob)
void ED_sculpt_undosys_type(UndoType *ut)
{
ut->name = "Sculpt";
- ut->poll = sculpt_undosys_poll;
ut->step_encode_init = sculpt_undosys_step_encode_init;
ut->step_encode = sculpt_undosys_step_encode;
ut->step_decode = sculpt_undosys_step_decode;
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 315a4c73e5f..9770b52158a 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -322,7 +322,7 @@ bool ED_undo_is_memfile_compatible(const bContext *C)
if (view_layer != NULL) {
Object *obact = OBACT(view_layer);
if (obact != NULL) {
- if (obact->mode & (OB_MODE_SCULPT | OB_MODE_EDIT)) {
+ if (obact->mode & OB_MODE_EDIT) {
return false;
}
}
diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c
index f3e2ee92558..a5f30409aa6 100644
--- a/source/blender/editors/undo/memfile_undo.c
+++ b/source/blender/editors/undo/memfile_undo.c
@@ -28,6 +28,7 @@
#include "BKE_blender_undo.h"
#include "BKE_context.h"
#include "BKE_undo_system.h"
+#include "BKE_main.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -74,6 +75,10 @@ static bool memfile_undosys_step_encode(struct bContext *UNUSED(C),
/* Important we only use 'main' from the context (see: BKE_undosys_stack_init_from_main). */
UndoStack *ustack = ED_undo_stack_get();
+ if (bmain->is_memfile_undo_flush_needed) {
+ ED_editors_flush_edits_ex(bmain, false, true);
+ }
+
/* can be NULL, use when set. */
MemFileUndoStep *us_prev = (MemFileUndoStep *)BKE_undosys_step_find_by_type(
ustack, BKE_UNDOSYS_TYPE_MEMFILE);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index f5548119e0a..1a33b50ff10 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -230,7 +230,7 @@ void ED_editors_exit(Main *bmain, bool do_undo_system)
/* flush any temp data from object editing to DNA before writing files,
* rendering, copying, etc. */
-bool ED_editors_flush_edits(Main *bmain, bool for_render)
+bool ED_editors_flush_edits_ex(Main *bmain, bool for_render, bool check_needs_flush)
{
bool has_edited = false;
Object *ob;
@@ -244,6 +244,15 @@ bool ED_editors_flush_edits(Main *bmain, bool for_render)
* Auto-save prevents this from happening but scripts
* may cause a flush on saving: T53986. */
if ((ob->sculpt && ob->sculpt->cache) == 0) {
+
+ {
+ char *needs_flush_ptr = &ob->sculpt->needs_flush_to_id;
+ if (check_needs_flush && (*needs_flush_ptr == 0)) {
+ continue;
+ }
+ *needs_flush_ptr = 0;
+ }
+
/* flush multires changes (for sculpt) */
multires_flush_sculpt_updates(ob);
has_edited = true;
@@ -260,15 +269,31 @@ bool ED_editors_flush_edits(Main *bmain, bool for_render)
}
}
else if (ob->mode & OB_MODE_EDIT) {
+
+ char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(ob->data);
+ if (needs_flush_ptr != NULL) {
+ if (check_needs_flush && (*needs_flush_ptr == 0)) {
+ continue;
+ }
+ *needs_flush_ptr = 0;
+ }
+
/* get editmode results */
has_edited = true;
ED_object_editmode_load(bmain, ob);
}
}
+ bmain->is_memfile_undo_flush_needed = false;
+
return has_edited;
}
+bool ED_editors_flush_edits(Main *bmain, bool for_render)
+{
+ return ED_editors_flush_edits_ex(bmain, for_render, false);
+}
+
/* ***** XXX: functions are using old blender names, cleanup later ***** */
/* now only used in 2d spaces, like time, ipo, nla, sima... */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 1b2345809ad..3bad2a04a65 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -126,6 +126,10 @@ typedef struct bArmature {
/** Active editbone (in editmode). */
struct EditBone *act_edbone;
+ /** ID data is older than edit-mode data (TODO: move to edit-mode struct). */
+ char needs_flush_to_id;
+ char _pad0[7];
+
int flag;
int drawtype;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 7a641189bcb..13eaa8925bc 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -206,7 +206,12 @@ typedef struct EditNurb {
/* shape key being edited */
int shapenr;
- char _pad[4];
+ /**
+ * ID data is older than edit-mode data.
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
+
} EditNurb;
typedef struct Curve {
diff --git a/source/blender/makesdna/DNA_lattice_types.h b/source/blender/makesdna/DNA_lattice_types.h
index 3864593158d..f67553c34de 100644
--- a/source/blender/makesdna/DNA_lattice_types.h
+++ b/source/blender/makesdna/DNA_lattice_types.h
@@ -39,6 +39,12 @@ typedef struct EditLatt {
struct Lattice *latt;
int shapenr;
+
+ /**
+ * ID data is older than edit-mode data.
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
} EditLatt;
typedef struct Lattice {
diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h
index c98842eb6d7..8b218dd7ce6 100644
--- a/source/blender/makesdna/DNA_meta_types.h
+++ b/source/blender/makesdna/DNA_meta_types.h
@@ -81,7 +81,13 @@ typedef struct MetaBall {
short totcol;
/** Used to store MB_AUTOSPACE. */
short texflag;
- char _pad[2];
+ char _pad[1];
+
+ /**
+ * ID data is older than edit-mode data (TODO: move to edit-mode struct).
+ * Set #Main.is_memfile_undo_flush_needed when enabling.
+ */
+ char needs_flush_to_id;
/* texture space, copied as one block in editobject.c */
float loc[3];