Undo: unified undo system w/ linear history

- Use a single undo history for all operations.
- UndoType's are registered and poll the context to check if they
  should be used when performing an undo push.
- Mode switching is used to ensure the state is correct before
  undo data is restored.
- Some undo types accumulate changes (image & text editing)
  others store the state multiple times (with de-duplication).
  This is supported by checking UndoStack.mode `ACCUMULATE` / `STORE`.
- Each undo step stores ID datablocks they use with utilities to help
  manage restoring correct ID's.
  Needed since global undo is now mixed with other modes undo.
- Currently performs each undo step when going up/down history
  Previously this wasn't done, making history fail in some cases.
  This can be optimized to skip some combinations of undo steps.

grease-pencil is an exception which has not been updated
since it integrates undo into the draw-session.

See D3113
This commit is contained in:
2018-03-19 14:17:59 +01:00
parent 91d0825b55
commit 651b8fb14e
66 changed files with 3066 additions and 1942 deletions

View File

@@ -49,6 +49,7 @@ struct Scene;
struct ViewContext;
struct wmKeyConfig;
struct wmOperator;
struct UndoType;
typedef struct EditBone {
struct EditBone *next, *prev;
@@ -139,7 +140,7 @@ bool ED_armature_select_pick(struct bContext *C, const int mval[2], bool extend,
int join_armature_exec(struct bContext *C, struct wmOperator *op);
struct Bone *get_indexed_bone(struct Object *ob, int index);
float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only);
EditBone *ED_armature_bone_find_name(const ListBase *edbo, const char *name);
EditBone *ED_armature_bone_find_name(const struct ListBase *edbo, const char *name);
EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo);
void ED_armature_sync_selection(struct ListBase *edbo);
void ED_armature_validate_active(struct bArmature *arm);
@@ -178,8 +179,6 @@ void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone);
void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep);
void ED_armature_bones_flip_names(struct bArmature *arm, struct ListBase *bones_names, const bool do_strip_numbers);
void undo_push_armature(struct bContext *C, const char *name);
/* low level selection functions which handle */
int ED_armature_ebone_selectflag_get(const EditBone *ebone);
void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag);
@@ -187,6 +186,9 @@ void ED_armature_ebone_select_set(EditBone *ebone, bool select);
void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag);
void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag);
/* editarmature_undo.c */
void ED_armature_undosys_type(struct UndoType *ut);
/* armature_utils.c */
void ED_armature_ebone_listbase_temp_clear(struct ListBase *lb);
void ED_armature_ebone_listbase_free(struct ListBase *lb);

View File

@@ -41,6 +41,7 @@ struct Curve;
struct EditNurb;
struct BezTriple;
struct BPoint;
struct UndoType;
/* curve_ops.c */
void ED_operatortypes_curve(void);
@@ -48,7 +49,7 @@ void ED_operatormacros_curve(void);
void ED_keymap_curve(struct wmKeyConfig *keyconf);
/* editcurve.c */
ListBase *object_editcurve_get(struct Object *ob);
struct ListBase *object_editcurve_get(struct Object *ob);
void ED_curve_editnurb_load(struct Object *obedit);
void ED_curve_editnurb_make(struct Object *obedit);
@@ -72,7 +73,7 @@ void ED_curve_select_all(struct EditNurb *editnurb);
void ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles);
/* editcurve_undo.c */
void undo_push_curve(struct bContext *C, const char *name);
void ED_curve_undosys_type(struct UndoType *ut);
/* editfont.c */
void ED_curve_editfont_load(struct Object *obedit);
@@ -91,7 +92,8 @@ bool ED_curve_active_center(struct Curve *cu, float center[3]);
bool ED_curve_editfont_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
/* editfont_undo.c */
void undo_push_font(struct bContext *C, const char *name);
void ED_font_undosys_type(struct UndoType *ut);
#if 0
/* debug only */

View File

@@ -31,6 +31,8 @@
#define __ED_LATTICE_H__
struct wmKeyConfig;
struct UndoType;
struct Object;
/* lattice_ops.c */
void ED_operatortypes_lattice(void);
@@ -41,6 +43,6 @@ void ED_lattice_flags_set(struct Object *obedit, int flag);
bool ED_lattice_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
/* editlattice_undo.c */
void undo_push_lattice(struct bContext *C, const char *name);
void ED_lattice_undosys_type(struct UndoType *ut);
#endif /* __ED_LATTICE_H__ */

View File

@@ -34,6 +34,7 @@
struct bContext;
struct Object;
struct wmKeyConfig;
struct UndoType;
void ED_operatortypes_metaball(void);
void ED_operatormacros_metaball(void);
@@ -47,6 +48,7 @@ void ED_mball_editmball_free(struct Object *obedit);
void ED_mball_editmball_make(struct Object *obedit);
void ED_mball_editmball_load(struct Object *obedit);
void undo_push_mball(struct bContext *C, const char *name);
/* editmball_undo.c */
void ED_mball_undosys_type(struct UndoType *ut);
#endif /* __ED_MBALL_H__ */

View File

@@ -62,6 +62,7 @@ struct UvMapVert;
struct ToolSettings;
struct Object;
struct rcti;
struct UndoType;
/* editmesh_utils.c */
void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const int axis,
@@ -98,8 +99,6 @@ void EDBM_selectmode_flush(struct BMEditMesh *em);
void EDBM_deselect_flush(struct BMEditMesh *em);
void EDBM_select_flush(struct BMEditMesh *em);
void undo_push_mesh(struct bContext *C, const char *name);
bool EDBM_vert_color_check(struct BMEditMesh *em);
void EDBM_mesh_hide(struct BMEditMesh *em, bool swap);
@@ -130,6 +129,9 @@ void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
bool BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e,
struct ARegion *ar, struct View3D *v3d, struct Object *obedit);
/* editmesh_undo.c */
void ED_mesh_undosys_type(struct UndoType *ut);
/* editmesh_select.c */
void EDBM_select_mirrored(
struct BMEditMesh *em, const int axis, const bool extend,

View File

@@ -196,6 +196,7 @@ void ED_object_constraint_dependency_tag_update(struct Main *bmain, struct Objec
bool ED_object_mode_compat_test(const struct Object *ob, eObjectMode mode);
bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, eObjectMode mode, struct ReportList *reports);
void ED_object_mode_toggle(struct bContext *C, eObjectMode mode);
void ED_object_mode_set(struct bContext *C, eObjectMode mode);
/* object_modifier.c */
enum {

View File

@@ -28,31 +28,16 @@
struct bContext;
struct wmKeyConfig;
struct wmOperator;
struct ImBuf;
struct Image;
struct UndoStep;
struct UndoType;
/* paint_ops.c */
void ED_operatortypes_paint(void);
void ED_operatormacros_paint(void);
void ED_keymap_paint(struct wmKeyConfig *keyconf);
/* paint_undo.c */
enum {
UNDO_PAINT_IMAGE = 0,
UNDO_PAINT_MESH = 1,
};
typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
typedef void (*UndoFreeCb)(struct ListBase *lb);
typedef bool (*UndoCleanupCb)(struct bContext *C, struct ListBase *lb);
int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
void ED_undo_paint_step_num(struct bContext *C, int type, int num);
const char *ED_undo_paint_get_name(struct bContext *C, int type, int nr, bool *r_active);
void ED_undo_paint_free(void);
bool ED_undo_paint_is_valid(int type, const char *name);
bool ED_undo_paint_empty(int type);
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free, UndoCleanupCb cleanup);
void ED_undo_paint_push_end(int type);
/* paint_image.c */
void ED_imapaint_clear_partial_redraw(void);
void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h, bool find_old);
@@ -61,6 +46,14 @@ void ED_imapaint_bucket_fill(struct bContext *C, float color[3], struct wmOperat
/* paint_image_undo.c */
void ED_image_undo_push_begin(const char *name);
void ED_image_undo_push_end(void);
void ED_image_undo_restore(void);
void ED_image_undo_restore(struct UndoStep *us);
void ED_image_undosys_type(struct UndoType *ut);
/* paint_curve_undo.c */
void ED_paintcurve_undo_push_begin(const char *name);
void ED_paintcurve_undo_push_end(void);
void ED_paintcurve_undosys_type(struct UndoType *ut);
#endif /* __ED_PAINT_H__ */

View File

@@ -38,6 +38,7 @@ struct ParticleEditSettings;
struct rcti;
struct PTCacheEdit;
struct Scene;
struct UndoType;
/* particle edit mode */
void PE_free_ptcache_edit(struct PTCacheEdit *edit);
@@ -61,14 +62,10 @@ int PE_circle_select(struct bContext *C, int selecting, const int mval[2], float
int PE_lasso_select(struct bContext *C, const int mcords[][2], const short moves, bool extend, bool select);
void PE_deselect_all_visible(struct PTCacheEdit *edit);
/* undo */
/* particle_edit_undo.c */
void ED_particle_undosys_type(struct UndoType *ut);
void PE_undo_push(struct Scene *scene, const char *str);
void PE_undo_step(struct Scene *scene, int step);
void PE_undo(struct Scene *scene);
void PE_redo(struct Scene *scene);
bool PE_undo_is_valid(struct Scene *scene);
void PE_undo_number(struct Scene *scene, int nr);
const char *PE_undo_get_name(struct Scene *scene, int nr, bool *r_active);
#endif /* __ED_PARTICLE_H__ */

View File

@@ -36,6 +36,9 @@ struct Object;
struct RegionView3D;
struct ViewContext;
struct rcti;
struct UndoStep;
struct UndoType;
struct ListBase;
/* sculpt.c */
void ED_operatortypes_sculpt(void);
@@ -43,4 +46,7 @@ void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar,
struct RegionView3D *rv3d, struct Object *ob);
int ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select, bool extend);
/* sculpt_undo.c */
void ED_sculpt_undosys_type(struct UndoType *ut);
#endif /* __ED_SCULPT_H__ */

View File

@@ -30,12 +30,13 @@
#ifndef __ED_TEXT_H__
#define __ED_TEXT_H__
struct bContext;
struct SpaceText;
struct ARegion;
struct UndoType;
void ED_text_undo_step(struct bContext *C, int step);
bool ED_text_region_location_from_cursor(struct SpaceText *st, struct ARegion *ar, const int cursor_co[2], int r_pixel_co[2]);
#endif /* __ED_TEXT_H__ */
/* text_undo.c */
void ED_text_undosys_type(struct UndoType *ut);
#endif /* __ED_TEXT_H__ */

View File

@@ -35,6 +35,9 @@ struct bContext;
struct SpaceLink;
struct wmOperator;
struct wmOperatorType;
struct UndoStack;
struct ScrArea;
struct PackedFile;
/* ed_util.c */
@@ -70,16 +73,12 @@ void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg
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,
void * (*getdata)(struct bContext *C),
void (*freedata)(void *),
void (*to_editmode)(void *, void *, void *),
void *(*from_editmode)(void *, void *),
int (*validate_undo)(void *, void *));
/* undo_system_types.c */
void ED_undosys_type_init(void);
void ED_undosys_type_free(void);
void undo_editmode_clear(void);
/* memfile_undo.c */
struct MemFile *ED_undosys_stack_memfile_get_active(struct UndoStack *ustack);
/* ************** XXX OLD CRUFT WARNING ************* */