diff options
-rw-r--r-- | intern/mantaflow/extern/manta_fluid_API.h | 3 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.cpp | 191 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.h | 17 | ||||
-rw-r--r-- | intern/mantaflow/intern/manta_fluid_API.cpp | 13 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/fluid_script.h | 111 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/liquid_script.h | 76 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/smoke_script.h | 75 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_physics_fluid.py | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluid.c | 72 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_fluid.c | 11 |
10 files changed, 336 insertions, 241 deletions
diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h index 691a98f9063..8dc2cf1805a 100644 --- a/intern/mantaflow/extern/manta_fluid_API.h +++ b/intern/mantaflow/extern/manta_fluid_API.h @@ -218,6 +218,9 @@ float manta_liquid_get_snd_particle_position_z_at(struct MANTA *liquid, int i); float manta_liquid_get_snd_particle_velocity_x_at(struct MANTA *liquid, int i); float manta_liquid_get_snd_particle_velocity_y_at(struct MANTA *liquid, int i); float manta_liquid_get_snd_particle_velocity_z_at(struct MANTA *liquid, int i); +bool manta_liquid_flip_from_file(struct MANTA *liquid); +bool manta_liquid_mesh_from_file(struct MANTA *liquid); +bool manta_liquid_particle_from_file(struct MANTA *liquid); #ifdef __cplusplus } diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index e44498bff84..0e0a0ddf021 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -160,6 +160,11 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) mSndParticleVelocity = NULL; mSndParticleLife = NULL; + // Cache read success indicators + mFlipFromFile = false; + mMeshFromFile = false; + mParticlesFromFile = false; + // Only start Mantaflow once. No need to start whenever new FLUID objected is allocated if (!mantaInitialized) initializeMantaflow(); @@ -376,8 +381,7 @@ void MANTA::initLiquid(FluidModifierData *mmd) if (!mPhiIn) { std::vector<std::string> pythonCommands; std::string tmpString = liquid_variables + liquid_alloc + liquid_init_phi + liquid_save_data + - liquid_save_flip + liquid_load_data + liquid_load_flip + - liquid_adaptive_step + liquid_step; + liquid_load_data + liquid_adaptive_step + liquid_step; std::string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); @@ -389,8 +393,7 @@ void MANTA::initLiquid(FluidModifierData *mmd) void MANTA::initMesh(FluidModifierData *mmd) { std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh + - liquid_load_meshvel; + std::string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh; std::string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); @@ -401,8 +404,7 @@ void MANTA::initMesh(FluidModifierData *mmd) void MANTA::initLiquidMesh(FluidModifierData *mmd) { std::vector<std::string> pythonCommands; - std::string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh + - liquid_save_meshvel; + std::string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh; std::string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); @@ -477,8 +479,7 @@ void MANTA::initOutflow(FluidModifierData *mmd) void MANTA::initSndParts(FluidModifierData *mmd) { std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_particles + fluid_solver_particles + - fluid_load_particles + fluid_save_particles; + std::string tmpString = fluid_variables_particles + fluid_solver_particles; std::string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); @@ -489,9 +490,9 @@ void MANTA::initLiquidSndParts(FluidModifierData *mmd) { if (!mSndParticleData) { std::vector<std::string> pythonCommands; - std::string tmpString = fluid_alloc_sndparts + liquid_alloc_particles + - liquid_variables_particles + liquid_step_particles + - fluid_with_sndparts + liquid_load_particles + liquid_save_particles; + std::string tmpString = liquid_alloc_particles + liquid_variables_particles + + liquid_step_particles + fluid_with_sndparts + liquid_load_particles + + liquid_save_particles; std::string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); @@ -1008,6 +1009,8 @@ int MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) if (MANTA::with_debug) std::cout << "MANTA::updateFlipStructures()" << std::endl; + mFlipFromFile = false; + // Ensure empty data structures at start if (mFlipParticleData) mFlipParticleData->clear(); @@ -1046,6 +1049,7 @@ int MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) if (BLI_exists(targetFile)) { updateParticlesFromFile(targetFile, false, true); } + mFlipFromFile = true; return 1; } @@ -1054,6 +1058,8 @@ int MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) if (MANTA::with_debug) std::cout << "MANTA::updateMeshStructures()" << std::endl; + mMeshFromFile = false; + if (!mUsingMesh) return 0; if (BLI_path_is_rel(mmd->domain->cache_directory)) @@ -1095,6 +1101,7 @@ int MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) updateMeshFromFile(targetFile); } } + mMeshFromFile = true; return 1; } @@ -1103,6 +1110,8 @@ int MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) if (MANTA::with_debug) std::cout << "MANTA::updateParticleStructures()" << std::endl; + mParticlesFromFile = false; + if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) return 0; if (BLI_path_is_rel(mmd->domain->cache_directory)) @@ -1150,6 +1159,7 @@ int MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) if (BLI_exists(targetFile)) { updateParticlesFromFile(targetFile, true, false); } + mParticlesFromFile = true; return 1; } @@ -1229,6 +1239,9 @@ int MANTA::writeData(FluidModifierData *mmd, int framenr) std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirData, sizeof(cacheDirData), mmd->domain->cache_directory, @@ -1238,23 +1251,19 @@ int MANTA::writeData(FluidModifierData *mmd, int framenr) ss.str(""); ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " << framenr - << ", '" << dformat << "')"; + << ", '" << dformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); if (mUsingSmoke) { ss.str(""); ss << "smoke_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; + << framenr << ", '" << dformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); } if (mUsingLiquid) { ss.str(""); ss << "liquid_save_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; - pythonCommands.push_back(ss.str()); - ss.str(""); - ss << "liquid_save_flip_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << pformat << "')"; + << framenr << ", '" << dformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); } runPythonString(pythonCommands); @@ -1329,6 +1338,9 @@ int MANTA::readData(FluidModifierData *mmd, int framenr) std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirData, sizeof(cacheDirData), mmd->domain->cache_directory, @@ -1336,44 +1348,30 @@ int MANTA::readData(FluidModifierData *mmd, int framenr) NULL); BLI_path_make_safe(cacheDirData); - if (mUsingSmoke) { - /* Exit early if there is nothing present in the cache for this frame */ - ss.str(""); - ss << "density_####" << dformat; - BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str()); - BLI_path_frame(targetFile, framenr, 0); - if (!BLI_exists(targetFile)) - return 0; + /* Exit early if there is nothing present in the cache for this frame */ + ss.str(""); + ss << "vel_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) + return 0; - ss.str(""); - ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; - pythonCommands.push_back(ss.str()); + ss.str(""); + ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " << framenr + << ", '" << dformat << "', " << resumable_cache << ")"; + pythonCommands.push_back(ss.str()); + + if (mUsingSmoke) { ss.str(""); ss << "smoke_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; + << framenr << ", '" << dformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); } if (mUsingLiquid) { /* Exit early if there is nothing present in the cache for this frame */ ss.str(""); - ss << "phiIn_####" << dformat; - BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str()); - BLI_path_frame(targetFile, framenr, 0); - if (!BLI_exists(targetFile)) - return 0; - - ss.str(""); - ss << "fluid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; - pythonCommands.push_back(ss.str()); - ss.str(""); ss << "liquid_load_data_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << dformat << "')"; - pythonCommands.push_back(ss.str()); - ss.str(""); - ss << "liquid_load_flip_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', " - << framenr << ", '" << pformat << "')"; + << framenr << ", '" << dformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); } runPythonString(pythonCommands); @@ -1385,7 +1383,7 @@ int MANTA::readNoise(FluidModifierData *mmd, int framenr) if (with_debug) std::cout << "MANTA::readNoise()" << std::endl; - if (!mUsingNoise) + if (!mUsingSmoke || !mUsingNoise) return 0; std::ostringstream ss; @@ -1397,6 +1395,9 @@ int MANTA::readNoise(FluidModifierData *mmd, int framenr) std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirNoise, sizeof(cacheDirNoise), mmd->domain->cache_directory, @@ -1412,22 +1413,24 @@ int MANTA::readNoise(FluidModifierData *mmd, int framenr) if (!BLI_exists(targetFile)) return 0; - if (mUsingSmoke && mUsingNoise) { - ss.str(""); - ss << "smoke_load_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirNoise) << "', " - << framenr << ", '" << nformat << "')"; - pythonCommands.push_back(ss.str()); - } + ss.str(""); + ss << "smoke_load_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirNoise) << "', " + << framenr << ", '" << nformat << "', " << resumable_cache << ")"; + pythonCommands.push_back(ss.str()); + runPythonString(pythonCommands); return 1; } +/* Deprecated! This function read mesh data via the Manta Python API. + * MANTA:updateMeshStructures() reads cache files directly from disk + * and is preferred due to its better performance. */ int MANTA::readMesh(FluidModifierData *mmd, int framenr) { if (with_debug) std::cout << "MANTA::readMesh()" << std::endl; - if (!mUsingMesh) + if (!mUsingLiquid || !mUsingMesh) return 0; std::ostringstream ss; @@ -1447,36 +1450,40 @@ int MANTA::readMesh(FluidModifierData *mmd, int framenr) NULL); BLI_path_make_safe(cacheDirMesh); - if (mUsingLiquid) { - /* Exit early if there is nothing present in the cache for this frame */ - ss.str(""); - ss << "lMesh_####" << mformat; - BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirMesh, ss.str().c_str()); - BLI_path_frame(targetFile, framenr, 0); - if (!BLI_exists(targetFile)) - return 0; + /* Exit early if there is nothing present in the cache for this frame */ + ss.str(""); + ss << "lMesh_####" << mformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirMesh, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) + return 0; + ss.str(""); + ss << "liquid_load_mesh_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " + << framenr << ", '" << mformat << "')"; + pythonCommands.push_back(ss.str()); + + if (mUsingMVel) { ss.str(""); - ss << "liquid_load_mesh_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " - << framenr << ", '" << mformat << "')"; + ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " + << framenr << ", '" << dformat << "')"; pythonCommands.push_back(ss.str()); - - if (mUsingMVel) { - ss.str(""); - ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapeSlashes(cacheDirMesh) << "', " - << framenr << ", '" << dformat << "')"; - pythonCommands.push_back(ss.str()); - } } + runPythonString(pythonCommands); return 1; } +/* 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. */ int MANTA::readParticles(FluidModifierData *mmd, int framenr) { if (with_debug) std::cout << "MANTA::readParticles()" << std::endl; + if (!mUsingLiquid) + return 0; if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) return 0; @@ -1489,6 +1496,9 @@ int MANTA::readParticles(FluidModifierData *mmd, int framenr) std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirParticles, sizeof(cacheDirParticles), mmd->domain->cache_directory, @@ -1504,16 +1514,11 @@ int MANTA::readParticles(FluidModifierData *mmd, int framenr) if (!BLI_exists(targetFile)) return 0; - if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) { - ss.str(""); - ss << "fluid_load_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirParticles) - << "', " << framenr << ", '" << pformat << "')"; - pythonCommands.push_back(ss.str()); - ss.str(""); - ss << "liquid_load_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirParticles) - << "', " << framenr << ", '" << pformat << "')"; - pythonCommands.push_back(ss.str()); - } + ss.str(""); + ss << "liquid_load_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirParticles) << "', " + << framenr << ", '" << pformat << "', " << resumable_cache << ")"; + pythonCommands.push_back(ss.str()); + runPythonString(pythonCommands); return 1; } @@ -1544,7 +1549,7 @@ int MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain) /* Exit early if there is nothing present in the cache for this frame */ ss.str(""); - ss << "guidevel_####" << gformat; + ss << (sourceDomain ? "vel_####" : "guidevel_####") << gformat; BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirGuiding, ss.str().c_str()); BLI_path_frame(targetFile, framenr, 0); if (!BLI_exists(targetFile)) @@ -1621,6 +1626,9 @@ int MANTA::bakeNoise(FluidModifierData *mmd, int framenr) std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirData, sizeof(cacheDirData), mmd->domain->cache_directory, @@ -1637,7 +1645,7 @@ int MANTA::bakeNoise(FluidModifierData *mmd, int framenr) ss.str(""); ss << "bake_noise_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '" << escapeSlashes(cacheDirNoise) << "', " << framenr << ", '" << dformat << "', '" << nformat - << "')"; + << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); runPythonString(pythonCommands); @@ -1698,6 +1706,9 @@ int MANTA::bakeParticles(FluidModifierData *mmd, int framenr) std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); + std::string resumable_cache = (final_cache) ? "False" : "True"; + BLI_path_join(cacheDirData, sizeof(cacheDirData), mmd->domain->cache_directory, @@ -1714,7 +1725,7 @@ int MANTA::bakeParticles(FluidModifierData *mmd, int framenr) ss.str(""); ss << "bake_particles_" << mCurrentID << "('" << escapeSlashes(cacheDirData) << "', '" << escapeSlashes(cacheDirParticles) << "', " << framenr << ", '" << dformat << "', '" - << pformat << "')"; + << pformat << "', " << resumable_cache << ")"; pythonCommands.push_back(ss.str()); runPythonString(pythonCommands); @@ -1937,7 +1948,7 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) if (mesh) manta_script += liquid_alloc_mesh; if (drops || bubble || floater || tracer) - manta_script += fluid_alloc_sndparts + liquid_alloc_particles; + manta_script += liquid_alloc_particles; if (guiding) manta_script += fluid_alloc_guiding; if (obstacle) @@ -1953,11 +1964,11 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) // Import manta_script += header_import + fluid_file_import + fluid_cache_helper + fluid_load_data + - liquid_load_data + liquid_load_flip; + liquid_load_data; if (mesh) manta_script += liquid_load_mesh; if (drops || bubble || floater || tracer) - manta_script += fluid_load_particles + liquid_load_particles; + manta_script += liquid_load_particles; if (guiding) manta_script += fluid_load_guiding; @@ -2668,4 +2679,8 @@ void MANTA::updatePointers() setPointers(mantaNodeObjects); setPointers(mantaTriangleObjects); setPointers(mantaFloatVecObjects); + + mFlipFromFile = true; + mMeshFromFile = false; + mParticlesFromFile = false; } diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index d45f30c9acf..d9b4f6789fd 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -692,6 +692,19 @@ struct MANTA { return (mSndParticleData && !mSndParticleData->empty()) ? mSndParticleData->size() : 0; } + inline bool usingFlipFromFile() + { + return mFlipFromFile; + } + inline bool usingMeshFromFile() + { + return mMeshFromFile; + } + inline bool usingParticleFromFile() + { + return mParticlesFromFile; + } + // Direct access to solver time attributes int getFrame(); float getTimestep(); @@ -726,6 +739,10 @@ struct MANTA { bool mUsingFloats; bool mUsingTracers; + bool mFlipFromFile; + bool mMeshFromFile; + bool mParticlesFromFile; + int mResX; int mResY; int mResZ; diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp index 4c9b5a93fc3..61dff91cd35 100644 --- a/intern/mantaflow/intern/manta_fluid_API.cpp +++ b/intern/mantaflow/intern/manta_fluid_API.cpp @@ -864,3 +864,16 @@ float manta_liquid_get_snd_particle_velocity_z_at(MANTA *liquid, int i) { return liquid->getSndParticleVelocityZAt(i); } + +bool manta_liquid_flip_from_file(MANTA *liquid) +{ + return liquid->usingFlipFromFile(); +} +bool manta_liquid_mesh_from_file(MANTA *liquid) +{ + return liquid->usingMeshFromFile(); +} +bool manta_liquid_particle_from_file(MANTA *liquid) +{ + return liquid->usingParticleFromFile(); +} diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index b7d3a5a195e..436bc037a92 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -238,7 +238,8 @@ z_force_s$ID$ = s$ID$.create(RealGrid)\n\ obvel_s$ID$ = None\n\ \n\ # Keep track of important objects in dict to load them later on\n\ -fluid_data_dict_s$ID$ = dict(vel=vel_s$ID$, phiObs=phiObs_s$ID$, phiIn=phiIn_s$ID$, phiOut=phiOut_s$ID$, flags=flags_s$ID$)\n"; +fluid_data_dict_final_s$ID$ = dict(vel=vel_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"; const std::string fluid_alloc_obstacle = "\n\ @@ -251,8 +252,8 @@ x_obvel_s$ID$ = s$ID$.create(RealGrid)\n\ y_obvel_s$ID$ = s$ID$.create(RealGrid)\n\ z_obvel_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ -tmpDict_s$ID$ = dict(phiObsIn=phiObsIn_s$ID$)\n\ -fluid_data_dict_s$ID$.update(tmpDict_s$ID$)\n"; +if 'fluid_data_dict_resume_s$ID$' in globals():\n\ + fluid_data_dict_resume_s$ID$.update(phiObsIn=phiObsIn_s$ID$)\n"; const std::string fluid_alloc_guiding = "\n\ @@ -291,23 +292,6 @@ const std::string fluid_alloc_outflow = mantaMsg('Allocating outflow data')\n\ phiOutIn_s$ID$ = s$ID$.create(LevelsetGrid)\n"; -const std::string fluid_alloc_sndparts = - "\n\ -mantaMsg('Allocating snd parts low')\n\ -ppSnd_sp$ID$ = sp$ID$.create(BasicParticleSystem)\n\ -pVelSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\ -pForceSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\ -pLifeSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataReal)\n\ -vel_sp$ID$ = sp$ID$.create(MACGrid)\n\ -flags_sp$ID$ = sp$ID$.create(FlagGrid)\n\ -phi_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ -phiIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ -phiObs_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ -phiObsIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ -\n\ -# Keep track of important objects in dict to load them later on\n\ -fluid_particles_dict_s$ID$ = dict(ppSnd=ppSnd_sp$ID$, pVelSnd=pVelSnd_pp$ID$, pLifeSnd=pLifeSnd_pp$ID$)\n"; - ////////////////////////////////////////////////////////////////////// // PRE / POST STEP ////////////////////////////////////////////////////////////////////// @@ -392,16 +376,21 @@ const std::string fluid_delete_all = mantaMsg('Deleting fluid')\n\ # Clear all helper dictionaries first\n\ mantaMsg('Clear helper dictionaries')\n\ -if 'liquid_data_dict_s$ID$' in globals(): liquid_data_dict_s$ID$.clear()\n\ -if 'liquid_flip_dict_s$ID$' in globals(): liquid_flip_dict_s$ID$.clear()\n\ +if 'liquid_data_dict_final_s$ID$' in globals(): liquid_data_dict_final_s$ID$.clear()\n\ +if 'liquid_data_dict_resume_s$ID$' in globals(): liquid_data_dict_resume_s$ID$.clear()\n\ if 'liquid_mesh_dict_s$ID$' in globals(): liquid_mesh_dict_s$ID$.clear()\n\ if 'liquid_meshvel_dict_s$ID$' in globals(): liquid_meshvel_dict_s$ID$.clear()\n\ -if 'liquid_particles_dict_s$ID$' in globals(): liquid_particles_dict_s$ID$.clear()\n\ -if 'smoke_data_dict_s$ID$' in globals(): smoke_data_dict_s$ID$.clear()\n\ -if 'smoke_noise_dict_s$ID$' in globals(): smoke_noise_dict_s$ID$.clear()\n\ -if 'fluid_particles_dict_s$ID$' in globals(): fluid_particles_dict_s$ID$.clear()\n\ +if 'liquid_particles_final_dict_s$ID$' in globals(): liquid_particles_final_dict_s$ID$.clear()\n\ +if 'liquid_particles_resume_dict_s$ID$' in globals(): liquid_particles_resume_dict_s$ID$.clear()\n\ +\n\ +if 'smoke_data_dict_final_s$ID$' in globals(): smoke_data_dict_final_s$ID$.clear()\n\ +if 'smoke_data_dict_resume_s$ID$' in globals(): smoke_data_dict_resume_s$ID$.clear()\n\ +if 'smoke_noise_dict_final_s$ID$' in globals(): smoke_noise_dict_final_s$ID$.clear()\n\ +if 'smoke_noise_dict_resume_s$ID$' in globals(): smoke_noise_dict_resume_s$ID$.clear()\n\ +\n\ +if 'fluid_data_dict_final_s$ID$' in globals(): fluid_data_dict_final_s$ID$.clear()\n\ +if 'fluid_data_dict_resume_s$ID$' in globals(): fluid_data_dict_resume_s$ID$.clear()\n\ if 'fluid_guiding_dict_s$ID$' in globals(): fluid_guiding_dict_s$ID$.clear()\n\ -if 'fluid_data_dict_s$ID$' in globals(): fluid_data_dict_s$ID$.clear()\n\ if 'fluid_vel_dict_s$ID$' in globals(): fluid_vel_dict_s$ID$.clear()\n\ \n\ # Delete all childs from objects (e.g. pdata for particles)\n\ @@ -452,7 +441,7 @@ 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):\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\ mantaMsg('Multiprocessing cache')\n\ if __name__ == '__main__':\n\ args = (framenr,)\n\ @@ -478,6 +467,7 @@ def fluid_cache_multiprocessing_start_$ID$(function, framenr, format_data=None, args += (path_guiding,)\n\ if dict:\n\ args += (dict,)\n\ + args += (resumable,)\n\ p$ID$ = multiprocessing.Process(target=function, args=args)\n\ p$ID$.start()\n\ if do_join:\n\ @@ -506,7 +496,7 @@ def bake_fluid_data_$ID$(path_data, path_guiding, framenr, format_data, format_p const std::string fluid_bake_noise = "\n\ -def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise):\n\ +def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise, resumable):\n\ mantaMsg('Bake fluid noise')\n\ \n\ sn$ID$.frame = framenr\n\ @@ -515,13 +505,13 @@ def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_ mantaMsg('sn$ID$.timeTotal: ' + str(sn$ID$.timeTotal))\n\ \n\ smoke_step_noise_$ID$(framenr)\n\ - smoke_save_noise_$ID$(path_noise, framenr, format_noise)\n\ + smoke_save_noise_$ID$(path_noise, framenr, format_noise, resumable)\n\ \n\ -def bake_noise_$ID$(path_data, path_noise, framenr, format_data, format_noise):\n\ +def bake_noise_$ID$(path_data, path_noise, framenr, format_data, format_noise, resumable):\n\ if not withMPBake or isWindows:\n\ - bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise)\n\ + bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise, resumable)\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)\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"; const std::string fluid_bake_mesh = "\n\ @@ -548,27 +538,24 @@ def bake_mesh_$ID$(path_data, path_mesh, framenr, format_data, format_mesh, form const std::string fluid_bake_particles = "\n\ -def bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles):\n\ +def bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles, resumable):\n\ mantaMsg('Bake secondary particles')\n\ \n\ sp$ID$.frame = framenr\n\ sp$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\ sp$ID$.timestep = dt0_s$ID$\n\ \n\ - fluid_load_data_$ID$(path_data, framenr, format_data)\n\ #if using_smoke_s$ID$:\n\ # TODO (sebbas): Future update could include smoke particles (e.g. fire sparks)\n\ if using_liquid_s$ID$:\n\ - liquid_load_data_$ID$(path_data, framenr, format_data)\n\ liquid_step_particles_$ID$()\n\ - fluid_save_particles_$ID$(path_particles, framenr, format_particles)\n\ - liquid_save_particles_$ID$(path_particles, framenr, format_particles)\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):\n\ +def bake_particles_$ID$(path_data, path_particles, framenr, format_data, format_particles, resumable):\n\ if not withMPBake or isWindows:\n\ - bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles)\n\ + bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, 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)\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"; const std::string fluid_bake_guiding = "\n\ @@ -623,20 +610,17 @@ def fluid_file_import_s$ID$(dict, path, framenr, file_format):\n\ #mantaMsg(str(e))\n\ pass # Just skip file load errors for now\n"; -const std::string fluid_load_particles = - "\n\ -def fluid_load_particles_$ID$(path, framenr, file_format):\n\ - mantaMsg('Fluid load particles, frame ' + str(framenr))\n\ - fluid_file_import_s$ID$(dict=fluid_particles_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n"; - const std::string fluid_load_data = "\n\ -def fluid_load_data_$ID$(path, framenr, file_format):\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_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\ + fluid_file_import_s$ID$(dict=fluid_data_dict_final_s$ID$, path=path, framenr=framenr, file_format=file_format)\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 resumable:\n\ + fluid_file_import_s$ID$(dict=fluid_data_dict_resume_s$ID$, path=path, framenr=framenr, file_format=file_format)\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"; const std::string fluid_load_guiding = "\n\ @@ -648,8 +632,8 @@ 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 = dict(vel=guidevel_sg$ID$)\n\ - fluid_file_import_s$ID$(dict=fluid_vel_dict, path=path, framenr=framenr, file_format=file_format)\n"; + fluid_vel_dict_s$ID$ = dict(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"; ////////////////////////////////////////////////////////////////////// // EXPORT @@ -672,29 +656,24 @@ def fluid_file_export_s$ID$(framenr, file_format, path, dict, mode_override=True mantaMsg(str(e))\n\ pass # Just skip file save errors for now\n"; -const std::string fluid_save_particles = - "\n\ -def fluid_save_particles_$ID$(path, framenr, file_format):\n\ - mantaMsg('Liquid save particles, frame ' + str(framenr))\n\ - if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=fluid_particles_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\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_particles_dict_s$ID$, do_join=False)\n"; - const std::string fluid_save_data = "\n\ -def fluid_save_data_$ID$(path, framenr, file_format):\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_s$ID$)\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_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=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):\n\ +def fluid_save_guiding_$ID$(path, framenr, file_format, resumable):\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\ diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index fc516201e87..df0a5254fe2 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -94,8 +94,8 @@ pindex_s$ID$ = s$ID$.create(ParticleIndexSystem)\n\ gpi_s$ID$ = s$ID$.create(IntGrid)\n\ \n\ # Keep track of important objects in dict to load them later on\n\ -liquid_data_dict_s$ID$ = dict(phiParts=phiParts_s$ID$, phi=phi_s$ID$, phiTmp=phiTmp_s$ID$)\n\ -liquid_flip_dict_s$ID$ = dict(pp=pp_s$ID$, pVel=pVel_pp$ID$)\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"; const std::string liquid_alloc_mesh = "\n\ @@ -122,6 +122,16 @@ if using_speedvectors_s$ID$:\n\ const std::string liquid_alloc_particles = "\n\ +ppSnd_sp$ID$ = sp$ID$.create(BasicParticleSystem)\n\ +pVelSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\ +pForceSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\ +pLifeSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataReal)\n\ +vel_sp$ID$ = sp$ID$.create(MACGrid)\n\ +flags_sp$ID$ = sp$ID$.create(FlagGrid)\n\ +phi_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ +phiIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ +phiObs_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ +phiObsIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\ normal_sp$ID$ = sp$ID$.create(VecGrid)\n\ neighborRatio_sp$ID$ = sp$ID$.create(RealGrid)\n\ trappedAir_sp$ID$ = sp$ID$.create(RealGrid)\n\ @@ -129,7 +139,8 @@ waveCrest_sp$ID$ = sp$ID$.create(RealGrid)\n\ kineticEnergy_sp$ID$ = sp$ID$.create(RealGrid)\n\ \n\ # Keep track of important objects in dict to load them later on\n\ -liquid_particles_dict_s$ID$ = dict(trappedAir=trappedAir_sp$ID$, waveCrest=waveCrest_sp$ID$, kineticEnergy=kineticEnergy_sp$ID$)\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"; const std::string liquid_init_phi = "\n\ @@ -350,33 +361,29 @@ def liquid_step_particles_$ID$():\n\ const std::string liquid_load_data = "\n\ -def liquid_load_data_$ID$(path, framenr, file_format):\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_s$ID$, path=path, framenr=framenr, file_format=file_format)\n"; - -const std::string liquid_load_flip = - "\n\ -def liquid_load_flip_$ID$(path, framenr, file_format):\n\ - mantaMsg('Liquid load flip')\n\ - fluid_file_import_s$ID$(dict=liquid_flip_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\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"; 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"; - -const std::string liquid_load_meshvel = - "\n\ + fluid_file_import_s$ID$(dict=liquid_mesh_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\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"; const std::string liquid_load_particles = "\n\ -def liquid_load_particles_$ID$(path, framenr, file_format):\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_s$ID$, path=path, framenr=framenr, file_format=file_format)\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"; ////////////////////////////////////////////////////////////////////// // EXPORT @@ -384,21 +391,16 @@ def liquid_load_particles_$ID$(path, framenr, file_format):\n\ const std::string liquid_save_data = "\n\ -def liquid_save_data_$ID$(path, framenr, file_format):\n\ +def liquid_save_data_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Liquid save data')\n\ if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=liquid_data_dict_s$ID$, 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_data_dict_s$ID$, do_join=False)\n"; - -const std::string liquid_save_flip = - "\n\ -def liquid_save_flip_$ID$(path, framenr, file_format):\n\ - mantaMsg('Liquid save flip')\n\ - if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=liquid_flip_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\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\ else:\n\ - fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_flip_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=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"; const std::string liquid_save_mesh = "\n\ @@ -407,10 +409,8 @@ def liquid_save_mesh_$ID$(path, framenr, file_format):\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\ 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"; - -const std::string liquid_save_meshvel = - "\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\ +\n\ def liquid_save_meshvel_$ID$(path, framenr, file_format):\n\ mantaMsg('Liquid save mesh vel')\n\ if not withMPSave or isWindows:\n\ @@ -420,12 +420,16 @@ def liquid_save_meshvel_$ID$(path, framenr, file_format):\n\ const std::string liquid_save_particles = "\n\ -def liquid_save_particles_$ID$(path, framenr, file_format):\n\ +def liquid_save_particles_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Liquid save particles')\n\ if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=liquid_particles_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\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\ 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_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=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"; ////////////////////////////////////////////////////////////////////// // STANDALONE MODE diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h index 3445bd56481..d8c81ebf66a 100644 --- a/intern/mantaflow/intern/strings/smoke_script.h +++ b/intern/mantaflow/intern/strings/smoke_script.h @@ -100,7 +100,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_s$ID$ = dict(density=density_s$ID$, shadow=shadow_s$ID$, densityIn=densityIn_s$ID$, emissionIn=emissionIn_s$ID$)\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$, emissionIn=emissionIn_s$ID$)\n"; const std::string smoke_alloc_noise = "\n\ @@ -140,7 +141,8 @@ copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_ copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n\ \n\ # Keep track of important objects in dict to load them later on\n\ -smoke_noise_dict_s$ID$ = dict(density_noise=density_sn$ID$, uv0_noise=uvGrid0_s$ID$, uv1_noise=uvGrid1_s$ID$)\n"; +smoke_noise_dict_final_s$ID$ = dict(density_noise=density_sn$ID$)\n\ +smoke_noise_dict_resume_s$ID$ = dict(uv0_noise=uvGrid0_s$ID$, uv1_noise=uvGrid1_s$ID$)\n"; ////////////////////////////////////////////////////////////////////// // ADDITIONAL GRIDS @@ -162,9 +164,10 @@ color_g_in_s$ID$ = s$ID$.create(RealGrid)\n\ color_b_in_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ -if 'smoke_data_dict_s$ID$' in globals():\n\ - smoke_data_dict_s$ID$.update(color_r=color_r_s$ID$, color_g=color_g_s$ID$, color_b=color_b_s$ID$)\n\ - smoke_data_dict_s$ID$.update(color_r_in=color_r_in_s$ID$, color_g_in=color_g_in_s$ID$, color_b_in=color_b_in_s$ID$)\n"; +if 'smoke_data_dict_final_s$ID$' in globals():\n\ + smoke_data_dict_final_s$ID$.update(color_r=color_r_s$ID$, color_g=color_g_s$ID$, color_b=color_b_s$ID$)\n\ +if 'smoke_data_dict_resume_s$ID$' in globals():\n\ + smoke_data_dict_resume_s$ID$.update(color_r_in=color_r_in_s$ID$, color_g_in=color_g_in_s$ID$, color_b_in=color_b_in_s$ID$)\n"; const std::string smoke_alloc_colors_noise = "\n\ @@ -179,8 +182,8 @@ color_g_sn$ID$ = sn$ID$.create(RealGrid)\n\ color_b_sn$ID$ = sn$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ -if 'smoke_noise_dict_s$ID$' in globals():\n\ - smoke_noise_dict_s$ID$.update(color_r_noise=color_r_sn$ID$, color_g_noise=color_g_sn$ID$, color_b_noise=color_b_sn$ID$)\n"; +if 'smoke_noise_dict_final_s$ID$' in globals():\n\ + smoke_noise_dict_final_s$ID$.update(color_r_noise=color_r_sn$ID$, color_g_noise=color_g_sn$ID$, color_b_noise=color_b_sn$ID$)\n"; const std::string smoke_init_colors = "\n\ @@ -213,8 +216,10 @@ heat_s$ID$ = s$ID$.create(RealGrid)\n\ heatIn_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ -if 'smoke_data_dict_s$ID$' in globals():\n\ - smoke_data_dict_s$ID$.update(heat=heat_s$ID$, heatIn=heatIn_s$ID$)\n"; +if 'smoke_data_dict_final_s$ID$' in globals():\n\ + smoke_data_dict_final_s$ID$.update(heat=heat_s$ID$)\n\ +if 'smoke_data_dict_resume_s$ID$' in globals():\n\ + smoke_data_dict_resume_s$ID$.update(heatIn=heatIn_s$ID$)\n"; const std::string smoke_alloc_fire = "\n\ @@ -233,9 +238,10 @@ fuelIn_s$ID$ = s$ID$.create(RealGrid)\n\ reactIn_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ -if 'smoke_data_dict_s$ID$' in globals():\n\ - smoke_data_dict_s$ID$.update(flame=flame_s$ID$, fuel=fuel_s$ID$, react=react_s$ID$)\n\ - smoke_data_dict_s$ID$.update(fuelIn=fuelIn_s$ID$, reactIn=reactIn_s$ID$)\n"; +if 'smoke_data_dict_final_s$ID$' in globals():\n\ + smoke_data_dict_final_s$ID$.update(flame=flame_s$ID$)\n\ +if 'smoke_data_dict_resume_s$ID$' in globals():\n\ + smoke_data_dict_resume_s$ID$.update(fuel=fuel_s$ID$, react=react_s$ID$, fuelIn=fuelIn_s$ID$, reactIn=reactIn_s$ID$)\n"; const std::string smoke_alloc_fire_noise = "\n\ @@ -250,8 +256,10 @@ fuel_sn$ID$ = sn$ID$.create(RealGrid)\n\ react_sn$ID$ = sn$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ -if 'smoke_noise_dict_s$ID$' in globals():\n\ - smoke_noise_dict_s$ID$.update(flame_noise=flame_sn$ID$, fuel_noise=fuel_sn$ID$, react_noise=react_sn$ID$)\n"; +if 'smoke_noise_dict_final_s$ID$' in globals():\n\ + smoke_noise_dict_final_s$ID$.update(flame_noise=flame_sn$ID$)\n\ +if 'smoke_noise_dict_resume_s$ID$' in globals():\n\ + smoke_noise_dict_resume_s$ID$.update(fuel_noise=fuel_sn$ID$, react_noise=react_sn$ID$)\n"; ////////////////////////////////////////////////////////////////////// // STEP FUNCTIONS @@ -518,19 +526,24 @@ def update_flame_noise_$ID$():\n\ const std::string smoke_load_data = "\n\ -def smoke_load_data_$ID$(path, framenr, file_format):\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_s$ID$, path=path, framenr=framenr, file_format=file_format)\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"; const std::string smoke_load_noise = "\n\ -def smoke_load_noise_$ID$(path, framenr, file_format):\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_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\ + fluid_file_import_s$ID$(dict=smoke_noise_dict_final_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"; + 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"; ////////////////////////////////////////////////////////////////////// // EXPORT @@ -538,23 +551,31 @@ def smoke_load_noise_$ID$(path, framenr, file_format):\n\ const std::string smoke_save_data = "\n\ -def smoke_save_data_$ID$(path, framenr, file_format):\n\ +def smoke_save_data_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Smoke save data')\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=smoke_data_dict_s$ID$,)\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\ 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_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=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\ 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):\n\ +def smoke_save_noise_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Smoke save noise')\n\ if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=smoke_noise_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\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\ 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_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=smoke_noise_final_dict_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"; ////////////////////////////////////////////////////////////////////// // STANDALONE MODE diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 6b0dd7ac36f..6252ba3bb74 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -1088,13 +1088,7 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): col.separator() split = layout.split() - 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: - 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: + if 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 pause") elif not domain.has_cache_baked_data and not domain.is_cache_baking_data: diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 0213d10796a..37eed869cb6 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3110,7 +3110,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *mds, Mesh *orgmesh, Obj // if reading raw data directly from manta, normalize now, otherwise omit this, ie when reading // from files - { + if (!manta_liquid_mesh_from_file(mds->fluid)) { // normalize to unit cube around 0 mverts->co[0] -= ((float)mds->res[0] * mds->mesh_scale) * 0.5f; mverts->co[1] -= ((float)mds->res[1] * mds->mesh_scale) * 0.5f; @@ -3664,12 +3664,14 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, /* Read mesh cache. */ if (with_liquid && with_mesh) { - has_mesh = manta_read_mesh(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); } /* Read particles cache. */ if (with_liquid && with_particles) { - has_particles = manta_read_particles(mds->fluid, mmd, particles_frame); + /* Update particle data from file is faster than via Python (manta_read_particles()). */ + has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame); } /* Read guide cache. */ @@ -3707,12 +3709,23 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, } /* Read data cache only */ else { - /* Read config and realloc fluid object if needed. */ - if (manta_read_config(mds->fluid, mmd, data_frame) && manta_needs_realloc(mds->fluid, mmd)) { - BKE_fluid_reallocate_fluid(mds, mds->res, 1); + if (with_smoke) { + /* Read config and realloc fluid object if needed. */ + if (manta_read_config(mds->fluid, mmd, data_frame) && + manta_needs_realloc(mds->fluid, mmd)) { + BKE_fluid_reallocate_fluid(mds, mds->res, 1); + } + /* Read data cache */ + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } + if (with_liquid) { + if (!baking_data && !baking_particles && !baking_mesh) { + has_data = manta_update_liquid_structures(mds->fluid, mmd, data_frame); + } + else { + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } } - /* Read data cache */ - has_data = manta_read_data(mds->fluid, mmd, data_frame); } } @@ -3806,15 +3819,46 @@ struct Mesh *BKE_fluid_modifier_do( BLI_rw_mutex_unlock(mmd->domain->fluid_mutex); } + /* Optimization: Do not update viewport during bakes (except in replay mode) + * Reason: UI is locked and updated liquid / smoke geometry is not visible anyways. */ + bool needs_viewport_update = false; + if (mmd->domain) { + FluidDomainSettings *mds = mmd->domain; + + /* Always update viewport in cache replay mode. */ + if (mds->cache_type == FLUID_DOMAIN_CACHE_REPLAY) { + needs_viewport_update = true; + } + /* In other cache modes, only update the viewport when no bake is going on. */ + else { + bool with_mesh; + with_mesh = mds->flags & FLUID_DOMAIN_USE_MESH; + bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide; + baking_data = mds->cache_flag & FLUID_DOMAIN_BAKING_DATA; + baking_noise = mds->cache_flag & FLUID_DOMAIN_BAKING_NOISE; + baking_mesh = mds->cache_flag & FLUID_DOMAIN_BAKING_MESH; + baking_particles = mds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES; + baking_guide = mds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE; + + if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles && + !baking_guide) { + needs_viewport_update = true; + } + } + } + Mesh *result = NULL; if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) { - /* Return generated geometry depending on domain type. */ - if (mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) { - result = create_liquid_geometry(mmd->domain, me, ob); - } - if (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { - result = create_smoke_geometry(mmd->domain, me, ob); + if (needs_viewport_update) { + /* Return generated geometry depending on domain type. */ + if (mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) { + result = create_liquid_geometry(mmd->domain, me, ob); + } + if (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { + result = create_smoke_geometry(mmd->domain, me, ob); + } } + /* Clear flag outside of locked block (above). */ mmd->domain->cache_flag &= ~FLUID_DOMAIN_OUTDATED_DATA; mmd->domain->cache_flag &= ~FLUID_DOMAIN_OUTDATED_NOISE; diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c index b84da6a4ed9..386aa89ea5c 100644 --- a/source/blender/makesrna/intern/rna_fluid.c +++ b/source/blender/makesrna/intern/rna_fluid.c @@ -997,13 +997,18 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) "REPLAY", 0, "Replay", - "Use the timeline to bake the scene. Pausing and resuming possible."}, + "Use the timeline to bake the scene. Pausing and resuming possible"}, {FLUID_DOMAIN_CACHE_MODULAR, "MODULAR", 0, "Modular", - "Bake every stage of the simulation on its own. Can pause and resume bake jobs."}, - {FLUID_DOMAIN_CACHE_FINAL, "FINAL", 0, "Final", "Bake the entire simulation at once."}, + "Bake every stage of the simulation on its own. Pausing and resuming possible"}, + {FLUID_DOMAIN_CACHE_FINAL, + "FINAL", + 0, + "Final", + "Bake the entire simulation at once. Only produces the most essential cache files. Pausing " + "and resuming not possible"}, {0, NULL, 0, NULL, NULL}}; static const EnumPropertyItem smoke_data_depth_items[] = { |