Fluid: Improved OpenVDB support for fluid caches
authorSebastián Barschkis <sebbas@sebbas.org>
Wed, 24 Jun 2020 13:30:49 +0000 (15:30 +0200)
committerSebastián Barschkis <sebbas@sebbas.org>
Wed, 24 Jun 2020 14:07:35 +0000 (16:07 +0200)
This commit makes uses of the new OpenVDB IO in Mantaflow (introduced in 781f783a66ac).

From now on, fluid cache files in OpenVDB format will contain a list of grids per frame (before: one .vdb file per grid per frame). Besides regular grids, particle systems are also stored using OpenVDBs PointGrid data structures.

All older cache formats will remain fully functional:
- Uni caches (.uni) files are still available from the UI and can be used as before
- Raw caches (.raw) are no longer available from the UI, but loading them is still possible
- Old OpenVDB caches (one .vdb per grid) can no longer be baked either, but loading them is still possible.

It is also no longer possible to choose file formats for 'Noise' and 'Particles'. Instead there are now options to set the file format for 'Volumetric' and for 'Mesh' data.

Known issues (planned to be resolved soon):
- OpenVDB files are currently not taking into consideration the clipping value (FluidDomainSettings). Empty cells are therefore being written too. Depending on the scene, this can make file sizes unnecessarily large.
- Domains are not being exported at their world position. Instead they are always clipped to the origin.

14 files changed:
intern/mantaflow/extern/manta_fluid_API.h
intern/mantaflow/intern/MANTA_main.cpp
intern/mantaflow/intern/MANTA_main.h
intern/mantaflow/intern/manta_fluid_API.cpp
intern/mantaflow/intern/strings/fluid_script.h
intern/mantaflow/intern/strings/liquid_script.h
intern/mantaflow/intern/strings/smoke_script.h
release/scripts/startup/bl_operators/object_quick_effects.py
release/scripts/startup/bl_ui/properties_physics_fluid.py
source/blender/blenkernel/intern/fluid.c
source/blender/blenkernel/intern/pointcache.c
source/blender/editors/physics/physics_fluid.c
source/blender/makesdna/DNA_fluid_types.h
source/blender/makesrna/intern/rna_fluid.c

index 7825ad14d7d38678bf3a3c6085af9a4267804d81..d78aa6732b1ad881e09a2c54b68181bb5ea3659a 100644 (file)
@@ -41,23 +41,23 @@ int manta_write_config(struct MANTA *fluid, struct FluidModifierData *mmd, int f
 int manta_write_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
 int manta_write_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
 int manta_read_config(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
-int manta_read_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
-int manta_read_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
+int manta_read_data(struct MANTA *fluid,
+                    struct FluidModifierData *mmd,
+                    int framenr,
+                    bool resumable);
+int manta_read_noise(struct MANTA *fluid,
+                     struct FluidModifierData *mmd,
+                     int framenr,
+                     bool resumable);
 int manta_read_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
-int manta_read_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
+int manta_read_particles(struct MANTA *fluid,
+                         struct FluidModifierData *mmd,
+                         int framenr,
+                         bool resumable);
 int manta_read_guiding(struct MANTA *fluid,
                        struct FluidModifierData *mmd,
                        int framenr,
                        bool sourceDomain);
-int manta_update_liquid_structures(struct MANTA *fluid,
-                                   struct FluidModifierData *mmd,
-                                   int framenr);
-int manta_update_mesh_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
-int manta_update_particle_structures(struct MANTA *fluid,
-                                     struct FluidModifierData *mmd,
-                                     int framenr);
-int manta_update_smoke_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
-int manta_update_noise_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
 int manta_bake_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
 int manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
 int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
index e760cef8641eb0bdd244e963f3193f93b8f84a0f..e81b2b2e2689795a4b16936c35073956507d642d 100644 (file)
@@ -301,9 +301,8 @@ void MANTA::initDomain(FluidModifierData *mmd)
   string tmpString = fluid_variables + fluid_solver + fluid_alloc + fluid_cache_helper +
                      fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise +
                      fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding +
-                     fluid_file_import + fluid_file_export + fluid_save_data + fluid_load_data +
-                     fluid_pre_step + fluid_post_step + fluid_adapt_time_step +
-                     fluid_time_stepping;
+                     fluid_file_import + fluid_file_export + fluid_pre_step + fluid_post_step +
+                     fluid_adapt_time_step + fluid_time_stepping;
   string finalString = parseScript(tmpString, mmd);
   pythonCommands.push_back(finalString);
   runPythonString(pythonCommands);
@@ -674,7 +673,7 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
 
   if (!mmd) {
     if (with_debug)
-      cout << "No modifier data given in RNA map setup - returning early" << endl;
+      cout << "Fluid: No modifier data given in RNA map setup - returning early" << endl;
     return;
   }
 
@@ -730,6 +729,20 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   float viscosity = mds->viscosity_base * pow(10.0f, -mds->viscosity_exponent);
   float domainSize = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]);
 
+  string vdbCompressionMethod = "Compression_None";
+  if (mds->openvdb_compression == VDB_COMPRESSION_NONE)
+    vdbCompressionMethod = "Compression_None";
+  else if (mds->openvdb_compression == VDB_COMPRESSION_ZIP)
+    vdbCompressionMethod = "Compression_Zip";
+  else if (mds->openvdb_compression == VDB_COMPRESSION_BLOSC)
+    vdbCompressionMethod = "Compression_Blosc";
+
+  string vdbPrecisionHalf = "True";
+  if (mds->openvdb_data_depth == VDB_PRECISION_HALF_FLOAT)
+    vdbPrecisionHalf = "True";
+  else if (mds->openvdb_data_depth == VDB_PRECISION_FULL_FLOAT)
+    vdbPrecisionHalf = "False";
+
   mRNAMap["USING_SMOKE"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_GAS);
   mRNAMap["USING_LIQUID"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_LIQUID);
   mRNAMap["USING_COLORS"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS);
@@ -743,7 +756,7 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["USING_LOG_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG);
   mRNAMap["USING_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE);
   mRNAMap["DO_OPEN"] = getBooleanString(mds->border_collisions == 0);
-  mRNAMap["CACHE_RESUMABLE"] = getBooleanString(mds->cache_type != FLUID_DOMAIN_CACHE_FINAL);
+  mRNAMap["CACHE_RESUMABLE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE);
   mRNAMap["USING_ADAPTIVETIME"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME);
   mRNAMap["USING_SPEEDVECTORS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS);
   mRNAMap["USING_FRACTIONS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_FRACTIONS);
@@ -850,6 +863,9 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["LIQUID_SURFACE_TENSION"] = to_string(mds->surface_tension);
   mRNAMap["FLUID_VISCOSITY"] = to_string(viscosity);
   mRNAMap["FLUID_DOMAIN_SIZE"] = to_string(domainSize);
+  mRNAMap["FLUID_DOMAIN_SIZE_X"] = to_string(mds->global_size[0]);
+  mRNAMap["FLUID_DOMAIN_SIZE_Y"] = to_string(mds->global_size[1]);
+  mRNAMap["FLUID_DOMAIN_SIZE_Z"] = to_string(mds->global_size[2]);
   mRNAMap["SNDPARTICLE_TYPES"] = particleTypesStr;
   mRNAMap["GUIDING_ALPHA"] = to_string(mds->guide_alpha);
   mRNAMap["GUIDING_BETA"] = to_string(mds->guide_beta);
@@ -858,6 +874,8 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["GRAVITY_Y"] = to_string(mds->gravity[1]);
   mRNAMap["GRAVITY_Z"] = to_string(mds->gravity[2]);
   mRNAMap["CACHE_DIR"] = cacheDirectory;
+  mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod;
+  mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf;
 
   /* Fluid object names. */
   mRNAMap["NAME_FLAGS"] = FLUID_NAME_FLAGS;
@@ -900,6 +918,8 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["NAME_DENSITYIN"] = FLUID_NAME_DENSITYIN;
   mRNAMap["NAME_HEAT"] = FLUID_NAME_HEAT;
   mRNAMap["NAME_HEATIN"] = FLUID_NAME_HEATIN;
+  mRNAMap["NAME_TEMPERATURE"] = FLUID_NAME_TEMPERATURE;
+  mRNAMap["NAME_TEMPERATUREIN"] = FLUID_NAME_TEMPERATUREIN;
   mRNAMap["NAME_COLORR"] = FLUID_NAME_COLORR;
   mRNAMap["NAME_COLORG"] = FLUID_NAME_COLORG;
   mRNAMap["NAME_COLORB"] = FLUID_NAME_COLORB;
@@ -921,6 +941,8 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["NAME_MAPWEIGHTS"] = FLUID_NAME_MAPWEIGHTS;
   mRNAMap["NAME_PP"] = FLUID_NAME_PP;
   mRNAMap["NAME_PVEL"] = FLUID_NAME_PVEL;
+  mRNAMap["NAME_PARTS"] = FLUID_NAME_PARTS;
+  mRNAMap["NAME_PARTSVELOCITY"] = FLUID_NAME_PARTSVELOCITY;
   mRNAMap["NAME_PINDEX"] = FLUID_NAME_PINDEX;
   mRNAMap["NAME_GPI"] = FLUID_NAME_GPI;
   mRNAMap["NAME_CURVATURE"] = FLUID_NAME_CURVATURE;
@@ -967,6 +989,10 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
   mRNAMap["NAME_PVEL_PARTICLES"] = FLUID_NAME_PVEL_PARTICLES;
   mRNAMap["NAME_PFORCE_PARTICLES"] = FLUID_NAME_PFORCE_PARTICLES;
   mRNAMap["NAME_PLIFE_PARTICLES"] = FLUID_NAME_PLIFE_PARTICLES;
+  mRNAMap["NAME_PARTS_PARTICLES"] = FLUID_NAME_PARTS_PARTICLES;
+  mRNAMap["NAME_PARTSVEL_PARTICLES"] = FLUID_NAME_PARTSVEL_PARTICLES;
+  mRNAMap["NAME_PARTSFORCE_PARTICLES"] = FLUID_NAME_PARTSFORCE_PARTICLES;
+  mRNAMap["NAME_PARTSLIFE_PARTICLES"] = FLUID_NAME_PARTSLIFE_PARTICLES;
   mRNAMap["NAME_VELOCITY_PARTICLES"] = FLUID_NAME_VELOCITY_PARTICLES;
   mRNAMap["NAME_FLAGS_PARTICLES"] = FLUID_NAME_FLAGS_PARTICLES;
   mRNAMap["NAME_PHI_PARTICLES"] = FLUID_NAME_PHI_PARTICLES;
@@ -1000,9 +1026,6 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
 
 string MANTA::getRealValue(const string &varName)
 {
-  if (with_debug)
-    cout << "MANTA::getRealValue()" << endl;
-
   unordered_map<string, string>::iterator it;
   it = mRNAMap.find(varName);
 
@@ -1011,9 +1034,6 @@ string MANTA::getRealValue(const string &varName)
          << endl;
     return "";
   }
-  if (with_debug) {
-    cout << "Found variable " << varName << " with value " << it->second << endl;
-  }
 
   return it->second;
 }
@@ -1062,409 +1082,6 @@ string MANTA::parseScript(const string &setup_string, FluidModifierData *mmd)
   return res.str();
 }
 
-bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
-{
-  if (MANTA::with_debug)
-    cout << "MANTA::updateFlipStructures()" << endl;
-
-  FluidDomainSettings *mds = mmd->domain;
-  mFlipFromFile = false;
-
-  if (!mUsingLiquid)
-    return false;
-  if (BLI_path_is_rel(mds->cache_directory))
-    return false;
-
-  int result = 0;
-  int expected = 0; /* Expected number of read successes for this frame. */
-
-  /* Ensure empty data structures at start. */
-  if (!mFlipParticleData || !mFlipParticleVelocity)
-    return false;
-
-  mFlipParticleData->clear();
-  mFlipParticleVelocity->clear();
-
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-  string file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_PP, pformat, framenr);
-
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateParticlesFromFile(file, false, false);
-    assert(result == expected);
-  }
-
-  file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_PVEL, pformat, framenr);
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateParticlesFromFile(file, false, true);
-    assert(result == expected);
-  }
-
-  return mFlipFromFile = (result == expected);
-}
-
-bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
-{
-  if (MANTA::with_debug)
-    cout << "MANTA::updateMeshStructures()" << endl;
-
-  FluidDomainSettings *mds = mmd->domain;
-  mMeshFromFile = false;
-
-  if (!mUsingMesh)
-    return false;
-  if (BLI_path_is_rel(mds->cache_directory))
-    return false;
-
-  int result = 0;
-  int expected = 0; /* Expected number of read successes for this frame. */
-
-  /* Ensure empty data structures at start. */
-  if (!mMeshNodes || !mMeshTriangles)
-    return false;
-
-  mMeshNodes->clear();
-  mMeshTriangles->clear();
-
-  if (mMeshVelocities)
-    mMeshVelocities->clear();
-
-  string mformat = getCacheFileEnding(mds->cache_mesh_format);
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, mformat, framenr);
-
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateMeshFromFile(file);
-    assert(result == expected);
-  }
-
-  if (mUsingMVel) {
-    file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_VELOCITYVEC_MESH, dformat, framenr);
-    expected += 1;
-    if (BLI_exists(file.c_str())) {
-      result += updateMeshFromFile(file);
-      assert(result == expected);
-    }
-  }
-
-  return mMeshFromFile = (result == expected);
-}
-
-bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
-{
-  if (MANTA::with_debug)
-    cout << "MANTA::updateParticleStructures()" << endl;
-
-  FluidDomainSettings *mds = mmd->domain;
-  mParticlesFromFile = false;
-
-  if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers)
-    return false;
-  if (BLI_path_is_rel(mds->cache_directory))
-    return false;
-
-  int result = 0;
-  int expected = 0; /* Expected number of read successes for this frame. */
-
-  /* Ensure empty data structures at start. */
-  if (!mSndParticleData || !mSndParticleVelocity || !mSndParticleLife)
-    return false;
-
-  mSndParticleData->clear();
-  mSndParticleVelocity->clear();
-  mSndParticleLife->clear();
-
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-  string file = getFile(
-      mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, pformat, framenr);
-
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateParticlesFromFile(file, true, false);
-    assert(result == expected);
-  }
-
-  file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PVEL_PARTICLES, pformat, framenr);
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateParticlesFromFile(file, true, true);
-    assert(result == expected);
-  }
-
-  file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PLIFE_PARTICLES, pformat, framenr);
-  expected += 1;
-  if (BLI_exists(file.c_str())) {
-    result += updateParticlesFromFile(file, true, false);
-    assert(result == expected);
-  }
-
-  return mParticlesFromFile = (result == expected);
-}
-
-static void assertGridItems(vector<MANTA::GridItem> gList)
-{
-  vector<MANTA::GridItem>::iterator gIter = gList.begin();
-  int *resPrev = (*gIter).res;
-
-  for (vector<MANTA::GridItem>::iterator it = gList.begin(); it != gList.end(); ++it) {
-    MANTA::GridItem item = *it;
-    assert(
-        ELEM(item.type, FLUID_DOMAIN_GRID_FLOAT, FLUID_DOMAIN_GRID_INT, FLUID_DOMAIN_GRID_VEC3F));
-    assert(item.pointer[0]);
-    if (item.type == FLUID_DOMAIN_GRID_VEC3F) {
-      assert(item.pointer[1] && item.pointer[2]);
-    }
-    assert(item.res[0] == resPrev[0] && item.res[1] == resPrev[1] && item.res[2] == resPrev[2]);
-    assert((item.name).compare("") != 0);
-  }
-
-  UNUSED_VARS(resPrev);
-}
-
-bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
-{
-  if (MANTA::with_debug)
-    cout << "MANTA::updateGridStructures()" << endl;
-
-  FluidDomainSettings *mds = mmd->domain;
-  mSmokeFromFile = false;
-
-  if (!mUsingSmoke)
-    return false;
-  if (BLI_path_is_rel(mds->cache_directory))
-    return false;
-
-  int result = 0;
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-
-  vector<FileItem> filesData;
-  vector<GridItem> gridsData;
-
-  int res[] = {mResX, mResY, mResZ};
-
-  /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */
-  void *aDensity[] = {mDensity};
-  void *aShadow[] = {mShadow};
-  void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ};
-  void *aHeat[] = {mHeat};
-  void *aColorR[] = {mColorR};
-  void *aColorG[] = {mColorG};
-  void *aColorB[] = {mColorB};
-  void *aFlame[] = {mFlame};
-  void *aFuel[] = {mFuel};
-  void *aReact[] = {mReact};
-
-  /* File names for grids. */
-  string fDensity = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_DENSITY, dformat, framenr);
-  string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_SHADOW, dformat, framenr);
-  string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_VELOCITY, dformat, framenr);
-  string fHeat = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_HEAT, dformat, framenr);
-  string fColorR = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_COLORR, dformat, framenr);
-  string fColorG = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_COLORG, dformat, framenr);
-  string fColorB = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_COLORB, dformat, framenr);
-  string fFlame = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_FLAME, dformat, framenr);
-  string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_FUEL, dformat, framenr);
-  string fReact = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_REACT, dformat, framenr);
-  string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_DATA, dformat, framenr);
-
-  /* Prepare grid info containers. */
-  GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_DENSITY};
-  GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_SHADOW};
-  GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, res, FLUID_NAME_VELOCITY};
-  GridItem gHeat = {aHeat, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_HEAT};
-  GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_COLORR};
-  GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_COLORG};
-  GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_COLORB};
-  GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_FLAME};
-  GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_FUEL};
-  GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_NAME_REACT};
-
-  /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */
-  const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE;
-  if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) {
-
-    filesData.push_back({fDensity, {gDensity}});
-    filesData.push_back({fShadow, {gShadow}});
-    filesData.push_back({fVel, {gVel}});
-    if (mUsingHeat) {
-      filesData.push_back({fHeat, {gHeat}});
-    }
-    if (mUsingColors) {
-      filesData.push_back({fColorR, {gColorR}});
-      filesData.push_back({fColorG, {gColorG}});
-      filesData.push_back({fColorB, {gColorB}});
-    }
-    if (mUsingFire) {
-      filesData.push_back({fFlame, {gFlame}});
-      filesData.push_back({fFuel, {gFuel}});
-      filesData.push_back({fReact, {gReact}});
-    }
-  }
-  else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) {
-
-    gridsData.push_back(gDensity);
-    gridsData.push_back(gShadow);
-    gridsData.push_back(gVel);
-    if (mUsingHeat) {
-      gridsData.push_back(gHeat);
-    }
-    if (mUsingColors) {
-      gridsData.push_back(gColorR);
-      gridsData.push_back(gColorG);
-      gridsData.push_back(gColorB);
-    }
-    if (mUsingFire) {
-      gridsData.push_back(gFlame);
-      gridsData.push_back(gFuel);
-      gridsData.push_back(gReact);
-    }
-
-    if (with_debug) {
-      assertGridItems(gridsData);
-    }
-    filesData.push_back({fFluid, gridsData});
-  }
-
-  /* Update files from data directory. */
-  for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) {
-    FileItem item = *it;
-    if (BLI_exists(item.filename.c_str())) {
-      result += updateGridsFromFile(item.filename, item.grids);
-      assert(result);
-    }
-  }
-
-  return mSmokeFromFile = result;
-}
-
-bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
-{
-  if (MANTA::with_debug)
-    cout << "MANTA::updateNoiseStructures()" << endl;
-
-  FluidDomainSettings *mds = mmd->domain;
-  mNoiseFromFile = false;
-
-  if (!mUsingSmoke || !mUsingNoise)
-    return false;
-  if (BLI_path_is_rel(mds->cache_directory))
-    return false;
-
-  int result = 0;
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string nformat = getCacheFileEnding(mds->cache_noise_format);
-
-  vector<FileItem> filesData, filesNoise;
-  vector<GridItem> gridsData, gridsNoise;
-
-  int resData[] = {mResX, mResY, mResZ};
-  int resNoise[] = {mResXNoise, mResYNoise, mResZNoise};
-
-  /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */
-  void *aShadow[] = {mShadow};
-  void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ};
-  void *aDensity[] = {mDensityHigh};
-  void *aColorR[] = {mColorRHigh};
-  void *aColorG[] = {mColorGHigh};
-  void *aColorB[] = {mColorBHigh};
-  void *aFlame[] = {mFlameHigh};
-  void *aFuel[] = {mFuelHigh};
-  void *aReact[] = {mReactHigh};
-
-  /* File names for grids. */
-  string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_SHADOW, dformat, framenr);
-  string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_VELOCITY, dformat, framenr);
-  string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DATA, dformat, framenr);
-
-  string fDensity = getFile(
-      mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, nformat, framenr);
-  string fColorR = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_COLORR_NOISE, nformat, framenr);
-  string fColorG = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_COLORG_NOISE, nformat, framenr);
-  string fColorB = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_COLORB_NOISE, nformat, framenr);
-  string fFlame = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_FLAME_NOISE, nformat, framenr);
-  string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_FUEL_NOISE, nformat, framenr);
-  string fReact = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_REACT_NOISE, nformat, framenr);
-  string fNoise = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_NOISE, nformat, framenr);
-
-  /* Prepare grid info containers. */
-  GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, resData, FLUID_NAME_SHADOW};
-  GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, resData, FLUID_NAME_VELOCITY};
-
-  GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_DENSITY_NOISE};
-  GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_COLORR_NOISE};
-  GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_COLORG_NOISE};
-  GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_COLORB_NOISE};
-  GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_FLAME_NOISE};
-  GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_FUEL_NOISE};
-  GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_NAME_REACT_NOISE};
-
-  /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */
-  const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE;
-  if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) {
-
-    filesData.push_back({fShadow, {gShadow}});
-    filesData.push_back({fVel, {gVel}});
-
-    filesNoise.push_back({fDensity, {gDensity}});
-    if (mUsingColors) {
-      filesNoise.push_back({fColorR, {gColorR}});
-      filesNoise.push_back({fColorG, {gColorG}});
-      filesNoise.push_back({fColorB, {gColorB}});
-    }
-    if (mUsingFire) {
-      filesNoise.push_back({fFlame, {gFlame}});
-      filesNoise.push_back({fFuel, {gFuel}});
-      filesNoise.push_back({fReact, {gReact}});
-    }
-  }
-  else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) {
-
-    gridsData.push_back(gShadow);
-    gridsData.push_back(gVel);
-
-    gridsNoise.push_back(gDensity);
-    if (mUsingColors) {
-      gridsNoise.push_back(gColorR);
-      gridsNoise.push_back(gColorG);
-      gridsNoise.push_back(gColorB);
-    }
-    if (mUsingFire) {
-      gridsNoise.push_back(gFlame);
-      gridsNoise.push_back(gFuel);
-      gridsNoise.push_back(gReact);
-    }
-
-    if (with_debug) {
-      assertGridItems(gridsData);
-      assertGridItems(gridsNoise);
-    }
-    filesData.push_back({fFluid, gridsData});
-    filesNoise.push_back({fNoise, gridsNoise});
-  }
-
-  /* Update files from data directory. */
-  for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) {
-    FileItem item = *it;
-    if (BLI_exists(item.filename.c_str())) {
-      result += updateGridsFromFile(item.filename, item.grids);
-      assert(result);
-    }
-  }
-
-  /* Update files from noise directory. */
-  for (vector<FileItem>::iterator it = filesNoise.begin(); it != filesNoise.end(); ++it) {
-    FileItem item = *it;
-    if (BLI_exists(item.filename.c_str())) {
-      result += updateGridsFromFile(item.filename, item.grids);
-      assert(result);
-    }
-  }
-
-  return mNoiseFromFile = result;
-}
-
 /* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */
 static string escapeSlashes(string const &s)
 {
@@ -1514,6 +1131,7 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr)
   gzwrite(gzf, &mds->res_max, 3 * sizeof(int));
   gzwrite(gzf, &mds->active_color, 3 * sizeof(float));
   gzwrite(gzf, &mds->time_total, sizeof(int));
+  gzwrite(gzf, &FLUID_CACHE_VERSION, 4 * sizeof(char));
 
   return (gzclose(gzf) == Z_OK);
 }
@@ -1528,27 +1146,19 @@ bool MANTA::writeData(FluidModifierData *mmd, int framenr)
   FluidDomainSettings *mds = mmd->domain;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
-
-  ss.str("");
-  ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-     << ", '" << dformat << "', " << resumable_cache << ")";
-  pythonCommands.push_back(ss.str());
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
+  string resumable_cache = !(mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
 
   if (mUsingSmoke) {
     ss.str("");
     ss << "smoke_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << dformat << "', " << resumable_cache << ")";
+       << ", '" << volume_format << "', " << resumable_cache << ")";
     pythonCommands.push_back(ss.str());
   }
   if (mUsingLiquid) {
     ss.str("");
     ss << "liquid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << dformat << "', " << resumable_cache << ")";
+       << ", '" << volume_format << "', " << resumable_cache << ")";
     pythonCommands.push_back(ss.str());
   }
   return runPythonString(pythonCommands);
@@ -1564,15 +1174,13 @@ bool MANTA::writeNoise(FluidModifierData *mmd, int framenr)
   FluidDomainSettings *mds = mmd->domain;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
-  string nformat = getCacheFileEnding(mds->cache_noise_format);
-
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
+  string resumable_cache = !(mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
 
   if (mUsingSmoke && mUsingNoise) {
     ss.str("");
     ss << "smoke_save_noise_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << nformat << "', " << resumable_cache << ")";
+       << ", '" << volume_format << "', " << resumable_cache << ")";
     pythonCommands.push_back(ss.str());
   }
   return runPythonString(pythonCommands);
@@ -1593,7 +1201,7 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
   if (!hasConfig(mmd, framenr))
     return false;
 
-  gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb");  // do some compression
+  gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); /* Do some compression. */
   if (!gzf) {
     cerr << "Fluid Error -- Cannot open file " << file << endl;
     return false;
@@ -1602,7 +1210,7 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
   gzread(gzf, &mds->active_fields, sizeof(int));
   gzread(gzf, &mds->res, 3 * sizeof(int));
   gzread(gzf, &mds->dx, sizeof(float));
-  gzread(gzf, &dummy, sizeof(float));  // dt not needed right now
+  gzread(gzf, &dummy, sizeof(float)); /* dt not needed right now. */
   gzread(gzf, &mds->p0, 3 * sizeof(float));
   gzread(gzf, &mds->p1, 3 * sizeof(float));
   gzread(gzf, &mds->dp0, 3 * sizeof(float));
@@ -1614,13 +1222,14 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
   gzread(gzf, &mds->res_max, 3 * sizeof(int));
   gzread(gzf, &mds->active_color, 3 * sizeof(float));
   gzread(gzf, &mds->time_total, sizeof(int));
+  gzread(gzf, &mds->cache_id, 4 * sizeof(char)); /* Older caches might have no id. */
 
   mds->total_cells = mds->res[0] * mds->res[1] * mds->res[2];
 
   return (gzclose(gzf) == Z_OK);
 }
 
-bool MANTA::readData(FluidModifierData *mmd, int framenr)
+bool MANTA::readData(FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (with_debug)
     cout << "MANTA::readData()" << endl;
@@ -1634,39 +1243,31 @@ bool MANTA::readData(FluidModifierData *mmd, int framenr)
   bool result = true;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
+  string resumable_cache = (!resumable) ? "False" : "True";
 
   /* Sanity check: Are cache files present? */
   if (!hasData(mmd, framenr))
     return false;
 
-  ss.str("");
-  ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-     << ", '" << dformat << "', " << resumable_cache << ")";
-  pythonCommands.push_back(ss.str());
-
   if (mUsingSmoke) {
     ss.str("");
     ss << "smoke_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << dformat << "', " << resumable_cache << ")";
+       << ", '" << volume_format << "', " << resumable_cache << ")";
     pythonCommands.push_back(ss.str());
     result &= runPythonString(pythonCommands);
   }
   if (mUsingLiquid) {
     ss.str("");
     ss << "liquid_load_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << dformat << "', " << resumable_cache << ")";
+       << ", '" << volume_format << "', " << resumable_cache << ")";
     pythonCommands.push_back(ss.str());
     result &= runPythonString(pythonCommands);
   }
   return result;
 }
 
-bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
+bool MANTA::readNoise(FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (with_debug)
     cout << "MANTA::readNoise()" << endl;
@@ -1679,10 +1280,12 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
   FluidDomainSettings *mds = mmd->domain;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
-  string nformat = getCacheFileEnding(mds->cache_noise_format);
+  string resumable_cache = (resumable) ? "False" : "True";
 
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  /* Support older caches which had more granular file format control. */
+  char format = (!strcmp(mds->cache_id, FLUID_CACHE_VERSION)) ? mds->cache_data_format :
+                                                                mds->cache_noise_format;
+  string volume_format = getCacheFileEnding(format);
 
   /* Sanity check: Are cache files present? */
   if (!hasNoise(mmd, framenr))
@@ -1690,15 +1293,12 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
 
   ss.str("");
   ss << "smoke_load_noise_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-     << ", '" << nformat << "', " << resumable_cache << ")";
+     << ", '" << volume_format << "', " << resumable_cache << ")";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
 }
 
-/* Deprecated! This function reads mesh data via the Manta Python API.
- * MANTA:updateMeshStructures() reads cache files directly from disk
- * and is preferred due to its better performance. */
 bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
 {
   if (with_debug)
@@ -1712,8 +1312,8 @@ bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
   FluidDomainSettings *mds = mmd->domain;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH);
-  string mformat = getCacheFileEnding(mds->cache_mesh_format);
-  string dformat = getCacheFileEnding(mds->cache_data_format);
+  string mesh_format = getCacheFileEnding(mds->cache_mesh_format);
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
 
   /* Sanity check: Are cache files present? */
   if (!hasMesh(mmd, framenr))
@@ -1721,23 +1321,20 @@ bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
 
   ss.str("");
   ss << "liquid_load_mesh_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-     << ", '" << mformat << "')";
+     << ", '" << mesh_format << "')";
   pythonCommands.push_back(ss.str());
 
   if (mUsingMVel) {
     ss.str("");
     ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
-       << framenr << ", '" << dformat << "')";
+       << framenr << ", '" << volume_format << "')";
     pythonCommands.push_back(ss.str());
   }
 
   return runPythonString(pythonCommands);
 }
 
-/* Deprecated! This function reads particle data via the Manta Python API.
- * MANTA:updateParticleStructures() reads cache files directly from disk
- * and is preferred due to its better performance. */
-bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
+bool MANTA::readParticles(FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (with_debug)
     cout << "MANTA::readParticles()" << endl;
@@ -1752,10 +1349,12 @@ bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
   FluidDomainSettings *mds = mmd->domain;
 
   string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
+  string resumable_cache = (!resumable) ? "False" : "True";
 
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  /* Support older caches which had more granular file format control. */
+  char format = (!strcmp(mds->cache_id, FLUID_CACHE_VERSION)) ? mds->cache_data_format :
+                                                                mds->cache_particle_format;
+  string volume_format = getCacheFileEnding(format);
 
   /* Sanity check: Are cache files present? */
   if (!hasParticles(mmd, framenr))
@@ -1763,7 +1362,7 @@ bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
 
   ss.str("");
   ss << "liquid_load_particles_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
-     << framenr << ", '" << pformat << "', " << resumable_cache << ")";
+     << framenr << ", '" << volume_format << "', " << resumable_cache << ")";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -1786,7 +1385,7 @@ bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
 
   string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) :
                                       getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE);
-  string gformat = getCacheFileEnding(mds->cache_data_format);
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
 
   /* Sanity check: Are cache files present? */
   if (!hasGuiding(mmd, framenr, sourceDomain))
@@ -1795,12 +1394,12 @@ bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
   if (sourceDomain) {
     ss.str("");
     ss << "fluid_load_vel_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
-       << ", '" << gformat << "')";
+       << ", '" << volume_format << "')";
   }
   else {
     ss.str("");
     ss << "fluid_load_guiding_" << mCurrentID << "('" << escapeSlashes(directory) << "', "
-       << framenr << ", '" << gformat << "')";
+       << framenr << ", '" << volume_format << "')";
   }
   pythonCommands.push_back(ss.str());
 
@@ -1821,9 +1420,7 @@ bool MANTA::bakeData(FluidModifierData *mmd, int framenr)
   cacheDirData[0] = '\0';
   cacheDirGuiding[0] = '\0';
 
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-  string gformat = dformat;  // Use same data format for guiding format
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
 
   BLI_path_join(
       cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
@@ -1836,9 +1433,8 @@ bool MANTA::bakeData(FluidModifierData *mmd, int framenr)
   BLI_path_make_safe(cacheDirGuiding);
 
   ss.str("");
-  ss << "bake_fluid_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '"
-     << escapeSlashes(cacheDirGuiding) << "', " << framenr << ", '" << dformat << "', '" << pformat
-     << "', '" << gformat << "')";
+  ss << "bake_fluid_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " << framenr
+     << ", '" << volume_format << "')";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -1853,27 +1449,18 @@ bool MANTA::bakeNoise(FluidModifierData *mmd, int framenr)
   vector<string> pythonCommands;
   FluidDomainSettings *mds = mmd->domain;
 
-  char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX];
-  cacheDirData[0] = '\0';
+  char cacheDirNoise[FILE_MAX];
   cacheDirNoise[0] = '\0';
 
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string nformat = getCacheFileEnding(mds->cache_noise_format);
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
 
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
-
-  BLI_path_join(
-      cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
   BLI_path_join(
       cacheDirNoise, sizeof(cacheDirNoise), mds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr);
-  BLI_path_make_safe(cacheDirData);
   BLI_path_make_safe(cacheDirNoise);
 
   ss.str("");
-  ss << "bake_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '"
-     << escapeSlashes(cacheDirNoise) << "', " << framenr << ", '" << dformat << "', '" << nformat
-     << "', " << resumable_cache << ")";
+  ss << "bake_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirNoise) << "', " << framenr
+     << ", '" << volume_format << "')";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -1888,25 +1475,19 @@ bool MANTA::bakeMesh(FluidModifierData *mmd, int framenr)
   vector<string> pythonCommands;
   FluidDomainSettings *mds = mmd->domain;
 
-  char cacheDirData[FILE_MAX], cacheDirMesh[FILE_MAX];
-  cacheDirData[0] = '\0';
+  char cacheDirMesh[FILE_MAX];
   cacheDirMesh[0] = '\0';
 
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string mformat = getCacheFileEnding(mds->cache_mesh_format);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
+  string mesh_format = getCacheFileEnding(mds->cache_mesh_format);
 
-  BLI_path_join(
-      cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
   BLI_path_join(
       cacheDirMesh, sizeof(cacheDirMesh), mds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
-  BLI_path_make_safe(cacheDirData);
   BLI_path_make_safe(cacheDirMesh);
 
   ss.str("");
-  ss << "bake_mesh_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '"
-     << escapeSlashes(cacheDirMesh) << "', " << framenr << ", '" << dformat << "', '" << mformat
-     << "', '" << pformat << "')";
+  ss << "bake_mesh_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " << framenr
+     << ", '" << volume_format << "', '" << mesh_format << "')";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -1921,30 +1502,22 @@ bool MANTA::bakeParticles(FluidModifierData *mmd, int framenr)
   vector<string> pythonCommands;
   FluidDomainSettings *mds = mmd->domain;
 
-  char cacheDirData[FILE_MAX], cacheDirParticles[FILE_MAX];
-  cacheDirData[0] = '\0';
+  char cacheDirParticles[FILE_MAX];
   cacheDirParticles[0] = '\0';
 
-  string dformat = getCacheFileEnding(mds->cache_data_format);
-  string pformat = getCacheFileEnding(mds->cache_particle_format);
-
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
+  string resumable_cache = !(mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
 
-  BLI_path_join(
-      cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
   BLI_path_join(cacheDirParticles,
                 sizeof(cacheDirParticles),
                 mds->cache_directory,
                 FLUID_DOMAIN_DIR_PARTICLES,
                 nullptr);
-  BLI_path_make_safe(cacheDirData);
   BLI_path_make_safe(cacheDirParticles);
 
   ss.str("");
-  ss << "bake_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '"
-     << escapeSlashes(cacheDirParticles) << "', " << framenr << ", '" << dformat << "', '"
-     << pformat << "', " << resumable_cache << ")";
+  ss << "bake_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirParticles) << "', "
+     << framenr << ", '" << volume_format << "', " << resumable_cache << ")";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -1962,10 +1535,7 @@ bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr)
   char cacheDirGuiding[FILE_MAX];
   cacheDirGuiding[0] = '\0';
 
-  string gformat = getCacheFileEnding(mds->cache_data_format);
-
-  bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
-  string resumable_cache = (final_cache) ? "False" : "True";
+  string volume_format = getCacheFileEnding(mds->cache_data_format);
 
   BLI_path_join(cacheDirGuiding,
                 sizeof(cacheDirGuiding),
@@ -1976,7 +1546,7 @@ bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr)
 
   ss.str("");
   ss << "bake_guiding_" << mCurrentID << "('" << escapeSlashes(cacheDirGuiding) << "', " << framenr
-     << ", '" << gformat << "', " << resumable_cache << ")";
+     << ", '" << volume_format << "')";
   pythonCommands.push_back(ss.str());
 
   return runPythonString(pythonCommands);
@@ -2092,8 +1662,7 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd)
   manta_script += header_time + fluid_time_stepping + fluid_adapt_time_step;
 
   // Import
-  manta_script += header_import + fluid_file_import + fluid_cache_helper + fluid_load_data +
-                  smoke_load_data;
+  manta_script += header_import + fluid_file_import + fluid_cache_helper + smoke_load_data;
   if (noise)
     manta_script += smoke_load_noise;
   if (guiding)
@@ -2198,8 +1767,7 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd)
   manta_script += header_time + fluid_time_stepping + fluid_adapt_time_step;
 
   // Import
-  manta_script += header_import + fluid_file_import + fluid_cache_helper + fluid_load_data +
-                  liquid_load_data;
+  manta_script += header_import + fluid_file_import + fluid_cache_helper + liquid_load_data;
   if (mesh)
     manta_script += liquid_load_mesh;
   if (drops || bubble || floater || tracer)
@@ -2241,7 +1809,7 @@ static PyObject *callPythonFunction(string varName, string functionName, bool is
 {
   if ((varName == "") || (functionName == "")) {
     if (MANTA::with_debug)
-      cout << "Missing Python variable name and/or function name -- name is: " << varName
+      cout << "Fluid: Missing Python variable name and/or function name -- name is: " << varName
            << ", function name is: " << functionName << endl;
     return nullptr;
   }
@@ -2384,952 +1952,6 @@ void MANTA::adaptTimestep()
   runPythonString(pythonCommands);
 }
 
-bool MANTA::updateMeshFromFile(string filename)
-{
-  string fname(filename);
-  string::size_type idx;
-
-  idx = fname.rfind('.');
-  if (idx != string::npos) {
-    string extension = fname.substr(idx + 1);
-
-    if (extension.compare("gz") == 0)
-      return updateMeshFromBobj(filename);
-    else if (extension.compare("obj") == 0)
-      return updateMeshFromObj(filename);
-    else if (extension.compare("uni") == 0)
-      return updateMeshFromUni(filename);
-    else
-      cerr << "Fluid Error -- updateMeshFromFile(): Invalid file extension in file: " << filename
-           << endl;
-  }
-  else {
-    cerr << "Fluid Error -- updateMeshFromFile(): Unable to open file: " << filename << endl;
-  }
-  return false;
-}
-
-bool MANTA::updateMeshFromBobj(string filename)
-{
-  if (with_debug)
-    cout << "MANTA::updateMeshFromBobj()" << endl;
-
-  gzFile gzf;
-
-  gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");  // do some compression
-  if (!gzf) {
-    cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename << endl;
-    return false;
-  }
-
-  int numBuffer = 0, readBytes = 0;
-
-  // Num vertices
-  readBytes = gzread(gzf, &numBuffer, sizeof(int));
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh vertices from "
-         << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  if (with_debug)
-    cout << "read mesh , num verts: " << numBuffer << " , in file: " << filename << endl;
-
-  int numChunks = (int)(ceil((float)numBuffer / NODE_CHUNK));
-  int readLen, readStart, readEnd, k;
-
-  if (numBuffer) {
-    // Vertices
-    int todoVertices = numBuffer;
-    float *bufferVerts = (float *)MEM_malloc_arrayN(
-        NODE_CHUNK, sizeof(float) * 3, "fluid_mesh_vertices");
-
-    mMeshNodes->resize(numBuffer);
-
-    for (int i = 0; i < numChunks && todoVertices > 0; ++i) {
-      readLen = NODE_CHUNK;
-      if (todoVertices < NODE_CHUNK) {
-        readLen = todoVertices;
-      }
-
-      readBytes = gzread(gzf, bufferVerts, readLen * sizeof(float) * 3);
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh vertices from "
-             << filename << endl;
-        MEM_freeN(bufferVerts);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numBuffer - todoVertices);
-      CLAMP(readStart, 0, numBuffer);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numBuffer);
-
-      k = 0;
-      for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
-        mMeshNodes->at(j).pos[0] = bufferVerts[k];
-        mMeshNodes->at(j).pos[1] = bufferVerts[k + 1];
-        mMeshNodes->at(j).pos[2] = bufferVerts[k + 2];
-      }
-      todoVertices -= readLen;
-    }
-    MEM_freeN(bufferVerts);
-  }
-
-  // Num normals
-  readBytes = gzread(gzf, &numBuffer, sizeof(int));
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh normals from "
-         << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  if (with_debug)
-    cout << "read mesh , num normals : " << numBuffer << " , in file: " << filename << endl;
-
-  if (numBuffer) {
-    // Normals
-    int todoNormals = numBuffer;
-    float *bufferNormals = (float *)MEM_malloc_arrayN(
-        NODE_CHUNK, sizeof(float) * 3, "fluid_mesh_normals");
-
-    if (!getNumVertices())
-      mMeshNodes->resize(numBuffer);
-
-    for (int i = 0; i < numChunks && todoNormals > 0; ++i) {
-      readLen = NODE_CHUNK;
-      if (todoNormals < NODE_CHUNK) {
-        readLen = todoNormals;
-      }
-
-      readBytes = gzread(gzf, bufferNormals, readLen * sizeof(float) * 3);
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh normals from "
-             << filename << endl;
-        MEM_freeN(bufferNormals);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numBuffer - todoNormals);
-      CLAMP(readStart, 0, numBuffer);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numBuffer);
-
-      k = 0;
-      for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
-        mMeshNodes->at(j).normal[0] = bufferNormals[k];
-        mMeshNodes->at(j).normal[1] = bufferNormals[k + 1];
-        mMeshNodes->at(j).normal[2] = bufferNormals[k + 2];
-      }
-      todoNormals -= readLen;
-    }
-    MEM_freeN(bufferNormals);
-  }
-
-  // Num triangles
-  readBytes = gzread(gzf, &numBuffer, sizeof(int));
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh triangles from "
-         << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  if (with_debug)
-    cout << "Fluid: Read mesh , num triangles : " << numBuffer << " , in file: " << filename
-         << endl;
-
-  numChunks = (int)(ceil((float)numBuffer / TRIANGLE_CHUNK));
-
-  if (numBuffer) {
-    // Triangles
-    int todoTriangles = numBuffer;
-    int *bufferTriangles = (int *)MEM_malloc_arrayN(
-        TRIANGLE_CHUNK, sizeof(int) * 3, "fluid_mesh_triangles");
-
-    mMeshTriangles->resize(numBuffer);
-
-    for (int i = 0; i < numChunks && todoTriangles > 0; ++i) {
-      readLen = TRIANGLE_CHUNK;
-      if (todoTriangles < TRIANGLE_CHUNK) {
-        readLen = todoTriangles;
-      }
-
-      readBytes = gzread(gzf, bufferTriangles, readLen * sizeof(int) * 3);
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh triangles from "
-             << filename << endl;
-        MEM_freeN(bufferTriangles);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numBuffer - todoTriangles);
-      CLAMP(readStart, 0, numBuffer);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numBuffer);
-
-      k = 0;
-      for (vector<MANTA::Triangle>::size_type j = readStart; j < readEnd; j++, k += 3) {
-        mMeshTriangles->at(j).c[0] = bufferTriangles[k];
-        mMeshTriangles->at(j).c[1] = bufferTriangles[k + 1];
-        mMeshTriangles->at(j).c[2] = bufferTriangles[k + 2];
-      }
-      todoTriangles -= readLen;
-    }
-    MEM_freeN(bufferTriangles);
-  }
-  return (gzclose(gzf) == Z_OK);
-}
-
-bool MANTA::updateMeshFromObj(string filename)
-{
-  if (with_debug)
-    cout << "MANTA::updateMeshFromObj()" << endl;
-
-  ifstream ifs(filename);
-  float fbuffer[3];
-  int ibuffer[3];
-  int cntVerts = 0, cntNormals = 0, cntTris = 0;
-
-  if (!ifs.good()) {
-    cerr << "Fluid Error -- updateMeshFromObj(): Unable to open file: " << filename << endl;
-    return false;
-  }
-
-  while (ifs.good() && !ifs.eof()) {
-    string id;
-    ifs >> id;
-
-    if (id[0] == '#') {
-      // comment
-      getline(ifs, id);
-      continue;
-    }
-    if (id == "vt") {
-      // tex coord, ignore
-    }
-    else if (id == "vn") {
-      // normals
-      if (getNumVertices() != cntVerts) {
-        cerr << "Fluid Error -- updateMeshFromObj(): Invalid number of mesh nodes in file: "
-             << filename << endl;
-        return false;
-      }
-
-      ifs >> fbuffer[0] >> fbuffer[1] >> fbuffer[2];
-      MANTA::Node *node = &mMeshNodes->at(cntNormals);
-      (*node).normal[0] = fbuffer[0];
-      (*node).normal[1] = fbuffer[1];
-      (*node).normal[2] = fbuffer[2];
-      cntNormals++;
-    }
-    else if (id == "v") {
-      // vertex
-      ifs >> fbuffer[0] >> fbuffer[1] >> fbuffer[2];
-      MANTA::Node node;
-      node.pos[0] = fbuffer[0];
-      node.pos[1] = fbuffer[1];
-      node.pos[2] = fbuffer[2];
-      mMeshNodes->push_back(node);
-      cntVerts++;
-    }
-    else if (id == "g") {
-      // group
-      string group;
-      ifs >> group;
-    }
-    else if (id == "f") {
-      // face
-      string face;
-      for (int i = 0; i < 3; i++) {
-        ifs >> face;
-        if (face.find('/') != string::npos)
-          face = face.substr(0, face.find('/'));  // ignore other indices
-        int idx = atoi(face.c_str()) - 1;
-        if (idx < 0) {
-          cerr << "Fluid Error -- updateMeshFromObj(): Invalid face encountered in file: "
-               << filename << endl;
-          return false;
-        }
-        ibuffer[i] = idx;
-      }
-      MANTA::Triangle triangle;
-      triangle.c[0] = ibuffer[0];
-      triangle.c[1] = ibuffer[1];
-      triangle.c[2] = ibuffer[2];
-      mMeshTriangles->push_back(triangle);
-      cntTris++;
-    }
-    else {
-      // whatever, ignore
-    }
-    // kill rest of line
-    getline(ifs, id);
-  }
-  ifs.close();
-  return true;
-}
-
-bool MANTA::updateMeshFromUni(string filename)
-{
-  if (with_debug)
-    cout << "MANTA::updateMeshFromUni()" << endl;
-
-  gzFile gzf;
-  float fbuffer[4];
-  int ibuffer[4];
-
-  gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");  // do some compression
-  if (!gzf) {
-    cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename << endl;
-    return false;
-  }
-
-  int readBytes = 0;
-  char file_magic[5] = {0, 0, 0, 0, 0};
-  readBytes = gzread(gzf, file_magic, 4);
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateMeshFromUni(): Unable to read header in file: " << filename
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  vector<pVel> *velocityPointer = mMeshVelocities;
-
-  // mdata uni header
-  const int STR_LEN_PDATA = 256;
-  int elementType, bytesPerElement, numParticles;
-  char info[STR_LEN_PDATA];      // mantaflow build information
-  unsigned long long timestamp;  // creation time
-
-  // read mesh header
-  gzread(gzf, &ibuffer, sizeof(int) * 4);  // num particles, dimX, dimY, dimZ
-  gzread(gzf, &elementType, sizeof(int));
-  gzread(gzf, &bytesPerElement, sizeof(int));
-  gzread(gzf, &info, sizeof(info));
-  gzread(gzf, &timestamp, sizeof(unsigned long long));
-
-  if (with_debug)
-    cout << "Fluid: Read " << ibuffer[0] << " vertices in file: " << filename << endl;
-
-  // Sanity checks
-  const int meshSize = sizeof(float) * 3 + sizeof(int);
-  if (!(bytesPerElement == meshSize) && (elementType == 0)) {
-    cerr << "Fluid Error -- updateMeshFromUni(): Invalid header in file: " << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-  if (!ibuffer[0]) {  // Any vertices present?
-    cerr << "Fluid Error -- updateMeshFromUni(): No vertices present in file: " << filename
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  // Reading mesh
-  if (!strcmp(file_magic, "MB01")) {
-    // TODO (sebbas): Future update could add uni mesh support
-  }
-  // Reading mesh data file v1 with vec3
-  else if (!strcmp(file_magic, "MD01")) {
-    numParticles = ibuffer[0];
-
-    velocityPointer->resize(numParticles);
-    MANTA::pVel *bufferPVel;
-    for (vector<pVel>::iterator it = velocityPointer->begin(); it != velocityPointer->end();
-         ++it) {
-      gzread(gzf, fbuffer, sizeof(float) * 3);
-      bufferPVel = (MANTA::pVel *)fbuffer;
-      it->pos[0] = bufferPVel->pos[0];
-      it->pos[1] = bufferPVel->pos[1];
-      it->pos[2] = bufferPVel->pos[2];
-    }
-  }
-  return (gzclose(gzf) == Z_OK);
-}
-
-bool MANTA::updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData)
-{
-  if (with_debug)
-    cout << "MANTA::updateParticlesFromFile()" << endl;
-
-  string fname(filename);
-  string::size_type idx;
-
-  idx = fname.rfind('.');
-  if (idx != string::npos) {
-    string extension = fname.substr(idx + 1);
-
-    if (extension.compare("uni") == 0)
-      return updateParticlesFromUni(filename, isSecondarySys, isVelData);
-    else
-      cerr << "Fluid Error -- updateParticlesFromFile(): Invalid file extension in file: "
-           << filename << endl;
-    return false;
-  }
-  else {
-    cerr << "Fluid Error -- updateParticlesFromFile(): Unable to open file: " << filename << endl;
-    return false;
-  }
-}
-
-bool MANTA::updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData)
-{
-  if (with_debug)
-    cout << "MANTA::updateParticlesFromUni()" << endl;
-
-  gzFile gzf;
-  int ibuffer[4];
-
-  gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");  // do some compression
-  if (!gzf) {
-    cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename << endl;
-    return false;
-  }
-
-  int readBytes = 0;
-  char file_magic[5] = {0, 0, 0, 0, 0};
-  readBytes = gzread(gzf, file_magic, 4);
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read header in file: " << filename
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  if (!strcmp(file_magic, "PB01")) {
-    cerr << "Fluid Error -- updateParticlesFromUni(): Particle uni file format v01 not "
-            "supported anymore."
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  // Pointer to FLIP system or to secondary particle system
-  vector<pData> *dataPointer = nullptr;
-  vector<pVel> *velocityPointer = nullptr;
-  vector<float> *lifePointer = nullptr;
-
-  if (isSecondarySys) {
-    dataPointer = mSndParticleData;
-    velocityPointer = mSndParticleVelocity;
-    lifePointer = mSndParticleLife;
-  }
-  else {
-    dataPointer = mFlipParticleData;
-    velocityPointer = mFlipParticleVelocity;
-  }
-
-  // pdata uni header
-  const int STR_LEN_PDATA = 256;
-  int elementType, bytesPerElement, numParticles;
-  char info[STR_LEN_PDATA];      // mantaflow build information
-  unsigned long long timestamp;  // creation time
-
-  // read particle header
-  gzread(gzf, &ibuffer, sizeof(int) * 4);  // num particles, dimX, dimY, dimZ
-  gzread(gzf, &elementType, sizeof(int));
-  gzread(gzf, &bytesPerElement, sizeof(int));
-  gzread(gzf, &info, sizeof(info));
-  gzread(gzf, &timestamp, sizeof(unsigned long long));
-
-  if (with_debug)
-    cout << "Fluid: Read " << ibuffer[0] << " particles in file: " << filename << endl;
-
-  // Sanity checks
-  const int partSysSize = sizeof(float) * 3 + sizeof(int);
-  if (!(bytesPerElement == partSysSize) && (elementType == 0)) {
-    cerr << "Fluid Error -- updateParticlesFromUni(): Invalid header in file: " << filename
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-  if (!ibuffer[0]) {  // Any particles present?
-    if (with_debug)
-      cout << "Fluid: No particles present in file: " << filename << endl;
-    gzclose(gzf);
-    return true;  // return true since having no particles in a cache file is valid
-  }
-
-  numParticles = ibuffer[0];
-
-  const int numChunks = (int)(ceil((float)numParticles / PARTICLE_CHUNK));
-  int todoParticles, readLen;
-  int readStart, readEnd;
-
-  // Reading base particle system file v2
-  if (!strcmp(file_magic, "PB02")) {
-    MANTA::pData *bufferPData;
-    todoParticles = numParticles;
-    bufferPData = (MANTA::pData *)MEM_malloc_arrayN(
-        PARTICLE_CHUNK, sizeof(MANTA::pData), "fluid_particle_data");
-
-    dataPointer->resize(numParticles);
-
-    for (int i = 0; i < numChunks && todoParticles > 0; ++i) {
-      readLen = PARTICLE_CHUNK;
-      if (todoParticles < PARTICLE_CHUNK) {
-        readLen = todoParticles;
-      }
-
-      readBytes = gzread(gzf, bufferPData, readLen * sizeof(pData));
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle data in file: "
-             << filename << endl;
-        MEM_freeN(bufferPData);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numParticles - todoParticles);
-      CLAMP(readStart, 0, numParticles);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numParticles);
-
-      int k = 0;
-      for (vector<MANTA::pData>::size_type j = readStart; j < readEnd; j++, k++) {
-        dataPointer->at(j).pos[0] = bufferPData[k].pos[0];
-        dataPointer->at(j).pos[1] = bufferPData[k].pos[1];
-        dataPointer->at(j).pos[2] = bufferPData[k].pos[2];
-        dataPointer->at(j).flag = bufferPData[k].flag;
-      }
-      todoParticles -= readLen;
-    }
-    MEM_freeN(bufferPData);
-  }
-  // Reading particle data file v1 with velocities
-  else if (!strcmp(file_magic, "PD01") && isVelData) {
-    MANTA::pVel *bufferPVel;
-    todoParticles = numParticles;
-    bufferPVel = (MANTA::pVel *)MEM_malloc_arrayN(
-        PARTICLE_CHUNK, sizeof(MANTA::pVel), "fluid_particle_velocity");
-
-    velocityPointer->resize(numParticles);
-
-    for (int i = 0; i < numChunks && todoParticles > 0; ++i) {
-      readLen = PARTICLE_CHUNK;
-      if (todoParticles < PARTICLE_CHUNK) {
-        readLen = todoParticles;
-      }
-
-      readBytes = gzread(gzf, bufferPVel, readLen * sizeof(pVel));
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle velocities "
-                "in file: "
-             << filename << endl;
-        MEM_freeN(bufferPVel);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numParticles - todoParticles);
-      CLAMP(readStart, 0, numParticles);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numParticles);
-
-      int k = 0;
-      for (vector<MANTA::pVel>::size_type j = readStart; j < readEnd; j++, k++) {
-        velocityPointer->at(j).pos[0] = bufferPVel[k].pos[0];
-        velocityPointer->at(j).pos[1] = bufferPVel[k].pos[1];
-        velocityPointer->at(j).pos[2] = bufferPVel[k].pos[2];
-      }
-      todoParticles -= readLen;
-    }
-    MEM_freeN(bufferPVel);
-  }
-  // Reading particle data file v1 with lifetime
-  else if (!strcmp(file_magic, "PD01")) {
-    float *bufferPLife;
-    todoParticles = numParticles;
-    bufferPLife = (float *)MEM_malloc_arrayN(PARTICLE_CHUNK, sizeof(float), "fluid_particle_life");
-
-    lifePointer->resize(numParticles);
-
-    for (int i = 0; i < numChunks && todoParticles > 0; ++i) {
-      readLen = PARTICLE_CHUNK;
-      if (todoParticles < PARTICLE_CHUNK) {
-        readLen = todoParticles;
-      }
-
-      readBytes = gzread(gzf, bufferPLife, readLen * sizeof(float));
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle life in file: "
-             << filename << endl;
-        MEM_freeN(bufferPLife);
-        gzclose(gzf);
-        return false;
-      }
-
-      readStart = (numParticles - todoParticles);
-      CLAMP(readStart, 0, numParticles);
-      readEnd = readStart + readLen;
-      CLAMP(readEnd, 0, numParticles);
-
-      int k = 0;
-      for (vector<float>::size_type j = readStart; j < readEnd; j++, k++) {
-        lifePointer->at(j) = bufferPLife[k];
-      }
-      todoParticles -= readLen;
-    }
-    MEM_freeN(bufferPLife);
-  }
-  return (gzclose(gzf) == Z_OK);
-}
-
-bool MANTA::updateGridsFromFile(string filename, vector<GridItem> grids)
-{
-  if (with_debug)
-    cout << "MANTA::updateGridsFromFile()" << endl;
-
-  if (grids.empty()) {
-    cerr << "Fluid Error -- updateGridsFromFile(): Cannot read into uninitialized grid vector."
-         << endl;
-    return false;
-  }
-
-  string fname(filename);
-  string::size_type idx;
-
-  idx = fname.rfind('.');
-  if (idx != string::npos) {
-    string extension = fname.substr(idx);
-
-    if (extension.compare(FLUID_DOMAIN_EXTENSION_UNI) == 0) {
-      return updateGridsFromUni(filename, grids);
-    }
-#if OPENVDB == 1
-    else if (extension.compare(FLUID_DOMAIN_EXTENSION_OPENVDB) == 0) {
-      return updateGridsFromVDB(filename, grids);
-    }
-#endif
-    else if (extension.compare(FLUID_DOMAIN_EXTENSION_RAW) == 0) {
-      return updateGridsFromRaw(filename, grids);
-    }
-    else {
-      cerr << "Fluid Error -- updateGridsFromFile(): Invalid file extension in file: " << filename
-           << endl;
-    }
-    return false;
-  }
-  else {
-    cerr << "Fluid Error -- updateGridsFromFile(): Unable to open file: " << filename << endl;
-    return false;
-  }
-}
-
-bool MANTA::updateGridsFromUni(string filename, vector<GridItem> grids)
-{
-  if (with_debug)
-    cout << "MANTA::updateGridsFromUni()" << endl;
-
-  gzFile gzf;
-  int expectedBytes = 0, readBytes = 0;
-  int ibuffer[4];
-
-  gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");
-  if (!gzf) {
-    cerr << "Fluid Error -- updateGridsFromUni(): Unable to open file: " << filename << endl;
-    return false;
-  }
-
-  char file_magic[5] = {0, 0, 0, 0, 0};
-  readBytes = gzread(gzf, file_magic, 4);
-  if (!readBytes) {
-    cerr << "Fluid Error -- updateGridsFromUni(): Invalid header in file: " << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-  if (!strcmp(file_magic, "DDF2") || !strcmp(file_magic, "MNT1") || !strcmp(file_magic, "MNT2")) {
-    cerr << "Fluid Error -- updateGridsFromUni(): Unsupported header in file: " << filename
-         << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  if (!strcmp(file_magic, "MNT3")) {
-
-    // grid uni header
-    const int STR_LEN_GRID = 252;
-    int elementType, bytesPerElement;  // data type info
-    char info[STR_LEN_GRID];           // mantaflow build information
-    int dimT;                          // optionally store forth dimension for 4d grids
-    unsigned long long timestamp;      // creation time
-
-    // read grid header
-    gzread(gzf, &ibuffer, sizeof(int) * 4);  // dimX, dimY, dimZ, gridType
-    gzread(gzf, &elementType, sizeof(int));
-    gzread(gzf, &bytesPerElement, sizeof(int));
-    gzread(gzf, &info, sizeof(info));
-    gzread(gzf, &dimT, sizeof(int));
-    gzread(gzf, &timestamp, sizeof(unsigned long long));
-
-    if (with_debug)
-      cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << endl;
-
-    for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
-      GridItem gridItem = *gIter;
-      void **pointerList = gridItem.pointer;
-      int type = gridItem.type;
-      int *res = gridItem.res;
-      assert(pointerList[0]);
-      assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
-      UNUSED_VARS(res);
-
-      switch (type) {
-        case FLUID_DOMAIN_GRID_VEC3F: {
-          assert(pointerList[1] && pointerList[2]);
-          float **fpointers = (float **)pointerList;
-          expectedBytes = sizeof(float) * 3 * ibuffer[0] * ibuffer[1] * ibuffer[2];
-          readBytes = 0;
-          for (int i = 0; i < ibuffer[0] * ibuffer[1] * ibuffer[2]; ++i) {
-            for (int j = 0; j < 3; ++j) {
-              readBytes += gzread(gzf, fpointers[j], sizeof(float));
-              ++fpointers[j];
-            }
-          }
-          break;
-        }
-        case FLUID_DOMAIN_GRID_FLOAT: {
-          float **fpointers = (float **)pointerList;
-          expectedBytes = sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2];
-          readBytes = gzread(
-              gzf, fpointers[0], sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]);
-          break;
-        }
-        default: {
-          cerr << "Fluid Error -- Unknown grid type" << endl;
-        }
-      }
-
-      if (!readBytes) {
-        cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename
-             << endl;
-        gzclose(gzf);
-        return false;
-      }
-      assert(expectedBytes == readBytes);
-      UNUSED_VARS(expectedBytes);
-
-      if (with_debug)
-        cout << "Fluid: Read successfully: " << filename << endl;
-    }
-  }
-  else {
-    cerr << "Fluid Error -- updateGridsFromUni(): Unknown header in file: " << filename << endl;
-    gzclose(gzf);
-    return false;
-  }
-
-  return (gzclose(gzf) == Z_OK);
-}
-
-#if OPENVDB == 1
-bool MANTA::updateGridsFromVDB(string filename, vector<GridItem> grids)
-{
-  if (with_debug)
-    cout << "MANTA::updateGridsFromVDB()" << endl;
-
-  openvdb::initialize();
-  openvdb::io::File file(filename);
-  try {
-    file.open();
-  }
-  catch (const openvdb::IoError &) {
-    cerr << "Fluid Error -- updateGridsFromVDB(): IOError, invalid OpenVDB file: " << filename
-         << endl;
-    return false;
-  }
-  if (grids.empty()) {
-    cerr << "Fluid Error -- updateGridsFromVDB(): No grids found in grid vector" << endl;
-    return false;
-  }
-
-  unordered_map<string, openvdb::FloatGrid::Accessor> floatAccessors;
-  unordered_map<string, openvdb::Vec3SGrid::Accessor> vec3fAccessors;
-  openvdb::GridBase::Ptr baseGrid;
-
-  /* Get accessors to all grids in this OpenVDB file.*/
-  for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
-    GridItem gridItem = *gIter;
-    string itemName = gridItem.name;
-    int itemType = gridItem.type;
-
-    for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName();
-         ++nameIter) {
-      string vdbName = nameIter.gridName();
-      bool nameMatch = !itemName.compare(vdbName);
-
-      /* Support for <= 2.83: If file has only one grid in it, use that grid. */
-      openvdb::io::File::NameIterator peekNext = nameIter;
-      bool onlyGrid = (++peekNext == file.endName());
-      if (onlyGrid) {
-        vdbName = itemName;
-      }
-
-      if (nameMatch || onlyGrid) {
-        baseGrid = file.readGrid(nameIter.gridName());
-
-        switch (itemType) {
-          case FLUID_DOMAIN_GRID_VEC3F: {
-            openvdb::Vec3SGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::Vec3SGrid>(baseGrid);
-            openvdb::Vec3SGrid::Accessor vdbAccessor = gridVDB->getAccessor();
-            vec3fAccessors.emplace(vdbName, vdbAccessor);
-            break;
-          }
-          case FLUID_DOMAIN_GRID_FLOAT: {
-            openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid);
-            openvdb::FloatGrid::Accessor vdbAccessor = gridVDB->getAccessor();
-            floatAccessors.emplace(vdbName, vdbAccessor);
-            break;
-          }
-          default: {
-            cerr << "Fluid Error -- Unknown grid type" << endl;
-          }
-        }
-      }
-      else {
-        cerr << "Fluid Error -- Could not read grid from file" << endl;
-        return false;
-      }
-    }
-  }
-  file.close();
-
-  size_t index = 0;
-
-  /* Use res of first grid for grid loop. All grids must be same size anyways. */
-  vector<GridItem>::iterator gIter = grids.begin();
-  int *res = (*gIter).res;
-
-  for (int z = 0; z < res[2]; ++z) {
-    for (int y = 0; y < res[1]; ++y) {
-      for (int x = 0; x < res[0]; ++x, ++index) {
-        openvdb::Coord xyz(x, y, z);
-
-        for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
-          GridItem gridItem = *gIter;
-          void **pointerList = gridItem.pointer;
-          int type = gridItem.type;
-          int *res = gridItem.res;
-          assert(pointerList[0]);
-          assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
-          UNUSED_VARS(res);
-
-          switch (type) {
-            case FLUID_DOMAIN_GRID_VEC3F: {
-              unordered_map<string, openvdb::Vec3SGrid::Accessor>::iterator it;
-              it = vec3fAccessors.find(gridItem.name);
-              if (it == vec3fAccessors.end()) {
-                cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl;
-                return false;
-              }
-              openvdb::Vec3f v = it->second.getValue(xyz);
-
-              assert(pointerList[1] && pointerList[2]);
-              float **fpointers = (float **)pointerList;
-              for (int j = 0; j < 3; ++j) {
-                (fpointers[j])[index] = (float)v[j];
-              }
-              break;
-            }
-            case FLUID_DOMAIN_GRID_FLOAT: {
-              unordered_map<string, openvdb::FloatGrid::Accessor>::iterator it;
-              it = floatAccessors.find(gridItem.name);
-              if (it == floatAccessors.end()) {
-                cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl;
-                return false;
-              }
-              float v = it->second.getValue(xyz);
-              float **fpointers = (float **)pointerList;
-              (fpointers[0])[index] = v;
-              break;
-            }
-            default: {
-              cerr << "Fluid Error -- Unknown grid type" << endl;
-            }
-          }
-        }
-      }
-    }
-  }
-  if (with_debug)
-    cout << "Fluid: Read successfully: " << filename << endl;
-
-  return true;
-}
-#endif
-
-bool MANTA::updateGridsFromRaw(string filename, vector<GridItem> grids)
-{
-  if (with_debug)
-    cout << "MANTA::updateGridsFromRaw()" << endl;
-
-  gzFile gzf;
-  int expectedBytes, readBytes;
-
-  gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb");
-  if (!gzf) {
-    cout << "MANTA::updateGridsFromRaw(): unable to open file" << endl;
-    return false;
-  }
-
-  for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
-    GridItem gridItem = *gIter;
-    void **pointerList = gridItem.pointer;
-    int type = gridItem.type;
-    int *res = gridItem.res;
-    assert(pointerList[0]);
-    assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
-    UNUSED_VARS(res);
-
-    switch (type) {
-      case FLUID_DOMAIN_GRID_VEC3F: {
-        assert(pointerList[1] && pointerList[2]);
-        float **fpointers = (float **)pointerList;
-        expectedBytes = sizeof(float) * 3 * res[0] * res[1] * res[2];
-        readBytes = 0;
-        for (int i = 0; i < res[0] * res[1] * res[2]; ++i) {
-          for (int j = 0; j < 3; ++j) {
-            readBytes += gzread(gzf, fpointers[j], sizeof(float));
-            ++fpointers[j];
-          }
-        }
-        break;
-      }
-      case FLUID_DOMAIN_GRID_FLOAT: {
-        float **fpointers = (float **)pointerList;
-        expectedBytes = sizeof(float) * res[0] * res[1] * res[2];
-        readBytes = gzread(gzf, fpointers[0], expectedBytes);
-        break;
-      }
-      default: {
-        cerr << "Fluid Error -- Unknown grid type" << endl;
-      }
-    }
-
-    if (!readBytes) {
-      cerr << "Fluid Error -- updateGridsFromRaw(): Unable to read raw file: " << filename << endl;
-      gzclose(gzf);
-      return false;
-    }
-    assert(expectedBytes == readBytes);
-
-    if (with_debug)
-      cout << "Fluid: Read successfully: " << filename << endl;
-  }
-
-  if (with_debug)
-    cout << "Fluid: Read successfully: " << filename << endl;
-
-  return (gzclose(gzf) == Z_OK);
-}
-
 void MANTA::updatePointers()
 {
   if (with_debug)
@@ -3487,43 +2109,78 @@ bool MANTA::hasData(FluidModifierData *mmd, int framenr)
     string filename = (mUsingSmoke) ? FLUID_NAME_DENSITY : FLUID_NAME_PP;
     exists = BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
   }
+  if (with_debug)
+    cout << "Fluid: Has Data: " << exists << endl;
+
   return exists;
 }
 
 bool MANTA::hasNoise(FluidModifierData *mmd, int framenr)
 {
-  string extension = getCacheFileEnding(mmd->domain->cache_noise_format);
+  string extension = getCacheFileEnding(mmd->domain->cache_data_format);
   bool exists = BLI_exists(
       getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_NOISE, extension, framenr).c_str());
 
   /* Check single file naming. */
   if (!exists) {
+    extension = getCacheFileEnding(mmd->domain->cache_data_format);
+    exists = BLI_exists(
+        getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
+            .c_str());
+  }
+  /* Check single file naming with deprecated extension. */
+  if (!exists) {
+    extension = getCacheFileEnding(mmd->domain->cache_noise_format);
     exists = BLI_exists(
         getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
             .c_str());
   }
+  if (with_debug)
+    cout << "Fluid: Has Noise: " << exists << endl;
+
   return exists;
 }
 
 bool MANTA::hasMesh(FluidModifierData *mmd, int framenr)
 {
   string extension = getCacheFileEnding(mmd->domain->cache_mesh_format);
-  return BLI_exists(
-      getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, extension, framenr).c_str());
+  bool exists = BLI_exists(
+      getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_MESH, extension, framenr).c_str());
+
+  /* Check old file naming. */
+  if (!exists) {
+    exists = BLI_exists(
+        getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, extension, framenr).c_str());
+  }
+  if (with_debug)
+    cout << "Fluid: Has Mesh: " << exists << endl;
+
+  return exists;
 }
 
 bool MANTA::hasParticles(FluidModifierData *mmd, int framenr)
 {
-  string extension = getCacheFileEnding(mmd->domain->cache_particle_format);
+  string extension = getCacheFileEnding(mmd->domain->cache_data_format);
   bool exists = BLI_exists(
       getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PARTICLES, extension, framenr).c_str());
 
   /* Check single file naming. */
   if (!exists) {
+    extension = getCacheFileEnding(mmd->domain->cache_data_format);
     exists = BLI_exists(
         getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
             .c_str());
   }
+  /* Check single file naming with deprecated extension. */
+  if (!exists) {
+    extension = getCacheFileEnding(mmd->domain->cache_particle_format);
+    exists = BLI_exists(
+        getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
+            .c_str());
+  }
+  if (with_debug)
+    cout << "Fluid: Has Particles: " << exists << endl;
+
   return exists;
 }
 
@@ -3532,7 +2189,11 @@ bool MANTA::hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
   string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
   string filename = (sourceDomain) ? FLUID_NAME_VELOCITY : FLUID_NAME_GUIDEVEL;
   string extension = getCacheFileEnding(mmd->domain->cache_data_format);
-  return BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str());
+  bool exists = BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str());
+  if (with_debug)
+    cout << "Fluid: Has Guiding: " << exists << endl;
+
+  return exists;
 }
 
 string MANTA::getDirectory(FluidModifierData *mmd, string subdirectory)
index 6a8484c75d99123cae5754bde49d1f42388936a4..38cbd33ea0a60f3a49a517363950e6c4d5ba9e28 100644 (file)
@@ -60,19 +60,6 @@ struct MANTA {
     int flags;
   } Triangle;
 
-  // Cache helper typedefs
-  typedef struct GridItem {
-    void **pointer; /* Array of pointers for this grid.*/
-    int type;
-    int *res;
-    string name;
-  } GridItem;
-
-  typedef struct FileItem {
-    string filename;
-    vector<GridItem> grids;
-  } FileItem;
-
   // Manta step, handling everything
   void step(struct FluidModifierData *mmd, int startFrame);
 
@@ -104,10 +91,10 @@ struct MANTA {
 
   // Read cache (via Manta save/load)
   bool readConfiguration(FluidModifierData *mmd, int framenr);
-  bool readData(FluidModifierData *mmd, int framenr);
-  bool readNoise(FluidModifierData *mmd, int framenr);
+  bool readData(FluidModifierData *mmd, int framenr, bool resumable);
+  bool readNoise(FluidModifierData *mmd, int framenr, bool resumable);
   bool readMesh(FluidModifierData *mmd, int framenr);
-  bool readParticles(FluidModifierData *mmd, int framenr);
+  bool readParticles(FluidModifierData *mmd, int framenr, bool resumable);
   bool readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain);
 
   // Read cache (via file read functions in MANTA - e.g. read .bobj.gz meshes, .uni particles)
@@ -899,16 +886,6 @@ struct MANTA {
   string getRealValue(const string &varName);
   string parseLine(const string &line);
   string parseScript(const string &setup_string, FluidModifierData *mmd = NULL);
-  bool updateMeshFromBobj(string filename);
-  bool updateMeshFromObj(string filename);
-  bool updateMeshFromUni(string filename);
-  bool updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData);
-  bool updateGridsFromUni(string filename, vector<GridItem> grids);
-  bool updateGridsFromVDB(string filename, vector<GridItem> grids);
-  bool updateGridsFromRaw(string filename, vector<GridItem> grids);
-  bool updateMeshFromFile(string filename);
-  bool updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData);
-  bool updateGridsFromFile(string filename, vector<GridItem> grids);
   string getDirectory(struct FluidModifierData *mmd, string subdirectory);
   string getFile(struct FluidModifierData *mmd,
                  string subdirectory,
index 49bc224b3faac76d6bee352c735ae782bdcb36a4..f1607f1bd995627f0f8897dc6d71b82364c6af7f 100644 (file)
@@ -94,18 +94,18 @@ int manta_read_config(MANTA *fluid, FluidModifierData *mmd, int framenr)
   return fluid->readConfiguration(mmd, framenr);
 }
 
-int manta_read_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
+int manta_read_data(MANTA *fluid, FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (!fluid || !mmd)
     return 0;
-  return fluid->readData(mmd, framenr);
+  return fluid->readData(mmd, framenr, resumable);
 }
 
-int manta_read_noise(MANTA *fluid, FluidModifierData *mmd, int framenr)
+int manta_read_noise(MANTA *fluid, FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (!fluid || !mmd)
     return 0;
-  return fluid->readNoise(mmd, framenr);
+  return fluid->readNoise(mmd, framenr, resumable);
 }
 
 int manta_read_mesh(MANTA *fluid, FluidModifierData *mmd, int framenr)
@@ -115,11 +115,11 @@ int manta_read_mesh(MANTA *fluid, FluidModifierData *mmd, int framenr)
   return fluid->readMesh(mmd, framenr);
 }
 
-int manta_read_particles(MANTA *fluid, FluidModifierData *mmd, int framenr)
+int manta_read_particles(MANTA *fluid, FluidModifierData *mmd, int framenr, bool resumable)
 {
   if (!fluid || !mmd)
     return 0;
-  return fluid->readParticles(mmd, framenr);
+  return fluid->readParticles(mmd, framenr, resumable);
 }
 
 int manta_read_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr, bool sourceDomain)
@@ -129,41 +129,6 @@ int manta_read_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr, bool s
   return fluid->readGuiding(mmd, framenr, sourceDomain);
 }
 
-int manta_update_liquid_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
-{
-  if (!fluid || !mmd)
-    return 0;
-  return fluid->updateFlipStructures(mmd, framenr);
-}
-
-int manta_update_mesh_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
-{
-  if (!fluid || !mmd)
-    return 0;
-  return fluid->updateMeshStructures(mmd, framenr);
-}
-
-int manta_update_particle_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
-{
-  if (!fluid || !mmd)
-    return 0;
-  return fluid->updateParticleStructures(mmd, framenr);
-}
-
-int manta_update_smoke_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
-{
-  if (!fluid || !mmd)
-    return 0;
-  return fluid->updateSmokeStructures(mmd, framenr);
-}
-
-int manta_update_noise_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
-{
-  if (!fluid || !mmd)
-    return 0;
-  return fluid->updateNoiseStructures(mmd, framenr);
-}
-
 int manta_bake_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
 {
   if (!fluid || !mmd)
index 637dd22f1280a947bf5774b2d767c3c5da3df6ab..0fb577cc109ac7039af0dad97e0c13d0e7b5151d 100644 (file)
@@ -33,7 +33,7 @@ from manta import *\n\
 import os.path, shutil, math, sys, gc, multiprocessing, platform, time\n\
 \n\
 withMPBake = False # Bake files asynchronously\n\
-withMPSave = True # Save files asynchronously\n\
+withMPSave = False # Save files asynchronously\n\
 isWindows = platform.system() != 'Darwin' and platform.system() != 'Linux'\n\
 # TODO (sebbas): Use this to simulate Windows multiprocessing (has default mode spawn)\n\
 #try:\n\
@@ -161,7 +161,19 @@ mantaMsg('scaleSpeed is ' + str(scaleSpeedFrames_s$ID$))\n\
 scaleSpeedTime_s$ID$ = ratioResToBLength_s$ID$ * ratioBTimeToTimstep_s$ID$ # [blength/btime] to [cells/frameLength]\n\
 mantaMsg('scaleSpeedTime is ' + str(scaleSpeedTime_s$ID$))\n\
 \n\
-gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell based acceleration\n";
+gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell based acceleration\n\
+\n\
+# OpenVDB options\n\
+vdbCompression_s$ID$ = $COMPRESSION_OPENVDB$\n\
+vdbPrecisionHalf_s$ID$ = $PRECISION_OPENVDB$\n\
+\n\
+# Cache file names\n\
+file_data_s$ID$ = '$NAME_DATA$'\n\
+file_noise_s$ID$ = '$NAME_NOISE$'\n\
+file_mesh_s$ID$ = '$NAME_MESH$'\n\
+file_meshvel_s$ID$ = '$NAME_MESH$'\n\
+file_particles_s$ID$ = '$NAME_PARTICLES$'\n\
+file_guiding_s$ID$ = '$NAME_GUIDING$'";
 
 const std::string fluid_variables_noise =
     "\n\
@@ -282,8 +294,8 @@ phiIn_s$ID$.setConst(9999)\n\
 phiOut_s$ID$.setConst(9999)\n\
 \n\
 # Keep track of important objects in dict to load them later on\n\
-fluid_data_dict_final_s$ID$  = dict(vel=vel_s$ID$, velTmp=velTmp_s$ID$)\n\
-fluid_data_dict_resume_s$ID$ = dict(phiObs=phiObs_s$ID$, phiIn=phiIn_s$ID$, phiOut=phiOut_s$ID$, flags=flags_s$ID$)\n";
+fluid_data_dict_final_s$ID$  = { 'vel' : vel_s$ID$ }\n\
+fluid_data_dict_resume_s$ID$ = { 'phiObs' : phiObs_s$ID$, 'phiIn' : phiIn_s$ID$, 'phiOut' : phiOut_s$ID$, 'flags' : flags_s$ID$, 'velTmp' : velTmp_s$ID$ }\n";
 
 const std::string fluid_alloc_obstacle =
     "\n\
@@ -497,10 +509,12 @@ def fluid_cache_get_framenr_formatted_$ID$(framenr):\n\
 
 const std::string fluid_bake_multiprocessing =
     "\n\
-def fluid_cache_multiprocessing_start_$ID$(function, framenr, format_data=None, format_noise=None, format_mesh=None, format_particles=None, format_guiding=None, path_data=None, path_noise=None, path_mesh=None, path_particles=None, path_guiding=None, dict=None, do_join=True, resumable=False):\n\
+def fluid_cache_multiprocessing_start_$ID$(function, framenr, file_name=None, format_data=None, format_noise=None, format_mesh=None, format_particles=None, format_guiding=None, path_data=None, path_noise=None, path_mesh=None, path_particles=None, path_guiding=None, dict=None, do_join=True, resumable=False):\n\
     mantaMsg('Multiprocessing cache')\n\
     if __name__ == '__main__':\n\
         args = (framenr,)\n\
+        if file_name:\n\
+            args += (file_name,)\n\
         if format_data:\n\
             args += (format_data,)\n\
         if format_noise:\n\
@@ -531,7 +545,7 @@ def fluid_cache_multiprocessing_start_$ID$(function, framenr, format_data=None,
 
 const std::string fluid_bake_data =
     "\n\
-def bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_guiding, path_data, path_guiding):\n\
+def bake_fluid_process_data_$ID$(framenr, format_data, path_data):\n\
     mantaMsg('Bake fluid data')\n\
     \n\
     s$ID$.frame = framenr\n\
@@ -545,15 +559,15 @@ def bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_
         liquid_adaptive_step_$ID$(framenr)\n\
     mantaMsg('--- Step: %s seconds ---' % (time.time() - start_time))\n\
 \n\
-def bake_fluid_data_$ID$(path_data, path_guiding, framenr, format_data, format_particles, format_guiding):\n\
+def bake_fluid_data_$ID$(path_data, framenr, format_data):\n\
     if not withMPBake or isWindows:\n\
-        bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_guiding, path_data, path_guiding)\n\
+        bake_fluid_process_data_$ID$(framenr, format_data, path_data)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=bake_fluid_process_data_$ID$, framenr=framenr, format_data=format_data, format_particles=format_particles, format_guiding=format_guiding, path_data=path_data, path_guiding=path_guiding, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=bake_fluid_process_data_$ID$, framenr=framenr, format_data=format_data, path_data=path_data, do_join=False)\n";
 
 const std::string fluid_bake_noise =
     "\n\
-def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise, resumable):\n\
+def bake_noise_process_$ID$(framenr, format_noise, path_noise):\n\
     mantaMsg('Bake fluid noise')\n\
     \n\
     sn$ID$.frame = framenr\n\
@@ -563,15 +577,15 @@ def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_
     \n\
     smoke_step_noise_$ID$(framenr)\n\
 \n\
-def bake_noise_$ID$(path_data, path_noise, framenr, format_data, format_noise, resumable):\n\
+def bake_noise_$ID$(path_noise, framenr, format_noise):\n\
     if not withMPBake or isWindows:\n\
-        bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise, resumable)\n\
+        bake_noise_process_$ID$(framenr, format_noise, path_noise)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=bake_noise_process_$ID$, framenr=framenr, format_data=format_data, format_noise=format_noise, path_data=path_data, path_noise=path_noise, resumable=resumable)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=bake_noise_process_$ID$, framenr=framenr, format_noise=format_noise, path_noise=path_noise)\n";
 
 const std::string fluid_bake_mesh =
     "\n\
-def bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles, path_data, path_mesh):\n\
+def bake_mesh_process_$ID$(framenr, format_data, format_mesh, path_mesh):\n\
     mantaMsg('Bake fluid mesh')\n\
     \n\
     sm$ID$.frame = framenr\n\
@@ -587,15 +601,15 @@ def bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles,
         if using_speedvectors_s$ID$:\n\
             liquid_save_meshvel_$ID$(path_mesh, framenr, format_data)\n\
 \n\
-def bake_mesh_$ID$(path_data, path_mesh, framenr, format_data, format_mesh, format_particles):\n\
+def bake_mesh_$ID$(path_mesh, framenr, format_data, format_mesh):\n\
     if not withMPBake or isWindows:\n\
-        bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles, path_data, path_mesh)\n\
+        bake_mesh_process_$ID$(framenr, format_data, format_mesh, path_mesh)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=bake_mesh_process_$ID$, framenr=framenr, format_data=format_data, format_mesh=format_mesh, format_particles=format_particles, path_data=path_data, path_mesh=path_mesh)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=bake_mesh_process_$ID$, framenr=framenr, format_data=format_data, format_mesh=format_mesh, path_mesh=path_mesh)\n";
 
 const std::string fluid_bake_particles =
     "\n\
-def bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles, resumable):\n\
+def bake_particles_process_$ID$(framenr, format_particles, path_particles, resumable):\n\
     mantaMsg('Bake secondary particles')\n\
     \n\
     sp$ID$.frame = framenr\n\
@@ -609,11 +623,11 @@ def bake_particles_process_$ID$(framenr, format_data, format_particles, path_dat
         liquid_step_particles_$ID$()\n\
         liquid_save_particles_$ID$(path_particles, framenr, format_particles, resumable)\n\
 \n\
-def bake_particles_$ID$(path_data, path_particles, framenr, format_data, format_particles, resumable):\n\
+def bake_particles_$ID$(path_particles, framenr, format_particles, resumable):\n\
     if not withMPBake or isWindows:\n\
-        bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles, resumable)\n\
+        bake_particles_process_$ID$(framenr, format_particles, path_particles, resumable)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=bake_particles_process_$ID$, framenr=framenr, format_data=format_data, format_particles=format_particles, path_data=path_data, path_particles=path_particles, resumable=resumable)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=bake_particles_process_$ID$, framenr=framenr, format_particles=format_particles, path_particles=path_particles, resumable=resumable)\n";
 
 const std::string fluid_bake_guiding =
     "\n\
@@ -650,43 +664,47 @@ def bake_guiding_$ID$(path_guiding, framenr, format_guiding, resumable):\n\
 
 const std::string fluid_file_import =
     "\n\
-def fluid_file_import_s$ID$(dict, path, framenr, file_format):\n\
+def fluid_file_import_s$ID$(dict, path, framenr, file_format, file_name=None):\n\
+    mantaMsg('Fluid file import, frame: ' + str(framenr))\n\
     try:\n\
         framenr = fluid_cache_get_framenr_formatted_$ID$(framenr)\n\
-        for name, object in dict.items():\n\
-            file = os.path.join(path, name + '_' + framenr + file_format)\n\
+        # New cache: Try to load the data from a single file\n\
+        loadCombined = 0\n\
+        if file_name is not None:\n\
+            file = os.path.join(path, file_name + '_' + framenr + file_format)\n\
             if os.path.isfile(file):\n\
-                object.load(file)\n\
-            else:\n\
-                mantaMsg('Could not load file ' + str(file))\n\
-    except:\n\
-        mantaMsg('exception found')\n\
-        #mantaMsg(str(e))\n\
-        pass # Just skip file load errors for now\n";
-
-const std::string fluid_load_data =
-    "\n\
-def fluid_load_data_$ID$(path, framenr, file_format, resumable):\n\
-    mantaMsg('Fluid load data, frame ' + str(framenr))\n\
-    fluid_file_import_s$ID$(dict=fluid_data_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-    \n\
-    if resumable:\n\
-        fluid_file_import_s$ID$(dict=fluid_data_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+                if file_format == '.vdb':\n\
+                    loadCombined = load(name=file, objects=list(dict.values()), worldSize=domainSize_s$ID$)\n\
+                elif file_format == '.bobj.gz' or file_format == '.obj':\n\
+                    for name, object in dict.items():\n\
+                        if os.path.isfile(file):\n\
+                            loadCombined = object.load(file)\n\
+        \n\
+        # Old cache: Try to load the data from separate files, i.e. per object with the object based load() function\n\
+        if not loadCombined:\n\
+            for name, object in dict.items():\n\
+                file = os.path.join(path, name + '_' + framenr + file_format)\n\
+                if os.path.isfile(file):\n\
+                    loadCombined = object.load(file)\n\
         \n\
-        # When adaptive domain bake is resumed we need correct values in xyz vel grids\n\
-        copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
+        if not loadCombined:\n\
+            mantaMsg('Could not load file ' + str(file))\n\
+    \n\
+    except Exception as e:\n\
+        mantaMsg('Exception in Python fluid file import: ' + str(e))\n\
+        pass # Just skip file load errors for now\n";
 
 const std::string fluid_load_guiding =
     "\n\
 def fluid_load_guiding_$ID$(path, framenr, file_format):\n\
     mantaMsg('Fluid load guiding, frame ' + str(framenr))\n\
-    fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+    fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format, file_name=file_guiding_s$ID$)\n";
 
 const std::string fluid_load_vel =
     "\n\
 def fluid_load_vel_$ID$(path, framenr, file_format):\n\
     mantaMsg('Fluid load vel, frame ' + str(framenr))\n\
-    fluid_vel_dict_s$ID$ = dict(vel=guidevel_sg$ID$)\n\
+    fluid_vel_dict_s$ID$ = { 'vel' : guidevel_sg$ID$ }\n\
     fluid_file_import_s$ID$(dict=fluid_vel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
 
 //////////////////////////////////////////////////////////////////////
@@ -695,7 +713,7 @@ def fluid_load_vel_$ID$(path, framenr, file_format):\n\
 
 const std::string fluid_file_export =
     "\n\
-def fluid_file_export_s$ID$(framenr, file_format, path, dict, mode_override=True, skip_subframes=True):\n\
+def fluid_file_export_s$ID$(framenr, file_format, path, dict, file_name=None, mode_override=True, skip_subframes=True):\n\
     if skip_subframes and ((timePerFrame_s$ID$ + dt0_s$ID$) < frameLength_s$ID$):\n\
         return\n\
     mantaMsg('Fluid file export, frame: ' + str(framenr))\n\
@@ -703,36 +721,37 @@ def fluid_file_export_s$ID$(framenr, file_format, path, dict, mode_override=True
         framenr = fluid_cache_get_framenr_formatted_$ID$(framenr)\n\
         if not os.path.exists(path):\n\
             os.makedirs(path)\n\
-        for name, object in dict.items():\n\
-            file = os.path.join(path, name + '_' + framenr + file_format)\n\
-            if not os.path.isfile(file) or mode_override: object.save(file)\n\
+        \n\
+        # New cache: Try to save the data to a single file\n\
+        saveCombined = 0\n\
+        if file_name is not None:\n\
+            file = os.path.join(path, file_name + '_' + framenr + file_format)\n\
+            if not os.path.isfile(file) or mode_override:\n\
+                if file_format == '.vdb':\n\
+                    saveCombined = save(name=file, objects=list(dict.values()), worldSize=domainSize_s$ID$, skipDeletedParts=True, compression=vdbCompression_s$ID$, precisionHalf=vdbPrecisionHalf_s$ID$)\n\
+                elif file_format == '.bobj.gz' or file_format == '.obj':\n\
+                    for name, object in dict.items():\n\
+                        if not os.path.isfile(file) or mode_override:\n\
+                            saveCombined = object.save(file)\n\
+        \n\
+        # Old cache: Try to save the data to separate files, i.e. per object with the object based save() function\n\
+        if not saveCombined:\n\
+            for name, object in dict.items():\n\
+                file = os.path.join(path, name + '_' + framenr + file_format)\n\
+                if not os.path.isfile(file) or mode_override: object.save(file)\n\
+    \n\
     except Exception as e:\n\
-        mantaMsg(str(e))\n\
+        mantaMsg('Exception in Python fluid file export: ' + str(e))\n\
         pass # Just skip file save errors for now\n";
 
-const std::string fluid_save_data =
-    "\n\
-def fluid_save_data_$ID$(path, framenr, file_format, resumable):\n\
-    mantaMsg('Fluid save data, frame ' + str(framenr))\n\
-    start_time = time.time()\n\
-    if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=fluid_data_dict_final_s$ID$)\n\
-        if resumable:\n\
-            fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=fluid_data_dict_resume_s$ID$)\n\
-    else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_data_dict_final_s$ID$, do_join=False)\n\
-        if resumable:\n\
-            fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_data_dict_resume_s$ID$, do_join=False)\n\
-    mantaMsg('--- Save: %s seconds ---' % (time.time() - start_time))\n";
-
 const std::string fluid_save_guiding =
     "\n\
-def fluid_save_guiding_$ID$(path, framenr, file_format, resumable):\n\
+def fluid_save_guiding_$ID$(path, framenr, file_format):\n\
     mantaMsg('Fluid save guiding, frame ' + str(framenr))\n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(dict=fluid_guiding_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
+        fluid_file_export_s$ID$(dict=fluid_guiding_dict_s$ID$, framenr=framenr, file_format=file_format, path=path, file_name=file_guiding_s$ID$)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_guiding_dict_s$ID$, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_guiding_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_guiding_dict_s$ID$, do_join=False)\n";
 
 //////////////////////////////////////////////////////////////////////
 // STANDALONE MODE
index 65733aad736878f371e0ee8ddd24e83c819c5317..1dec61c02dacb5be316a7fed3ea17b67ad23c367 100644 (file)
@@ -86,16 +86,16 @@ mapWeights_s$ID$ = s$ID$.create(MACGrid, name='$NAME_MAPWEIGHTS$')\n\
 fractions_s$ID$  = None # allocated dynamically\n\
 curvature_s$ID$  = None\n\
 \n\
-pp_s$ID$         = s$ID$.create(BasicParticleSystem, name='$NAME_PP$')\n\
-pVel_pp$ID$      = pp_s$ID$.create(PdataVec3, name='$NAME_PVEL$')\n\
+pp_s$ID$         = s$ID$.create(BasicParticleSystem, name='$NAME_PARTS$')\n\
+pVel_pp$ID$      = pp_s$ID$.create(PdataVec3, name='$NAME_PARTSVELOCITY$')\n\
 \n\
 # Acceleration data for particle nbs\n\
 pindex_s$ID$     = s$ID$.create(ParticleIndexSystem, name='$NAME_PINDEX$')\n\
 gpi_s$ID$        = s$ID$.create(IntGrid, name='$NAME_GPI$')\n\
 \n\
 # Keep track of important objects in dict to load them later on\n\
-liquid_data_dict_final_s$ID$ = dict(pp=pp_s$ID$, pVel=pVel_pp$ID$)\n\
-liquid_data_dict_resume_s$ID$ = dict(phiParts=phiParts_s$ID$, phi=phi_s$ID$, phiTmp=phiTmp_s$ID$)\n";
+liquid_data_dict_final_s$ID$ = { 'pVel' : pVel_pp$ID$, 'pp' : pp_s$ID$ }\n\
+liquid_data_dict_resume_s$ID$ = { 'phiParts' : phiParts_s$ID$, 'phi' : phi_s$ID$, 'phiTmp' : phiTmp_s$ID$ }\n";
 
 const std::string liquid_alloc_mesh =
     "\n\
@@ -104,7 +104,7 @@ phiParts_sm$ID$ = sm$ID$.create(LevelsetGrid, name='$NAME_PHIPARTS_MESH$')\n\
 phi_sm$ID$      = sm$ID$.create(LevelsetGrid, name='$NAME_PHI_MESH$')\n\
 pp_sm$ID$       = sm$ID$.create(BasicParticleSystem, name='$NAME_PP_MESH$')\n\
 flags_sm$ID$    = sm$ID$.create(FlagGrid, name='$NAME_FLAGS_MESH$')\n\
-mesh_sm$ID$     = sm$ID$.create(Mesh, name='$NAME_LMESH$')\n\
+mesh_sm$ID$     = sm$ID$.create(Mesh, name='$NAME_MESH$')\n\
 \n\
 if using_speedvectors_s$ID$:\n\
     mVel_mesh$ID$ = mesh_sm$ID$.create(MdataVec3, name='$NAME_VELOCITYVEC_MESH$')\n\
@@ -119,10 +119,10 @@ phiParts_sm$ID$.setConst(9999)\n\
 phi_sm$ID$.setConst(9999)\n\
 \n\
 # Keep track of important objects in dict to load them later on\n\
-liquid_mesh_dict_s$ID$ = dict(lMesh=mesh_sm$ID$)\n\
+liquid_mesh_dict_s$ID$ = { 'lMesh' : mesh_sm$ID$ }\n\
 \n\
 if using_speedvectors_s$ID$:\n\
-    liquid_meshvel_dict_s$ID$ = dict(lVelMesh=mVel_mesh$ID$)\n";
+    liquid_meshvel_dict_s$ID$ = { 'lVelMesh' : mVel_mesh$ID$ }\n";
 
 const std::string liquid_alloc_curvature =
     "\n\
@@ -131,10 +131,10 @@ curvature_s$ID$  = s$ID$.create(RealGrid, name='$NAME_CURVATURE$')\n";
 
 const std::string liquid_alloc_particles =
     "\n\
-ppSnd_sp$ID$         = sp$ID$.create(BasicParticleSystem, name='$NAME_PP_PARTICLES$')\n\
-pVelSnd_pp$ID$       = ppSnd_sp$ID$.create(PdataVec3, name='$NAME_PVEL_PARTICLES$')\n\
-pForceSnd_pp$ID$     = ppSnd_sp$ID$.create(PdataVec3, name='$NAME_PFORCE_PARTICLES$')\n\
-pLifeSnd_pp$ID$      = ppSnd_sp$ID$.create(PdataReal, name='$NAME_PLIFE_PARTICLES$')\n\
+ppSnd_sp$ID$         = sp$ID$.create(BasicParticleSystem, name='$NAME_PARTS_PARTICLES$')\n\
+pVelSnd_pp$ID$       = ppSnd_sp$ID$.create(PdataVec3, name='$NAME_PARTSVEL_PARTICLES$')\n\
+pForceSnd_pp$ID$     = ppSnd_sp$ID$.create(PdataVec3, name='$NAME_PARTSFORCE_PARTICLES$')\n\
+pLifeSnd_pp$ID$      = ppSnd_sp$ID$.create(PdataReal, name='$NAME_PARTSLIFE_PARTICLES$')\n\
 vel_sp$ID$           = sp$ID$.create(MACGrid, name='$NAME_VELOCITY_PARTICLES$')\n\
 flags_sp$ID$         = sp$ID$.create(FlagGrid, name='$NAME_FLAGS_PARTICLES$')\n\
 phi_sp$ID$           = sp$ID$.create(LevelsetGrid, name='$NAME_PHI_PARTICLES$')\n\
@@ -152,8 +152,8 @@ phiObs_sp$ID$.setConst(9999)\n\
 phiOut_sp$ID$.setConst(9999)\n\
 \n\
 # Keep track of important objects in dict to load them later on\n\
-liquid_particles_dict_final_s$ID$  = dict(ppSnd=ppSnd_sp$ID$, pVelSnd=pVelSnd_pp$ID$, pLifeSnd=pLifeSnd_pp$ID$)\n\
-liquid_particles_dict_resume_s$ID$ = dict(trappedAir=trappedAir_sp$ID$, waveCrest=waveCrest_sp$ID$, kineticEnergy=kineticEnergy_sp$ID$)\n";
+liquid_particles_dict_final_s$ID$  = { 'pVelSnd' : pVelSnd_pp$ID$, 'pLifeSnd' : pLifeSnd_pp$ID$, 'ppSnd' : ppSnd_sp$ID$ }\n\
+liquid_particles_dict_resume_s$ID$ = { 'trappedAir' : trappedAir_sp$ID$, 'waveCrest' : waveCrest_sp$ID$, 'kineticEnergy' : kineticEnergy_sp$ID$ }\n";
 
 const std::string liquid_init_phi =
     "\n\
@@ -401,27 +401,29 @@ const std::string liquid_load_data =
     "\n\
 def liquid_load_data_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Liquid load data')\n\
-    fluid_file_import_s$ID$(dict=liquid_data_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-    if resumable:\n\
-        fluid_file_import_s$ID$(dict=liquid_data_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+    dict = { **fluid_data_dict_final_s$ID$, **fluid_data_dict_resume_s$ID$, **liquid_data_dict_final_s$ID$, **liquid_data_dict_resume_s$ID$ } if resumable else { **fluid_data_dict_final_s$ID$, **liquid_data_dict_final_s$ID$ }\n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n\
+    \n\
+    copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
 
 const std::string liquid_load_mesh =
     "\n\
 def liquid_load_mesh_$ID$(path, framenr, file_format):\n\
     mantaMsg('Liquid load mesh')\n\
-    fluid_file_import_s$ID$(dict=liquid_mesh_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+    dict = liquid_mesh_dict_s$ID$\n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_mesh_s$ID$)\n\
 \n\
 def liquid_load_meshvel_$ID$(path, framenr, file_format):\n\
     mantaMsg('Liquid load meshvel')\n\
-    fluid_file_import_s$ID$(dict=liquid_meshvel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+    dict = liquid_meshvel_dict_s$ID$\n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_meshvel_s$ID$)\n";
 
 const std::string liquid_load_particles =
     "\n\
 def liquid_load_particles_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Liquid load particles')\n\
-    fluid_file_import_s$ID$(dict=liquid_particles_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-    if resumable:\n\
-        fluid_file_import_s$ID$(dict=liquid_particles_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+    dict = { **liquid_particles_dict_final_s$ID$, **liquid_particles_dict_resume_s$ID$ } if resumable else { **liquid_particles_dict_final_s$ID$ }\n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_particles_s$ID$)\n";
 
 //////////////////////////////////////////////////////////////////////
 // EXPORT
@@ -431,43 +433,39 @@ const std::string liquid_save_data =
     "\n\
 def liquid_save_data_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Liquid save data')\n\
+    dict = { **fluid_data_dict_final_s$ID$, **fluid_data_dict_resume_s$ID$, **liquid_data_dict_final_s$ID$, **liquid_data_dict_resume_s$ID$ } if resumable else { **fluid_data_dict_final_s$ID$, **liquid_data_dict_final_s$ID$ }\n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(dict=liquid_data_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-        if resumable:\n\
-            fluid_file_export_s$ID$(dict=liquid_data_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+        fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_data_dict_final_s$ID$, do_join=False)\n\
-        if resumable:\n\
-            fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_data_dict_resume_s$ID$, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_data_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n";
 
 const std::string liquid_save_mesh =
     "\n\
 def liquid_save_mesh_$ID$(path, framenr, file_format):\n\
     mantaMsg('Liquid save mesh')\n\
+    dict = liquid_mesh_dict_s$ID$\n\
     if not withMPSave or isWindows:\n\
-         fluid_file_export_s$ID$(dict=liquid_mesh_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+         fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_mesh_s$ID$)\n\
     else:\n\
-         fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_mesh_dict_s$ID$, do_join=False)\n\
+         fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_mesh_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n\
 \n\
 def liquid_save_meshvel_$ID$(path, framenr, file_format):\n\
     mantaMsg('Liquid save mesh vel')\n\
+    dict = liquid_meshvel_dict_s$ID$\n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(dict=liquid_meshvel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+        fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_meshvel_dict_s$ID$, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n";
 
 const std::string liquid_save_particles =
     "\n\
 def liquid_save_particles_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Liquid save particles')\n\
+    dict = { **liquid_particles_dict_final_s$ID$, **liquid_particles_dict_resume_s$ID$ } if resumable else { **liquid_particles_dict_final_s$ID$ }\n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(dict=liquid_particles_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-        if resumable:\n\
-            fluid_file_export_s$ID$(dict=liquid_particles_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+        fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_particles_s$ID$)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_particles_dict_final_s$ID$, do_join=False)\n\
-        if resumable:\n\
-            fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_particles_dict_resume_s$ID$, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_particles_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n";
 
 //////////////////////////////////////////////////////////////////////
 // STANDALONE MODE
@@ -477,7 +475,6 @@ const std::string liquid_standalone =
     "\n\
 # Helper function to call cache load functions\n\
 def load(frame, cache_resumable):\n\
-    fluid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
     liquid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
     if using_sndparts_s$ID$:\n\
         liquid_load_particles_$ID$(os.path.join(cache_dir, 'particles'), frame, file_format_particles, cache_resumable)\n\
index a592ad8644a8be3a9433fe42a31f45da2c290be5..5e80e4443a3ec7a1cd731db37817af475ee16b8d 100644 (file)
@@ -101,8 +101,8 @@ color_g_in_s$ID$ = None\n\
 color_b_in_s$ID$ = None\n\
 \n\
 # Keep track of important objects in dict to load them later on\n\
-smoke_data_dict_final_s$ID$ = dict(density=density_s$ID$, shadow=shadow_s$ID$)\n\
-smoke_data_dict_resume_s$ID$ = dict(densityIn=densityIn_s$ID$, emission=emission_s$ID$)\n";
+smoke_data_dict_final_s$ID$ = { 'density' : density_s$ID$, 'shadow' : shadow_s$ID$ }\n\
+smoke_data_dict_resume_s$ID$ = { 'densityIn' : densityIn_s$ID$, 'emission' : emission_s$ID$ }\n";
 
 const std::string smoke_alloc_noise =
     "\n\
@@ -213,8 +213,8 @@ if 'heat_s$ID$' in globals(): del heat_s$ID$\n\
 if 'heatIn_s$ID$' in globals(): del heatIn_s$ID$\n\
 \n\
 mantaMsg('Allocating heat')\n\
-heat_s$ID$   = s$ID$.create(RealGrid, name='$NAME_HEAT$')\n\
-heatIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_HEATIN$')\n\
+heat_s$ID$   = s$ID$.create(RealGrid, name='$NAME_TEMPERATURE$')\n\
+heatIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_TEMPERATUREIN$')\n\
 \n\
 # Add objects to dict to load them later on\n\
 if 'smoke_data_dict_final_s$ID$' in globals():\n\
@@ -542,19 +542,19 @@ const std::string smoke_load_data =
     "\n\
 def smoke_load_data_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Smoke load data')\n\
-    fluid_file_import_s$ID$(dict=smoke_data_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-    if resumable:\n\
-        fluid_file_import_s$ID$(dict=smoke_data_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+    dict = { **fluid_data_dict_final_s$ID$, **fluid_data_dict_resume_s$ID$, **smoke_data_dict_final_s$ID$, **smoke_data_dict_resume_s$ID$ } if resumable else { **fluid_data_dict_final_s$ID$, **smoke_data_dict_final_s$ID$ }\n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n\
+    \n\
+    copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
 
 const std::string smoke_load_noise =
     "\n\
 def smoke_load_noise_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Smoke load noise')\n\
-    fluid_file_import_s$ID$(dict=smoke_noise_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
+    dict = { **smoke_noise_dict_final_s$ID$, **smoke_data_dict_resume_s$ID$ } if resumable else { **smoke_noise_dict_final_s$ID$ } \n\
+    fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_noise_s$ID$)\n\
     \n\
     if resumable:\n\
-        fluid_file_import_s$ID$(dict=smoke_noise_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
-        \n\
         # Fill up xyz texture grids, important when resuming a bake\n\
         copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_s$ID$, targetZ=texture_w_s$ID$)\n\
         copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n";
@@ -568,28 +568,22 @@ const std::string smoke_save_data =
 def smoke_save_data_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Smoke save data')\n\
     start_time = time.time()\n\
+    dict = { **fluid_data_dict_final_s$ID$, **fluid_data_dict_resume_s$ID$, **smoke_data_dict_final_s$ID$, **smoke_data_dict_resume_s$ID$ } if resumable else { **fluid_data_dict_final_s$ID$, **smoke_data_dict_final_s$ID$ } \n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=smoke_data_dict_final_s$ID$,)\n\
-        if resumable:\n\
-            fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=smoke_data_dict_resume_s$ID$,)\n\
+        fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_data_dict_final_s$ID$, do_join=False)\n\
-        if resumable:\n\
-            fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_data_dict_resume_s$ID$, do_join=False)\n\
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_data_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n\
     mantaMsg('--- Save: %s seconds ---' % (time.time() - start_time))\n";
 
 const std::string smoke_save_noise =
     "\n\
 def smoke_save_noise_$ID$(path, framenr, file_format, resumable):\n\
     mantaMsg('Smoke save noise')\n\
+    dict = { **smoke_noise_dict_final_s$ID$, **smoke_noise_dict_resume_s$ID$ } if resumable else { **smoke_noise_dict_final_s$ID$ } \n\
     if not withMPSave or isWindows:\n\
-        fluid_file_export_s$ID$(dict=smoke_noise_dict_final_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
-        if resumable:\n\
-            fluid_file_export_s$ID$(dict=smoke_noise_dict_resume_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
+        fluid_file_export_s$ID$(dict=dict, framenr=framenr, file_format=file_format, path=path, file_name=file_noise_s$ID$)\n\
     else:\n\
-        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_noise_dict_final_s$ID$, do_join=False)\n\
-        if resumable:\n\
-            fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_noise_dict_resume_s$ID$, do_join=False)\n";
+        fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_noise_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n";
 
 //////////////////////////////////////////////////////////////////////
 // STANDALONE MODE
@@ -599,7 +593,6 @@ const std::string smoke_standalone =
     "\n\
 # Helper function to call cache load functions\n\
 def load(frame, cache_resumable):\n\
-    fluid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
     smoke_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
     if using_noise_s$ID$:\n\
         smoke_load_noise_$ID$(os.path.join(cache_dir, 'noise'), frame, file_format_noise, cache_resumable)\n\
index 71153ba8b74b7e8b75a3bdc051f3d214900487ee..59b66b427f15d4413a6e6bb4b735653193106750 100644 (file)
@@ -399,9 +399,6 @@ class QuickSmoke(ObjectModeOperator, Operator):
         if self.style == 'FIRE' or self.style == 'BOTH':
             obj.modifiers[-1].domain_settings.use_noise = True
 
-        # set correct cache file format for smoke
-        obj.modifiers[-1].domain_settings.cache_data_format = 'UNI'
-
         # Setup material
 
         # Cycles and Eevee
index 833cd05dd818c9e4c8e287de4bb085805ffa3458..1727771637d4ed3e2eec235b25dca8b3c18877e0 100644 (file)
@@ -213,7 +213,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
                 split.enabled = note_flag
 
                 bake_incomplete = (domain.cache_frame_pause_data < domain.cache_frame_end)
-                if domain.has_cache_baked_data and not domain.is_cache_baking_data and bake_incomplete:
+                if domain.cache_resumable and domain.has_cache_baked_data and not domain.is_cache_baking_data and bake_incomplete:
                     col = split.column()
                     col.operator("fluid.bake_data", text="Resume")
                     col = split.column()
@@ -1119,9 +1119,7 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel):
 
         is_baking_any = domain.is_cache_baking_any
         has_baked_data = domain.has_cache_baked_data
-        has_baked_noise = domain.has_cache_baked_noise
         has_baked_mesh = domain.has_cache_baked_mesh
-        has_baked_particles = domain.has_cache_baked_particles
 
         col = layout.column()
         col.prop(domain, "cache_directory", text="")
@@ -1146,35 +1144,32 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel):
         col.separator()
 
         col = flow.column()
+        col.enabled = not is_baking_any and not has_baked_data
+        col.prop(domain, "cache_resumable", text="Is Resumable")
+
         row = col.row()
         row.enabled = not is_baking_any and not has_baked_data
-        row.prop(domain, "cache_data_format", text="Data File Format")
-
-        if md.domain_settings.domain_type in {'GAS'}:
-            if domain.use_noise:
-                row = col.row()
-                row.enabled = not is_baking_any and not has_baked_noise
-                row.prop(domain, "cache_noise_format", text="Noise File Format")
+        row.prop(domain, "cache_data_format", text="Format Volumes")
 
-        if md.domain_settings.domain_type in {'LIQUID'}:
-            # File format for all particle systemes (FLIP and secondary)
+        if md.domain_settings.domain_type in {'LIQUID'} and domain.use_mesh:
             row = col.row()
-            row.enabled = not is_baking_any and not has_baked_particles and not has_baked_data
-            row.prop(domain, "cache_particle_format", text="Particle File Format")
+            row.enabled = not is_baking_any and not has_baked_mesh
+            row.prop(domain, "cache_mesh_format", text="Meshes")
 
-            if domain.use_mesh:
-                row = col.row()
-                row.enabled = not is_baking_any and not has_baked_mesh
-                row.prop(domain, "cache_mesh_format", text="Mesh File Format")
-
-        if domain.cache_type == 'FINAL':
+        if domain.cache_type == 'ALL':
 
             col.separator()
             split = layout.split()
 
-            if domain.is_cache_baking_data and not domain.has_cache_baked_data:
+            bake_incomplete = (domain.cache_frame_pause_data < domain.cache_frame_end)
+            if domain.cache_resumable and domain.has_cache_baked_data and not domain.is_cache_baking_data and bake_incomplete:
+                col = split.column()
+                col.operator("fluid.bake_all", text="Resume")
+                col = split.column()
+                col.operator("fluid.free_all", text="Free")
+            elif domain.is_cache_baking_data and not domain.has_cache_baked_data:
                 split.enabled = False
-                split.operator("fluid.pause_bake", text="Baking All - ESC to cancel")
+                split.operator("fluid.pause_bake", text="Baking All - ESC to pause")
             elif not domain.has_cache_baked_data and not domain.is_cache_baking_data:
                 split.operator("fluid.bake_all", text="Bake All")
             else:
@@ -1189,8 +1184,8 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel):
 
     @classmethod
     def poll(cls, context):
-        # Only show the advanced panel to advanced users who know Mantaflow's birthday :)
-        if not PhysicButtonsPanel.poll_fluid_domain(context) or bpy.app.debug_value != 3001:
+        domain = context.fluid.domain_settings
+        if not PhysicButtonsPanel.poll_fluid_domain(context) or (domain.cache_data_format != 'OPENVDB' and bpy.app.debug_value != 3001):
             return False
 
         return (context.engine in cls.COMPAT_ENGINES)
@@ -1203,12 +1198,24 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel):
 
         is_baking_any = domain.is_cache_baking_any
         has_baked_any = domain.has_cache_baked_any
+        has_baked_data = domain.has_cache_baked_data
 
         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
         flow.enabled = not is_baking_any and not has_baked_any
 
         col = flow.column()
-        col.prop(domain, "export_manta_script", text="Export Mantaflow Script")
+
+        if domain.cache_data_format == 'OPENVDB':
+            col.enabled = not is_baking_any and not has_baked_data
+            col.prop(domain, "openvdb_cache_compress_type", text="Compression Volumes")
+
+            col = flow.column()
+            col.prop(domain, "openvdb_data_depth", text="Precision Volumes")
+
+        # Only show the advanced panel to advanced users who know Mantaflow's birthday :)
+        if bpy.app.debug_value == 3001:
+            col = flow.column()
+            col.prop(domain, "export_manta_script", text="Export Mantaflow Script")
 
 
 class PHYSICS_PT_field_weights(PhysicButtonsPanel, Panel):
index a66454d2bcc16b58bc197c1b553ad0e3a47a846a..103c3bb119d6503e335b9c223f515094f1fface7 100644 (file)
@@ -3809,6 +3809,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
   bubble = mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE;
   floater = mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
 
+  bool with_resumable_cache = mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE;
   bool with_script, with_adaptive, with_noise, with_mesh, with_particles, with_guide;
   with_script = mds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT;
   with_adaptive = mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN;
@@ -3868,13 +3869,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
 
   /* Cache mode specific settings. */
   switch (mode) {
-    case FLUID_DOMAIN_CACHE_FINAL:
-      /* Just load the data that has already been baked */
-      if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
-        read_cache = true;
-        bake_cache = false;
-      }
-      break;
+    case FLUID_DOMAIN_CACHE_ALL:
     case FLUID_DOMAIN_CACHE_MODULAR:
       /* Just load the data that has already been baked */
       if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
@@ -3929,6 +3924,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
       break;
   }
 
+  bool read_partial = false, read_all = false;
   /* Try to read from cache and keep track of read success. */
   if (read_cache) {
 
@@ -3937,20 +3933,16 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
       has_config = manta_read_config(mds->fluid, mmd, mesh_frame);
 
       /* Update mesh data from file is faster than via Python (manta_read_mesh()). */
-      has_mesh = manta_update_mesh_structures(mds->fluid, mmd, mesh_frame);
+      has_mesh = manta_read_mesh(mds->fluid, mmd, mesh_frame);
     }
 
     /* Read particles cache. */
     if (with_liquid && with_particles) {
       has_config = manta_read_config(mds->fluid, mmd, particles_frame);
 
-      if (!baking_data && !baking_particles && next_particles) {
-        /* Update particle data from file is faster than via Python (manta_read_particles()). */
-        has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame);
-      }
-      else {
-        has_particles = manta_read_particles(mds->fluid, mmd, particles_frame);
-      }
+      read_partial = !baking_data && !baking_particles && next_particles;
+      read_all = !read_partial && with_resumable_cache;
+      has_particles = manta_read_particles(mds->fluid, mmd, particles_frame, read_all);
     }
 
     /* Read guide cache. */
@@ -3968,12 +3960,10 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
           manta_needs_realloc(mds->fluid, mmd)) {
         BKE_fluid_reallocate_fluid(mds, mds->res, 1);
       }
-      if (!baking_data && !baking_noise && next_noise) {
-        has_noise = manta_update_noise_structures(mds->fluid, mmd, noise_frame);
-      }
-      else {
-        has_noise = manta_read_noise(mds->fluid, mmd, noise_frame);
-      }
+
+      read_partial = !baking_data && !baking_noise && next_noise;
+      read_all = !read_partial && with_resumable_cache;
+      has_noise = manta_read_noise(mds->fluid, mmd, noise_frame, read_all);
 
       /* When using the adaptive domain, copy all data that was read to a new fluid object. */
       if (with_adaptive && baking_noise) {
@@ -3987,12 +3977,10 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
               mds, o_res, mds->res, o_min, mds->res_min, o_max, o_shift, mds->shift);
         }
       }
-      if (!baking_data && !baking_noise && next_data && next_noise) {
-        /* Nothing to do here since we already loaded noise grids. */
-      }
-      else {
-        has_data = manta_read_data(mds->fluid, mmd, data_frame);
-      }
+
+      read_partial = !baking_data && !baking_noise && next_data && next_noise;
+      read_all = !read_partial && with_resumable_cache;
+      has_data = manta_read_data(mds->fluid, mmd, data_frame, read_all);
     }
     /* Read data cache only */
     else {
@@ -4003,28 +3991,17 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
         if (has_config && manta_needs_realloc(mds->fluid, mmd)) {
           BKE_fluid_reallocate_fluid(mds, mds->res, 1);
         }
-        /* Read data cache */
-        if (!baking_data && !baking_particles && !baking_mesh && next_data) {
-          has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame);
-        }
-        else {
-          has_data = manta_read_data(mds->fluid, mmd, data_frame);
-        }
-      }
-      if (with_liquid) {
-        if (!baking_data && !baking_particles && !baking_mesh && next_data) {
-          has_data = manta_update_liquid_structures(mds->fluid, mmd, data_frame);
-        }
-        else {
-          has_data = manta_read_data(mds->fluid, mmd, data_frame);
-        }
       }
+
+      read_partial = !baking_data && !baking_particles && !baking_mesh && next_data;
+      read_all = !read_partial && with_resumable_cache;
+      has_data = manta_read_data(mds->fluid, mmd, data_frame, read_all);
     }
   }
 
   /* Cache mode specific settings */
   switch (mode) {
-    case FLUID_DOMAIN_CACHE_FINAL:
+    case FLUID_DOMAIN_CACHE_ALL:
     case FLUID_DOMAIN_CACHE_MODULAR:
       if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
         bake_cache = false;
@@ -4987,12 +4964,12 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *mmd)
 
     /* OpenVDB cache options */
 #ifdef WITH_OPENVDB_BLOSC
-    mmd->domain->openvdb_comp = VDB_COMPRESSION_BLOSC;
+    mmd->domain->openvdb_compression = VDB_COMPRESSION_BLOSC;
 #else
-    mmd->domain->openvdb_comp = VDB_COMPRESSION_ZIP;
+    mmd->domain->openvdb_compression = VDB_COMPRESSION_ZIP;
 #endif
     mmd->domain->clipping = 1e-6f;
-    mmd->domain->data_depth = 0;
+    mmd->domain->openvdb_data_depth = 0;
   }
   else if (mmd->type & MOD_FLUID_TYPE_FLOW) {
     if (mmd->flow) {
@@ -5229,9 +5206,9 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *mmd,
     }
 
     /* OpenVDB cache options */
-    tmds->openvdb_comp = mds->openvdb_comp;
+    tmds->openvdb_compression = mds->openvdb_compression;
     tmds->clipping = mds->clipping;
-    tmds->data_depth = mds->data_depth;
+    tmds->openvdb_data_depth = mds->openvdb_data_depth;
   }
   else if (tmmd->flow) {
     FluidFlowSettings *tmfs = tmmd->flow;
index 298c0b1d78b5670392782d76c1c3587aa50c99de..c56dbcba13326a4b2b10db03e4bfb63a74c8e07d 100644 (file)
@@ -1062,7 +1062,7 @@ static int ptcache_smoke_openvdb_write(struct OpenVDBWriter *writer, void *smoke
   FluidModifierData *mmd = (FluidModifierData *)smoke_v;
   FluidDomainSettings *mds = mmd->domain;
 
-  OpenVDBWriter_set_flags(writer, mds->openvdb_comp, (mds->data_depth == 16));
+  OpenVDBWriter_set_flags(writer, mds->openvdb_compression, (mds->openvdb_data_depth == 16));
 
   OpenVDBWriter_add_meta_int(writer, "blender/smoke/active_fields", mds->active_fields);
   OpenVDBWriter_add_meta_v3_int(writer, "blender/smoke/resolution", mds->res);
index 8524870c15ec86ba66d47250782ec528de9bfcdf..8f6b5aa8bc3f2030f20d0b7a3ed4d1ec0a4a642b 100644 (file)
@@ -270,31 +270,31 @@ static void fluid_bake_sequence(FluidJob *job)
     *(job->do_update) = true;
   }
 
-  /* Get current pause frame (pointer) - depending on bake type */
+  /* Get current pause frame (pointer) - depending on bake type. */
   pause_frame = job->pause_frame;
 
-  /* Set frame to start point (depending on current pause frame value) */
+  /* Set frame to start point (depending on current pause frame value). */
   is_first_frame = ((*pause_frame) == 0);
   frame = is_first_frame ? mds->cache_frame_start : (*pause_frame);
 
-  /* Save orig frame and update scene frame */
+  /* Save orig frame and update scene frame. */
   orig_frame = CFRA;
   CFRA = frame;
 
-  /* Loop through selected frames */
+  /* Loop through selected frames. */
   for (; frame <= mds->cache_frame_end; frame++) {
     const float progress = (frame - mds->cache_frame_start) / (float)frames;
 
-    /* Keep track of pause frame - needed to init future loop */
+    /* Keep track of pause frame - needed to init future loop. */
     (*pause_frame) = frame;
 
-    /* If user requested stop, quit baking */
+    /* If user requested stop, quit baking. */
     if (G.is_break) {
       job->success = 0;
       return;
     }
 
-    /* Update progress bar */
+    /* Update progress bar. */
     if (job->do_update) {
       *(job->do_update) = true;
     }
@@ -304,17 +304,17 @@ static void fluid_bake_sequence(FluidJob *job)
 
     CFRA = frame;
 
-    /* Update animation system */
+    /* Update animation system. */
     ED_update_for_newframe(job->bmain, job->depsgraph);
 
-    /* If user requested stop, quit baking */
+    /* If user requested stop, quit baking. */
     if (G.is_break) {
       job->success = 0;
       return;
     }
   }
 
-  /* Restore frame position that we were on before bake */
+  /* Restore frame position that we were on before bake. */
   CFRA = orig_frame;
 }
 
@@ -355,9 +355,9 @@ static void fluid_bake_endjob(void *customdata)
   WM_set_locked_interface(G_MAIN->wm.first, false);
 
   /* Bake was successful:
-   *  Report for ended bake and how long it took */
+   * Report for ended bake and how long it took. */
   if (job->success) {
-    /* Show bake info */
+    /* Show bake info. */
     WM_reportf(
         RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, PIL_check_seconds_timer() - job->start);
   }
@@ -365,7 +365,7 @@ static void fluid_bake_endjob(void *customdata)
     if (mds->error[0] != '\0') {
       WM_reportf(RPT_ERROR, "Fluid: %s failed: %s", job->name, mds->error);
     }
-    else { /* User canceled the bake */
+    else { /* User canceled the bake. */
       WM_reportf(RPT_WARNING, "Fluid: %s canceled!", job->name);
     }
   }
index e8a22d8c82177a8d333279ed24233e39b2e71859..263cd3f788765d95bec7d3cfff703563eec6178f 100644 (file)
@@ -45,6 +45,7 @@ enum {
   FLUID_DOMAIN_USE_FRACTIONS = (1 << 13),       /* Use second order obstacles. */
   FLUID_DOMAIN_DELETE_IN_OBSTACLE = (1 << 14),  /* Delete fluid inside obstacles. */
   FLUID_DOMAIN_USE_DIFFUSION = (1 << 15), /* Use diffusion (e.g. viscosity, surface tension). */
+  FLUID_DOMAIN_USE_RESUMABLE_CACHE = (1 << 16), /* Determine if cache should be resumable. */
 };
 
 /* Border collisions. */
@@ -214,6 +215,7 @@ enum {
 #define FLUID_DOMAIN_DIR_SCRIPT "script"
 #define FLUID_DOMAIN_SMOKE_SCRIPT "smoke_script.py"
 #define FLUID_DOMAIN_LIQUID_SCRIPT "liquid_script.py"
+#define FLUID_CACHE_VERSION "C01"
 
 /* Cache file names. */
 #define FLUID_NAME_CONFIG "config"
@@ -224,24 +226,24 @@ enum {
 #define FLUID_NAME_GUIDING "fluid_guiding"
 
 /* Fluid object names.*/
-#define FLUID_NAME_FLAGS "flags"
-#define FLUID_NAME_VELOCITY "vel"
-#define FLUID_NAME_VELOCITYTMP "velocityTmp"
+#define FLUID_NAME_FLAGS "flags"                   /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_VELOCITY "velocity"             /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_VELOCITYTMP "velocity_previous" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_VELOCITYX "x_vel"
 #define FLUID_NAME_VELOCITYY "y_vel"
 #define FLUID_NAME_VELOCITYZ "z_vel"
 #define FLUID_NAME_PRESSURE "pressure"
-#define FLUID_NAME_PHIOBS "phiObs"
+#define FLUID_NAME_PHIOBS "phi_obstacle" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_PHISIN "phiSIn"
-#define FLUID_NAME_PHIIN "phiIn"
-#define FLUID_NAME_PHIOUT "phiOut"
+#define FLUID_NAME_PHIIN "phi_inflow" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PHIOUT "phi_out"   /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_FORCES "forces"
 #define FLUID_NAME_FORCE_X "x_force"
 #define FLUID_NAME_FORCE_Y "y_force"
 #define FLUID_NAME_FORCE_Z "z_force"
 #define FLUID_NAME_NUMOBS "numObs"
 #define FLUID_NAME_PHIOBSSIN "phiObsSIn"
-#define FLUID_NAME_PHIOBSIN "phiObsIn"
+#define FLUID_NAME_PHIOBSIN "phi_obstacle_inflow"
 #define FLUID_NAME_OBVEL "obvel"
 #define FLUID_NAME_OBVELC "obvelC"
 #define FLUID_NAME_OBVEL_X "x_obvel"
@@ -254,44 +256,48 @@ enum {
 #define FLUID_NAME_INVEL_Y "y_invel"
 #define FLUID_NAME_INVEL_Z "z_invel"
 #define FLUID_NAME_PHIOUTSIN "phiOutSIn"
-#define FLUID_NAME_PHIOUTIN "phiOutIn"
+#define FLUID_NAME_PHIOUTIN "phi_out_inflow"
 
 /* Smoke object names. */
-#define FLUID_NAME_SHADOW "shadow"
-#define FLUID_NAME_EMISSION "emission"
+#define FLUID_NAME_SHADOW "shadow"     /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_EMISSION "emission" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_EMISSIONIN "emissionIn"
-#define FLUID_NAME_DENSITY "density"
-#define FLUID_NAME_DENSITYIN "densityIn"
+#define FLUID_NAME_DENSITY "density"          /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_DENSITYIN "density_inflow" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_HEAT "heat"
 #define FLUID_NAME_HEATIN "heatIn"
-#define FLUID_NAME_COLORR "color_r"
-#define FLUID_NAME_COLORG "color_g"
-#define FLUID_NAME_COLORB "color_b"
-#define FLUID_NAME_COLORRIN "color_r_in"
-#define FLUID_NAME_COLORGIN "color_g_in"
-#define FLUID_NAME_COLORBIN "color_b_in"
-#define FLUID_NAME_FLAME "flame"
-#define FLUID_NAME_FUEL "fuel"
-#define FLUID_NAME_REACT "react"
-#define FLUID_NAME_FUELIN "fuelIn"
-#define FLUID_NAME_REACTIN "reactIn"
+#define FLUID_NAME_TEMPERATURE "temperature"          /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_TEMPERATUREIN "temperature_inflow" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORR "color_r"                   /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORG "color_g"                   /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORB "color_b"                   /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORRIN "color_r_inflow"          /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORGIN "color_g_inflow"          /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORBIN "color_b_inflow"          /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_FLAME "flame"                      /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_FUEL "fuel"                        /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_REACT "react"                      /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_FUELIN "fuel_inflow"               /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_REACTIN "react_inflow"             /* == OpenVDB grid attribute name. */
 
 /* Liquid object names. */
-#define FLUID_NAME_PHIPARTS "phiParts"
-#define FLUID_NAME_PHI "phi"
-#define FLUID_NAME_PHITMP "phiTmp"
+#define FLUID_NAME_PHIPARTS "phi_particles" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PHI "phi"                /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PHITMP "phi_previous"    /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_VELOCITYOLD "velOld"
 #define FLUID_NAME_VELOCITYPARTS "velParts"
 #define FLUID_NAME_MAPWEIGHTS "mapWeights"
 #define FLUID_NAME_PP "pp"
 #define FLUID_NAME_PVEL "pVel"
+#define FLUID_NAME_PARTS "particles"                  /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PARTSVELOCITY "particles_velocity" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_PINDEX "pindex"
 #define FLUID_NAME_GPI "gpi"
 #define FLUID_NAME_CURVATURE "gpi"
 
 /* Noise object names. */
 #define FLUID_NAME_VELOCITY_NOISE "velocity_noise"
-#define FLUID_NAME_DENSITY_NOISE "density_noise"
+#define FLUID_NAME_DENSITY_NOISE "density_noise" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_PHIIN_NOISE "phiIn_noise"
 #define FLUID_NAME_PHIOUT_NOISE "phiOut_noise"
 #define FLUID_NAME_PHIOBS_NOISE "phiObs_noise"
@@ -306,11 +312,11 @@ enum {
 #define FLUID_NAME_TEXTURE_U2 "textureU2"
 #define FLUID_NAME_TEXTURE_V2 "textureV2"
 #define FLUID_NAME_TEXTURE_W2 "textureW2"
-#define FLUID_NAME_UV0 "uvGrid0"
-#define FLUID_NAME_UV1 "uvGrid1"
-#define FLUID_NAME_COLORR_NOISE "color_r_noise"
-#define FLUID_NAME_COLORG_NOISE "color_g_noise"
-#define FLUID_NAME_COLORB_NOISE "color_b_noise"
+#define FLUID_NAME_UV0 "uv_grid_0"              /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_UV1 "uv_grid_1"              /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORR_NOISE "color_r_noise" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORG_NOISE "color_g_noise" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_COLORB_NOISE "color_b_noise" /* == OpenVDB grid attribute name. */
 #define FLUID_NAME_FLAME_NOISE "flame_noise"
 #define FLUID_NAME_FUEL_NOISE "fuel_noise"
 #define FLUID_NAME_REACT_NOISE "react_noise"
@@ -321,7 +327,8 @@ enum {
 #define FLUID_NAME_PP_MESH "pp_mesh"
 #define FLUID_NAME_FLAGS_MESH "flags_mesh"
 #define FLUID_NAME_LMESH "lMesh"
-#define FLUID_NAME_VELOCITYVEC_MESH "lVelMesh"
+#define FLUID_NAME_VELOCITYVEC_MESH "vertex_velocities_mesh" /* == OpenVDB grid attribute name. \
+                                                              */
 #define FLUID_NAME_VELOCITY_MESH "velocity_mesh"
 #define FLUID_NAME_PINDEX_MESH "pindex_mesh"
 #define FLUID_NAME_GPI_MESH "gpi_mesh"
@@ -329,18 +336,27 @@ enum {
 /* Particles object names. */
 #define FLUID_NAME_PP_PARTICLES "ppSnd"
 #define FLUID_NAME_PVEL_PARTICLES "pVelSnd"
-#define FLUID_NAME_PFORCE_PARTICLES "pForceSnd"
 #define FLUID_NAME_PLIFE_PARTICLES "pLifeSnd"
-#define FLUID_NAME_VELOCITY_PARTICLES "velocity_particles"
-#define FLUID_NAME_FLAGS_PARTICLES "flags_particles"
-#define FLUID_NAME_PHI_PARTICLES "phi_particles"
-#define FLUID_NAME_PHIOBS_PARTICLES "phiObs_particles"
-#define FLUID_NAME_PHIOUT_PARTICLES "phiOut_particles"
-#define FLUID_NAME_NORMAL_PARTICLES "normal_particles"
-#define FLUID_NAME_NEIGHBORRATIO_PARTICLES "neighborRatio_particles"
-#define FLUID_NAME_TRAPPEDAIR_PARTICLES "trappedAir_particles"
-#define FLUID_NAME_WAVECREST_PARTICLES "waveCrest_particles"
-#define FLUID_NAME_KINETICENERGY_PARTICLES "kineticEnergy_particles"
+#define FLUID_NAME_PFORCE_PARTICLES "pForceSnd"
+#define FLUID_NAME_PARTS_PARTICLES "particles_secondary" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PARTSVEL_PARTICLES \
+  "particles_velocity_secondary" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PARTSLIFE_PARTICLES \
+  "particles_life_secondary" /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_PARTSFORCE_PARTICLES "particles_force_secondary"
+#define FLUID_NAME_VELOCITY_PARTICLES "velocity_secondary"
+#define FLUID_NAME_FLAGS_PARTICLES "flags_secondary"
+#define FLUID_NAME_PHI_PARTICLES "phi_secondary"
+#define FLUID_NAME_PHIOBS_PARTICLES "phiObs_secondary"
+#define FLUID_NAME_PHIOUT_PARTICLES "phiOut_secondary"
+#define FLUID_NAME_NORMAL_PARTICLES "normal_secondary"
+#define FLUID_NAME_NEIGHBORRATIO_PARTICLES "neighbor_ratio_secondary"
+#define FLUID_NAME_TRAPPEDAIR_PARTICLES \
+  "trapped_air_secondary"                                     /* == OpenVDB grid attribute name. */
+#define FLUID_NAME_WAVECREST_PARTICLES "wave_crest_secondary" /* == OpenVDB grid attribute name. \
+                                                               */
+#define FLUID_NAME_KINETICENERGY_PARTICLES \
+  "kinetic_energy_secondary" /* == OpenVDB grid attribute name. */
 
 /* Guiding object names. */
 #define FLUID_NAME_VELT "velT"
@@ -349,9 +365,9 @@ enum {
 #define FLUID_NAME_PHIGUIDEIN "phiGuideIn"
 #define FLUID_NAME_GUIDEVELC "guidevelC"
 #define FLUID_NAME_GUIDEVEL_X "x_guidevel"
-#define FLUID_NAME_GUIDEVEL_Y "Y_guidevel"
+#define FLUID_NAME_GUIDEVEL_Y "y_guidevel"
 #define FLUID_NAME_GUIDEVEL_Z "z_guidevel"
-#define FLUID_NAME_GUIDEVEL "guidevel"
+#define FLUID_NAME_GUIDEVEL "velocity_guide"
 
 /* Cache file extensions. */
 #define FLUID_DOMAIN_EXTENSION_UNI ".uni"
@@ -374,7 +390,18 @@ enum {
 enum {
   FLUID_DOMAIN_CACHE_REPLAY = 0,
   FLUID_DOMAIN_CACHE_MODULAR = 1,
-  FLUID_DOMAIN_CACHE_FINAL = 2,
+  FLUID_DOMAIN_CACHE_ALL = 2,
+};
+
+enum {
+  VDB_COMPRESSION_BLOSC = 0,
+  VDB_COMPRESSION_ZIP = 1,
+  VDB_COMPRESSION_NONE = 2,
+};
+
+enum {
+  VDB_PRECISION_HALF_FLOAT = 0,
+  VDB_PRECISION_FULL_FLOAT = 1,
 };
 
 /* Deprecated values (i.e. all defines and enums below this line up until typedefs). */
@@ -391,12 +418,6 @@ enum {
   SM_HRES_FULLSAMPLE = 2,
 };
 
-enum {
-  VDB_COMPRESSION_BLOSC = 0,
-  VDB_COMPRESSION_ZIP = 1,
-  VDB_COMPRESSION_NONE = 2,
-};
-
 typedef struct FluidDomainVertexVelocity {
   float vel[3];
 } FluidDomainVertexVelocity;
@@ -566,7 +587,8 @@ typedef struct FluidDomainSettings {
   char cache_directory[1024];
   char error[64]; /* Bake error description. */
   short cache_type;
-  char _pad8[2]; /* Unused. */
+  char cache_id[4]; /* Run-time only */
+  char _pad8[6];
 
   /* Time options. */
   float dt;
@@ -591,17 +613,17 @@ typedef struct FluidDomainSettings {
   char coba_field; /* Simulation field used for the color mapping. */
   char interp_method;
 
+  /* OpenVDB cache options. */
+  int openvdb_compression;
+  float clipping;
+  char openvdb_data_depth;
+  char _pad9[7]; /* Unused. */
+
   /* -- Deprecated / unsed options (below). -- */
 
   /* View options. */
   int viewsettings;
-  char _pad9[4]; /* Unused. */
-
-  /* OpenVDB cache options. */
-  int openvdb_comp;
-  float clipping;
-  char data_depth;
-  char _pad10[7]; /* Unused. */
+  char _pad10[4]; /* Unused. */
 
   /* Pointcache options. */
   /* Smoke uses only one cache from now on (index [0]), but keeping the array for now for reading
index 94ba09b2bb844c99d4ffefcf9d2c61168e66bec4..b4fa791362f2f9271ee3a1d82e44c74ab8d82819 100644 (file)
@@ -557,7 +557,7 @@ static const EnumPropertyItem *rna_Fluid_cachetype_mesh_itemf(bContext *UNUSED(C
 }
 
 static const EnumPropertyItem *rna_Fluid_cachetype_volume_itemf(bContext *UNUSED(C),
-                                                                PointerRNA *UNUSED(ptr),
+                                                                PointerRNA *ptr,
                                                                 PropertyRNA *UNUSED(prop),
                                                                 bool *r_free)
 {
@@ -579,11 +579,16 @@ static const EnumPropertyItem *rna_Fluid_cachetype_volume_itemf(bContext *UNUSED
   RNA_enum_item_add(&item, &totitem, &tmp);
 #  endif
 
-  tmp.value = FLUID_DOMAIN_FILE_RAW;
-  tmp.identifier = "RAW";
-  tmp.name = "Raw Cache";
-  tmp.description = "Raw file format (.raw)";
-  RNA_enum_item_add(&item, &totitem, &tmp);
+  /* Support for deprecated .raw format. */
+  FluidDomainSettings *mds = (FluidDomainSettings *)ptr->data;
+  if (mds->cache_data_format == FLUID_DOMAIN_FILE_RAW ||
+      mds->cache_noise_format == FLUID_DOMAIN_FILE_RAW) {
+    tmp.value = FLUID_DOMAIN_FILE_RAW;
+    tmp.identifier = "RAW";
+    tmp.name = "Raw Cache";
+    tmp.description = "Raw file format (.raw)";
+    RNA_enum_item_add(&item, &totitem, &tmp);
+  }
 
   RNA_enum_item_end(&item, &totitem);
   *r_free = true;
@@ -1058,27 +1063,18 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
   };
 
   static EnumPropertyItem cache_types[] = {
-      {FLUID_DOMAIN_CACHE_REPLAY,
-       "REPLAY",
-       0,
-       "Replay",
-       "Use the timeline to bake the scene. Pausing and resuming possible"},
+      {FLUID_DOMAIN_CACHE_REPLAY, "REPLAY", 0, "Replay", "Use the timeline to bake the scene"},
       {FLUID_DOMAIN_CACHE_MODULAR,
        "MODULAR",
        0,
        "Modular",
-       "Bake every stage of the simulation separately. Pausing and resuming possible"},
-      {FLUID_DOMAIN_CACHE_FINAL,
-       "FINAL",
-       0,
-       "Final",
-       "Bake the entire simulation at once. Only generates the most essential cache files. "
-       "Pausing and resuming not possible"},
+       "Bake every stage of the simulation separately"},
+      {FLUID_DOMAIN_CACHE_ALL, "ALL", 0, "All", "Bake all simulation settings at once"},
       {0, NULL, 0, NULL, NULL}};
 
-  static const EnumPropertyItem smoke_data_depth_items[] = {
-      {16, "16", 0, "Float (Half)", "Half float (16 bit data)"},
-      {0, "32", 0, "Float (Full)", "Full float (32 bit data)"}, /* default */
+  static const EnumPropertyItem fluid_data_depth_items[] = {
+      {VDB_PRECISION_HALF_FLOAT, "16", 0, "Half", "Half float (16 bit data)"},
+      {VDB_PRECISION_FULL_FLOAT, "32", 0, "Full", "Full float (32 bit data)"},
       {0, NULL, 0, NULL, NULL},
   };
 
@@ -2072,6 +2068,16 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Type", "Change the cache type of the simulation");
   RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_domain_reset");
 
+  prop = RNA_def_property(srna, "cache_resumable", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_USE_RESUMABLE_CACHE);
+  RNA_def_property_ui_text(
+      prop,
+      "Resumable",
+      "Additional data will be saved so that the bake jobs can be resumed after pausing. Because "
+      "more data will be written to disk it is recommended to avoid enabling this option when "
+      "baking at high resolutions");
+  RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
+
   prop = RNA_def_property(srna, "cache_directory", PROP_STRING, PROP_DIRPATH);
   RNA_def_property_string_maxlength(prop, FILE_MAX);
   RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Fluid_cache_directory_set");
@@ -2320,13 +2326,13 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
   /* OpenVDB options */
 
   prop = RNA_def_property(srna, "openvdb_cache_compress_type", PROP_ENUM, PROP_NONE);
-  RNA_def_property_enum_sdna(prop, NULL, "openvdb_comp");
+  RNA_def_property_enum_sdna(prop, NULL, "openvdb_compression");
   RNA_def_property_enum_items(prop, prop_compression_items);
-  RNA_def_property_ui_text(prop, "Compression", "Compression method to be used");
+  RNA_def_property_ui_text(prop, "Compression", "facession method to be used");
 
-  prop = RNA_def_property(srna, "data_depth", PROP_ENUM, PROP_NONE);
-  RNA_def_property_enum_bitflag_sdna(prop, NULL, "data_depth");
-  RNA_def_property_enum_items(prop, smoke_data_depth_items);
+  prop = RNA_def_property(srna, "openvdb_data_depth", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_bitflag_sdna(prop, NULL, "openvdb_data_depth");
+  RNA_def_property_enum_items(prop, fluid_data_depth_items);
   RNA_def_property_ui_text(prop,
                            "Data Depth",
                            "Bit depth for writing all scalar (including vector) "