Fix T62612: Saving with "Remap Relative" makes ALL paths relative
This commit is contained in:
parent
d4e38d99b2
commit
f7386b9757
Notes:
blender-bot
2023-02-14 06:23:08 +01:00
Referenced by commit aec0cfaf08
, Fix T79676: Video Sequencer image sequence strip source path breaks when
Referenced by issue #79676, Video Editor: sequence SOURCE PATH goes haywire when: Save As... /3d/comp/comp.blend to /comp/comp.blend (Remap Relative is ON)
Referenced by issue #77768, relative_remap in bpy.data.libraries.write() no longer working
Referenced by issue #62612, Saving with "Remap Relative" makes ALL paths relative
|
@ -74,6 +74,10 @@ void BKE_bpath_missing_files_find(struct Main *bmain,
|
|||
const char *searchpath,
|
||||
struct ReportList *reports,
|
||||
const bool find_all);
|
||||
void BKE_bpath_relative_rebase(struct Main *bmain,
|
||||
const char *basedir_src,
|
||||
const char *basedir_dst,
|
||||
struct ReportList *reports);
|
||||
void BKE_bpath_relative_convert(struct Main *bmain,
|
||||
const char *basedir,
|
||||
struct ReportList *reports);
|
||||
|
|
|
@ -112,6 +112,81 @@ void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Rebase Relative Paths
|
||||
* \{ */
|
||||
|
||||
typedef struct BPathRebase_Data {
|
||||
const char *basedir_src;
|
||||
const char *basedir_dst;
|
||||
ReportList *reports;
|
||||
|
||||
int count_tot;
|
||||
int count_changed;
|
||||
int count_failed;
|
||||
} BPathRebase_Data;
|
||||
|
||||
static bool bpath_relative_rebase_visit_cb(void *userdata, char *path_dst, const char *path_src)
|
||||
{
|
||||
BPathRebase_Data *data = (BPathRebase_Data *)userdata;
|
||||
|
||||
data->count_tot++;
|
||||
|
||||
if (BLI_path_is_rel(path_src)) {
|
||||
char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
||||
BLI_strncpy(filepath, path_src, FILE_MAX);
|
||||
if (BLI_path_abs(filepath, data->basedir_src)) {
|
||||
BLI_cleanup_path(NULL, filepath);
|
||||
|
||||
/* This may fail, if so it's fine to leave absolute since the path is still valid. */
|
||||
BLI_path_rel(filepath, data->basedir_dst);
|
||||
|
||||
BLI_strncpy(path_dst, filepath, FILE_MAX);
|
||||
data->count_changed++;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
/* Failed to make relative path absolute. */
|
||||
BLI_assert(0);
|
||||
BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
|
||||
data->count_failed++;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
/* Absolute, leave this as-is. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_bpath_relative_rebase(Main *bmain,
|
||||
const char *basedir_src,
|
||||
const char *basedir_dst,
|
||||
ReportList *reports)
|
||||
{
|
||||
BPathRebase_Data data = {NULL};
|
||||
const int flag = BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
|
||||
|
||||
BLI_assert(basedir_src[0] != '\0');
|
||||
BLI_assert(basedir_dst[0] != '\0');
|
||||
|
||||
data.basedir_src = basedir_src;
|
||||
data.basedir_dst = basedir_dst;
|
||||
data.reports = reports;
|
||||
|
||||
BKE_bpath_traverse_main(bmain, bpath_relative_rebase_visit_cb, flag, (void *)&data);
|
||||
|
||||
BKE_reportf(reports,
|
||||
data.count_failed ? RPT_WARNING : RPT_INFO,
|
||||
"Total files %d | Changed %d | Failed %d",
|
||||
data.count_tot,
|
||||
data.count_changed,
|
||||
data.count_failed);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Make Paths Relative
|
||||
* \{ */
|
||||
|
|
|
@ -4056,41 +4056,38 @@ bool BLO_write_file(Main *mainvar,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* check if we need to backup and restore paths */
|
||||
if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) {
|
||||
path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag);
|
||||
}
|
||||
|
||||
/* remapping of relative paths to new file location */
|
||||
/* Remapping of relative paths to new file location. */
|
||||
if (write_flags & G_FILE_RELATIVE_REMAP) {
|
||||
char dir1[FILE_MAX];
|
||||
char dir2[FILE_MAX];
|
||||
BLI_split_dir_part(filepath, dir1, sizeof(dir1));
|
||||
BLI_split_dir_part(mainvar->name, dir2, sizeof(dir2));
|
||||
char dir_src[FILE_MAX];
|
||||
char dir_dst[FILE_MAX];
|
||||
BLI_split_dir_part(mainvar->name, dir_src, sizeof(dir_src));
|
||||
BLI_split_dir_part(filepath, dir_dst, sizeof(dir_dst));
|
||||
|
||||
/* just in case there is some subtle difference */
|
||||
BLI_cleanup_dir(mainvar->name, dir1);
|
||||
BLI_cleanup_dir(mainvar->name, dir2);
|
||||
BLI_cleanup_dir(mainvar->name, dir_dst);
|
||||
BLI_cleanup_dir(mainvar->name, dir_src);
|
||||
|
||||
if (G.relbase_valid && (BLI_path_cmp(dir1, dir2) == 0)) {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
/* Check if we need to backup and restore paths. */
|
||||
if (UNLIKELY(G_FILE_SAVE_COPY & write_flags)) {
|
||||
path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag);
|
||||
}
|
||||
|
||||
if (G.relbase_valid) {
|
||||
/* blend may not have been saved before. Tn this case
|
||||
* we should not have any relative paths, but if there
|
||||
* is somehow, an invalid or empty G_MAIN->name it will
|
||||
* print an error, don't try make the absolute in this case. */
|
||||
BKE_bpath_absolute_convert(mainvar, BKE_main_blendfile_path_from_global(), NULL);
|
||||
/* Saved, make relative paths relative to new location (if possible). */
|
||||
BKE_bpath_relative_rebase(mainvar, dir_src, dir_dst, NULL);
|
||||
}
|
||||
else {
|
||||
/* Unsaved, make all relative. */
|
||||
BKE_bpath_relative_convert(mainvar, dir_dst, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (write_flags & G_FILE_RELATIVE_REMAP) {
|
||||
/* note, making relative to something OTHER then G_MAIN->name */
|
||||
BKE_bpath_relative_convert(mainvar, filepath, NULL);
|
||||
}
|
||||
|
||||
/* actual file writing */
|
||||
const bool err = write_file_handle(mainvar, &ww, NULL, NULL, write_flags, thumb);
|
||||
|
||||
|
|
|
@ -2668,7 +2668,7 @@ void WM_OT_save_as_mainfile(wmOperatorType *ot)
|
|||
"relative_remap",
|
||||
true,
|
||||
"Remap Relative",
|
||||
"Make paths relative when saving to a different directory");
|
||||
"Remap relative paths when saving to a different directory");
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna,
|
||||
"copy",
|
||||
|
@ -2740,7 +2740,7 @@ void WM_OT_save_mainfile(wmOperatorType *ot)
|
|||
"relative_remap",
|
||||
false,
|
||||
"Remap Relative",
|
||||
"Make paths relative when saving to a different directory");
|
||||
"Remap relative paths when saving to a different directory");
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "exit", false, "Exit", "Exit Blender after saving");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
|
Loading…
Reference in New Issue