[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51963] trunk/blender/source/blender: fix [#33108] Running save_as_mainfile breaks relative texture paths

Campbell Barton ideasman42 at gmail.com
Wed Nov 7 05:13:11 CET 2012


Revision: 51963
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51963
Author:   campbellbarton
Date:     2012-11-07 04:13:03 +0000 (Wed, 07 Nov 2012)
Log Message:
-----------
fix [#33108] Running save_as_mainfile breaks relative texture paths

save-as with path remapping left the paths relate to the file written.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_global.h
    trunk/blender/source/blender/blenkernel/BKE_utildefines.h
    trunk/blender/source/blender/blenlib/BLI_bpath.h
    trunk/blender/source/blender/blenlib/intern/bpath.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_files.c
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: trunk/blender/source/blender/blenkernel/BKE_global.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_global.h	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/blenkernel/BKE_global.h	2012-11-07 04:13:03 UTC (rev 51963)
@@ -167,7 +167,10 @@
 #define G_FILE_RELATIVE_REMAP    (1 << 24)
 #define G_FILE_HISTORY           (1 << 25)
 #define G_FILE_MESH_COMPAT       (1 << 26)              /* BMesh option to save as older mesh format */
+#define G_FILE_SAVE_COPY         (1 << 27)              /* restore paths after editing them */
 
+#define G_FILE_FLAGS_RUNTIME (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_MESH_COMPAT | G_FILE_SAVE_COPY)
+
 /* G.windowstate */
 #define G_WINDOWSTATE_USERDEF       0
 #define G_WINDOWSTATE_BORDER        1

Modified: trunk/blender/source/blender/blenkernel/BKE_utildefines.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_utildefines.h	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/blenkernel/BKE_utildefines.h	2012-11-07 04:13:03 UTC (rev 51963)
@@ -32,7 +32,11 @@
 extern "C" {
 #endif
 
-/* currently unused but we may want to add macros here for BKE later */
+#define BKE_BIT_TEST_SET(value, test, flag) \
+{                                           \
+	if (test) (value) |=  flag;             \
+	else      (value) &= ~flag;             \
+} (void)0
 
 #ifdef __cplusplus
 }

Modified: trunk/blender/source/blender/blenlib/BLI_bpath.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_bpath.h	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/blenlib/BLI_bpath.h	2012-11-07 04:13:03 UTC (rev 51963)
@@ -48,6 +48,11 @@
 void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
 int  BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
 
+/* Functions for temp backup/restore of paths, path count must NOT change */
+void *BLI_bpath_list_backup(struct Main *bmain, const int flag);
+void  BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
+void  BLI_bpath_list_free(void *ls_handle);
+
 #define BLI_BPATH_TRAVERSE_ABS             (1 << 0) /* convert paths to absolute */
 #define BLI_BPATH_TRAVERSE_SKIP_LIBRARY    (1 << 2) /* skip library paths */
 #define BLI_BPATH_TRAVERSE_SKIP_PACKED     (1 << 3) /* skip packed data */

Modified: trunk/blender/source/blender/blenlib/intern/bpath.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/bpath.c	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/blenlib/intern/bpath.c	2012-11-07 04:13:03 UTC (rev 51963)
@@ -618,3 +618,73 @@
 		return FALSE;
 	}
 }
+
+
+/* -------------------------------------------------------------------- */
+/**
+ * Backup/Restore/Free functions,
+ * \note These functions assume the data won't chane order.
+ */
+
+struct PathStore {
+	struct PathStore *next, *prev;
+} PathStore;
+
+static int bpath_list_append(void *userdata, char *UNUSED(path_dst), const char *path_src)
+{
+	/* store the path and string in a single alloc */
+	ListBase *ls = userdata;
+	size_t path_size = strlen(path_src) + 1;
+	struct PathStore *path_store = MEM_mallocN(sizeof(PathStore) + path_size, __func__);
+	char *filepath = (char *)(path_store + 1);
+
+	memcpy(filepath, path_src, path_size);
+	BLI_addtail(ls, path_store);
+	return FALSE;
+}
+
+static int bpath_list_restore(void *userdata, char *path_dst, const char *path_src)
+{
+	/* assume ls->first wont be NULL because the number of paths can't change!
+	 * (if they do caller is wrong) */
+	ListBase *ls = userdata;
+	struct PathStore *path_store = ls->first;
+	const char *filepath = (char *)(path_store + 1);
+	int ret;
+
+	if (strcmp(path_src, filepath) == 0) {
+		ret = FALSE;
+	}
+	else {
+		BLI_strncpy(path_dst, filepath, FILE_MAX);
+		ret = TRUE;
+	}
+
+	BLI_freelinkN(ls, path_store);
+	return ret;
+}
+
+/* return ls_handle */
+void *BLI_bpath_list_backup(Main *bmain, const int flag)
+{
+	ListBase *ls = MEM_callocN(sizeof(ListBase), __func__);
+
+	BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls);
+
+	return ls;
+}
+
+void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle)
+{
+	ListBase *ls = ls_handle;
+
+	BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls);
+}
+
+void BLI_bpath_list_free(void *ls_handle)
+{
+	ListBase *ls = ls_handle;
+	BLI_assert(ls->first == NULL);  /* assumes we were used */
+	BLI_freelistN(ls);
+	MEM_freeN(ls);
+}

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c	2012-11-07 04:13:03 UTC (rev 51963)
@@ -2890,7 +2890,7 @@
 	fg.winpos= G.winpos;
 
 	/* prevent to save this, is not good convention, and feature with concerns... */
-	fg.fileflags= (fileflags & ~(G_FILE_NO_UI|G_FILE_RELATIVE_REMAP|G_FILE_MESH_COMPAT));
+	fg.fileflags= (fileflags & ~G_FILE_FLAGS_RUNTIME);
 
 	fg.globalf= G.f;
 	BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
@@ -3039,6 +3039,10 @@
 	char tempname[FILE_MAX+1];
 	int file, err, write_user_block;
 
+	/* path backup/restore */
+	void     *path_list_backup = NULL;
+	const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE);
+
 	/* open temporary file, so we preserve the original in case we crash */
 	BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
 
@@ -3048,6 +3052,11 @@
 		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 = BLI_bpath_list_backup(mainvar, path_list_flag);
+	}
+
 	/* remapping of relative paths to new file location */
 	if (write_flags & G_FILE_RELATIVE_REMAP) {
 		char dir1[FILE_MAX];
@@ -3083,6 +3092,11 @@
 	err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb);
 	close(file);
 
+	if (UNLIKELY(path_list_backup)) {
+		BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
+		BLI_bpath_list_free(path_list_backup);
+	}
+
 	if (err) {
 		BKE_report(reports, RPT_ERROR, strerror(errno));
 		remove(tempname);

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2012-11-07 04:13:03 UTC (rev 51963)
@@ -106,7 +106,7 @@
 int			WM_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory);
 int			WM_homefile_write_exec(struct bContext *C, struct wmOperator *op);
 void		WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
-int			WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports, int copy);
+int			WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports);
 void		WM_autosave_init(struct wmWindowManager *wm);
 
 			/* mouse cursors */

Modified: trunk/blender/source/blender/windowmanager/intern/wm_files.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_files.c	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/windowmanager/intern/wm_files.c	2012-11-07 04:13:03 UTC (rev 51963)
@@ -762,7 +762,7 @@
 	}
 }
 
-int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports, int copy)
+int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports)
 {
 	Library *li;
 	int len;
@@ -818,7 +818,7 @@
 	fileflags |= G_FILE_HISTORY; /* write file history */
 
 	if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
-		if (!copy) {
+		if (!(fileflags & G_FILE_SAVE_COPY)) {
 			G.relbase_valid = 1;
 			BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));  /* is guaranteed current file */
 	

Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2012-11-07 02:37:00 UTC (rev 51962)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2012-11-07 04:13:03 UTC (rev 51963)
@@ -72,6 +72,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h" /* BKE_ST_MAXNAME */
+#include "BKE_utildefines.h"
 
 #include "BKE_idcode.h"
 
@@ -2077,7 +2078,6 @@
 {
 	char path[FILE_MAX];
 	int fileflags;
-	int copy = 0;
 
 	save_set_compress(op);
 	
@@ -2087,29 +2087,27 @@
 		BLI_strncpy(path, G.main->name, FILE_MAX);
 		untitled(path);
 	}
-
-	if (RNA_struct_property_is_set(op->ptr, "copy"))
-		copy = RNA_boolean_get(op->ptr, "copy");
 	
 	fileflags = G.fileflags;
 
 	/* set compression flag */
-	if (RNA_boolean_get(op->ptr, "compress")) fileflags |=  G_FILE_COMPRESS;
-	else fileflags &= ~G_FILE_COMPRESS;
-	if (RNA_boolean_get(op->ptr, "relative_remap")) fileflags |=  G_FILE_RELATIVE_REMAP;
-	else fileflags &= ~G_FILE_RELATIVE_REMAP;
+	BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"),
+	                 G_FILE_COMPRESS);
+	BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "relative_remap"),
+	                 G_FILE_RELATIVE_REMAP);
+	BKE_BIT_TEST_SET(fileflags,
+	                 (RNA_struct_property_is_set(op->ptr, "copy") &&
+	                  RNA_boolean_get(op->ptr, "copy")),
+	                 G_FILE_SAVE_COPY);
+
 #ifdef USE_BMESH_SAVE_AS_COMPAT
-	/* property only exists for 'Save As' */
-	if (RNA_struct_find_property(op->ptr, "use_mesh_compat")) {
-		if (RNA_boolean_get(op->ptr, "use_mesh_compat")) fileflags |=  G_FILE_MESH_COMPAT;
-		else fileflags &= ~G_FILE_MESH_COMPAT;
-	}
-	else {
-		fileflags &= ~G_FILE_MESH_COMPAT;
-	}
+	BKE_BIT_TEST_SET(fileflags,
+	                 (RNA_struct_find_property(op->ptr, "use_mesh_compat") &&
+	                  RNA_boolean_get(op->ptr, "use_mesh_compat")),
+	                 G_FILE_MESH_COMPAT);
 #endif
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list