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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-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];