Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/mantaflow/extern/manta_fluid_API.h3
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp191
-rw-r--r--intern/mantaflow/intern/MANTA_main.h17
-rw-r--r--intern/mantaflow/intern/manta_fluid_API.cpp13
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h111
-rw-r--r--intern/mantaflow/intern/strings/liquid_script.h76
-rw-r--r--intern/mantaflow/intern/strings/smoke_script.h75
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py8
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc6
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c6
-rw-r--r--source/blender/blenkernel/intern/fluid.c74
-rw-r--r--source/blender/blenkernel/intern/particle_system.c68
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c7
-rw-r--r--source/blender/makesdna/DNA_particle_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c215
-rw-r--r--source/blender/makesrna/intern/rna_particle.c6
17 files changed, 520 insertions, 364 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/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index cacf0676481..c2201c706bc 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -558,7 +558,11 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x
else if (m_settings.export_particles &&
(psys->part->type == PART_EMITTER || psys->part->type == PART_FLUID_FLIP ||
psys->part->type == PART_FLUID_SPRAY || psys->part->type == PART_FLUID_BUBBLE ||
- psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_TRACER)) {
+ psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_TRACER ||
+ psys->part->type == PART_FLUID_SPRAYFOAM ||
+ psys->part->type == PART_FLUID_SPRAYBUBBLE ||
+ psys->part->type == PART_FLUID_FOAMBUBBLE ||
+ psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE)) {
m_shapes.push_back(new AbcPointsWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
}
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 74a523bfbdc..a70e5b67a15 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -6285,7 +6285,11 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph,
PART_FLUID_SPRAY,
PART_FLUID_BUBBLE,
PART_FLUID_FOAM,
- PART_FLUID_TRACER) &&
+ PART_FLUID_TRACER,
+ PART_FLUID_SPRAYFOAM,
+ PART_FLUID_SPRAYBUBBLE,
+ PART_FLUID_FOAMBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE) &&
psys_check_enabled(brushObj, brush->psys, for_render)) {
/* Paint a particle system */
dynamicPaint_paintParticles(surface, brush->psys, brush, timescale);
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 0213d10796a..106f1216d2a 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;
@@ -4161,7 +4205,7 @@ void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_typ
for (psys = ob->particlesystem.first; psys; psys = next_psys) {
next_psys = psys->next;
- if (psys->part->type & particle_type) {
+ if (psys->part->type == particle_type) {
/* clear modifier */
pmmd = psys_get_modifier(ob, psys);
BLI_remlink(&ob->modifiers, pmmd);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 34f2aa73817..172940760f9 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4137,6 +4137,34 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
}
}
+static bool particles_has_flip(short parttype)
+{
+ return (parttype == PART_FLUID_FLIP);
+}
+
+static bool particles_has_tracer(short parttype)
+{
+ return (parttype == PART_FLUID_TRACER);
+}
+
+static bool particles_has_spray(short parttype)
+{
+ return ((parttype == PART_FLUID_SPRAY) || (parttype == PART_FLUID_SPRAYFOAM) ||
+ (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+}
+
+static bool particles_has_bubble(short parttype)
+{
+ return ((parttype == PART_FLUID_BUBBLE) || (parttype == PART_FLUID_FOAMBUBBLE) ||
+ (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+}
+
+static bool particles_has_foam(short parttype)
+{
+ return ((parttype == PART_FLUID_FOAM) || (parttype == PART_FLUID_SPRAYFOAM) ||
+ (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+}
+
static void particles_fluid_step(ParticleSimulationData *sim,
int cfra,
const bool use_render_params)
@@ -4173,15 +4201,15 @@ static void particles_fluid_step(ParticleSimulationData *sim,
float min[3], max[3], size[3], cell_size_scaled[3], max_size;
/* Sanity check: parts also enabled in fluid domain? */
- if ((part->type == PART_FLUID_FLIP &&
+ if ((particles_has_flip(part->type) &&
(mds->particle_type & FLUID_DOMAIN_PARTICLE_FLIP) == 0) ||
- (part->type == PART_FLUID_SPRAY &&
+ (particles_has_spray(part->type) &&
(mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) == 0) ||
- (part->type == PART_FLUID_BUBBLE &&
+ (particles_has_bubble(part->type) &&
(mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) == 0) ||
- (part->type == PART_FLUID_FOAM &&
+ (particles_has_foam(part->type) &&
(mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) == 0) ||
- (part->type == PART_FLUID_TRACER &&
+ (particles_has_tracer(part->type) &&
(mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) == 0)) {
BLI_snprintf(debugStrBuffer,
sizeof(debugStrBuffer),
@@ -4194,23 +4222,23 @@ static void particles_fluid_step(ParticleSimulationData *sim,
if (part->type == PART_FLUID_FLIP) {
tottypepart = totpart = manta_liquid_get_num_flip_particles(mds->fluid);
}
- if ((part->type == PART_FLUID_SPRAY) || (part->type == PART_FLUID_BUBBLE) ||
- (part->type == PART_FLUID_FOAM) || (part->type == PART_FLUID_TRACER)) {
+ if (particles_has_spray(part->type) || particles_has_bubble(part->type) ||
+ particles_has_foam(part->type) || particles_has_tracer(part->type)) {
totpart = manta_liquid_get_num_snd_particles(mds->fluid);
/* tottypepart is the amount of particles of a snd particle type. */
for (p = 0; p < totpart; p++) {
flagActivePart = manta_liquid_get_snd_particle_flag_at(mds->fluid, p);
- if ((part->type & PART_FLUID_SPRAY) && (flagActivePart & PARTICLE_TYPE_SPRAY)) {
+ if (particles_has_spray(part->type) && (flagActivePart & PARTICLE_TYPE_SPRAY)) {
tottypepart++;
}
- if ((part->type & PART_FLUID_BUBBLE) && (flagActivePart & PARTICLE_TYPE_BUBBLE)) {
+ if (particles_has_bubble(part->type) && (flagActivePart & PARTICLE_TYPE_BUBBLE)) {
tottypepart++;
}
- if ((part->type & PART_FLUID_FOAM) && (flagActivePart & PARTICLE_TYPE_FOAM)) {
+ if (particles_has_foam(part->type) && (flagActivePart & PARTICLE_TYPE_FOAM)) {
tottypepart++;
}
- if ((part->type & PART_FLUID_TRACER) && (flagActivePart & PARTICLE_TYPE_TRACER)) {
+ if (particles_has_tracer(part->type) && (flagActivePart & PARTICLE_TYPE_TRACER)) {
tottypepart++;
}
}
@@ -4261,8 +4289,8 @@ static void particles_fluid_step(ParticleSimulationData *sim,
velY = manta_liquid_get_flip_particle_velocity_y_at(mds->fluid, p);
velZ = manta_liquid_get_flip_particle_velocity_z_at(mds->fluid, p);
}
- else if ((part->type == PART_FLUID_SPRAY) || (part->type == PART_FLUID_BUBBLE) ||
- (part->type == PART_FLUID_FOAM) || (part->type == PART_FLUID_TRACER)) {
+ else if (particles_has_spray(part->type) || particles_has_bubble(part->type) ||
+ particles_has_foam(part->type) || particles_has_tracer(part->type)) {
flagActivePart = manta_liquid_get_snd_particle_flag_at(mds->fluid, p);
resX = (float)manta_liquid_get_particle_res_x(mds->fluid);
@@ -4292,16 +4320,16 @@ static void particles_fluid_step(ParticleSimulationData *sim,
/* Type of particle must match current particle system type
* (only important for snd particles). */
- if ((flagActivePart & PARTICLE_TYPE_SPRAY) && (part->type & PART_FLUID_SPRAY) == 0) {
+ if ((flagActivePart & PARTICLE_TYPE_SPRAY) && !particles_has_spray(part->type)) {
continue;
}
- if ((flagActivePart & PARTICLE_TYPE_BUBBLE) && (part->type & PART_FLUID_BUBBLE) == 0) {
+ if ((flagActivePart & PARTICLE_TYPE_BUBBLE) && !particles_has_bubble(part->type)) {
continue;
}
- if ((flagActivePart & PARTICLE_TYPE_FOAM) && (part->type & PART_FLUID_FOAM) == 0) {
+ if ((flagActivePart & PARTICLE_TYPE_FOAM) && !particles_has_foam(part->type)) {
continue;
}
- if ((flagActivePart & PARTICLE_TYPE_TRACER) && (part->type & PART_FLUID_TRACER) == 0) {
+ if ((flagActivePart & PARTICLE_TYPE_TRACER) && !particles_has_tracer(part->type)) {
continue;
}
# if 0
@@ -4844,9 +4872,9 @@ void particle_system_update(struct Depsgraph *depsgraph,
hair_step(&sim, cfra, use_render_params);
}
}
- else if ((part->type == PART_FLUID_FLIP) || (part->type == PART_FLUID_SPRAY) ||
- (part->type == PART_FLUID_BUBBLE) || (part->type == PART_FLUID_FOAM) ||
- (part->type == PART_FLUID_TRACER)) {
+ else if (particles_has_flip(part->type) || particles_has_spray(part->type) ||
+ particles_has_bubble(part->type) || particles_has_foam(part->type) ||
+ particles_has_tracer(part->type)) {
particles_fluid_step(&sim, (int)cfra, use_render_params);
}
else {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 4fcc8ba4112..c43b7385a36 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1822,7 +1822,9 @@ static int modifier_can_delete(ModifierData *md)
short particle_type = ((ParticleSystemModifierData *)md)->psys->part->type;
if (particle_type == PART_FLUID || particle_type == PART_FLUID_FLIP ||
particle_type == PART_FLUID_FOAM || particle_type == PART_FLUID_SPRAY ||
- particle_type == PART_FLUID_BUBBLE || particle_type == PART_FLUID_TRACER) {
+ particle_type == PART_FLUID_BUBBLE || particle_type == PART_FLUID_TRACER ||
+ particle_type == PART_FLUID_SPRAYFOAM || particle_type == PART_FLUID_SPRAYBUBBLE ||
+ particle_type == PART_FLUID_FOAMBUBBLE || particle_type == PART_FLUID_SPRAYFOAMBUBBLE) {
return 0;
}
}
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 0bf9688888b..b2af58e47f2 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -346,10 +346,9 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
BMOperator bmop_fill;
BMOperator bmop_attr;
+ /* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
+ * The normal is passed so triangle fill wont have to calculate it. */
normalize_v3_v3(normal_fill, plane_no_local);
- if (clear_outer == true && clear_inner == false) {
- negate_v3(normal_fill);
- }
/* Fill */
BMO_op_initf(bm,
@@ -369,7 +368,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
"face_attribute_fill faces=%S use_normals=%b use_data=%b",
&bmop_fill,
"geom.out",
- false,
+ true,
true);
BMO_op_exec(bm, &bmop_attr);
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 5012fbeca91..373c193b4ab 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -443,6 +443,10 @@ enum {
PART_FLUID_BUBBLE = 6,
PART_FLUID_FOAM = 7,
PART_FLUID_TRACER = 8,
+ PART_FLUID_SPRAYFOAM = 9,
+ PART_FLUID_SPRAYBUBBLE = 10,
+ PART_FLUID_FOAMBUBBLE = 11,
+ PART_FLUID_SPRAYFOAMBUBBLE = 12,
};
/* Mirroring Mantaflow particle types from particle.h (Mantaflow header). */
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index b84da6a4ed9..0e819b555e8 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -192,15 +192,13 @@ static void rna_Fluid_flip_parts_update(Main *bmain, Scene *scene, PointerRNA *p
}
else {
rna_Fluid_parts_delete(ptr, PART_FLUID_FLIP);
- rna_Fluid_resetCache(bmain, scene, ptr);
-
mmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FLIP;
}
rna_Fluid_draw_type_update(NULL, NULL, ptr);
- rna_Fluid_reset(bmain, scene, ptr);
+ rna_Fluid_update(bmain, scene, ptr);
}
-static void rna_Fluid_spray_parts_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Fluid_spray_parts_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
FluidModifierData *mmd;
@@ -218,15 +216,12 @@ static void rna_Fluid_spray_parts_update(Main *bmain, Scene *scene, PointerRNA *
}
else {
rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAY);
- rna_Fluid_resetCache(bmain, scene, ptr);
-
mmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_SPRAY;
}
rna_Fluid_draw_type_update(NULL, NULL, ptr);
- rna_Fluid_reset(bmain, scene, ptr);
}
-static void rna_Fluid_bubble_parts_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Fluid_bubble_parts_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
FluidModifierData *mmd;
@@ -244,15 +239,12 @@ static void rna_Fluid_bubble_parts_update(Main *bmain, Scene *scene, PointerRNA
}
else {
rna_Fluid_parts_delete(ptr, PART_FLUID_BUBBLE);
- rna_Fluid_resetCache(bmain, scene, ptr);
-
mmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_BUBBLE;
}
rna_Fluid_draw_type_update(NULL, NULL, ptr);
- rna_Fluid_reset(bmain, scene, ptr);
}
-static void rna_Fluid_foam_parts_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Fluid_foam_parts_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
FluidModifierData *mmd;
@@ -270,15 +262,12 @@ static void rna_Fluid_foam_parts_update(Main *bmain, Scene *scene, PointerRNA *p
}
else {
rna_Fluid_parts_delete(ptr, PART_FLUID_FOAM);
- rna_Fluid_resetCache(bmain, scene, ptr);
-
mmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FOAM;
}
rna_Fluid_draw_type_update(NULL, NULL, ptr);
- rna_Fluid_reset(bmain, scene, ptr);
}
-static void rna_Fluid_tracer_parts_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Fluid_tracer_parts_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
FluidModifierData *mmd;
@@ -296,12 +285,9 @@ static void rna_Fluid_tracer_parts_update(Main *bmain, Scene *scene, PointerRNA
}
else {
rna_Fluid_parts_delete(ptr, PART_FLUID_TRACER);
- rna_Fluid_resetCache(bmain, scene, ptr);
-
mmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_TRACER;
}
rna_Fluid_draw_type_update(NULL, NULL, ptr);
- rna_Fluid_reset(bmain, scene, ptr);
}
static void rna_Fluid_combined_export_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -311,101 +297,131 @@ static void rna_Fluid_combined_export_update(Main *bmain, Scene *scene, PointerR
mmd = (FluidModifierData *)modifiers_findByType(ob, eModifierType_Fluid);
if (mmd->domain->sndparticle_combined_export == SNDPARTICLE_COMBINED_EXPORT_OFF) {
- rna_Fluid_parts_delete(ptr, (PART_FLUID_SPRAY | PART_FLUID_FOAM | PART_FLUID_BUBBLE));
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAMBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAMBUBBLE);
- // re-add each particle type if enabled
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) != 0) {
+ bool exists_spray = rna_Fluid_parts_exists(ptr, PART_FLUID_SPRAY);
+ bool exists_foam = rna_Fluid_parts_exists(ptr, PART_FLUID_FOAM);
+ bool exists_bubble = rna_Fluid_parts_exists(ptr, PART_FLUID_BUBBLE);
+
+ /* Re-add each particle type if enabled and no particle system exists for them anymore. */
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && !exists_spray) {
rna_Fluid_spray_parts_update(bmain, scene, ptr);
}
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) != 0) {
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && !exists_foam) {
rna_Fluid_foam_parts_update(bmain, scene, ptr);
}
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) != 0) {
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && !exists_bubble) {
rna_Fluid_bubble_parts_update(bmain, scene, ptr);
}
}
else if (mmd->domain->sndparticle_combined_export == SNDPARTICLE_COMBINED_EXPORT_SPRAY_FOAM) {
- if (ob->type == OB_MESH &&
- !rna_Fluid_parts_exists(ptr, (PART_FLUID_SPRAY | PART_FLUID_FOAM))) {
- rna_Fluid_parts_delete(ptr, (PART_FLUID_SPRAY | PART_FLUID_FOAM));
- }
- rna_Fluid_parts_create(bmain,
- ptr,
- "SprayFoamParticleSettings",
- "Spray + Foam Particles",
- "Spray + Foam Particle System",
- (PART_FLUID_SPRAY | PART_FLUID_FOAM));
-
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
-
- // re-add bubbles if enabled
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) != 0) {
- rna_Fluid_bubble_parts_update(bmain, scene, ptr);
+ if (ob->type == OB_MESH && !rna_Fluid_parts_exists(ptr, PART_FLUID_SPRAYFOAM)) {
+
+ rna_Fluid_parts_create(bmain,
+ ptr,
+ "SprayFoamParticleSettings",
+ "Spray + Foam Particles",
+ "Spray + Foam Particle System",
+ PART_FLUID_SPRAYFOAM);
+
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
+
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAY);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAMBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAMBUBBLE);
+
+ /* Re-add spray if enabled and no particle system exists for it anymore. */
+ bool exists_bubble = rna_Fluid_parts_exists(ptr, PART_FLUID_BUBBLE);
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && !exists_bubble) {
+ rna_Fluid_bubble_parts_update(bmain, scene, ptr);
+ }
}
}
else if (mmd->domain->sndparticle_combined_export == SNDPARTICLE_COMBINED_EXPORT_SPRAY_BUBBLE) {
- if (ob->type == OB_MESH &&
- !rna_Fluid_parts_exists(ptr, (PART_FLUID_SPRAY | PART_FLUID_BUBBLE))) {
- rna_Fluid_parts_delete(ptr, (PART_FLUID_SPRAY | PART_FLUID_BUBBLE));
- }
- rna_Fluid_parts_create(bmain,
- ptr,
- "SprayBubbleParticleSettings",
- "Spray + Bubble Particles",
- "Spray + Bubble Particle System",
- (PART_FLUID_SPRAY | PART_FLUID_BUBBLE));
-
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
-
- // re-add foam if enabled
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) != 0) {
- rna_Fluid_foam_parts_update(bmain, scene, ptr);
+ if (ob->type == OB_MESH && !rna_Fluid_parts_exists(ptr, PART_FLUID_SPRAYBUBBLE)) {
+
+ rna_Fluid_parts_create(bmain,
+ ptr,
+ "SprayBubbleParticleSettings",
+ "Spray + Bubble Particles",
+ "Spray + Bubble Particle System",
+ PART_FLUID_SPRAYBUBBLE);
+
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
+
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAY);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_BUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAMBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAMBUBBLE);
+
+ /* Re-add foam if enabled and no particle system exists for it anymore. */
+ bool exists_foam = rna_Fluid_parts_exists(ptr, PART_FLUID_FOAM);
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && !exists_foam) {
+ rna_Fluid_foam_parts_update(bmain, scene, ptr);
+ }
}
}
else if (mmd->domain->sndparticle_combined_export == SNDPARTICLE_COMBINED_EXPORT_FOAM_BUBBLE) {
- if (ob->type == OB_MESH &&
- !rna_Fluid_parts_exists(ptr, (PART_FLUID_FOAM | PART_FLUID_BUBBLE))) {
- rna_Fluid_parts_delete(ptr, (PART_FLUID_FOAM | PART_FLUID_BUBBLE));
- }
- rna_Fluid_parts_create(bmain,
- ptr,
- "FoamBubbleParticleSettings",
- "Foam + Bubble Particles",
- "Foam + Bubble Particle System",
- (PART_FLUID_FOAM | PART_FLUID_BUBBLE));
-
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
-
- // re-add spray if enabled
- if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) != 0) {
- rna_Fluid_spray_parts_update(bmain, scene, ptr);
+ if (ob->type == OB_MESH && !rna_Fluid_parts_exists(ptr, PART_FLUID_FOAMBUBBLE)) {
+
+ rna_Fluid_parts_create(bmain,
+ ptr,
+ "FoamBubbleParticleSettings",
+ "Foam + Bubble Particles",
+ "Foam + Bubble Particle System",
+ PART_FLUID_FOAMBUBBLE);
+
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
+
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_BUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAMBUBBLE);
+
+ /* Re-add foam if enabled and no particle system exists for it anymore. */
+ bool exists_spray = rna_Fluid_parts_exists(ptr, PART_FLUID_SPRAY);
+ if ((mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && !exists_spray) {
+ rna_Fluid_spray_parts_update(bmain, scene, ptr);
+ }
}
}
else if (mmd->domain->sndparticle_combined_export ==
SNDPARTICLE_COMBINED_EXPORT_SPRAY_FOAM_BUBBLE) {
- if (ob->type == OB_MESH &&
- !rna_Fluid_parts_exists(ptr, (PART_FLUID_SPRAY | PART_FLUID_FOAM | PART_FLUID_BUBBLE))) {
- rna_Fluid_parts_delete(ptr, (PART_FLUID_SPRAY | PART_FLUID_FOAM | PART_FLUID_BUBBLE));
+ if (ob->type == OB_MESH && !rna_Fluid_parts_exists(ptr, PART_FLUID_SPRAYFOAMBUBBLE)) {
+
+ rna_Fluid_parts_create(bmain,
+ ptr,
+ "SprayFoamBubbleParticleSettings",
+ "Spray + Foam + Bubble Particles",
+ "Spray + Foam + Bubble Particle System",
+ PART_FLUID_SPRAYFOAMBUBBLE);
+
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
+ mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
+
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAY);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_BUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYFOAM);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_SPRAYBUBBLE);
+ rna_Fluid_parts_delete(ptr, PART_FLUID_FOAMBUBBLE);
}
- rna_Fluid_parts_create(bmain,
- ptr,
- "SprayFoamBubbleParticleSettings",
- "Spray + Foam + Bubble Particles",
- "Spray + Foam + Bubble Particle System",
- (PART_FLUID_SPRAY | PART_FLUID_FOAM | PART_FLUID_BUBBLE));
-
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_SPRAY;
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_FOAM;
- mmd->domain->particle_type |= FLUID_DOMAIN_PARTICLE_BUBBLE;
}
else {
// sanity check, should not occur
printf("ERROR: Unexpected combined export setting encountered!");
}
- rna_Fluid_resetCache(bmain, scene, ptr);
rna_Fluid_draw_type_update(NULL, NULL, ptr);
}
@@ -997,13 +1013,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[] = {
@@ -1537,7 +1558,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_FLIP);
RNA_def_property_ui_text(prop, "FLIP", "Create FLIP particle system");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, 0, "rna_Fluid_flip_parts_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_flip_parts_update");
prop = RNA_def_property(srna, "use_fractions", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_USE_FRACTIONS);
@@ -1822,25 +1843,25 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_SPRAY);
RNA_def_property_ui_text(prop, "Spray", "Create spray particle system");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, 0, "rna_Fluid_spray_parts_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_spray_parts_update");
prop = RNA_def_property(srna, "use_bubble_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_BUBBLE);
RNA_def_property_ui_text(prop, "Bubble", "Create bubble particle system");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, 0, "rna_Fluid_bubble_parts_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_bubble_parts_update");
prop = RNA_def_property(srna, "use_foam_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_FOAM);
RNA_def_property_ui_text(prop, "Foam", "Create foam particle system");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, 0, "rna_Fluid_foam_parts_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_foam_parts_update");
prop = RNA_def_property(srna, "use_tracer_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_TRACER);
RNA_def_property_ui_text(prop, "Tracer", "Create tracer particle system");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, 0, "rna_Fluid_tracer_parts_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_tracer_parts_update");
/* fluid guiding options */
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 9bc65de11e0..d914dc3b8dd 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -964,7 +964,11 @@ static int rna_PartSettings_is_fluid_get(PointerRNA *ptr)
PART_FLUID_FOAM,
PART_FLUID_SPRAY,
PART_FLUID_BUBBLE,
- PART_FLUID_TRACER));
+ PART_FLUID_TRACER,
+ PART_FLUID_SPRAYFOAM,
+ PART_FLUID_SPRAYBUBBLE,
+ PART_FLUID_FOAMBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE));
}
static void rna_ParticleSettings_use_clump_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)