[Bf-blender-cvs] [de3f9303eb9] master: Fix Copy Selection to Buffer breaking library paths.

Brecht Van Lommel noreply at git.blender.org
Thu Oct 18 20:30:54 CEST 2018


Commit: de3f9303eb958d34e4793ff91fafedda0b41ee98
Author: Brecht Van Lommel
Date:   Thu Oct 18 19:51:34 2018 +0200
Branches: master
https://developer.blender.org/rBde3f9303eb958d34e4793ff91fafedda0b41ee98

Fix Copy Selection to Buffer breaking library paths.

This is a bug experienced by animators in the Blender Studio that developers
have been trying to fix for a /long/ time.

What happens is that partial file writing extracts the needed datablocks from
the main list of datablocks into a smaller one. Afterwards they are added back
to the main list, but in some cases not exactly in the same order.

There is file path remapping code that depends on the datablocks being in
exactly the same order as before, and when this was not the case filepaths
would get swapped between datablocks

The reason datablocks are not restored in the same order is because the sorting
of datablocks by name is a) case insensitive and b) undefined if there are
multiple datablocks with the same name from different libraries. This should
be made well defined, but the fix in this commit is simpler.

The way animators ran into this bug is that they use the Copy Attributes addon
a lot, which has as the first item in the menu Copy Selection to Buffer. In
some cases this would be clicked accidentally when menu is near the edge of the
window, breaking the library paths which would only be noticed a much later on
file save and reload.

The way this bug was finally tracked down is that it was suspected that the
undo system was the cause, and so Bastien added library validation for undo.
When Hjalti then did undo and noticed the error, he remembered accidentally
clicking Copy Selection to Buffer just before, and we could finally reproduce
the bug.

===================================================================

M	source/blender/blenkernel/intern/blendfile.c

===================================================================

diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index aa5530704c6..c92648da67c 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -590,10 +590,6 @@ bool BKE_blendfile_write_partial(
 	 * (otherwise main->name will not be set at read time). */
 	BLI_strncpy(bmain_dst->name, bmain_src->name, sizeof(bmain_dst->name));
 
-	if (write_flags & G_FILE_RELATIVE_REMAP) {
-		path_list_backup = BKE_bpath_list_backup(bmain_src, path_list_flag);
-	}
-
 	BLO_main_expander(blendfile_write_partial_cb);
 	BLO_expand_main(NULL, bmain_src);
 
@@ -613,10 +609,27 @@ bool BKE_blendfile_write_partial(
 		}
 	}
 
+	/* Backup paths because remap relative will overwrite them.
+	 *
+	 * NOTE: we do this only on the list of datablocks that we are writing
+	 * because the restored full list is not guaranteed to be in the same
+	 * order as before, as expected by BKE_bpath_list_restore.
+	 *
+	 * This happens because id_sort_by_name does not take into account
+	 * string case or the library name, so the order is not strictly
+	 * defined for two linked datablocks with the same name! */
+	if (write_flags & G_FILE_RELATIVE_REMAP) {
+		path_list_backup = BKE_bpath_list_backup(bmain_dst, path_list_flag);
+	}
 
 	/* save the buffer */
 	retval = BLO_write_file(bmain_dst, filepath, write_flags, reports, NULL);
 
+	if (path_list_backup) {
+		BKE_bpath_list_restore(bmain_dst, path_list_flag, path_list_backup);
+		BKE_bpath_list_free(path_list_backup);
+	}
+
 	/* move back the main, now sorted again */
 	set_listbasepointers(bmain_src, lbarray_dst);
 	a = set_listbasepointers(bmain_dst, lbarray_src);
@@ -632,11 +645,6 @@ bool BKE_blendfile_write_partial(
 
 	MEM_freeN(bmain_dst);
 
-	if (path_list_backup) {
-		BKE_bpath_list_restore(bmain_src, path_list_flag, path_list_backup);
-		BKE_bpath_list_free(path_list_backup);
-	}
-
 	return retval;
 }



More information about the Bf-blender-cvs mailing list