Merge branch 'blender-v2.81-release'
This commit is contained in:
commit
322cec8e4d
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define __ED_MBALL_H__
|
||||
|
||||
struct Base;
|
||||
struct MetaBall;
|
||||
struct Object;
|
||||
struct UndoType;
|
||||
struct bContext;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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... */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user