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:
authorSebastián Barschkis <sebbas@sebbas.org>2020-04-15 15:16:13 +0300
committerSebastián Barschkis <sebbas@sebbas.org>2020-04-15 15:22:47 +0300
commit7de86ad61fb1135c9e18f6336b5b01600b381b06 (patch)
tree7ff7757ec5f9e07a8460cf9be2ae2aa9e9a9141d /source/blender/blenkernel/intern
parent0f6044610faa71db9050c41980c31cbd56eb2469 (diff)
Fluid: Improved cache 'Replay' option
When using the 'Replay' cache mode the cache needs to be invalidated whenever simulation variables have been changed. The invalidation will always only affect the according subcaches, e.g. when changing a mesh paramter only the mesh cache will be invalidated, the base cache will remain intact. Before this change Blender always invalidated the entire cache.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/fluid.c237
1 files changed, 140 insertions, 97 deletions
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 8076cc0967b..c4dd674790b 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -334,6 +334,14 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *mds,
manta_free(fluid_old);
}
+void BKE_fluid_cache_free_all(FluidDomainSettings *mds, Object *ob)
+{
+ int cache_map = (FLUID_DOMAIN_OUTDATED_DATA | FLUID_DOMAIN_OUTDATED_NOISE |
+ FLUID_DOMAIN_OUTDATED_MESH | FLUID_DOMAIN_OUTDATED_PARTICLES |
+ FLUID_DOMAIN_OUTDATED_GUIDE);
+ BKE_fluid_cache_free(mds, ob, cache_map);
+}
+
void BKE_fluid_cache_free(FluidDomainSettings *mds, Object *ob, int cache_map)
{
char temp_dir[FILE_MAX];
@@ -1130,7 +1138,18 @@ static void obstacles_from_mesh(Object *coll_ob,
}
}
+static void ensure_obstaclefields(FluidDomainSettings *mds)
+{
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE) {
+ manta_ensure_obstacle(mds->fluid, mds->mmd);
+ }
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) {
+ manta_ensure_guiding(mds->fluid, mds->mmd);
+ }
+}
+
static void update_obstacleflags(FluidDomainSettings *mds,
+ Object *domain,
Object **coll_ob_array,
int coll_ob_array_len)
{
@@ -1157,6 +1176,11 @@ static void update_obstacleflags(FluidDomainSettings *mds,
if (!mes) {
break;
}
+ if (mes->flags & FLUID_EFFECTOR_NEEDS_UPDATE) {
+ mes->flags &= ~FLUID_EFFECTOR_NEEDS_UPDATE;
+ BKE_fluid_cache_free_all(mds, domain);
+ mds->cache_flag |= FLUID_DOMAIN_OUTDATED_DATA;
+ }
if (mes->type == FLUID_EFFECTOR_TYPE_COLLISION) {
active_fields |= FLUID_DOMAIN_ACTIVE_OBSTACLE;
}
@@ -1165,13 +1189,6 @@ static void update_obstacleflags(FluidDomainSettings *mds,
}
}
}
- /* Finally, initialize new data fields if any */
- if (active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE) {
- manta_ensure_obstacle(mds->fluid, mds->mmd);
- }
- if (active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) {
- manta_ensure_guiding(mds->fluid, mds->mmd);
- }
mds->active_fields = active_fields;
}
@@ -1193,7 +1210,8 @@ static void update_obstacles(Depsgraph *depsgraph,
depsgraph, ob, mds->effector_group, &numeffecobjs, eModifierType_Fluid);
/* Update all effector related flags and ensure that corresponding grids get initialized. */
- update_obstacleflags(mds, effecobjs, numeffecobjs);
+ update_obstacleflags(mds, ob, effecobjs, numeffecobjs);
+ ensure_obstaclefields(mds);
/* Initialize effector maps for each flow. */
bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numeffecobjs, "fluid_effector_bb_maps");
@@ -2573,21 +2591,49 @@ BLI_INLINE void apply_inflow_fields(FluidFlowSettings *mfs,
}
}
-static void update_flowsflags(FluidDomainSettings *mds, Object **flowobjs, int numflowobj)
+static void ensure_flowsfields(FluidDomainSettings *mds)
+{
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL) {
+ manta_ensure_invelocity(mds->fluid, mds->mmd);
+ }
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW) {
+ manta_ensure_outflow(mds->fluid, mds->mmd);
+ }
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) {
+ manta_smoke_ensure_heat(mds->fluid, mds->mmd);
+ }
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) {
+ manta_smoke_ensure_fire(mds->fluid, mds->mmd);
+ }
+ if (mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) {
+ /* initialize all smoke with "active_color" */
+ manta_smoke_ensure_colors(mds->fluid, mds->mmd);
+ }
+ if (mds->type == FLUID_DOMAIN_TYPE_LIQUID &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY ||
+ mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM ||
+ mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) {
+ manta_liquid_ensure_sndparts(mds->fluid, mds->mmd);
+ }
+}
+
+static void update_flowsflags(FluidDomainSettings *mds,
+ Object *domain,
+ Object **flowobjs,
+ int numflowobj)
{
int active_fields = mds->active_fields;
uint flow_index;
/* First, remove all flags that we want to update. */
int prev_flags = (FLUID_DOMAIN_ACTIVE_INVEL | FLUID_DOMAIN_ACTIVE_OUTFLOW |
- FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE |
- FLUID_DOMAIN_ACTIVE_COLOR_SET | FLUID_DOMAIN_ACTIVE_COLORS);
+ FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE);
active_fields &= ~prev_flags;
/* Monitor active fields based on flow settings */
for (flow_index = 0; flow_index < numflowobj; flow_index++) {
- Object *coll_ob = flowobjs[flow_index];
- FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(coll_ob,
+ Object *flow_ob = flowobjs[flow_index];
+ FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flow_ob,
eModifierType_Fluid);
/* Sanity check. */
@@ -2600,6 +2646,11 @@ static void update_flowsflags(FluidDomainSettings *mds, Object **flowobjs, int n
if (!mfs) {
break;
}
+ if (mfs->flags & FLUID_FLOW_NEEDS_UPDATE) {
+ mfs->flags &= ~FLUID_FLOW_NEEDS_UPDATE;
+ BKE_fluid_cache_free_all(mds, domain);
+ mds->cache_flag |= FLUID_DOMAIN_OUTDATED_DATA;
+ }
if (mfs->flags & FLUID_FLOW_INITVELOCITY) {
active_fields |= FLUID_DOMAIN_ACTIVE_INVEL;
}
@@ -2648,29 +2699,6 @@ static void update_flowsflags(FluidDomainSettings *mds, Object **flowobjs, int n
active_fields |= FLUID_DOMAIN_ACTIVE_COLORS;
}
}
- /* Finally, initialize new data fields if any */
- if (active_fields & FLUID_DOMAIN_ACTIVE_INVEL) {
- manta_ensure_invelocity(mds->fluid, mds->mmd);
- }
- if (active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW) {
- manta_ensure_outflow(mds->fluid, mds->mmd);
- }
- if (active_fields & FLUID_DOMAIN_ACTIVE_HEAT) {
- manta_smoke_ensure_heat(mds->fluid, mds->mmd);
- }
- if (active_fields & FLUID_DOMAIN_ACTIVE_FIRE) {
- manta_smoke_ensure_fire(mds->fluid, mds->mmd);
- }
- if (active_fields & FLUID_DOMAIN_ACTIVE_COLORS) {
- /* initialize all smoke with "active_color" */
- manta_smoke_ensure_colors(mds->fluid, mds->mmd);
- }
- if (mds->type == FLUID_DOMAIN_TYPE_LIQUID &&
- (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY ||
- mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM ||
- mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) {
- manta_liquid_ensure_sndparts(mds->fluid, mds->mmd);
- }
mds->active_fields = active_fields;
}
@@ -2692,7 +2720,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
depsgraph, ob, mds->fluid_group, &numflowobj, eModifierType_Fluid);
/* Update all flow related flags and ensure that corresponding grids get initialized. */
- update_flowsflags(mds, flowobjs, numflowobj);
+ update_flowsflags(mds, ob, flowobjs, numflowobj);
+ ensure_flowsfields(mds);
/* Initialize emission maps for each flow. */
bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numflowobj, "fluid_flow_bb_maps");
@@ -3566,6 +3595,7 @@ static int manta_step(
break;
}
+ /* Only bake if the domain is bigger than one cell (important for adaptive domain). */
if (mds->total_cells > 1) {
update_effectors(depsgraph, scene, ob, mds, dt);
manta_bake_data(mds->fluid, mmd, frame);
@@ -3585,7 +3615,7 @@ static int manta_step(
}
}
- if (mds->type == FLUID_DOMAIN_TYPE_GAS) {
+ if (mds->type == FLUID_DOMAIN_TYPE_GAS && result) {
manta_smoke_calc_transparency(mds, DEG_get_evaluated_view_layer(depsgraph));
}
BLI_mutex_unlock(&object_update_lock);
@@ -3684,8 +3714,35 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
return;
}
+ bool bake_outdated = mds->cache_flag &
+ (FLUID_DOMAIN_OUTDATED_DATA | FLUID_DOMAIN_OUTDATED_NOISE |
+ FLUID_DOMAIN_OUTDATED_MESH | FLUID_DOMAIN_OUTDATED_PARTICLES |
+ FLUID_DOMAIN_OUTDATED_GUIDE);
+
+ /* Exit early if cache is outdated. */
+ if (bake_outdated) {
+ return;
+ }
+
+ /* Ensure cache directory is not relative. */
+ const char *relbase = modifier_path_relbase_from_global(ob);
+ BLI_path_abs(mds->cache_directory, relbase);
+
+ objs = BKE_collision_objects_create(
+ depsgraph, ob, mds->fluid_group, &numobj, eModifierType_Fluid);
+ update_flowsflags(mds, ob, objs, numobj);
+ if (objs) {
+ MEM_freeN(objs);
+ }
+ objs = BKE_collision_objects_create(
+ depsgraph, ob, mds->effector_group, &numobj, eModifierType_Fluid);
+ update_obstacleflags(mds, ob, objs, numobj);
+ if (objs) {
+ MEM_freeN(objs);
+ }
+
/* Reset fluid if no fluid present. */
- if (!mds->fluid) {
+ if (!mds->fluid || mds->cache_flag & FLUID_DOMAIN_OUTDATED_DATA) {
BKE_fluid_modifier_reset_ex(mmd, false);
/* Fluid domain init must not fail in order to continue modifier evaluation. */
@@ -3712,23 +3769,10 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
/* 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);
- update_flowsflags(mds, objs, numobj);
- if (objs) {
- MEM_freeN(objs);
- }
-
- objs = BKE_collision_objects_create(
- depsgraph, ob, mds->effector_group, &numobj, eModifierType_Fluid);
- update_obstacleflags(mds, objs, numobj);
- if (objs) {
- MEM_freeN(objs);
- }
-
- /* Ensure cache directory is not relative. */
- const char *relbase = modifier_path_relbase_from_global(ob);
- BLI_path_abs(mds->cache_directory, relbase);
+ int next_frame = scene_framenr + 1;
+ int prev_frame = scene_framenr - 1;
+ /* Ensure positivity of previous frame. */
+ CLAMP(prev_frame, mds->cache_frame_start, prev_frame);
int data_frame = scene_framenr, noise_frame = scene_framenr;
int mesh_frame = scene_framenr, particles_frame = scene_framenr, guide_frame = scene_framenr;
@@ -3751,17 +3795,18 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
with_particles = drops || bubble || floater;
bool has_data, has_noise, has_mesh, has_particles, has_guide;
- has_data = has_noise = has_mesh = has_particles = has_guide = false;
+ has_data = manta_has_data(mds->fluid, mmd, scene_framenr);
+ has_noise = manta_has_noise(mds->fluid, mmd, scene_framenr);
+ has_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr);
+ has_particles = manta_has_particles(mds->fluid, mmd, scene_framenr);
+ has_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr, guide_parent);
- bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide, bake_outdated;
+ 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;
- bake_outdated = mds->cache_flag & (FLUID_DOMAIN_OUTDATED_DATA | FLUID_DOMAIN_OUTDATED_NOISE |
- FLUID_DOMAIN_OUTDATED_MESH | FLUID_DOMAIN_OUTDATED_PARTICLES |
- FLUID_DOMAIN_OUTDATED_GUIDE);
bool resume_data, resume_noise, resume_mesh, resume_particles, resume_guide;
resume_data = (!is_startframe) && (mds->cache_frame_pause_data == scene_framenr);
@@ -3775,35 +3820,27 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
bake_cache = baking_data || baking_noise || baking_mesh || baking_particles || baking_guide;
bool next_data, next_noise, next_mesh, next_particles, next_guide;
- next_data = manta_has_data(mds->fluid, mmd, scene_framenr + 1);
- next_noise = manta_has_noise(mds->fluid, mmd, scene_framenr + 1);
- next_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr + 1);
- next_particles = manta_has_particles(mds->fluid, mmd, scene_framenr + 1);
- next_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr + 1, guide_parent);
+ next_data = manta_has_data(mds->fluid, mmd, next_frame);
+ next_noise = manta_has_noise(mds->fluid, mmd, next_frame);
+ next_mesh = manta_has_mesh(mds->fluid, mmd, next_frame);
+ next_particles = manta_has_particles(mds->fluid, mmd, next_frame);
+ next_guide = manta_has_guiding(mds->fluid, mmd, next_frame, guide_parent);
bool prev_data, prev_noise, prev_mesh, prev_particles, prev_guide;
- prev_data = manta_has_data(mds->fluid, mmd, scene_framenr - 1);
- prev_noise = manta_has_noise(mds->fluid, mmd, scene_framenr - 1);
- prev_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr - 1);
- prev_particles = manta_has_particles(mds->fluid, mmd, scene_framenr - 1);
- prev_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr - 1, guide_parent);
-
- /* Unused for now, but needed for proper caching. */
- UNUSED_VARS(prev_guide);
- UNUSED_VARS(next_noise);
- UNUSED_VARS(next_mesh);
- UNUSED_VARS(next_particles);
- UNUSED_VARS(next_guide);
+ prev_data = manta_has_data(mds->fluid, mmd, prev_frame);
+ prev_noise = manta_has_noise(mds->fluid, mmd, prev_frame);
+ prev_mesh = manta_has_mesh(mds->fluid, mmd, prev_frame);
+ prev_particles = manta_has_particles(mds->fluid, mmd, prev_frame);
+ prev_guide = manta_has_guiding(mds->fluid, mmd, prev_frame, guide_parent);
+
+ /* Unused for now. */
+ UNUSED_VARS(prev_guide, next_mesh, next_guide);
bool with_gdomain;
with_gdomain = (mds->guide_source == FLUID_DOMAIN_GUIDE_SRC_DOMAIN);
int o_res[3], o_min[3], o_max[3], o_shift[3];
int mode = mds->cache_type;
- int prev_frame = scene_framenr - 1;
-
- /* Ensure positivity of previous frame. */
- CLAMP(prev_frame, 1, prev_frame);
/* Cache mode specific settings. */
switch (mode) {
@@ -3851,21 +3888,23 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
break;
case FLUID_DOMAIN_CACHE_REPLAY:
default:
+ baking_data = !has_data && (is_startframe || prev_data);
+ if (with_smoke && with_noise) {
+ baking_noise = !has_noise && (is_startframe || prev_noise);
+ }
+ if (with_liquid && with_mesh) {
+ baking_mesh = !has_mesh && (is_startframe || prev_mesh);
+ }
+ if (with_liquid && with_particles) {
+ baking_particles = !has_particles && (is_startframe || prev_particles);
+ }
+
/* Always trying to read the cache in replay mode. */
read_cache = true;
bake_cache = false;
break;
}
- /* Cache outdated? If so reset, don't read, and then just rebake.
- * Note: Only do this in replay mode! */
- bool mode_replay = (mode == FLUID_DOMAIN_CACHE_REPLAY);
- if (bake_outdated && mode_replay) {
- read_cache = false;
- bake_cache = true;
- BKE_fluid_cache_free(mds, ob, mds->cache_flag);
- }
-
/* Try to read from cache and keep track of read success. */
if (read_cache) {
@@ -3877,7 +3916,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
/* Read particles cache. */
if (with_liquid && with_particles) {
- if (!baking_data && !baking_particles && !mode_replay) {
+ if (!baking_data && !baking_particles && next_particles) {
/* Update particle data from file is faster than via Python (manta_read_particles()). */
has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame);
}
@@ -3901,8 +3940,8 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
manta_needs_realloc(mds->fluid, mmd)) {
BKE_fluid_reallocate_fluid(mds, mds->res, 1);
}
- if (!baking_data && !baking_noise && !mode_replay) {
- has_data = manta_update_noise_structures(mds->fluid, mmd, noise_frame);
+ if (!baking_data && !baking_noise && next_noise) {
+ has_noise = manta_update_noise_structures(mds->fluid, mmd, noise_frame);
}
else {
has_noise = manta_read_noise(mds->fluid, mmd, noise_frame);
@@ -3921,8 +3960,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
mds, o_res, mds->res, o_min, mds->res_min, o_max, o_shift, mds->shift);
}
}
- if (!baking_data && !baking_noise && !mode_replay) {
- /* TODO (sebbas): Confirm if this read call is really needed or not. */
+ if (!baking_data && !baking_noise && next_data && next_noise) {
+ /* TODO (sebbas): Confirm if this read call is really needed or not.
+ * Currently only important to load the shadow grid. */
has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame);
}
else {
@@ -3946,7 +3986,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
}
}
if (with_liquid) {
- if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) {
+ if (!baking_data && !baking_particles && !baking_mesh && next_data) {
has_data = manta_update_liquid_structures(mds->fluid, mmd, data_frame);
}
else {
@@ -3960,6 +4000,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
switch (mode) {
case FLUID_DOMAIN_CACHE_FINAL:
case FLUID_DOMAIN_CACHE_MODULAR:
+ if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
+ bake_cache = false;
+ }
break;
case FLUID_DOMAIN_CACHE_REPLAY:
default: