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/intern/MANTA_main.cpp2
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h44
-rw-r--r--intern/mantaflow/intern/strings/liquid_script.h58
-rw-r--r--source/blender/blenkernel/intern/fluid.c41
4 files changed, 85 insertions, 60 deletions
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 5d35de7898f..c169d242583 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -837,6 +837,8 @@ std::string MANTA::getRealValue(const std::string &varName, FluidModifierData *m
ss << mmd->domain->flame_smoke_color[2];
else if (varName == "CURRENT_FRAME")
ss << mmd->time;
+ else if (varName == "START_FRAME")
+ ss << mmd->domain->cache_frame_start;
else if (varName == "END_FRAME")
ss << mmd->domain->cache_frame_end;
else if (varName == "CACHE_DATA_FORMAT")
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index c442dd56c09..0aad0546aea 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -123,6 +123,11 @@ cflCond_s$ID$ = $CFL$\n\
timestepsMin_s$ID$ = $TIMESTEPS_MIN$\n\
timestepsMax_s$ID$ = $TIMESTEPS_MAX$\n\
\n\
+# Start and stop for simulation\n\
+current_frame_s$ID$ = $CURRENT_FRAME$\n\
+start_frame_s$ID$ = $START_FRAME$\n\
+end_frame_s$ID$ = $END_FRAME$\n\
+\n\
# Fluid diffusion / viscosity\n\
domainSize_s$ID$ = $FLUID_DOMAIN_SIZE$ # longest domain side in meters\n\
viscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\
@@ -208,6 +213,8 @@ def fluid_adapt_time_step_$ID$():\n\
# time params are animatable\n\
s$ID$.frameLength = frameLength_s$ID$\n\
s$ID$.cfl = cflCond_s$ID$\n\
+ s$ID$.timestepMin = s$ID$.frameLength / max(1, timestepsMax_s$ID$)\n\
+ s$ID$.timestepMax = s$ID$.frameLength / max(1, timestepsMin_s$ID$)\n\
\n\
# ensure that vel grid is full (remember: adaptive domain can reallocate solver)\n\
copyRealToVec3(sourceX=x_vel_s$ID$, sourceY=y_vel_s$ID$, sourceZ=z_vel_s$ID$, target=vel_s$ID$)\n\
@@ -225,7 +232,7 @@ const std::string fluid_alloc =
mantaMsg('Fluid alloc data')\n\
flags_s$ID$ = s$ID$.create(FlagGrid)\n\
vel_s$ID$ = s$ID$.create(MACGrid)\n\
-velC_s$ID$ = s$ID$.create(MACGrid)\n\
+velTmp_s$ID$ = s$ID$.create(MACGrid)\n\
x_vel_s$ID$ = s$ID$.create(RealGrid)\n\
y_vel_s$ID$ = s$ID$.create(RealGrid)\n\
z_vel_s$ID$ = s$ID$.create(RealGrid)\n\
@@ -247,7 +254,7 @@ phiIn_s$ID$.setConst(9999)\n\
phiOut_s$ID$.setConst(9999)\n\
\n\
# Keep track of important objects in dict to load them later on\n\
-fluid_data_dict_final_s$ID$ = dict(vel=vel_s$ID$)\n\
+fluid_data_dict_final_s$ID$ = dict(vel=vel_s$ID$, velTmp=velTmp_s$ID$)\n\
fluid_data_dict_resume_s$ID$ = dict(phiObs=phiObs_s$ID$, phiIn=phiIn_s$ID$, phiOut=phiOut_s$ID$, flags=flags_s$ID$)\n";
const std::string fluid_alloc_obstacle =
@@ -493,7 +500,8 @@ def bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_
mantaMsg('Bake fluid data')\n\
\n\
s$ID$.frame = framenr\n\
- # Must not set 'timeTotal' here. Remember, this function is called from manta.c while-loop\n\
+ s$ID$.frameLength = frameLength_s$ID$\n\
+ s$ID$.timeTotal = timeTotal_s$ID$\n\
\n\
start_time = time.time()\n\
if using_smoke_s$ID$:\n\
@@ -514,9 +522,9 @@ def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_
mantaMsg('Bake fluid noise')\n\
\n\
sn$ID$.frame = framenr\n\
- sn$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\
- sn$ID$.timestep = dt0_s$ID$\n\
- mantaMsg('sn$ID$.timeTotal: ' + str(sn$ID$.timeTotal))\n\
+ sn$ID$.frameLength = frameLength_s$ID$\n\
+ sn$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\
+ sn$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for noise\n\
\n\
smoke_step_noise_$ID$(framenr)\n\
smoke_save_noise_$ID$(path_noise, framenr, format_noise, resumable)\n\
@@ -533,8 +541,9 @@ def bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles,
mantaMsg('Bake fluid mesh')\n\
\n\
sm$ID$.frame = framenr\n\
- sm$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\
- sm$ID$.timestep = dt0_s$ID$\n\
+ sm$ID$.frameLength = frameLength_s$ID$\n\
+ sm$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\
+ sm$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for mesh\n\
\n\
#if using_smoke_s$ID$:\n\
# TODO (sebbas): Future update could include smoke mesh (vortex sheets)\n\
@@ -556,8 +565,9 @@ def bake_particles_process_$ID$(framenr, format_data, format_particles, path_dat
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\
+ sp$ID$.frameLength = frameLength_s$ID$\n\
+ sp$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\
+ sp$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for particles\n\
\n\
#if using_smoke_s$ID$:\n\
# TODO (sebbas): Future update could include smoke particles (e.g. fire sparks)\n\
@@ -710,28 +720,24 @@ file_format_noise = '$CACHE_NOISE_FORMAT$'\n\
file_format_particles = '$CACHE_PARTICLE_FORMAT$'\n\
file_format_mesh = '$CACHE_MESH_FORMAT$'\n\
\n\
-# Start and stop for simulation\n\
-current_frame = $CURRENT_FRAME$\n\
-end_frame = $END_FRAME$\n\
-\n\
# How many frame to load from cache\n\
from_cache_cnt = 100\n\
\n\
loop_cnt = 0\n\
-while current_frame <= end_frame:\n\
+while current_frame_s$ID$ <= end_frame_s$ID$:\n\
\n\
# Load already simulated data from cache:\n\
if loop_cnt < from_cache_cnt:\n\
- load(current_frame, cache_resumable)\n\
+ load(current_frame_s$ID$, cache_resumable)\n\
\n\
# Otherwise simulate new data\n\
else:\n\
- while(s$ID$.frame <= current_frame):\n\
+ while(s$ID$.frame <= current_frame_s$ID$):\n\
if using_adaptTime_s$ID$:\n\
fluid_adapt_time_step_$ID$()\n\
- step(current_frame)\n\
+ step(current_frame_s$ID$)\n\
\n\
- current_frame += 1\n\
+ current_frame_s$ID$ += 1\n\
loop_cnt += 1\n\
\n\
if gui:\n\
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index 23ec16b9d84..2376d49aace 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -133,9 +133,8 @@ 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\
+phiOut_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\
@@ -144,9 +143,8 @@ kineticEnergy_sp$ID$ = sp$ID$.create(RealGrid)\n\
\n\
# Set some initial values\n\
phi_sp$ID$.setConst(9999)\n\
-phiIn_sp$ID$.setConst(9999)\n\
phiObs_sp$ID$.setConst(9999)\n\
-phiObsIn_sp$ID$.setConst(9999)\n\
+phiOut_sp$ID$.setConst(9999)\n\
\n\
# Keep track of important objects in dict to load them later on\n\
liquid_particles_dict_final_s$ID$ = dict(ppSnd=ppSnd_sp$ID$, pVelSnd=pVelSnd_pp$ID$, pLifeSnd=pLifeSnd_pp$ID$)\n\
@@ -229,13 +227,15 @@ def liquid_step_$ID$():\n\
mantaMsg('Pushing particles out of obstacles')\n\
pushOutofObs(parts=pp_s$ID$, flags=flags_s$ID$, phiObs=phiObs_s$ID$)\n\
\n\
+ # save original states for later (used during mesh / secondary particle creation)\n\
+ phiTmp_s$ID$.copyFrom(phi_s$ID$)\n\
+ velTmp_s$ID$.copyFrom(vel_s$ID$)\n\
+ \n\
mantaMsg('Advecting phi')\n\
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=phi_s$ID$, order=1) # first order is usually enough\n\
mantaMsg('Advecting velocity')\n\
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=vel_s$ID$, order=2)\n\
\n\
- phiTmp_s$ID$.copyFrom(phi_s$ID$) # save original phi for later use in mesh creation\n\
- \n\
# create level set of particles\n\
gridParticleIndex(parts=pp_s$ID$, flags=flags_s$ID$, indexSys=pindex_s$ID$, index=gpi_s$ID$)\n\
unionParticleLevelset(parts=pp_s$ID$, indexSys=pindex_s$ID$, flags=flags_s$ID$, index=gpi_s$ID$, phi=phiParts_s$ID$, radiusFactor=radiusFactor_s$ID$)\n\
@@ -308,7 +308,13 @@ const std::string liquid_step_mesh =
def liquid_step_mesh_$ID$():\n\
mantaMsg('Liquid step mesh')\n\
\n\
- interpolateGrid(target=phi_sm$ID$, source=phiTmp_s$ID$)\n\
+ # no upres: just use the loaded grids\n\
+ if upres_sm$ID$ <= 1:\n\
+ phi_sm$ID$.copyFrom(phiTmp_s$ID$)\n\
+ \n\
+ # with upres: recreate grids\n\
+ else:\n\
+ interpolateGrid(target=phi_sm$ID$, source=phiTmp_s$ID$)\n\
\n\
# create surface\n\
pp_sm$ID$.readParticles(pp_s$ID$)\n\
@@ -342,30 +348,36 @@ def liquid_step_particles_$ID$():\n\
\n\
# no upres: just use the loaded grids\n\
if upres_sp$ID$ <= 1:\n\
- flags_sp$ID$.copyFrom(flags_s$ID$)\n\
- vel_sp$ID$.copyFrom(vel_s$ID$)\n\
+ vel_sp$ID$.copyFrom(velTmp_s$ID$)\n\
phiObs_sp$ID$.copyFrom(phiObs_s$ID$)\n\
- phi_sp$ID$.copyFrom(phi_s$ID$)\n\
+ phi_sp$ID$.copyFrom(phiTmp_s$ID$)\n\
+ phiOut_sp$ID$.copyFrom(phiOut_s$ID$)\n\
\n\
# with upres: recreate grids\n\
else:\n\
# create highres grids by interpolation\n\
- interpolateMACGrid(target=vel_sp$ID$, source=vel_s$ID$)\n\
- interpolateGrid(target=phi_sp$ID$, source=phi_s$ID$)\n\
- flags_sp$ID$.initDomain(boundaryWidth=boundaryWidth_s$ID$, phiWalls=phiObs_sp$ID$, outflow=boundConditions_s$ID$)\n\
- flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\
+ interpolateMACGrid(target=vel_sp$ID$, source=velTmp_s$ID$)\n\
+ interpolateGrid(target=phiObs_sp$ID$, source=phiObs_s$ID$)\n\
+ interpolateGrid(target=phi_sp$ID$, source=phiTmp_s$ID$)\n\
+ interpolateGrid(target=phiOut_sp$ID$, source=phiOut_s$ID$)\n\
+ \n\
+ flags_sp$ID$.initDomain(boundaryWidth=1 if using_fractions_s$ID$ else 0, phiWalls=phiObs_sp$ID$, outflow=boundConditions_s$ID$)\n\
+ setObstacleFlags(flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, phiOut=None, phiIn=None) # phiIn not needed\n\
+ flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\
\n\
- # actual secondary simulation\n\
- #extrapolateLsSimple(phi=phi_sp$ID$, distance=radius+1, inside=True)\n\
+ # Actual secondary particle simulation\n\
flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=scaleFromManta_sp$ID$)\n\
- flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$, dt=s$ID$.frameLength)\n\
- flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, dt=s$ID$.frameLength)\n\
+ flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$, dt=sp$ID$.timestep)\n\
+ flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, dt=sp$ID$.timestep)\n\
if $SNDPARTICLE_BOUNDARY_PUSHOUT$:\n\
- pushOutofObs(parts = ppSnd_sp$ID$, flags = flags_sp$ID$, phiObs = phiObs_sp$ID$, shift = 1.0)\n\
- flipDeleteParticlesInObstacle(pts=ppSnd_sp$ID$, flags=flags_sp$ID$)\n\
- #debugGridInfo(flags = flags_sp$ID$, grid = trappedAir_sp$ID$, name = 'Trapped Air')\n\
- #debugGridInfo(flags = flags_sp$ID$, grid = waveCrest_sp$ID$, name = 'Wave Crest')\n\
- #debugGridInfo(flags = flags_sp$ID$, grid = kineticEnergy_sp$ID$, name = 'Kinetic Energy')\n";
+ pushOutofObs(parts=ppSnd_sp$ID$, flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, shift=1.0)\n\
+ flipDeleteParticlesInObstacle(pts=ppSnd_sp$ID$, flags=flags_sp$ID$) # delete particles inside obstacle and outflow cells\n\
+ \n\
+ # Print debug information in the console\n\
+ if 0:\n\
+ debugGridInfo(flags=flags_sp$ID$, grid=trappedAir_sp$ID$, name='Trapped Air')\n\
+ debugGridInfo(flags=flags_sp$ID$, grid=waveCrest_sp$ID$, name='Wave Crest')\n\
+ debugGridInfo(flags=flags_sp$ID$, grid=kineticEnergy_sp$ID$, name='Kinetic Energy')\n";
//////////////////////////////////////////////////////////////////////
// IMPORT
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 15f3fdf6a40..58a1ae28d42 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -538,7 +538,7 @@ static bool BKE_fluid_modifier_init(
/* Initially dt is equal to frame length (dt can change with adaptive-time stepping though). */
mds->dt = mds->frame_length;
mds->time_per_frame = 0;
- mds->time_total = (scene_framenr - 1) * mds->frame_length;
+ mds->time_total = abs(scene_framenr - mds->cache_frame_start) * mds->frame_length;
mmd->time = scene_framenr;
@@ -3561,7 +3561,7 @@ static int manta_step(
BLI_mutex_lock(&object_update_lock);
/* Loop as long as time_per_frame (sum of sub dt's) does not exceed actual framelength. */
- while (time_per_frame < frame_length) {
+ while (time_per_frame + FLT_EPSILON < frame_length) {
manta_adapt_timestep(mds->fluid);
dt = manta_get_timestep(mds->fluid);
@@ -3569,10 +3569,6 @@ static int manta_step(
* new MANTA object). */
mds->dt = dt;
- /* Count for how long this while loop is running. */
- time_per_frame += dt;
- time_total += dt;
-
/* Calculate inflow geometry. */
update_flowsfluids(depsgraph, scene, ob, mds, time_per_frame, frame_length, frame, dt);
@@ -3596,11 +3592,15 @@ static int manta_step(
if (mds->total_cells > 1) {
update_effectors(depsgraph, scene, ob, mds, dt);
manta_bake_data(mds->fluid, mmd, frame);
-
- mds->time_per_frame = time_per_frame;
- mds->time_total = time_total;
}
+ /* Count for how long this while loop is running. */
+ time_per_frame += dt;
+ time_total += dt;
+
+ mds->time_per_frame = time_per_frame;
+ mds->time_total = time_total;
+
/* If user requested stop, quit baking */
if (G.is_break && !mode_replay) {
result = 0;
@@ -3701,8 +3701,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
bool is_startframe;
is_startframe = (scene_framenr == mds->cache_frame_start);
- /* Reset fluid if no fluid present (obviously)
- * or if timeline gets reset to startframe */
+ /* Reset fluid if no fluid present. */
if (!mds->fluid) {
BKE_fluid_modifier_reset_ex(mmd, false);
@@ -3713,7 +3712,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
}
BLI_assert(mds->fluid);
- /* Guiding parent res pointer needs initialization */
+ /* Guiding parent res pointer needs initialization. */
guide_parent = mds->guide_parent;
if (guide_parent) {
mmd_parent = (FluidModifierData *)modifiers_findByType(guide_parent, eModifierType_Fluid);
@@ -3722,12 +3721,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
}
}
- /* ensure that time parameters are initialized correctly before every step */
+ /* Ensure that time parameters are initialized correctly before every step. */
float fps = scene->r.frs_sec / scene->r.frs_sec_base;
mds->frame_length = DT_DEFAULT * (25.0f / fps) * mds->time_scale;
mds->dt = mds->frame_length;
mds->time_per_frame = 0;
- mds->time_total = (scene_framenr - 1) * mds->frame_length;
+ /* Get distance between cache start and current frame for total time. */
+ mds->time_total = abs(scene_framenr - mds->cache_frame_start) * mds->frame_length;
objs = BKE_collision_objects_create(
depsgraph, ob, mds->fluid_group, &numobj, eModifierType_Fluid);
@@ -3743,7 +3743,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
MEM_freeN(objs);
}
- /* Ensure cache directory is not relative */
+ /* Ensure cache directory is not relative. */
const char *relbase = modifier_path_relbase_from_global(ob);
BLI_path_abs(mds->cache_directory, relbase);
@@ -3801,7 +3801,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
/* Ensure positivity of previous frame. */
CLAMP(prev_frame, 1, prev_frame);
- /* Cache mode specific settings */
+ /* Cache mode specific settings. */
switch (mode) {
case FLUID_DOMAIN_CACHE_FINAL:
/* Just load the data that has already been baked */
@@ -3872,8 +3872,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
/* Read particles cache. */
if (with_liquid && with_particles) {
- /* Update particle data from file is faster than via Python (manta_read_particles()). */
- has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame);
+ if (!baking_data && !baking_particles && !mode_replay) {
+ /* Update particle data from file is faster than via Python (manta_read_particles()). */
+ has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame);
+ }
+ else {
+ has_particles = manta_read_particles(mds->fluid, mmd, particles_frame);
+ }
}
/* Read guide cache. */