[Bf-blender-cvs] [3ada1949f86] master: Python API: path mapping options for library writing function

Campbell Barton noreply at git.blender.org
Thu Jun 18 07:50:06 CEST 2020


Commit: 3ada1949f8633293b4a424bf20789d94cf924c43
Author: Campbell Barton
Date:   Thu Jun 18 15:25:22 2020 +1000
Branches: master
https://developer.blender.org/rB3ada1949f8633293b4a424bf20789d94cf924c43

Python API: path mapping options for library writing function

When "Relative Remap" option was added, the intention was only to remap
paths that were already relative. However it remapped all paths.

This was reported as T62612 and fixed recently,
however some Python script authors depended on the old behavior.

For users, it's reasonable to use the existing operators to make paths
absolute/relative. For scripts however it's useful to be able to write
out individual data-blocks with the ability to make all paths relative.

Now `bpy.data.libraries.write()` takes a path_remap argument which can
be `NONE/RELATIVE/RELATIVE_ALL/ABSOLUTE` allowing the script author to
choose how paths are handled when writing out data-blocks.

Addresses T77768.

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

M	source/blender/blenkernel/BKE_blendfile.h
M	source/blender/blenkernel/BKE_global.h
M	source/blender/blenkernel/intern/blender_copybuffer.c
M	source/blender/blenkernel/intern/blender_undo.c
M	source/blender/blenkernel/intern/blendfile.c
M	source/blender/blenloader/BLO_writefile.h
M	source/blender/blenloader/intern/writefile.c
M	source/blender/python/intern/bpy_library_write.c
M	source/blender/windowmanager/intern/wm_files.c
M	source/blender/windowmanager/intern/wm_init_exit.c

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

diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index 2bff684948d..e835137bfa1 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -74,6 +74,7 @@ void BKE_blendfile_write_partial_begin(struct Main *bmain_src);
 bool BKE_blendfile_write_partial(struct Main *bmain_src,
                                  const char *filepath,
                                  const int write_flags,
+                                 const int remap_mode,
                                  struct ReportList *reports);
 void BKE_blendfile_write_partial_end(struct Main *bmain_src);
 
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index a1871d22da7..a134f29228f 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -177,13 +177,11 @@ enum {
   /** On read, use #FileGlobal.filename instead of the real location on-disk,
    * needed for recovering temp files so relative paths resolve */
   G_FILE_RECOVER = (1 << 23),
-  /** On write, remap relative file paths to the new file location. */
-  G_FILE_RELATIVE_REMAP = (1 << 24),
   /** On write, make backup `.blend1`, `.blend2` ... files, when the users preference is enabled */
   G_FILE_HISTORY = (1 << 25),
   /** BMesh option to save as older mesh format */
   /* #define G_FILE_MESH_COMPAT       (1 << 26) */
-  /** On write, restore paths after editing them (G_FILE_RELATIVE_REMAP) */
+  /** On write, restore paths after editing them (see #BLO_WRITE_PATH_REMAP_RELATIVE). */
   G_FILE_SAVE_COPY = (1 << 27),
   /* #define G_FILE_GLSL_NO_ENV_LIGHTING (1 << 28) */ /* deprecated */
 };
@@ -192,8 +190,7 @@ enum {
  * Run-time only #G.fileflags which are never read or written to/from Blend files.
  * This means we can change the values without worrying about do-versions.
  */
-#define G_FILE_FLAG_ALL_RUNTIME \
-  (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_HISTORY | G_FILE_SAVE_COPY)
+#define G_FILE_FLAG_ALL_RUNTIME (G_FILE_NO_UI | G_FILE_HISTORY | G_FILE_SAVE_COPY)
 
 /** ENDIAN_ORDER: indicates what endianness the platform where the file was written had. */
 #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index 4d27621a861..bd133ce9ea6 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -72,9 +72,10 @@ void BKE_copybuffer_tag_ID(ID *id)
  */
 bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *reports)
 {
-  const int write_flags = G_FILE_RELATIVE_REMAP;
+  const int write_flags = 0;
+  const eBLO_WritePathRemap remap_mode = BLO_WRITE_PATH_REMAP_RELATIVE;
 
-  bool retval = BKE_blendfile_write_partial(bmain_src, filename, write_flags, reports);
+  bool retval = BKE_blendfile_write_partial(bmain_src, filename, write_flags, remap_mode, reports);
 
   BKE_blendfile_write_partial_end(bmain_src);
 
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index c8aff345487..e19a4935698 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -119,7 +119,7 @@ MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev)
     BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
     BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), numstr);
 
-    /* success = */ /* UNUSED */ BLO_write_file(bmain, filename, fileflags, NULL, NULL);
+    /* success = */ /* UNUSED */ BLO_write_file(bmain, filename, fileflags, NULL);
 
     BLI_strncpy(mfu->filename, filename, sizeof(mfu->filename));
   }
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index ef474022f19..a3031e9047f 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -646,7 +646,7 @@ bool BKE_blendfile_userdef_write(const char *filepath, ReportList *reports)
   Main *mainb = MEM_callocN(sizeof(Main), "empty main");
   bool ok = false;
 
-  if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) {
+  if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports)) {
     ok = true;
   }
 
@@ -777,7 +777,8 @@ bool BKE_blendfile_workspace_config_write(Main *bmain, const char *filepath, Rep
     BKE_blendfile_write_partial_tag_ID(&workspace->id, true);
   }
 
-  if (BKE_blendfile_write_partial(bmain, filepath, fileflags, reports)) {
+  if (BKE_blendfile_write_partial(
+          bmain, filepath, fileflags, BLO_WRITE_PATH_REMAP_NONE, reports)) {
     retval = true;
   }
 
@@ -829,11 +830,13 @@ static void blendfile_write_partial_cb(void *UNUSED(handle), Main *UNUSED(bmain)
 }
 
 /**
+ * \param remap_mode: Choose the kind of path remapping or none #eBLO_FilePathRemap.
  * \return Success.
  */
 bool BKE_blendfile_write_partial(Main *bmain_src,
                                  const char *filepath,
                                  const int write_flags,
+                                 const int remap_mode,
                                  ReportList *reports)
 {
   Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer");
@@ -875,12 +878,12 @@ bool BKE_blendfile_write_partial(Main *bmain_src,
    * 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 data-blocks with the same name! */
-  if (write_flags & G_FILE_RELATIVE_REMAP) {
+  if (remap_mode != BLO_WRITE_PATH_REMAP_NONE) {
     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);
+  retval = BLO_write_file_ex(bmain_dst, filepath, write_flags, reports, remap_mode, NULL);
 
   if (path_list_backup) {
     BKE_bpath_list_restore(bmain_dst, path_list_flag, path_list_backup);
diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h
index d83abf7f9ed..18783474392 100644
--- a/source/blender/blenloader/BLO_writefile.h
+++ b/source/blender/blenloader/BLO_writefile.h
@@ -30,11 +30,32 @@ struct Main;
 struct MemFile;
 struct ReportList;
 
+/**
+ * Adjust paths when saving (kept unless #G_FILE_SAVE_COPY is set).
+ */
+typedef enum eBLO_WritePathRemap {
+  /** No path manipulation. */
+  BLO_WRITE_PATH_REMAP_NONE = 1,
+  /** Remap existing relative paths (default). */
+  BLO_WRITE_PATH_REMAP_RELATIVE = 2,
+  /** Remap paths making all paths relative to the new location. */
+  BLO_WRITE_PATH_REMAP_RELATIVE_ALL = 3,
+  /** Make all paths absolute. */
+  BLO_WRITE_PATH_REMAP_ABSOLUTE = 4,
+} eBLO_WritePathRemap;
+
+extern bool BLO_write_file_ex(struct Main *mainvar,
+                              const char *filepath,
+                              const int write_flags,
+                              struct ReportList *reports,
+                              /* Extra arguments. */
+                              eBLO_WritePathRemap remap_mode,
+                              const struct BlendThumbnail *thumb);
 extern bool BLO_write_file(struct Main *mainvar,
                            const char *filepath,
-                           int write_flags,
-                           struct ReportList *reports,
-                           const struct BlendThumbnail *thumb);
+                           const int write_flags,
+                           struct ReportList *reports);
+
 extern bool BLO_write_file_mem(struct Main *mainvar,
                                struct MemFile *compare,
                                struct MemFile *current,
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index a40cc4c3ad2..1cda22de941 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -4400,11 +4400,13 @@ static bool do_history(const char *name, ReportList *reports)
 /**
  * \return Success.
  */
-bool BLO_write_file(Main *mainvar,
-                    const char *filepath,
-                    int write_flags,
-                    ReportList *reports,
-                    const BlendThumbnail *thumb)
+bool BLO_write_file_ex(Main *mainvar,
+                       const char *filepath,
+                       const int write_flags,
+                       ReportList *reports,
+                       /* Extra arguments. */
+                       eBLO_WritePathRemap remap_mode,
+                       const BlendThumbnail *thumb)
 {
   char tempname[FILE_MAX + 1];
   eWriteWrapType ww_type;
@@ -4439,7 +4441,15 @@ bool BLO_write_file(Main *mainvar,
   }
 
   /* Remapping of relative paths to new file location. */
-  if (write_flags & G_FILE_RELATIVE_REMAP) {
+  if (remap_mode != BLO_WRITE_PATH_REMAP_NONE) {
+
+    if (remap_mode == BLO_WRITE_PATH_REMAP_RELATIVE) {
+      /* Make all relative as none of the existing paths can be relative in an unsaved document. */
+      if (G.relbase_valid == false) {
+        remap_mode = BLO_WRITE_PATH_REMAP_RELATIVE_ALL;
+      }
+    }
+
     char dir_src[FILE_MAX];
     char dir_dst[FILE_MAX];
     BLI_split_dir_part(mainvar->name, dir_src, sizeof(dir_src));
@@ -4449,23 +4459,43 @@ bool BLO_write_file(Main *mainvar,
     BLI_path_normalize(mainvar->name, dir_dst);
     BLI_path_normalize(mainvar->name, dir_src);
 
-    if (G.relbase_valid && (BLI_path_cmp(dir_dst, dir_src) == 0)) {
-      /* Saved to same path. Nothing to do. */
-      write_flags &= ~G_FILE_RELATIVE_REMAP;
+    /* Only for relative, not relative-all, as this means making existing paths relative. */
+    if (remap_mode == BLO_WRITE_PATH_REMAP_RELATIVE) {
+      if (G.relbase_valid && (BLI_path_cmp(dir_dst, dir_src) == 0)) {
+        /* Saved to same path. Nothing to do. */
+        remap_mode = BLO_WRITE_PATH_REMAP_NONE;
+      }
     }
-    else {
+    else if (remap_mode == BLO_WRITE_PATH_REMAP_ABSOLUTE) {
+      if (G.relbase_valid == false) {
+        /* Unsaved, a

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list