Add a callback to `IDTypeInfo` to allow preservation of some data accross memfile undos

This is essentially adding that new callback, and using it only for already
existing Scene's 3DCursor.

Note that the place where this is called has been moved again, after all
have been lib-linked, such that those callbacks may also work on ID pointers.

Maniphest Tasks: T71759

Differential Revision: https://developer.blender.org/D9237
This commit is contained in:
Bastien Montagne 2020-11-03 11:39:36 +01:00
parent da03eb854b
commit 5610ccdc08
Notes: blender-bot 2023-02-14 03:52:45 +01:00
Referenced by issue #71759, Sculpt/Vertex/Weight Paint Brush Size Gets Undone After Undoing a Stroke
43 changed files with 129 additions and 9 deletions

View File

@ -102,6 +102,10 @@ typedef void (*IDTypeBlendReadDataFunction)(struct BlendDataReader *reader, stru
typedef void (*IDTypeBlendReadLibFunction)(struct BlendLibReader *reader, struct ID *id);
typedef void (*IDTypeBlendReadExpandFunction)(struct BlendExpander *expander, struct ID *id);
typedef void (*IDTypeBlendReadUndoPreserve)(struct BlendLibReader *reader,
struct ID *id_new,
struct ID *id_old);
typedef struct IDTypeInfo {
/* ********** General IDType data. ********** */
@ -196,6 +200,13 @@ typedef struct IDTypeInfo {
* Specify which other id data blocks should be loaded when the current one is loaded.
*/
IDTypeBlendReadExpandFunction blend_read_expand;
/**
* Allow an ID type to preserve some of its data accross (memfile) undo steps.
*
* \note Called from #setup_app_data when undoing or redoing a memfile step.
*/
IDTypeBlendReadUndoPreserve blend_read_undo_preserve;
} IDTypeInfo;
/* ********** Declaration of each IDTypeInfo. ********** */

View File

@ -295,6 +295,8 @@ IDTypeInfo IDType_ID_AC = {
.blend_read_data = action_blend_read_data,
.blend_read_lib = action_blend_read_lib,
.blend_read_expand = action_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/* ***************** Library data level operations on action ************** */

View File

@ -329,6 +329,8 @@ IDTypeInfo IDType_ID_AR = {
.blend_read_data = armature_blend_read_data,
.blend_read_lib = armature_blend_read_lib,
.blend_read_expand = armature_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/** \} */

View File

@ -376,6 +376,8 @@ IDTypeInfo IDType_ID_BR = {
.blend_read_data = brush_blend_read_data,
.blend_read_lib = brush_blend_read_lib,
.blend_read_expand = brush_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static RNG *brush_rng;

View File

@ -140,6 +140,8 @@ IDTypeInfo IDType_ID_CF = {
.blend_read_data = cache_file_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/* TODO: make this per cache file to avoid global locks. */

View File

@ -201,6 +201,8 @@ IDTypeInfo IDType_ID_CA = {
.blend_read_data = camera_blend_read_data,
.blend_read_lib = camera_blend_read_lib,
.blend_read_expand = camera_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/** \} */

View File

@ -359,6 +359,8 @@ IDTypeInfo IDType_ID_GR = {
.blend_read_data = collection_blend_read_data,
.blend_read_lib = collection_blend_read_lib,
.blend_read_expand = collection_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/** \} */

View File

@ -325,6 +325,8 @@ IDTypeInfo IDType_ID_CU = {
.blend_read_data = curve_blend_read_data,
.blend_read_lib = curve_blend_read_lib,
.blend_read_expand = curve_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static int cu_isectLL(const float v1[3],

View File

@ -168,6 +168,8 @@ IDTypeInfo IDType_ID_VF = {
.blend_read_data = vfont_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/***************************** VFont *******************************/

View File

@ -288,6 +288,8 @@ IDTypeInfo IDType_ID_GD = {
.blend_read_data = greasepencil_blend_read_data,
.blend_read_lib = greasepencil_blend_read_lib,
.blend_read_expand = greasepencil_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/* ************************************************** */

View File

@ -195,6 +195,8 @@ IDTypeInfo IDType_ID_HA = {
.blend_read_data = hair_blend_read_data,
.blend_read_lib = hair_blend_read_lib,
.blend_read_expand = hair_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static void hair_random(Hair *hair)

View File

@ -325,6 +325,8 @@ IDTypeInfo IDType_ID_IM = {
.blend_read_data = image_blend_read_data,
.blend_read_lib = image_blend_read_lib,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/* prototypes */

View File

@ -132,6 +132,8 @@ IDTypeInfo IDType_ID_IP = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/* *************************************************** */

View File

@ -214,6 +214,8 @@ IDTypeInfo IDType_ID_KE = {
.blend_read_data = shapekey_blend_read_data,
.blend_read_lib = shapekey_blend_read_lib,
.blend_read_expand = shapekey_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
#define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */

View File

@ -203,6 +203,8 @@ IDTypeInfo IDType_ID_LT = {
.blend_read_data = lattice_blend_read_data,
.blend_read_lib = lattice_blend_read_lib,
.blend_read_expand = lattice_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w)

View File

@ -101,6 +101,15 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
.copy_data = NULL,
.free_data = NULL,
.make_local = NULL,
.foreach_id = NULL,
.foreach_cache = NULL,
.blend_write = NULL,
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/* GS reads the memory pointed at in a specific ordering.

View File

@ -82,6 +82,8 @@ IDTypeInfo IDType_ID_LI = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)

View File

@ -207,6 +207,8 @@ IDTypeInfo IDType_ID_LA = {
.blend_read_data = light_blend_read_data,
.blend_read_lib = light_blend_read_lib,
.blend_read_expand = light_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
Light *BKE_light_add(Main *bmain, const char *name)

View File

@ -105,6 +105,8 @@ IDTypeInfo IDType_ID_LP = {
.blend_read_data = lightprobe_blend_read_data,
.blend_read_lib = lightprobe_blend_read_lib,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
void BKE_lightprobe_type_set(LightProbe *probe, const short lightprobe_type)

View File

@ -765,6 +765,8 @@ IDTypeInfo IDType_ID_LS = {
.blend_read_data = linestyle_blend_read_data,
.blend_read_lib = linestyle_blend_read_lib,
.blend_read_expand = linestyle_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static const char *modifier_name[LS_MODIFIER_NUM] = {

View File

@ -268,6 +268,8 @@ IDTypeInfo IDType_ID_MSK = {
.blend_read_data = mask_blend_read_data,
.blend_read_lib = mask_blend_read_lib,
.blend_read_expand = mask_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static struct {

View File

@ -272,6 +272,8 @@ IDTypeInfo IDType_ID_MA = {
.blend_read_data = material_blend_read_data,
.blend_read_lib = material_blend_read_lib,
.blend_read_expand = material_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
void BKE_gpencil_material_attr_init(Material *ma)

View File

@ -202,6 +202,8 @@ IDTypeInfo IDType_ID_MB = {
.blend_read_data = metaball_blend_read_data,
.blend_read_lib = metaball_blend_read_lib,
.blend_read_expand = metaball_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/* Functions */

View File

@ -333,6 +333,8 @@ IDTypeInfo IDType_ID_ME = {
.blend_read_data = mesh_blend_read_data,
.blend_read_lib = mesh_blend_read_lib,
.blend_read_expand = mesh_read_expand,
.blend_read_undo_preserve = NULL,
};
enum {

View File

@ -359,6 +359,8 @@ IDTypeInfo IDType_ID_MC = {
.blend_read_data = movieclip_blend_read_data,
.blend_read_lib = movieclip_blend_read_lib,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/*********************** movieclip buffer loaders *************************/

View File

@ -853,6 +853,8 @@ IDTypeInfo IDType_ID_NT = {
.blend_read_data = ntree_blend_read_data,
.blend_read_lib = ntree_blend_read_lib,
.blend_read_expand = ntree_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)

View File

@ -538,6 +538,8 @@ IDTypeInfo IDType_ID_OB = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
void BKE_object_workob_clear(Object *workob)

View File

@ -146,6 +146,8 @@ IDTypeInfo IDType_ID_PAL = {
.blend_read_data = palette_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@ -207,6 +209,8 @@ IDTypeInfo IDType_ID_PC = {
.blend_read_data = paint_curve_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};

View File

@ -506,6 +506,8 @@ IDTypeInfo IDType_ID_PA = {
.blend_read_data = particle_settings_blend_read_data,
.blend_read_lib = particle_settings_blend_read_lib,
.blend_read_expand = particle_settings_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];

View File

@ -184,6 +184,8 @@ IDTypeInfo IDType_ID_PT = {
.blend_read_data = pointcloud_blend_read_data,
.blend_read_lib = pointcloud_blend_read_lib,
.blend_read_expand = pointcloud_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
static void pointcloud_random(PointCloud *pointcloud)

View File

@ -104,6 +104,8 @@
#include "SEQ_sequencer.h"
#include "BLO_read_write.h"
#include "engines/eevee/eevee_lightcache.h"
#include "PIL_time.h"
@ -620,6 +622,15 @@ static void scene_foreach_cache(ID *id,
user_data);
}
static void scene_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID *id_old)
{
Scene *scene_new = (Scene *)id_new;
Scene *scene_old = (Scene *)id_old;
SWAP(View3DCursor, scene_old->cursor, scene_new->cursor);
/* TODO: handle tool settings here too. */
}
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@ -643,6 +654,8 @@ IDTypeInfo IDType_ID_SCE = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = scene_undo_preserve,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";

View File

@ -293,6 +293,8 @@ IDTypeInfo IDType_ID_SCR = {
.blend_read_data = NULL,
.blend_read_lib = screen_blend_read_lib,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/* ************ Spacetype/regiontype handling ************** */

View File

@ -171,6 +171,8 @@ IDTypeInfo IDType_ID_SIM = {
/* blend_read_data */ simulation_blend_read_data,
/* blend_read_lib */ simulation_blend_read_lib,
/* blend_read_expand */ simulation_blend_read_expand,
/* blend_read_undo_preserve */ NULL,
};
void *BKE_simulation_add(Main *bmain, const char *name)

View File

@ -212,6 +212,8 @@ IDTypeInfo IDType_ID_SO = {
.blend_read_data = sound_blend_read_data,
.blend_read_lib = sound_blend_read_lib,
.blend_read_expand = sound_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
#ifdef WITH_AUDASPACE

View File

@ -112,6 +112,8 @@ IDTypeInfo IDType_ID_SPK = {
.blend_read_data = speaker_blend_read_data,
.blend_read_lib = speaker_blend_read_lib,
.blend_read_expand = speaker_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
void *BKE_speaker_add(Main *bmain, const char *name)

View File

@ -256,6 +256,8 @@ IDTypeInfo IDType_ID_TXT = {
.blend_read_data = text_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
/** \} */

View File

@ -224,6 +224,8 @@ IDTypeInfo IDType_ID_TE = {
.blend_read_data = texture_blend_read_data,
.blend_read_lib = texture_blend_read_lib,
.blend_read_expand = texture_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/* Utils for all IDs using those texture slots. */

View File

@ -633,6 +633,8 @@ IDTypeInfo IDType_ID_VO = {
/* blend_read_data */ volume_blend_read_data,
/* blend_read_lib */ volume_blend_read_lib,
/* blend_read_expand */ volume_blend_read_expand,
/* blend_read_undo_preserve */ NULL,
};
void BKE_volume_init_grids(Volume *volume)

View File

@ -190,6 +190,8 @@ IDTypeInfo IDType_ID_WS = {
.blend_read_data = workspace_blend_read_data,
.blend_read_lib = workspace_blend_read_lib,
.blend_read_expand = workspace_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
/* -------------------------------------------------------------------- */

View File

@ -204,6 +204,8 @@ IDTypeInfo IDType_ID_WO = {
.blend_read_data = world_blend_read_data,
.blend_read_lib = world_blend_read_lib,
.blend_read_expand = world_blend_read_expand,
.blend_read_undo_preserve = NULL,
};
World *BKE_world_add(Main *bmain, const char *name)

View File

@ -5672,15 +5672,6 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main,
const short idcode = GS(id->name);
/* XXX 3DCursor (witch is UI data and as such should not be affected by undo) is stored in
* Scene... So this requires some special handling, previously done in `blo_lib_link_restore()`,
* but this cannot work anymore when we overwrite existing memory... */
if (idcode == ID_SCE) {
Scene *scene_old = (Scene *)id_old;
Scene *scene = (Scene *)id;
SWAP(View3DCursor, scene_old->cursor, scene->cursor);
}
Main *old_bmain = fd->old_mainlist->first;
ListBase *old_lb = which_libbase(old_bmain, idcode);
ListBase *new_lb = which_libbase(main, idcode);
@ -5692,6 +5683,11 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main,
* process). So we can pass NULL for the Main pointer parameter. */
BKE_lib_id_swap_full(NULL, id, id_old);
/* Special temporary usage of this pointer, necessary for the `undo_preserve` call after
* lib-linking to restore some data that should never be affected by undo, e.g. the 3D cursor of
* #Scene. */
id_old->orig_id = id;
BLI_addtail(new_lb, id_old);
BLI_addtail(old_lb, id);
}
@ -6123,6 +6119,18 @@ static void lib_link_all(FileData *fd, Main *bmain)
}
id->tag &= ~LIB_TAG_NEED_LINK;
/* Some data that should be persistent, like the 3DCursor or the tool settings, are
* stored in IDs affected by undo, like Scene. So this requires some specific handling. */
if (id_type->blend_read_undo_preserve != NULL && id->orig_id != NULL) {
id_type->blend_read_undo_preserve(&reader, id, id->orig_id);
}
}
FOREACH_MAIN_ID_END;
/* Cleanup `ID.orig_id`, this is now reserved for depsgraph/COW usage only. */
FOREACH_MAIN_ID_BEGIN (bmain, id) {
id->orig_id = NULL;
}
FOREACH_MAIN_ID_END;

View File

@ -305,6 +305,7 @@ typedef struct ID {
/**
* Only set for data-blocks which are coming from copy-on-write, points to
* the original version of it.
* Also used temporarily during memfile undo to keep a reference to old ID when found.
*/
struct ID *orig_id;

View File

@ -120,6 +120,8 @@ IDTypeInfo IDType_ID_WM = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
};
#define MAX_OP_REGISTERED 32