Fluid: Refactored caching in main Mantaflow class

This refactor cleans up code for the Manta file IO. It also improves the cache 'Replay' option.
This commit is contained in:
Sebastián Barschkis 2020-04-03 16:38:38 +02:00
parent bfdc42d990
commit 70b061b4fd
6 changed files with 377 additions and 402 deletions

@ -62,6 +62,15 @@ int manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int fra
int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_bake_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_bake_guiding(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_guiding(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_has_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_has_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_has_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_has_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
int manta_has_guiding(struct MANTA *fluid,
struct FluidModifierData *mmd,
int framenr,
bool domain);
void manta_update_variables(struct MANTA *fluid, struct FluidModifierData *mmd); void manta_update_variables(struct MANTA *fluid, struct FluidModifierData *mmd);
int manta_get_frame(struct MANTA *fluid); int manta_get_frame(struct MANTA *fluid);
float manta_get_timestep(struct MANTA *fluid); float manta_get_timestep(struct MANTA *fluid);

@ -595,19 +595,19 @@ static std::string getCacheFileEnding(char cache_format)
switch (cache_format) { switch (cache_format) {
case FLUID_DOMAIN_FILE_UNI: case FLUID_DOMAIN_FILE_UNI:
return ".uni"; return FLUID_DOMAIN_EXTENSION_UNI;
case FLUID_DOMAIN_FILE_OPENVDB: case FLUID_DOMAIN_FILE_OPENVDB:
return ".vdb"; return FLUID_DOMAIN_EXTENSION_OPENVDB;
case FLUID_DOMAIN_FILE_RAW: case FLUID_DOMAIN_FILE_RAW:
return ".raw"; return FLUID_DOMAIN_EXTENSION_RAW;
case FLUID_DOMAIN_FILE_BIN_OBJECT: case FLUID_DOMAIN_FILE_BIN_OBJECT:
return ".bobj.gz"; return FLUID_DOMAIN_EXTENSION_BINOBJ;
case FLUID_DOMAIN_FILE_OBJECT: case FLUID_DOMAIN_FILE_OBJECT:
return ".obj"; return FLUID_DOMAIN_EXTENSION_OBJ;
default: default:
std::cerr << "Fluid Error -- Could not find file extension. Using default file extension." std::cerr << "Fluid Error -- Could not find file extension. Using default file extension."
<< std::endl; << std::endl;
return ".uni"; return FLUID_DOMAIN_EXTENSION_UNI;
} }
} }
@ -1054,38 +1054,27 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
int result = 0; int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */ int expected = 0; /* Expected number of read successes for this frame. */
// Ensure empty data structures at start /* Ensure empty data structures at start. */
if (mFlipParticleData) if (!mFlipParticleData || !mFlipParticleVelocity)
mFlipParticleData->clear(); return false;
if (mFlipParticleVelocity)
mFlipParticleVelocity->clear();
std::ostringstream ss; mFlipParticleData->clear();
char cacheDir[FILE_MAX], targetFile[FILE_MAX]; mFlipParticleVelocity->clear();
cacheDir[0] = '\0';
targetFile[0] = '\0';
std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
BLI_path_join( std::string file = getFile(
cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PP, pformat.c_str(), framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "pp_####" << pformat; result += updateParticlesFromFile(file, false, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateParticlesFromFile(targetFile, false, false);
assert(result == expected); assert(result == expected);
} }
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PVEL, pformat.c_str(), framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "pVel_####" << pformat; result += updateParticlesFromFile(file, false, true);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateParticlesFromFile(targetFile, false, true);
assert(result == expected); assert(result == expected);
} }
@ -1108,42 +1097,29 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
int result = 0; int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */ int expected = 0; /* Expected number of read successes for this frame. */
// Ensure empty data structures at start /* Ensure empty data structures at start. */
if (mMeshNodes) if (!mMeshNodes || !mMeshTriangles || !mMeshVelocities)
mMeshNodes->clear(); return false;
if (mMeshTriangles)
mMeshTriangles->clear();
if (mMeshVelocities)
mMeshVelocities->clear();
std::ostringstream ss; mMeshNodes->clear();
char cacheDir[FILE_MAX], targetFile[FILE_MAX]; mMeshTriangles->clear();
cacheDir[0] = '\0'; mMeshVelocities->clear();
targetFile[0] = '\0';
std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format); std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format);
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
BLI_path_join( std::string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, mformat, framenr);
cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "lMesh_####" << mformat; result += updateMeshFromFile(file);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateMeshFromFile(targetFile);
assert(result == expected); assert(result == expected);
} }
if (mUsingMVel) { if (mUsingMVel) {
file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESHVEL, dformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "lVelMesh_####" << dformat; result += updateMeshFromFile(file);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateMeshFromFile(targetFile);
assert(result == expected); assert(result == expected);
} }
} }
@ -1167,53 +1143,35 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
int result = 0; int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */ int expected = 0; /* Expected number of read successes for this frame. */
// Ensure empty data structures at start /* Ensure empty data structures at start. */
if (mSndParticleData) if (!mSndParticleData || !mSndParticleVelocity || !mSndParticleLife)
mSndParticleData->clear(); return false;
if (mSndParticleVelocity)
mSndParticleVelocity->clear();
if (mSndParticleLife)
mSndParticleLife->clear();
std::ostringstream ss; mSndParticleData->clear();
char cacheDir[FILE_MAX], targetFile[FILE_MAX]; mSndParticleVelocity->clear();
cacheDir[0] = '\0'; mSndParticleLife->clear();
targetFile[0] = '\0';
std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
BLI_path_join(cacheDir, std::string file = getFile(
sizeof(cacheDir), mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, pformat, framenr);
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_PARTICLES,
nullptr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "ppSnd_####" << pformat; result += updateParticlesFromFile(file, true, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateParticlesFromFile(targetFile, true, false);
assert(result == expected); assert(result == expected);
} }
file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PVELSND, pformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "pVelSnd_####" << pformat; result += updateParticlesFromFile(file, true, true);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateParticlesFromFile(targetFile, true, true);
assert(result == expected); assert(result == expected);
} }
file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PLIFESND, pformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "pLifeSnd_####" << pformat; result += updateParticlesFromFile(file, true, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateParticlesFromFile(targetFile, true, false);
assert(result == expected); assert(result == expected);
} }
@ -1236,103 +1194,70 @@ bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
int result = 0; int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */ int expected = 0; /* Expected number of read successes for this frame. */
std::ostringstream ss;
char cacheDir[FILE_MAX], targetFile[FILE_MAX];
cacheDir[0] = '\0';
targetFile[0] = '\0';
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
BLI_path_join( std::string file = getFile(
cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_DENSITY, dformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "density_####" << dformat; result += updateGridFromFile(file, mDensity, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mDensity, false);
assert(result == expected); assert(result == expected);
} }
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "shadow_####" << dformat; result += updateGridFromFile(file, mShadow, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mShadow, false);
assert(result == expected); assert(result == expected);
} }
if (mUsingHeat) { if (mUsingHeat) {
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_HEAT, dformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "heat_####" << dformat; result += updateGridFromFile(file, mHeat, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mHeat, false);
assert(result == expected); assert(result == expected);
} }
} }
if (mUsingColors) { if (mUsingColors) {
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORR, dformat, framenr);
expected += 3; expected += 3;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "color_r_####" << dformat; result += updateGridFromFile(file, mColorR, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorR, false);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORG, dformat, framenr);
ss << "color_g_####" << dformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); result += updateGridFromFile(file, mColorG, false);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorG, false);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORB, dformat, framenr);
ss << "color_b_####" << dformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); result += updateGridFromFile(file, mColorB, false);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorB, false);
assert(result == expected); assert(result == expected);
} }
} }
if (mUsingFire) { if (mUsingFire) {
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FLAME, dformat, framenr);
expected += 3; expected += 3;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "flame_####" << dformat; result += updateGridFromFile(file, mFlame, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mFlame, false);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FUEL, dformat, framenr);
ss << "fuel_####" << dformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); result += updateGridFromFile(file, mFuel, false);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mFuel, false);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_REACT, dformat, framenr);
ss << "react_####" << dformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); result += updateGridFromFile(file, mReact, false);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mReact, false);
assert(result == expected); assert(result == expected);
} }
} }
@ -1356,101 +1281,62 @@ bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
int result = 0; int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */ int expected = 0; /* Expected number of read successes for this frame. */
std::ostringstream ss;
char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX], targetFile[FILE_MAX];
cacheDirData[0] = '\0';
cacheDirNoise[0] = '\0';
targetFile[0] = '\0';
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
BLI_path_join(cacheDirData, std::string file = getFile(
sizeof(cacheDirData), mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, nformat, framenr);
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_DATA,
nullptr);
BLI_path_join(cacheDirNoise,
sizeof(cacheDirNoise),
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_NOISE,
nullptr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "density_noise_####" << nformat; result += updateGridFromFile(file, mDensityHigh, true);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mDensityHigh, true);
assert(result == expected); assert(result == expected);
} }
file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr);
expected += 1; expected += 1;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "shadow_####" << dformat; result += updateGridFromFile(file, mShadow, false);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mShadow, false);
assert(result == expected); assert(result == expected);
} }
if (mUsingColors) { if (mUsingColors) {
file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORRNOISE, nformat, framenr);
expected += 3; expected += 3;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "color_r_noise_####" << nformat; result += updateGridFromFile(file, mColorRHigh, true);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorRHigh, true);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORGNOISE, nformat, framenr);
ss << "color_g_noise_####" << nformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); result += updateGridFromFile(file, mColorGHigh, true);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorGHigh, true);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORBNOISE, nformat, framenr);
ss << "color_b_noise_####" << nformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); result += updateGridFromFile(file, mColorBHigh, true);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mColorBHigh, true);
assert(result == expected); assert(result == expected);
} }
} }
if (mUsingFire) { if (mUsingFire) {
file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FLAMENOISE, nformat, framenr);
expected += 3; expected += 3;
ss.str(""); if (BLI_exists(file.c_str())) {
ss << "flame_noise_####" << nformat; result += updateGridFromFile(file, mFlameHigh, true);
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mFlameHigh, true);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FUELNOISE, nformat, framenr);
ss << "fuel_noise_####" << nformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); result += updateGridFromFile(file, mFuelHigh, true);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mFuelHigh, true);
assert(result == expected); assert(result == expected);
} }
ss.str(""); file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_REACTNOISE, nformat, framenr);
ss << "react_noise_####" << nformat; if (BLI_exists(file.c_str())) {
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); result += updateGridFromFile(file, mReactHigh, true);
BLI_path_frame(targetFile, framenr, 0);
if (BLI_exists(targetFile)) {
result += updateGridFromFile(targetFile, mReactHigh, true);
assert(result == expected); assert(result == expected);
} }
} }
@ -1479,26 +1365,18 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr)
std::cout << "MANTA::writeConfiguration()" << std::endl; std::cout << "MANTA::writeConfiguration()" << std::endl;
FluidDomainSettings *mds = mmd->domain; FluidDomainSettings *mds = mmd->domain;
std::ostringstream ss;
char cacheDir[FILE_MAX], targetFile[FILE_MAX];
cacheDir[0] = '\0';
targetFile[0] = '\0';
std::string dformat = ".uni"; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
std::string format = FLUID_DOMAIN_EXTENSION_UNI;
std::string file = getFile(
mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
BLI_path_join( /* Create 'config' subdir if it does not exist already. */
cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr); BLI_dir_create_recursive(directory.c_str());
BLI_path_make_safe(cacheDir);
BLI_dir_create_recursive(cacheDir); /* Create 'config' subdir if it does not exist already */
ss.str(""); gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "wb1"); // do some compression
ss << "config_####" << dformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
gzFile gzf = (gzFile)BLI_gzopen(targetFile, "wb1"); // do some compression
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- Cannot open file " << targetFile << std::endl; std::cerr << "Fluid Error -- Cannot open file " << file << std::endl;
return false; return false;
} }
@ -1528,37 +1406,28 @@ bool MANTA::writeData(FluidModifierData *mmd, int framenr)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
char cacheDirData[FILE_MAX]; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
cacheDirData[0] = '\0';
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
std::string resumable_cache = (final_cache) ? "False" : "True"; std::string resumable_cache = (final_cache) ? "False" : "True";
BLI_path_join(cacheDirData,
sizeof(cacheDirData),
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_DATA,
nullptr);
BLI_path_make_safe(cacheDirData);
ss.str(""); ss.str("");
ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " << framenr ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
if (mUsingSmoke) { if (mUsingSmoke) {
ss.str(""); ss.str("");
ss << "smoke_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " ss << "smoke_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
} }
if (mUsingLiquid) { if (mUsingLiquid) {
ss.str(""); ss.str("");
ss << "liquid_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " ss << "liquid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
} }
return runPythonString(pythonCommands); return runPythonString(pythonCommands);
@ -1570,29 +1439,19 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
std::cout << "MANTA::readConfiguration()" << std::endl; std::cout << "MANTA::readConfiguration()" << std::endl;
FluidDomainSettings *mds = mmd->domain; FluidDomainSettings *mds = mmd->domain;
std::ostringstream ss;
char cacheDir[FILE_MAX], targetFile[FILE_MAX];
cacheDir[0] = '\0';
targetFile[0] = '\0';
float dummy; float dummy;
std::string dformat = ".uni"; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
std::string format = FLUID_DOMAIN_EXTENSION_UNI;
std::string file = getFile(
mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
BLI_path_join( if (!hasConfig(mmd, framenr))
cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr);
BLI_path_make_safe(cacheDir);
ss.str("");
ss << "config_####" << dformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false; return false;
gzFile gzf = (gzFile)BLI_gzopen(targetFile, "rb"); // do some compression gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); // do some compression
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- Cannot open file " << targetFile << std::endl; std::cerr << "Fluid Error -- Cannot open file " << file << std::endl;
return false; return false;
} }
@ -1625,60 +1484,39 @@ bool MANTA::readData(FluidModifierData *mmd, int framenr)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
bool result = true;
char cacheDirData[FILE_MAX], targetFile[FILE_MAX]; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
cacheDirData[0] = '\0';
targetFile[0] = '\0';
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
std::string resumable_cache = (final_cache) ? "False" : "True"; std::string resumable_cache = (final_cache) ? "False" : "True";
BLI_path_join(cacheDirData, /* Sanity check: Are cache files present? */
sizeof(cacheDirData), if (!hasData(mmd, framenr))
mmd->domain->cache_directory, return false;
FLUID_DOMAIN_DIR_DATA,
nullptr);
BLI_path_make_safe(cacheDirData);
/* Exit early if there is nothing present in the cache for this frame */
ss.str("");
if (mUsingSmoke) {
ss << "density_####" << dformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false;
}
if (mUsingLiquid) {
ss << "phi_####" << dformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false;
}
ss.str(""); ss.str("");
ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " << framenr ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
if (mUsingSmoke) { if (mUsingSmoke) {
ss.str(""); ss.str("");
ss << "smoke_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " ss << "smoke_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
result &= runPythonString(pythonCommands);
} }
if (mUsingLiquid) { if (mUsingLiquid) {
/* Exit early if there is nothing present in the cache for this frame */
ss.str(""); ss.str("");
ss << "liquid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " ss << "liquid_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << dformat << "', " << resumable_cache << ")"; << ", '" << dformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
result &= runPythonString(pythonCommands);
} }
return runPythonString(pythonCommands); return result;
} }
bool MANTA::readNoise(FluidModifierData *mmd, int framenr) bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
@ -1692,33 +1530,19 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
char cacheDirNoise[FILE_MAX], targetFile[FILE_MAX]; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
cacheDirNoise[0] = '\0';
targetFile[0] = '\0';
std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
std::string resumable_cache = (final_cache) ? "False" : "True"; std::string resumable_cache = (final_cache) ? "False" : "True";
BLI_path_join(cacheDirNoise, /* Sanity check: Are cache files present? */
sizeof(cacheDirNoise), if (!hasNoise(mmd, framenr))
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_NOISE,
nullptr);
BLI_path_make_safe(cacheDirNoise);
/* Exit early if there is nothing present in the cache for this frame */
ss.str("");
ss << "density_noise_####" << nformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false; return false;
ss.str(""); ss.str("");
ss << "smoke_load_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirNoise) << "', " ss << "smoke_load_noise_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << nformat << "', " << resumable_cache << ")"; << ", '" << nformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
return runPythonString(pythonCommands); return runPythonString(pythonCommands);
@ -1738,36 +1562,22 @@ bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
char cacheDirMesh[FILE_MAX], targetFile[FILE_MAX]; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH);
cacheDirMesh[0] = '\0';
targetFile[0] = '\0';
std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format); std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format);
std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
BLI_path_join(cacheDirMesh, /* Sanity check: Are cache files present? */
sizeof(cacheDirMesh), if (!hasMesh(mmd, framenr))
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_MESH,
nullptr);
BLI_path_make_safe(cacheDirMesh);
/* Exit early if there is nothing present in the cache for this frame */
ss.str("");
ss << "lMesh_####" << mformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirMesh, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false; return false;
ss.str(""); ss.str("");
ss << "liquid_load_mesh_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " ss << "liquid_load_mesh_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << mformat << "')"; << ", '" << mformat << "')";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
if (mUsingMVel) { if (mUsingMVel) {
ss.str(""); ss.str("");
ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
<< framenr << ", '" << dformat << "')"; << framenr << ", '" << dformat << "')";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
} }
@ -1791,32 +1601,18 @@ bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
char cacheDirParticles[FILE_MAX], targetFile[FILE_MAX]; std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES);
cacheDirParticles[0] = '\0';
targetFile[0] = '\0';
std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
std::string resumable_cache = (final_cache) ? "False" : "True"; std::string resumable_cache = (final_cache) ? "False" : "True";
BLI_path_join(cacheDirParticles, /* Sanity check: Are cache files present? */
sizeof(cacheDirParticles), if (!hasParticles(mmd, framenr))
mmd->domain->cache_directory,
FLUID_DOMAIN_DIR_PARTICLES,
nullptr);
BLI_path_make_safe(cacheDirParticles);
/* Exit early if there is nothing present in the cache for this frame */
ss.str("");
ss << "ppSnd_####" << pformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirParticles, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false; return false;
ss.str(""); ss.str("");
ss << "liquid_load_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirParticles) << "', " ss << "liquid_load_particles_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
<< framenr << ", '" << pformat << "', " << resumable_cache << ")"; << framenr << ", '" << pformat << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
@ -1836,33 +1632,22 @@ bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
std::ostringstream ss; std::ostringstream ss;
std::vector<std::string> pythonCommands; std::vector<std::string> pythonCommands;
char cacheDirGuiding[FILE_MAX], targetFile[FILE_MAX]; std::string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) :
cacheDirGuiding[0] = '\0'; getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE);
targetFile[0] = '\0';
std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format);
const char *subdir = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
BLI_path_join( /* Sanity check: Are cache files present? */
cacheDirGuiding, sizeof(cacheDirGuiding), mmd->domain->cache_directory, subdir, nullptr); if (!hasGuiding(mmd, framenr, sourceDomain))
BLI_path_make_safe(cacheDirGuiding);
/* Exit early if there is nothing present in the cache for this frame */
ss.str("");
ss << (sourceDomain ? "vel_####" : "guidevel_####") << gformat;
BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirGuiding, ss.str().c_str());
BLI_path_frame(targetFile, framenr, 0);
if (!BLI_exists(targetFile))
return false; return false;
if (sourceDomain) { if (sourceDomain) {
ss.str(""); ss.str("");
ss << "fluid_load_vel_" << mCurrentID << "('" << escapeSlashes(cacheDirGuiding) << "', " ss << "fluid_load_vel_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
<< framenr << ", '" << gformat << "')"; << ", '" << gformat << "')";
} }
else { else {
ss.str(""); ss.str("");
ss << "fluid_load_guiding_" << mCurrentID << "('" << escapeSlashes(cacheDirGuiding) << "', " ss << "fluid_load_guiding_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
<< framenr << ", '" << gformat << "')"; << framenr << ", '" << gformat << "')";
} }
pythonCommands.push_back(ss.str()); pythonCommands.push_back(ss.str());
@ -2453,7 +2238,7 @@ void MANTA::adaptTimestep()
runPythonString(pythonCommands); runPythonString(pythonCommands);
} }
bool MANTA::updateMeshFromFile(const char *filename) bool MANTA::updateMeshFromFile(std::string filename)
{ {
std::string fname(filename); std::string fname(filename);
std::string::size_type idx; std::string::size_type idx;
@ -2479,14 +2264,14 @@ bool MANTA::updateMeshFromFile(const char *filename)
return false; return false;
} }
bool MANTA::updateMeshFromBobj(const char *filename) bool MANTA::updateMeshFromBobj(std::string filename)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateMeshFromBobj()" << std::endl; std::cout << "MANTA::updateMeshFromBobj()" << std::endl;
gzFile gzf; gzFile gzf;
gzf = (gzFile)BLI_gzopen(filename, "rb1"); // do some compression gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename
<< std::endl; << std::endl;
@ -2660,7 +2445,7 @@ bool MANTA::updateMeshFromBobj(const char *filename)
return (gzclose(gzf) == Z_OK); return (gzclose(gzf) == Z_OK);
} }
bool MANTA::updateMeshFromObj(const char *filename) bool MANTA::updateMeshFromObj(std::string filename)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateMeshFromObj()" << std::endl; std::cout << "MANTA::updateMeshFromObj()" << std::endl;
@ -2750,7 +2535,7 @@ bool MANTA::updateMeshFromObj(const char *filename)
return true; return true;
} }
bool MANTA::updateMeshFromUni(const char *filename) bool MANTA::updateMeshFromUni(std::string filename)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateMeshFromUni()" << std::endl; std::cout << "MANTA::updateMeshFromUni()" << std::endl;
@ -2759,7 +2544,7 @@ bool MANTA::updateMeshFromUni(const char *filename)
float fbuffer[4]; float fbuffer[4];
int ibuffer[4]; int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename, "rb1"); // do some compression gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename
<< std::endl; << std::endl;
@ -2831,7 +2616,7 @@ bool MANTA::updateMeshFromUni(const char *filename)
return (gzclose(gzf) == Z_OK); return (gzclose(gzf) == Z_OK);
} }
bool MANTA::updateParticlesFromFile(const char *filename, bool isSecondarySys, bool isVelData) bool MANTA::updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateParticlesFromFile()" << std::endl; std::cout << "MANTA::updateParticlesFromFile()" << std::endl;
@ -2857,7 +2642,7 @@ bool MANTA::updateParticlesFromFile(const char *filename, bool isSecondarySys, b
} }
} }
bool MANTA::updateParticlesFromUni(const char *filename, bool isSecondarySys, bool isVelData) bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateParticlesFromUni()" << std::endl; std::cout << "MANTA::updateParticlesFromUni()" << std::endl;
@ -2865,7 +2650,7 @@ bool MANTA::updateParticlesFromUni(const char *filename, bool isSecondarySys, bo
gzFile gzf; gzFile gzf;
int ibuffer[4]; int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename, "rb1"); // do some compression gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename
<< std::endl; << std::endl;
@ -3063,7 +2848,7 @@ bool MANTA::updateParticlesFromUni(const char *filename, bool isSecondarySys, bo
return (gzclose(gzf) == Z_OK); return (gzclose(gzf) == Z_OK);
} }
bool MANTA::updateGridFromFile(const char *filename, float *grid, bool isNoise) bool MANTA::updateGridFromFile(std::string filename, float *grid, bool isNoise)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateGridFromFile()" << std::endl; std::cout << "MANTA::updateGridFromFile()" << std::endl;
@ -3102,7 +2887,7 @@ bool MANTA::updateGridFromFile(const char *filename, float *grid, bool isNoise)
} }
} }
bool MANTA::updateGridFromUni(const char *filename, float *grid, bool isNoise) bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateGridFromUni()" << std::endl; std::cout << "MANTA::updateGridFromUni()" << std::endl;
@ -3110,7 +2895,7 @@ bool MANTA::updateGridFromUni(const char *filename, float *grid, bool isNoise)
gzFile gzf; gzFile gzf;
int ibuffer[4]; int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename, "rb1"); gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");
if (!gzf) { if (!gzf) {
std::cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename std::cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename
<< std::endl; << std::endl;
@ -3194,7 +2979,7 @@ bool MANTA::updateGridFromUni(const char *filename, float *grid, bool isNoise)
} }
#if OPENVDB == 1 #if OPENVDB == 1
bool MANTA::updateGridFromVDB(const char *filename, float *grid, bool isNoise) bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateGridFromVDB()" << std::endl; std::cout << "MANTA::updateGridFromVDB()" << std::endl;
@ -3238,7 +3023,7 @@ bool MANTA::updateGridFromVDB(const char *filename, float *grid, bool isNoise)
} }
#endif #endif
bool MANTA::updateGridFromRaw(const char *filename, float *grid, bool isNoise) bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise)
{ {
if (with_debug) if (with_debug)
std::cout << "MANTA::updateGridFromRaw()" << std::endl; std::cout << "MANTA::updateGridFromRaw()" << std::endl;
@ -3246,7 +3031,7 @@ bool MANTA::updateGridFromRaw(const char *filename, float *grid, bool isNoise)
gzFile gzf; gzFile gzf;
int expectedBytes, readBytes; int expectedBytes, readBytes;
gzf = (gzFile)BLI_gzopen(filename, "rb"); gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb");
if (!gzf) { if (!gzf) {
std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl; std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl;
return false; return false;
@ -3406,3 +3191,71 @@ void MANTA::updatePointers()
mSmokeFromFile = false; mSmokeFromFile = false;
mNoiseFromFile = false; mNoiseFromFile = false;
} }
bool MANTA::hasConfig(FluidModifierData *mmd, int framenr)
{
std::string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, extension, framenr).c_str());
}
bool MANTA::hasData(FluidModifierData *mmd, int framenr)
{
std::string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PHI;
std::string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
}
bool MANTA::hasNoise(FluidModifierData *mmd, int framenr)
{
std::string extension = getCacheFileEnding(mmd->domain->cache_noise_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, extension, framenr)
.c_str());
}
bool MANTA::hasMesh(FluidModifierData *mmd, int framenr)
{
std::string extension = getCacheFileEnding(mmd->domain->cache_mesh_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, extension, framenr).c_str());
}
bool MANTA::hasParticles(FluidModifierData *mmd, int framenr)
{
std::string extension = getCacheFileEnding(mmd->domain->cache_particle_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, extension, framenr)
.c_str());
}
bool MANTA::hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
{
std::string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
std::string filename = (sourceDomain) ? FLUID_DOMAIN_FILE_VEL : FLUID_DOMAIN_FILE_GUIDEVEL;
std::string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str());
}
std::string MANTA::getDirectory(FluidModifierData *mmd, std::string subdirectory)
{
char directory[FILE_MAX];
BLI_path_join(
directory, sizeof(directory), mmd->domain->cache_directory, subdirectory.c_str(), nullptr);
BLI_path_make_safe(directory);
return directory;
}
std::string MANTA::getFile(FluidModifierData *mmd,
std::string subdirectory,
std::string fname,
std::string extension,
int framenr)
{
char targetFile[FILE_MAX];
std::string path = getDirectory(mmd, subdirectory);
std::string filename = fname + extension;
BLI_join_dirfile(targetFile, sizeof(targetFile), path.c_str(), filename.c_str());
BLI_path_frame(targetFile, framenr, 0);
return targetFile;
}

@ -108,6 +108,14 @@ struct MANTA {
void exportSmokeScript(struct FluidModifierData *mmd); void exportSmokeScript(struct FluidModifierData *mmd);
void exportLiquidScript(struct FluidModifierData *mmd); void exportLiquidScript(struct FluidModifierData *mmd);
// Check cache status by frame
bool hasConfig(FluidModifierData *mmd, int framenr);
bool hasData(FluidModifierData *mmd, int framenr);
bool hasNoise(FluidModifierData *mmd, int framenr);
bool hasMesh(FluidModifierData *mmd, int framenr);
bool hasParticles(FluidModifierData *mmd, int framenr);
bool hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain);
inline size_t getTotalCells() inline size_t getTotalCells()
{ {
return mTotalCells; return mTotalCells;
@ -861,16 +869,22 @@ struct MANTA {
std::string getRealValue(const std::string &varName, FluidModifierData *mmd); std::string getRealValue(const std::string &varName, FluidModifierData *mmd);
std::string parseLine(const std::string &line, FluidModifierData *mmd); std::string parseLine(const std::string &line, FluidModifierData *mmd);
std::string parseScript(const std::string &setup_string, FluidModifierData *mmd = NULL); std::string parseScript(const std::string &setup_string, FluidModifierData *mmd = NULL);
bool updateMeshFromBobj(const char *filename); bool updateMeshFromBobj(std::string filename);
bool updateMeshFromObj(const char *filename); bool updateMeshFromObj(std::string filename);
bool updateMeshFromUni(const char *filename); bool updateMeshFromUni(std::string filename);
bool updateParticlesFromUni(const char *filename, bool isSecondarySys, bool isVelData); bool updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData);
bool updateGridFromUni(const char *filename, float *grid, bool isNoise); bool updateGridFromUni(std::string filename, float *grid, bool isNoise);
bool updateGridFromVDB(const char *filename, float *grid, bool isNoise); bool updateGridFromVDB(std::string filename, float *grid, bool isNoise);
bool updateGridFromRaw(const char *filename, float *grid, bool isNoise); bool updateGridFromRaw(std::string filename, float *grid, bool isNoise);
bool updateMeshFromFile(const char *filename); bool updateMeshFromFile(std::string filename);
bool updateParticlesFromFile(const char *filename, bool isSecondarySys, bool isVelData); bool updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData);
bool updateGridFromFile(const char *filename, float *grid, bool isNoise); bool updateGridFromFile(std::string filename, float *grid, bool isNoise);
std::string getDirectory(struct FluidModifierData *mmd, std::string subdirectory);
std::string getFile(struct FluidModifierData *mmd,
std::string subdirectory,
std::string fname,
std::string extension,
int framenr);
}; };
#endif #endif

@ -192,6 +192,41 @@ int manta_bake_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr)
return fluid->bakeGuiding(mmd, framenr); return fluid->bakeGuiding(mmd, framenr);
} }
int manta_has_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
{
if (!fluid || !mmd)
return 0;
return fluid->hasData(mmd, framenr);
}
int manta_has_noise(MANTA *fluid, FluidModifierData *mmd, int framenr)
{
if (!fluid || !mmd)
return 0;
return fluid->hasNoise(mmd, framenr);
}
int manta_has_mesh(MANTA *fluid, FluidModifierData *mmd, int framenr)
{
if (!fluid || !mmd)
return 0;
return fluid->hasMesh(mmd, framenr);
}
int manta_has_particles(MANTA *fluid, FluidModifierData *mmd, int framenr)
{
if (!fluid || !mmd)
return 0;
return fluid->hasParticles(mmd, framenr);
}
int manta_has_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr, bool domain)
{
if (!fluid || !mmd)
return 0;
return fluid->hasGuiding(mmd, framenr, domain);
}
void manta_update_variables(MANTA *fluid, FluidModifierData *mmd) void manta_update_variables(MANTA *fluid, FluidModifierData *mmd)
{ {
if (!fluid) if (!fluid)

@ -3673,8 +3673,14 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
uint numobj = 0; uint numobj = 0;
FluidModifierData *mmd_parent = NULL; FluidModifierData *mmd_parent = NULL;
bool is_startframe; bool is_startframe, has_advanced;
is_startframe = (scene_framenr == mds->cache_frame_start); is_startframe = (scene_framenr == mds->cache_frame_start);
has_advanced = (scene_framenr == mmd->time + 1);
/* Do not process modifier if current frame is out of cache range. */
if (scene_framenr < mds->cache_frame_start || scene_framenr > mds->cache_frame_end) {
return;
}
/* Reset fluid if no fluid present. */ /* Reset fluid if no fluid present. */
if (!mds->fluid) { if (!mds->fluid) {
@ -3766,6 +3772,20 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
read_cache = false; read_cache = false;
bake_cache = baking_data || baking_noise || baking_mesh || baking_particles || baking_guide; bake_cache = baking_data || baking_noise || baking_mesh || baking_particles || baking_guide;
bool next_data, next_noise, next_mesh, next_particles, next_guide;
next_data = manta_has_data(mds->fluid, mmd, scene_framenr + 1);
next_noise = manta_has_noise(mds->fluid, mmd, scene_framenr + 1);
next_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr + 1);
next_particles = manta_has_particles(mds->fluid, mmd, scene_framenr + 1);
next_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr + 1, guide_parent);
bool prev_data, prev_noise, prev_mesh, prev_particles, prev_guide;
prev_data = manta_has_data(mds->fluid, mmd, scene_framenr - 1);
prev_noise = manta_has_noise(mds->fluid, mmd, scene_framenr - 1);
prev_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr - 1);
prev_particles = manta_has_particles(mds->fluid, mmd, scene_framenr - 1);
prev_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr - 1, guide_parent);
bool with_gdomain; bool with_gdomain;
with_gdomain = (mds->guide_source == FLUID_DOMAIN_GUIDE_SRC_DOMAIN); with_gdomain = (mds->guide_source == FLUID_DOMAIN_GUIDE_SRC_DOMAIN);
@ -3824,6 +3844,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
default: default:
/* Always trying to read the cache in replay mode. */ /* Always trying to read the cache in replay mode. */
read_cache = true; read_cache = true;
bake_cache = false;
break; break;
} }
@ -3908,7 +3929,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
BKE_fluid_reallocate_fluid(mds, mds->res, 1); BKE_fluid_reallocate_fluid(mds, mds->res, 1);
} }
/* Read data cache */ /* Read data cache */
if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) { if (!baking_data && !baking_particles && !baking_mesh && next_data) {
has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame); has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame);
} }
else { else {
@ -3933,18 +3954,21 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
break; break;
case FLUID_DOMAIN_CACHE_REPLAY: case FLUID_DOMAIN_CACHE_REPLAY:
default: default:
baking_data = !has_data; baking_data = !has_data && (is_startframe || prev_data);
if (with_smoke && with_noise) { if (with_smoke && with_noise) {
baking_noise = !has_noise; baking_noise = !has_noise && (is_startframe || prev_noise);
} }
if (with_liquid && with_mesh) { if (with_liquid && with_mesh) {
baking_mesh = !has_mesh; baking_mesh = !has_mesh && (is_startframe || prev_mesh);
} }
if (with_liquid && with_particles) { if (with_liquid && with_particles) {
baking_particles = !has_particles; baking_particles = !has_particles && (is_startframe || prev_particles);
} }
bake_cache = baking_data || baking_noise || baking_mesh || baking_particles; /* Only bake if time advanced by one frame. */
if (is_startframe || has_advanced) {
bake_cache = baking_data || baking_noise || baking_mesh || baking_particles;
}
break; break;
} }

@ -215,6 +215,46 @@ enum {
#define FLUID_DOMAIN_SMOKE_SCRIPT "smoke_script.py" #define FLUID_DOMAIN_SMOKE_SCRIPT "smoke_script.py"
#define FLUID_DOMAIN_LIQUID_SCRIPT "liquid_script.py" #define FLUID_DOMAIN_LIQUID_SCRIPT "liquid_script.py"
#define FLUID_DOMAIN_FILE_CONFIG "config_####"
#define FLUID_DOMAIN_FILE_DENSITY "density_####"
#define FLUID_DOMAIN_FILE_SHADOW "shadow_####"
#define FLUID_DOMAIN_FILE_VEL "vel_####"
#define FLUID_DOMAIN_FILE_HEAT "heat_####"
#define FLUID_DOMAIN_FILE_COLORR "color_r_####"
#define FLUID_DOMAIN_FILE_COLORG "color_g_####"
#define FLUID_DOMAIN_FILE_COLORB "color_b_####"
#define FLUID_DOMAIN_FILE_FLAME "flame_####"
#define FLUID_DOMAIN_FILE_FUEL "fuel_####"
#define FLUID_DOMAIN_FILE_REACT "react_####"
#define FLUID_DOMAIN_FILE_PHI "phi_####"
#define FLUID_DOMAIN_FILE_PP "pp_####"
#define FLUID_DOMAIN_FILE_PVEL "pVel_####"
#define FLUID_DOMAIN_FILE_DENSITYNOISE "density_noise_####"
#define FLUID_DOMAIN_FILE_COLORRNOISE "color_r_noise_####"
#define FLUID_DOMAIN_FILE_COLORGNOISE "color_g_noise_####"
#define FLUID_DOMAIN_FILE_COLORBNOISE "color_b_noise_####"
#define FLUID_DOMAIN_FILE_FLAMENOISE "flame_noise_####"
#define FLUID_DOMAIN_FILE_FUELNOISE "fuel_noise_####"
#define FLUID_DOMAIN_FILE_REACTNOISE "react_noise_####"
#define FLUID_DOMAIN_FILE_MESH "lMesh_####"
#define FLUID_DOMAIN_FILE_MESHVEL "lVelMesh_####"
#define FLUID_DOMAIN_FILE_PPSND "ppSnd_####"
#define FLUID_DOMAIN_FILE_PVELSND "pVelSnd_####"
#define FLUID_DOMAIN_FILE_PLIFESND "pLifeSnd_####"
#define FLUID_DOMAIN_FILE_GUIDEVEL "guidevel_####"
#define FLUID_DOMAIN_EXTENSION_UNI ".uni"
#define FLUID_DOMAIN_EXTENSION_OPENVDB ".vdb"
#define FLUID_DOMAIN_EXTENSION_RAW ".raw"
#define FLUID_DOMAIN_EXTENSION_OBJ ".obj"
#define FLUID_DOMAIN_EXTENSION_BINOBJ ".bobj.gz"
enum { enum {
FLUID_DOMAIN_CACHE_REPLAY = 0, FLUID_DOMAIN_CACHE_REPLAY = 0,
FLUID_DOMAIN_CACHE_MODULAR = 1, FLUID_DOMAIN_CACHE_MODULAR = 1,