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:
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/BLO_undofile.h26
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/undofile.c49
-rw-r--r--source/blender/blenloader/intern/versioning_290.c2
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c68
6 files changed, 127 insertions, 22 deletions
diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h
index f280b8f3b9c..175aa4ab9d0 100644
--- a/source/blender/blenloader/BLO_undofile.h
+++ b/source/blender/blenloader/BLO_undofile.h
@@ -26,6 +26,7 @@
*/
struct Scene;
+struct GHash;
typedef struct {
void *next, *prev;
@@ -38,6 +39,9 @@ typedef struct {
* detect unchanged IDs).
* Defined when writing the next step (i.e. last undo step has those always false). */
bool is_identical_future;
+ /** Session uuid of the ID being curently written (MAIN_ID_SESSION_UUID_UNSET when not writing
+ * ID-related data). Used to find matching chunks in previous memundo step. */
+ uint id_session_uuid;
} MemFileChunk;
typedef struct MemFile {
@@ -45,6 +49,17 @@ typedef struct MemFile {
size_t size;
} MemFile;
+typedef struct MemFileWriteData {
+ MemFile *written_memfile;
+ MemFile *reference_memfile;
+
+ uint current_id_session_uuid;
+ MemFileChunk *reference_current_chunk;
+
+ /** Maps an ID session uuid to its first reference MemFileChunk, if existing. */
+ struct GHash *id_session_uuid_mapping;
+} MemFileWriteData;
+
typedef struct MemFileUndoData {
char filename[1024]; /* FILE_MAX */
MemFile memfile;
@@ -52,10 +67,13 @@ typedef struct MemFileUndoData {
} MemFileUndoData;
/* actually only used writefile.c */
-extern void memfile_chunk_add(MemFile *memfile,
- const char *buf,
- unsigned int size,
- MemFileChunk **compchunk_step);
+
+void BLO_memfile_write_init(MemFileWriteData *mem_data,
+ MemFile *written_memfile,
+ MemFile *reference_memfile);
+void BLO_memfile_write_finalize(MemFileWriteData *mem_data);
+
+void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, unsigned int size);
/* exports */
extern void BLO_memfile_free(MemFile *memfile);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index db63091ce36..c9027eae296 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6984,7 +6984,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
direct_link_paint(fd, sce, &sce->toolsettings->imapaint.paint);
- sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
sce->toolsettings->particle.scene = NULL;
sce->toolsettings->particle.object = NULL;
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c
index c7057883f88..28b37c4a737 100644
--- a/source/blender/blenloader/intern/undofile.c
+++ b/source/blender/blenloader/intern/undofile.c
@@ -41,10 +41,12 @@
#include "DNA_listBase.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
/* keep last */
@@ -100,8 +102,52 @@ void BLO_memfile_clear_future(MemFile *memfile)
}
}
-void memfile_chunk_add(MemFile *memfile, const char *buf, uint size, MemFileChunk **compchunk_step)
+void BLO_memfile_write_init(MemFileWriteData *mem_data,
+ MemFile *written_memfile,
+ MemFile *reference_memfile)
{
+ mem_data->written_memfile = written_memfile;
+ mem_data->reference_memfile = reference_memfile;
+ mem_data->reference_current_chunk = reference_memfile ? reference_memfile->chunks.first : NULL;
+
+ /* If we have a reference memfile, we generate a mapping between the session_uuid's of the IDs
+ * stored in that previous undo step, and its first matching memchunk.
+ * This will allow us to easily find the existing undo memory storage of IDs even when some
+ * re-ordering in current Main data-base broke the order matching with the memchunks from
+ * previous step. */
+ if (reference_memfile != NULL) {
+ mem_data->id_session_uuid_mapping = BLI_ghash_new(
+ BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, __func__);
+ uint current_session_uuid = MAIN_ID_SESSION_UUID_UNSET;
+ LISTBASE_FOREACH (MemFileChunk *, mem_chunk, &reference_memfile->chunks) {
+ if (!ELEM(mem_chunk->id_session_uuid, MAIN_ID_SESSION_UUID_UNSET, current_session_uuid)) {
+ current_session_uuid = mem_chunk->id_session_uuid;
+ void **entry;
+ if (!BLI_ghash_ensure_p(mem_data->id_session_uuid_mapping,
+ POINTER_FROM_UINT(current_session_uuid),
+ &entry)) {
+ *entry = mem_chunk;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+}
+
+void BLO_memfile_write_finalize(MemFileWriteData *mem_data)
+{
+ if (mem_data->id_session_uuid_mapping != NULL) {
+ BLI_ghash_free(mem_data->id_session_uuid_mapping, NULL, NULL);
+ }
+}
+
+void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, uint size)
+{
+ MemFile *memfile = mem_data->written_memfile;
+ MemFileChunk **compchunk_step = &mem_data->reference_current_chunk;
+
MemFileChunk *curchunk = MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
curchunk->size = size;
curchunk->buf = NULL;
@@ -110,6 +156,7 @@ void memfile_chunk_add(MemFile *memfile, const char *buf, uint size, MemFileChun
* perform an undo push may make changes after the last undo push that
* will then not be undo. Though it's not entirely clear that is wrong behavior. */
curchunk->is_identical_future = true;
+ curchunk->id_session_uuid = mem_data->current_id_session_uuid;
BLI_addtail(&memfile->chunks, curchunk);
/* we compare compchunk with buf */
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 6574c983b09..1aa569d8336 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -249,7 +249,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_WeightVGEdit) {
- md->flag &= ~MOD_WVG_EDIT_WEIGHTS_NORMALIZE;
+ ((WeightVGEditModifierData *)md)->edit_flags &= ~MOD_WVG_EDIT_WEIGHTS_NORMALIZE;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 57c9ca16693..91d89254c90 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -465,6 +465,9 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
/* Reset all grease pencil brushes. */
Scene *scene = bmain->scenes.first;
BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings, true);
+ BKE_brush_gpencil_sculpt_presets(bmain, scene->toolsettings, true);
+ BKE_brush_gpencil_vertex_presets(bmain, scene->toolsettings, true);
+ BKE_brush_gpencil_weight_presets(bmain, scene->toolsettings, true);
/* Ensure new Paint modes. */
BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index c7d9fbf7268..bc36497dd9f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -164,6 +164,7 @@
#include "BKE_gpencil_modifier.h"
#include "BKE_idtype.h"
#include "BKE_layer.h"
+#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
@@ -328,12 +329,7 @@ typedef struct {
bool error;
/** #MemFile writing (used for undo). */
- struct {
- MemFile *current;
- MemFile *compare;
- /** Use to de-duplicate chunks when writing. */
- MemFileChunk *compare_chunk;
- } mem;
+ MemFileWriteData mem;
/** When true, write to #WriteData.current, could also call 'is_undo'. */
bool use_memfile;
@@ -372,7 +368,7 @@ static void writedata_do_write(WriteData *wd, const void *mem, int memlen)
/* memory based save */
if (wd->use_memfile) {
- memfile_chunk_add(wd->mem.current, mem, memlen, &wd->mem.compare_chunk);
+ BLO_memfile_chunk_add(&wd->mem, mem, memlen);
}
else {
if (wd->ww->write(wd->ww, mem, memlen) != memlen) {
@@ -473,9 +469,7 @@ static WriteData *mywrite_begin(WriteWrap *ww, MemFile *compare, MemFile *curren
WriteData *wd = writedata_new(ww);
if (current != NULL) {
- wd->mem.current = current;
- wd->mem.compare = compare;
- wd->mem.compare_chunk = compare ? compare->chunks.first : NULL;
+ BLO_memfile_write_init(&wd->mem, current, compare);
wd->use_memfile = true;
}
@@ -495,12 +489,58 @@ static bool mywrite_end(WriteData *wd)
wd->buf_used_len = 0;
}
+ if (wd->use_memfile) {
+ BLO_memfile_write_finalize(&wd->mem);
+ }
+
const bool err = wd->error;
writedata_free(wd);
return err;
}
+/**
+ * Start writing of data related to a single ID.
+ *
+ * Only does something when storing an undo step.
+ */
+static void mywrite_id_begin(WriteData *wd, ID *id)
+{
+ if (wd->use_memfile) {
+ wd->mem.current_id_session_uuid = id->session_uuid;
+
+ /* If current next memchunk does not match the ID we are about to write, try to find the
+ * correct memchunk in the mapping using ID's session_uuid. */
+ if (wd->mem.id_session_uuid_mapping != NULL &&
+ (wd->mem.reference_current_chunk == NULL ||
+ wd->mem.reference_current_chunk->id_session_uuid != id->session_uuid)) {
+ void *ref = BLI_ghash_lookup(wd->mem.id_session_uuid_mapping,
+ POINTER_FROM_UINT(id->session_uuid));
+ if (ref != NULL) {
+ wd->mem.reference_current_chunk = ref;
+ }
+ /* Else, no existing memchunk found, i.e. this is supposed to be a new ID. */
+ }
+ /* Otherwise, we try with the current memchunk in any case, whether it is matching current
+ * ID's session_uuid or not. */
+ }
+}
+
+/**
+ * Start writing of data related to a single ID.
+ *
+ * Only does something when storing an undo step.
+ */
+static void mywrite_id_end(WriteData *wd, ID *UNUSED(id))
+{
+ if (wd->use_memfile) {
+ /* Very important to do it after every ID write now, otherwise we cannot know whether a
+ * specific ID changed or not. */
+ mywrite_flush(wd);
+ wd->mem.current_id_session_uuid = MAIN_ID_SESSION_UUID_UNSET;
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -4149,6 +4189,8 @@ static bool write_file_handle(Main *mainvar,
}
}
+ mywrite_id_begin(wd, id);
+
memcpy(id_buffer, id, idtype_struct_size);
((ID *)id_buffer)->tag = 0;
@@ -4290,11 +4332,7 @@ static bool write_file_handle(Main *mainvar,
BKE_lib_override_library_operations_store_end(override_storage, id);
}
- if (wd->use_memfile) {
- /* Very important to do it after every ID write now, otherwise we cannot know whether a
- * specific ID changed or not. */
- mywrite_flush(wd);
- }
+ mywrite_id_end(wd, id);
}
if (id_buffer != id_buffer_static) {