[Bf-blender-cvs] [4621392353c] master: Fix T51176: Cache file location can be blank and prevent fluid simulation from reading baked data

Bastien Montagne noreply at git.blender.org
Mon Apr 17 17:50:33 CEST 2017


Commit: 4621392353c24124a8fe9dc0d5a86c9331a7a0c1
Author: Bastien Montagne
Date:   Mon Apr 17 17:26:18 2017 +0200
Branches: master
https://developer.blender.org/rB4621392353c24124a8fe9dc0d5a86c9331a7a0c1

Fix T51176: Cache file location can be blank and prevent fluid simulation from reading baked data

Sanitize a bit how cache path is handled by fluidsim (there is much more
to be done here though :( ), and forbid empty path (we reset to default
path relative to current .blend file in case it's empty).

If people really, really want to use current OS-wise directory, they can at
least use '.' as path. ;)

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

M	source/blender/editors/physics/physics_fluid.c
M	source/blender/makesdna/DNA_object_fluidsim.h
M	source/blender/modifiers/intern/MOD_fluidsim_util.c

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

diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index b5adf38527b..6460e83e2a0 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -631,71 +631,63 @@ static int fluid_validate_scene(ReportList *reports, Scene *scene, Object *fsDom
 #define FLUID_SUFFIX_CONFIG_TMP	(FLUID_SUFFIX_CONFIG ".tmp")
 #define FLUID_SUFFIX_SURFACE	"fluidsurface"
 
-static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetFile, char *debugStrBuffer)
+static bool fluid_init_filepaths(
+        ReportList *reports, FluidsimSettings *domainSettings, Object *fsDomain,
+        char *targetDir, char *targetFile)
 {
-	FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
-	FluidsimSettings *domainSettings= fluidmd->fss;
-	FILE *fileCfg;
-	int dirExist = 0;
-	char newSurfdataPath[FILE_MAX]; /* modified output settings */
 	const char *suffixConfigTmp = FLUID_SUFFIX_CONFIG_TMP;
-	int outStringsChanged = 0;
 
 	/* prepare names... */
-	const char *relbase= modifier_path_relbase(fsDomain);
+	const char *relbase = modifier_path_relbase(fsDomain);
+
+	/* We do not accept empty paths, they can end in random places silently, see T51176. */
+	if (domainSettings->surfdataPath[0] == '\0') {
+		modifier_path_init(domainSettings->surfdataPath, sizeof(domainSettings->surfdataPath),
+		                   OB_FLUIDSIM_SURF_DIR_DEFAULT);
+		BKE_reportf(reports, RPT_WARNING, "Fluidsim: empty cache path, reset to default '%s'",
+		            domainSettings->surfdataPath);
+	}
 
 	BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
-	BLI_strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR); /* if 0'd out below, this value is never used! */
-	BLI_path_abs(targetDir, relbase); /* fixed #frame-no */
+	BLI_path_abs(targetDir, relbase);
 
 	/* .tmp: don't overwrite/delete original file */
 	BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp);
 
-	// make sure all directories exist
-	// as the bobjs use the same dir, this only needs to be checked
-	// for the cfg output
-	BLI_make_existing_file(targetFile);
-	
-	// check selected directory
-	// simply try to open cfg file for writing to test validity of settings
-	fileCfg = BLI_fopen(targetFile, "w");
-	if (fileCfg) {
-		dirExist = 1; fclose(fileCfg); 
-		// remove cfg dummy from  directory test
-		BLI_delete(targetFile, false, false);
-	}
-	
-	if (targetDir[0] == '\0' || (!dirExist)) {
-		char blendFile[FILE_MAX];
-		
-		// invalid dir, reset to current/previous
-		BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile));
-		BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */
-		BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
-		
-		BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
-		elbeemDebugOut(debugStrBuffer);
-		outStringsChanged=1;
-	}
-	
-	/* check if modified output dir is ok */
-#if 0
-	if (outStringsChanged) {
-		char dispmsg[FILE_MAX+256];
-		int  selection=0;
-		BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg));
-		strcat(dispmsg, newSurfdataPath);
-		strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0");
-		
-		/* ask user if thats what he/she wants... */
-		selection = pupmenu(dispmsg);
-		if (selection < 1) return 0; /* 0 from menu, or -1 aborted */
-		BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir));
-		strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
-		BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */
+	/* Ensure whole path exists and is wirtable. */
+	const bool dir_exists = BLI_dir_create_recursive(targetDir);
+	const bool is_writable = BLI_file_is_writable(targetFile);
+
+	/* We change path to some presumably valid default value, but do not allow bake process to continue,
+	 * this gives user chance to set manually another path. */
+	if (!dir_exists || !is_writable) {
+		modifier_path_init(domainSettings->surfdataPath, sizeof(domainSettings->surfdataPath),
+		                   OB_FLUIDSIM_SURF_DIR_DEFAULT);
+
+		if (!dir_exists) {
+			BKE_reportf(reports, RPT_ERROR, "Fluidsim: could not create cache directory '%s', reset to default '%s'",
+			            targetDir, domainSettings->surfdataPath);
+		}
+		else {
+			BKE_reportf(reports, RPT_ERROR, "Fluidsim: cache directory '%s' is not writable, reset to default '%s'",
+			            targetDir, domainSettings->surfdataPath);
+		}
+
+		BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
+		BLI_path_abs(targetDir, relbase);
+
+		/* .tmp: don't overwrite/delete original file */
+		BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp);
+
+		/* Ensure whole path exists and is wirtable. */
+		if (!BLI_dir_create_recursive(targetDir) || !BLI_file_is_writable(targetFile)) {
+			BKE_reportf(reports, RPT_ERROR, "Fluidsim: could not use default cache directory '%s', "
+			                                "please define a valid cache path manually", targetDir);
+		}
+		return false;
 	}
-#endif
-	return outStringsChanged;
+
+	return true;
 }
 
 /* ******************************************************************************** */
@@ -857,7 +849,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
 
 	char targetDir[FILE_MAX];  // store & modify output settings
 	char targetFile[FILE_MAX]; // temp. store filename from targetDir for access
-	int  outStringsChanged = 0;             // modified? copy back before baking
 
 	float domainMat[4][4];
 	float invDomMat[4][4];
@@ -943,7 +934,11 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
 	
 	
 	/* ******** prepare output file paths ******** */
-	outStringsChanged = fluid_init_filepaths(fsDomain, targetDir, targetFile, debugStrBuffer);
+	if (!fluid_init_filepaths(reports, domainSettings, fsDomain, targetDir, targetFile)) {
+		fluidbake_free_data(channels, fobjects, fsset, fb);
+		return false;
+	}
+
 	channels->length = scene->r.efra; // DG TODO: why using endframe and not "noFrames" here? .. because "noFrames" is buggy too? (not using sfra)
 	channels->aniFrameTime = (double)((double)domainSettings->animEnd - (double)domainSettings->animStart) / (double)noFrames;
 	
@@ -968,11 +963,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
 	/* ********  start writing / exporting ******** */
 	// use .tmp, don't overwrite/delete original file
 	BLI_join_dirfile(targetFile, sizeof(targetFile), targetDir, suffixConfigTmp);
-	
-	// make sure these directories exist as well
-	if (outStringsChanged) {
-		BLI_make_existing_file(targetFile);
-	}
 
 	/* ******** export domain to elbeem ******** */
 	elbeemResetSettings(fsset);
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h
index a714195dd5d..846d5788d63 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim.h
@@ -179,6 +179,7 @@ typedef struct FluidsimSettings {
 #define OB_FLUIDSIM_ACTIVE			(1 << 1)
 #define OB_FLUIDSIM_OVERRIDE_TIME	(1 << 2)
 
+#define OB_FLUIDSIM_SURF_DIR_DEFAULT "cache_fluid"
 #define OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME "fluidsurface_preview_####.bobj.gz"
 #define OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME   "fluidsurface_final_####.bobj.gz"
 #define OB_FLUIDSIM_SURF_FINAL_VEL_FNAME   "fluidsurface_final_####.bvel.gz"
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index c1050ee7a4b..2ecf06057db 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -98,7 +98,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
 		/* fluid/inflow settings
 		 * fss->iniVel --> automatically set to 0 */
 
-		modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), "cache_fluid");
+		modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT);
 
 		/* first init of bounding box */
 		/* no bounding box needed */




More information about the Bf-blender-cvs mailing list