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:
Diffstat (limited to 'source/blender/blenkernel/intern/fluid.c')
-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 8697cd03827..578a6a13bb7 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: