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.c596
1 files changed, 233 insertions, 363 deletions
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index df7d308a87c..eb1d77eb0f4 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -33,6 +33,7 @@
#include "BLI_task.h"
#include "BLI_utildefines.h"
+#include "DNA_defaults.h"
#include "DNA_fluid_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -79,7 +80,7 @@
# include "DEG_depsgraph.h"
# include "DEG_depsgraph_query.h"
-# include "RE_shader_ext.h"
+# include "RE_texture.h"
# include "CLG_log.h"
@@ -342,32 +343,37 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_data = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) {
flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_noise = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) {
flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_mesh = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) {
@@ -376,17 +382,18 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_particles = 0;
}
-
if (cache_map & FLUID_DOMAIN_OUTDATED_GUIDE) {
flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_guide = 0;
}
fds->cache_flag = flags;
@@ -816,44 +823,43 @@ static void bb_combineMaps(FluidObjectBB *output,
BLI_INLINE void apply_effector_fields(FluidEffectorSettings *UNUSED(fes),
int index,
- float distance_value,
- float *phi_in,
- float numobjs_value,
- float *numobjs,
- float vel_x_value,
- float *vel_x,
- float vel_y_value,
- float *vel_y,
- float vel_z_value,
- float *vel_z)
+ float src_distance_value,
+ float *dest_phi_in,
+ float src_numobjs_value,
+ float *dest_numobjs,
+ float const src_vel_value[3],
+ float *dest_vel_x,
+ float *dest_vel_y,
+ float *dest_vel_z)
{
/* Ensure that distance value is "joined" into the levelset. */
- if (phi_in) {
- phi_in[index] = MIN2(distance_value, phi_in[index]);
+ if (dest_phi_in) {
+ dest_phi_in[index] = MIN2(src_distance_value, dest_phi_in[index]);
}
/* Accumulate effector object count (important once effector object overlap). */
- if (numobjs && numobjs_value > 0) {
- numobjs[index] += 1;
+ if (dest_numobjs && src_numobjs_value > 0) {
+ dest_numobjs[index] += 1;
}
- if (vel_x) {
- vel_x[index] = vel_x_value;
- vel_y[index] = vel_y_value;
- vel_z[index] = vel_z_value;
+ /* Accumulate effector velocities for each cell. */
+ if (dest_vel_x && src_numobjs_value > 0) {
+ dest_vel_x[index] += src_vel_value[0];
+ dest_vel_y[index] += src_vel_value[1];
+ dest_vel_z[index] += src_vel_value[2];
}
}
-static void sample_effector(FluidEffectorSettings *fes,
- const MVert *mvert,
- const MLoop *mloop,
- const MLoopTri *mlooptri,
- float *velocity_map,
- int index,
- BVHTreeFromMesh *tree_data,
- const float ray_start[3],
- const float *vert_vel,
- bool has_velocity)
+static void update_velocities(FluidEffectorSettings *fes,
+ const MVert *mvert,
+ const MLoop *mloop,
+ const MLoopTri *mlooptri,
+ float *velocity_map,
+ int index,
+ BVHTreeFromMesh *tree_data,
+ const float ray_start[3],
+ const float *vert_vel,
+ bool has_velocity)
{
BVHTreeNearest nearest = {0};
nearest.index = -1;
@@ -865,7 +871,8 @@ static void sample_effector(FluidEffectorSettings *fes,
nearest.dist_sq = surface_distance * surface_distance; /* find_nearest uses squared distance */
/* Find the nearest point on the mesh. */
- if (BLI_bvhtree_find_nearest(
+ if (has_velocity &&
+ BLI_bvhtree_find_nearest(
tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) {
float weights[3];
int v1, v2, v3, f_index = nearest.index;
@@ -876,56 +883,66 @@ static void sample_effector(FluidEffectorSettings *fes,
v3 = mloop[mlooptri[f_index].tri[2]].v;
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co);
- if (has_velocity) {
-
- /* Apply object velocity. */
- float hit_vel[3];
- interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights);
-
- /* Guiding has additional velocity multiplier */
- if (fes->type == FLUID_EFFECTOR_TYPE_GUIDE) {
- mul_v3_fl(hit_vel, fes->vel_multi);
-
- switch (fes->guide_mode) {
- case FLUID_EFFECTOR_GUIDE_AVERAGED:
- velocity_map[index * 3] = (velocity_map[index * 3] + hit_vel[0]) * 0.5f;
- velocity_map[index * 3 + 1] = (velocity_map[index * 3 + 1] + hit_vel[1]) * 0.5f;
- velocity_map[index * 3 + 2] = (velocity_map[index * 3 + 2] + hit_vel[2]) * 0.5f;
- break;
- case FLUID_EFFECTOR_GUIDE_OVERRIDE:
- velocity_map[index * 3] = hit_vel[0];
- velocity_map[index * 3 + 1] = hit_vel[1];
- velocity_map[index * 3 + 2] = hit_vel[2];
- break;
- case FLUID_EFFECTOR_GUIDE_MIN:
- velocity_map[index * 3] = MIN2(fabsf(hit_vel[0]), fabsf(velocity_map[index * 3]));
- velocity_map[index * 3 + 1] = MIN2(fabsf(hit_vel[1]),
- fabsf(velocity_map[index * 3 + 1]));
- velocity_map[index * 3 + 2] = MIN2(fabsf(hit_vel[2]),
- fabsf(velocity_map[index * 3 + 2]));
- break;
- case FLUID_EFFECTOR_GUIDE_MAX:
- default:
- velocity_map[index * 3] = MAX2(fabsf(hit_vel[0]), fabsf(velocity_map[index * 3]));
- velocity_map[index * 3 + 1] = MAX2(fabsf(hit_vel[1]),
- fabsf(velocity_map[index * 3 + 1]));
- velocity_map[index * 3 + 2] = MAX2(fabsf(hit_vel[2]),
- fabsf(velocity_map[index * 3 + 2]));
- break;
- }
+ /* Apply object velocity. */
+ float hit_vel[3];
+ interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights);
+
+ /* Guiding has additional velocity multiplier */
+ if (fes->type == FLUID_EFFECTOR_TYPE_GUIDE) {
+ mul_v3_fl(hit_vel, fes->vel_multi);
+
+ /* Absolute representation of new object velocity. */
+ float abs_hit_vel[3];
+ copy_v3_v3(abs_hit_vel, hit_vel);
+ abs_v3(abs_hit_vel);
+
+ /* Absolute representation of current object velocity. */
+ float abs_vel[3];
+ copy_v3_v3(abs_vel, &velocity_map[index * 3]);
+ abs_v3(abs_vel);
+
+ switch (fes->guide_mode) {
+ case FLUID_EFFECTOR_GUIDE_AVERAGED:
+ velocity_map[index * 3] = (velocity_map[index * 3] + hit_vel[0]) * 0.5f;
+ velocity_map[index * 3 + 1] = (velocity_map[index * 3 + 1] + hit_vel[1]) * 0.5f;
+ velocity_map[index * 3 + 2] = (velocity_map[index * 3 + 2] + hit_vel[2]) * 0.5f;
+ break;
+ case FLUID_EFFECTOR_GUIDE_OVERRIDE:
+ velocity_map[index * 3] = hit_vel[0];
+ velocity_map[index * 3 + 1] = hit_vel[1];
+ velocity_map[index * 3 + 2] = hit_vel[2];
+ break;
+ case FLUID_EFFECTOR_GUIDE_MIN:
+ velocity_map[index * 3] = MIN2(abs_hit_vel[0], abs_vel[0]);
+ velocity_map[index * 3 + 1] = MIN2(abs_hit_vel[1], abs_vel[1]);
+ velocity_map[index * 3 + 2] = MIN2(abs_hit_vel[2], abs_vel[2]);
+ break;
+ case FLUID_EFFECTOR_GUIDE_MAX:
+ default:
+ velocity_map[index * 3] = MAX2(abs_hit_vel[0], abs_vel[0]);
+ velocity_map[index * 3 + 1] = MAX2(abs_hit_vel[1], abs_vel[1]);
+ velocity_map[index * 3 + 2] = MAX2(abs_hit_vel[2], abs_vel[2]);
+ break;
}
- else {
- /* Apply (i.e. add) effector object velocity */
- velocity_map[index * 3] += hit_vel[0];
- velocity_map[index * 3 + 1] += hit_vel[1];
- velocity_map[index * 3 + 2] += hit_vel[2];
+ }
+ else if (fes->type == FLUID_EFFECTOR_TYPE_COLLISION) {
+ velocity_map[index * 3] = hit_vel[0];
+ velocity_map[index * 3 + 1] = hit_vel[1];
+ velocity_map[index * 3 + 2] = hit_vel[2];
# ifdef DEBUG_PRINT
- /* Debugging: Print object velocities. */
- printf("adding effector object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]);
+ /* Debugging: Print object velocities. */
+ printf("setting effector object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]);
# endif
- }
+ }
+ else {
+ /* Should never reach this block. */
+ BLI_assert(false);
}
}
+ else {
+ /* Clear velocities at cells that are not moving. */
+ copy_v3_fl(velocity_map, 0.0);
+ }
}
typedef struct ObstaclesFromDMData {
@@ -956,18 +973,6 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]);
const float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f};
- /* Calculate object velocities. Result in bb->velocity. */
- sample_effector(data->fes,
- data->mvert,
- data->mloop,
- data->mlooptri,
- bb->velocity,
- index,
- data->tree,
- ray_start,
- data->vert_vel,
- data->has_velocity);
-
/* Calculate levelset values from meshes. Result in bb->distances. */
update_distances(index,
bb->distances,
@@ -976,8 +981,19 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
data->fes->surface_distance,
data->fes->flags & FLUID_EFFECTOR_USE_PLANE_INIT);
- /* Ensure that num objects are also counted inside object.
- * But don't count twice (see object inc for nearest point). */
+ /* Calculate object velocities. Result in bb->velocity. */
+ update_velocities(data->fes,
+ data->mvert,
+ data->mloop,
+ data->mlooptri,
+ bb->velocity,
+ index,
+ data->tree,
+ ray_start,
+ data->vert_vel,
+ data->has_velocity);
+
+ /* Increase obstacle count inside of moving obstacles. */
if (bb->distances[index] < 0) {
bb->numobjs[index]++;
}
@@ -1018,7 +1034,7 @@ static void obstacles_from_mesh(Object *coll_ob,
looptri = BKE_mesh_runtime_looptri_ensure(me);
numverts = me->totvert;
- /* TODO (sebbas): Make initialization of vertex velocities optional? */
+ /* TODO(sebbas): Make initialization of vertex velocities optional? */
{
vert_vel = MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_velocity");
@@ -1055,7 +1071,7 @@ static void obstacles_from_mesh(Object *coll_ob,
add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &fes->verts_old[i * 3]);
- mul_v3_fl(&vert_vel[i * 3], fds->dx / dt);
+ mul_v3_fl(&vert_vel[i * 3], 1.0f / dt);
}
copy_v3_v3(&fes->verts_old[i * 3], co);
@@ -1076,7 +1092,9 @@ static void obstacles_from_mesh(Object *coll_ob,
res[i] = bb->res[i];
}
- if (BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) {
+ /* Skip effector sampling loop if object has disabled effector. */
+ bool use_effector = fes->flags & FLUID_EFFECTOR_USE_EFFEC;
+ if (use_effector && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) {
ObstaclesFromDMData data = {
.fes = fes,
@@ -1165,13 +1183,11 @@ static void update_obstacleflags(FluidDomainSettings *fds,
static bool escape_effectorobject(Object *flowobj,
FluidDomainSettings *fds,
- FluidEffectorSettings *fes,
+ FluidEffectorSettings *UNUSED(fes),
int frame)
{
bool is_static = is_static_object(flowobj);
- bool use_effector = (fes->flags & FLUID_EFFECTOR_USE_EFFEC);
-
bool is_resume = (fds->cache_frame_pause_data == frame);
bool is_adaptive = (fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN);
bool is_first_frame = (frame == fds->cache_frame_start);
@@ -1181,10 +1197,6 @@ static bool escape_effectorobject(Object *flowobj,
if (is_adaptive) {
is_static = false;
}
- /* Skip flow objects with disabled inflow flag. */
- if (!use_effector) {
- return true;
- }
/* Skip static effector objects after initial frame. */
if (is_static && !is_first_frame && !is_resume) {
return true;
@@ -1269,7 +1281,7 @@ static void compute_obstaclesemission(Scene *scene,
# endif
/* Update frame time, this is considering current subframe fraction
* BLI_mutex_lock() called in manta_step(), so safe to update subframe here
- * TODO (sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph)
+ * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph)
* as subframes don't work with the latter yet. */
BKE_object_modifier_update_subframe(
depsgraph, scene, effecobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid);
@@ -1441,11 +1453,9 @@ static void update_obstacles(Depsgraph *depsgraph,
levelset,
numobjs_map[e_index],
num_obstacles,
- velocity_map[e_index * 3],
+ &velocity_map[e_index * 3],
vel_x,
- velocity_map[e_index * 3 + 1],
vel_y,
- velocity_map[e_index * 3 + 2],
vel_z);
}
if (fes->type == FLUID_EFFECTOR_TYPE_GUIDE) {
@@ -1455,11 +1465,9 @@ static void update_obstacles(Depsgraph *depsgraph,
phi_guide_in,
numobjs_map[e_index],
num_guides,
- velocity_map[e_index * 3],
+ &velocity_map[e_index * 3],
vel_x_guide,
- velocity_map[e_index * 3 + 1],
vel_y_guide,
- velocity_map[e_index * 3 + 2],
vel_z_guide);
}
}
@@ -1822,6 +1830,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
float *velocity_map,
int index,
const int base_res[3],
+ const float global_size[3],
const float flow_center[3],
BVHTreeFromMesh *tree_data,
const float ray_start[3],
@@ -1981,9 +1990,23 @@ static void sample_mesh(FluidFlowSettings *ffs,
printf("adding flow object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]);
# endif
}
- velocity_map[index * 3] += ffs->vel_coord[0];
- velocity_map[index * 3 + 1] += ffs->vel_coord[1];
- velocity_map[index * 3 + 2] += ffs->vel_coord[2];
+ /* Convert xyz velocities flow settings from world to grid space. */
+ float convert_vel[3];
+ copy_v3_v3(convert_vel, ffs->vel_coord);
+ float time_mult = 1.0 / (25.0f * DT_DEFAULT);
+ float size_mult = MAX3(base_res[0], base_res[1], base_res[2]) /
+ MAX3(global_size[0], global_size[1], global_size[2]);
+ mul_v3_v3fl(convert_vel, ffs->vel_coord, size_mult * time_mult);
+
+ velocity_map[index * 3] += convert_vel[0];
+ velocity_map[index * 3 + 1] += convert_vel[1];
+ velocity_map[index * 3 + 2] += convert_vel[2];
+# ifdef DEBUG_PRINT
+ printf("initial vel: [%f, %f, %f]\n",
+ velocity_map[index * 3],
+ velocity_map[index * 3 + 1],
+ velocity_map[index * 3 + 2]);
+# endif
}
}
@@ -2037,6 +2060,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata,
bb->velocity,
index,
data->fds->base_res,
+ data->fds->global_size,
data->flow_center,
data->tree,
ray_start,
@@ -2134,7 +2158,7 @@ static void emit_from_mesh(
add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &ffs->verts_old[i * 3]);
- mul_v3_fl(&vert_vel[i * 3], fds->dx / dt);
+ mul_v3_fl(&vert_vel[i * 3], 1.0 / dt);
}
copy_v3_v3(&ffs->verts_old[i * 3], co);
}
@@ -2158,7 +2182,9 @@ static void emit_from_mesh(
res[i] = bb->res[i];
}
- if (BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) {
+ /* Skip flow sampling loop if object has disabled flow. */
+ bool use_flow = ffs->flags & FLUID_FLOW_USE_INFLOW;
+ if (use_flow && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) {
EmitFromDMData data = {
.fds = fds,
@@ -2430,19 +2456,6 @@ static void adaptive_domain_adjust(
/* Redo adapt time step in manta to refresh solver state (ie time variables) */
manta_adapt_timestep(fds->fluid);
}
-
- /* update global size field with new bbox size */
- /* volume bounds */
- float minf[3], maxf[3], size[3];
- madd_v3fl_v3fl_v3fl_v3i(minf, fds->p0, fds->cell_size, fds->res_min);
- madd_v3fl_v3fl_v3fl_v3i(maxf, fds->p0, fds->cell_size, fds->res_max);
- /* calculate domain dimensions */
- sub_v3_v3v3(size, maxf, minf);
- /* apply object scale */
- for (int i = 0; i < 3; i++) {
- size[i] = fabsf(size[i] * ob->scale[i]);
- }
- copy_v3_v3(fds->global_size, size);
}
BLI_INLINE void apply_outflow_fields(int index,
@@ -2701,9 +2714,6 @@ static bool escape_flowsobject(Object *flowobj,
bool gas_flow = (ffs->type == FLUID_FLOW_TYPE_SMOKE || ffs->type == FLUID_FLOW_TYPE_FIRE ||
ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE);
bool is_geometry = (ffs->behavior == FLUID_FLOW_BEHAVIOR_GEOMETRY);
- bool is_inflow = (ffs->behavior == FLUID_FLOW_BEHAVIOR_INFLOW);
- bool is_outflow = (ffs->behavior == FLUID_FLOW_BEHAVIOR_OUTFLOW);
- bool use_flow = (ffs->flags & FLUID_FLOW_USE_INFLOW);
bool liquid_domain = fds->type == FLUID_DOMAIN_TYPE_LIQUID;
bool gas_domain = fds->type == FLUID_DOMAIN_TYPE_GAS;
@@ -2716,10 +2726,6 @@ static bool escape_flowsobject(Object *flowobj,
if (is_adaptive) {
is_static = false;
}
- /* Skip flow objects with disabled inflow flag. */
- if ((is_inflow || is_outflow) && !use_flow) {
- return true;
- }
/* No need to compute emission value if it won't be applied. */
if (liquid_flow && is_geometry && !is_first_frame) {
return true;
@@ -2729,7 +2735,7 @@ static bool escape_flowsobject(Object *flowobj,
return true;
}
/* Optimization: Static liquid flow objects don't need emission after first frame.
- * TODO (sebbas): Also do not use static mode if initial velocities are enabled. */
+ * TODO(sebbas): Also do not use static mode if initial velocities are enabled. */
if (liquid_flow && is_static && !is_first_frame && !is_resume && !use_velocity) {
return true;
}
@@ -2811,7 +2817,7 @@ static void compute_flowsemission(Scene *scene,
# endif
/* Update frame time, this is considering current subframe fraction
* BLI_mutex_lock() called in manta_step(), so safe to update subframe here
- * TODO (sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph)
+ * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph)
* as subframes don't work with the latter yet. */
BKE_object_modifier_update_subframe(
depsgraph, scene, flowobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid);
@@ -3196,9 +3202,18 @@ static void update_effectors_task_cb(void *__restrict userdata,
mul_v3_fl(retvel, mag);
/* Constrain forces to interval -1 to 1. */
- data->force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f);
- data->force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f);
- data->force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f);
+ CLAMP3(retvel, -1.0f, 1.0f);
+ data->force_x[index] = retvel[0];
+ data->force_y[index] = retvel[1];
+ data->force_z[index] = retvel[2];
+
+# ifdef DEBUG_PRINT
+ /* Debugging: Print forces. */
+ printf("setting force: [%f, %f, %f]\n",
+ data->force_x[index],
+ data->force_y[index],
+ data->force_z[index]);
+# endif
}
}
}
@@ -3212,7 +3227,7 @@ static void update_effectors(
effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights);
if (effectors) {
- // precalculate wind forces
+ /* Precalculate wind forces. */
UpdateEffectorsData data;
data.scene = scene;
data.fds = fds;
@@ -3287,7 +3302,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
/* If needed, vertex velocities will be read too. */
bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS;
FluidDomainVertexVelocity *velarray = NULL;
- float time_mult = 25.f * DT_DEFAULT;
+ float time_mult = 25.0f * DT_DEFAULT;
if (use_speedvectors) {
if (fds->mesh_velocities) {
@@ -3788,7 +3803,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
MEM_freeN(objs);
}
- /* TODO (sebbas): Cache reset for when flow / effector object need update flag is set. */
+ /* TODO(sebbas): Cache reset for when flow / effector object need update flag is set. */
# if 0
/* If the just updated flags now carry the 'outdated' flag, reset the cache here!
* Plus sanity check: Do not clear cache on file load. */
@@ -4424,9 +4439,9 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain && fmd->domain->fluid) {
FluidDomainSettings *fds = fmd->domain;
- float time_mult = 25.f * DT_DEFAULT;
+ float time_mult = 25.0f * DT_DEFAULT;
float size_mult = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]) /
- fds->maxres;
+ MAX3(fds->base_res[0], fds->base_res[1], fds->base_res[2]);
float vel_mag;
float density = 0.0f, fuel = 0.0f;
float pos[3];
@@ -4519,6 +4534,7 @@ void BKE_fluid_particle_system_create(struct Main *bmain,
part->totpart = 0;
part->draw_size = 0.01f; /* Make fluid particles more subtle in viewport. */
part->draw_col = PART_DRAW_COL_VEL;
+ part->phystype = PART_PHYS_NO; /* No physics needed, part system only used to display data. */
psys->part = part;
psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
BLI_strncpy(psys->name, parts_name, sizeof(psys->name));
@@ -4682,6 +4698,43 @@ void BKE_fluid_effector_type_set(Object *UNUSED(object), FluidEffectorSettings *
settings->type = type;
}
+void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
+{
+ /* Based on the domain type, certain fields are defaulted accordingly if the selected field
+ * is unsupported. */
+ const char coba_field = settings->coba_field;
+ const char data_depth = settings->openvdb_data_depth;
+
+ if (settings->type == FLUID_DOMAIN_TYPE_GAS) {
+ if (ELEM(coba_field,
+ FLUID_DOMAIN_FIELD_PHI,
+ FLUID_DOMAIN_FIELD_PHI_IN,
+ FLUID_DOMAIN_FIELD_PHI_OUT,
+ FLUID_DOMAIN_FIELD_PHI_OBSTACLE)) {
+ /* Defaulted to density for gas domain. */
+ settings->coba_field = FLUID_DOMAIN_FIELD_DENSITY;
+ }
+
+ /* Gas domains do not support vdb mini precision. */
+ if (data_depth == VDB_PRECISION_MINI_FLOAT) {
+ settings->openvdb_data_depth = VDB_PRECISION_HALF_FLOAT;
+ }
+ }
+ else if (settings->type == FLUID_DOMAIN_TYPE_LIQUID) {
+ if (ELEM(coba_field,
+ FLUID_DOMAIN_FIELD_COLOR_R,
+ FLUID_DOMAIN_FIELD_COLOR_G,
+ FLUID_DOMAIN_FIELD_COLOR_B,
+ FLUID_DOMAIN_FIELD_DENSITY,
+ FLUID_DOMAIN_FIELD_FLAME,
+ FLUID_DOMAIN_FIELD_FUEL,
+ FLUID_DOMAIN_FIELD_HEAT)) {
+ /* Defaulted to phi for liquid domain. */
+ settings->coba_field = FLUID_DOMAIN_FIELD_PHI;
+ }
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -4838,242 +4891,48 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
BKE_fluid_modifier_freeDomain(fmd);
}
- /* domain object data */
- fmd->domain = MEM_callocN(sizeof(FluidDomainSettings), "FluidDomain");
+ fmd->domain = DNA_struct_default_alloc(FluidDomainSettings);
fmd->domain->fmd = fmd;
- fmd->domain->effector_weights = BKE_effector_add_weights(NULL);
- fmd->domain->fluid = NULL;
- fmd->domain->fluid_mutex = BLI_rw_mutex_alloc();
- fmd->domain->force_group = NULL;
- fmd->domain->fluid_group = NULL;
- fmd->domain->effector_group = NULL;
-
- /* adaptive domain options */
- fmd->domain->adapt_margin = 4;
- fmd->domain->adapt_res = 0;
- fmd->domain->adapt_threshold = 0.02f;
-
- /* fluid domain options */
- fmd->domain->maxres = 32;
- fmd->domain->solver_res = 3;
- fmd->domain->border_collisions = 0; // open domain
- fmd->domain->flags = FLUID_DOMAIN_USE_DISSOLVE_LOG | FLUID_DOMAIN_USE_ADAPTIVE_TIME;
- fmd->domain->gravity[0] = 0.0f;
- fmd->domain->gravity[1] = 0.0f;
- fmd->domain->gravity[2] = -9.81f;
- fmd->domain->active_fields = 0;
- fmd->domain->type = FLUID_DOMAIN_TYPE_GAS;
- fmd->domain->boundary_width = 1;
- /* smoke domain options */
- fmd->domain->alpha = 1.0f;
- fmd->domain->beta = 1.0f;
- fmd->domain->diss_speed = 5;
- fmd->domain->vorticity = 0;
- fmd->domain->active_color[0] = 0.0f;
- fmd->domain->active_color[1] = 0.0f;
- fmd->domain->active_color[2] = 0.0f;
- fmd->domain->highres_sampling = SM_HRES_FULLSAMPLE;
-
- /* flame options */
- fmd->domain->burning_rate = 0.75f;
- fmd->domain->flame_smoke = 1.0f;
- fmd->domain->flame_vorticity = 0.5f;
- fmd->domain->flame_ignition = 1.5f;
- fmd->domain->flame_max_temp = 3.0f;
- fmd->domain->flame_smoke_color[0] = 0.7f;
- fmd->domain->flame_smoke_color[1] = 0.7f;
- fmd->domain->flame_smoke_color[2] = 0.7f;
-
- /* noise options */
- fmd->domain->noise_strength = 1.0;
- fmd->domain->noise_pos_scale = 2.0f;
- fmd->domain->noise_time_anim = 0.1f;
- fmd->domain->noise_scale = 2;
- fmd->domain->noise_type = FLUID_NOISE_TYPE_WAVELET;
-
- /* liquid domain options */
- fmd->domain->simulation_method = FLUID_DOMAIN_METHOD_FLIP;
- fmd->domain->flip_ratio = 0.97f;
- fmd->domain->particle_randomness = 0.1f;
- fmd->domain->particle_number = 2;
- fmd->domain->particle_minimum = 8;
- fmd->domain->particle_maximum = 16;
- fmd->domain->particle_radius = 1.0f;
- fmd->domain->particle_band_width = 3.0f;
- fmd->domain->fractions_threshold = 0.05f;
- fmd->domain->sys_particle_maximum = 0;
-
- /* diffusion options*/
- fmd->domain->surface_tension = 0.0f;
- fmd->domain->viscosity_base = 1.0f;
- fmd->domain->viscosity_exponent = 6.0f;
-
- /* mesh options */
- fmd->domain->mesh_velocities = NULL;
- fmd->domain->mesh_concave_upper = 3.5f;
- fmd->domain->mesh_concave_lower = 0.4f;
- fmd->domain->mesh_particle_radius = 2.0;
- fmd->domain->mesh_smoothen_pos = 1;
- fmd->domain->mesh_smoothen_neg = 1;
- fmd->domain->mesh_scale = 2;
- fmd->domain->totvert = 0;
- fmd->domain->mesh_generator = FLUID_DOMAIN_MESH_IMPROVED;
-
- /* secondary particle options */
- fmd->domain->sndparticle_tau_min_wc = 2.0;
- fmd->domain->sndparticle_tau_max_wc = 8.0;
- fmd->domain->sndparticle_tau_min_ta = 5.0;
- fmd->domain->sndparticle_tau_max_ta = 20.0;
- fmd->domain->sndparticle_tau_min_k = 1.0;
- fmd->domain->sndparticle_tau_max_k = 5.0;
- fmd->domain->sndparticle_k_wc = 200;
- fmd->domain->sndparticle_k_ta = 40;
- fmd->domain->sndparticle_k_b = 0.5;
- fmd->domain->sndparticle_k_d = 0.6;
- fmd->domain->sndparticle_l_min = 10.0;
- fmd->domain->sndparticle_l_max = 25.0;
- fmd->domain->sndparticle_boundary = SNDPARTICLE_BOUNDARY_DELETE;
- fmd->domain->sndparticle_combined_export = SNDPARTICLE_COMBINED_EXPORT_OFF;
- fmd->domain->sndparticle_potential_radius = 2;
- fmd->domain->sndparticle_update_radius = 2;
- fmd->domain->particle_type = 0;
- fmd->domain->particle_scale = 1;
-
- /* fluid guide options */
- fmd->domain->guide_parent = NULL;
- fmd->domain->guide_alpha = 2.0f;
- fmd->domain->guide_beta = 5;
- fmd->domain->guide_vel_factor = 2.0f;
- fmd->domain->guide_source = FLUID_DOMAIN_GUIDE_SRC_DOMAIN;
-
- /* cache options */
- fmd->domain->cache_frame_start = 1;
- fmd->domain->cache_frame_end = 250;
- fmd->domain->cache_frame_pause_data = 0;
- fmd->domain->cache_frame_pause_noise = 0;
- fmd->domain->cache_frame_pause_mesh = 0;
- fmd->domain->cache_frame_pause_particles = 0;
- fmd->domain->cache_frame_pause_guide = 0;
- fmd->domain->cache_frame_offset = 0;
- fmd->domain->cache_flag = 0;
- fmd->domain->cache_type = FLUID_DOMAIN_CACHE_REPLAY;
- fmd->domain->cache_mesh_format = FLUID_DOMAIN_FILE_BIN_OBJECT;
-#ifdef WITH_OPENVDB
- fmd->domain->cache_data_format = FLUID_DOMAIN_FILE_OPENVDB;
- fmd->domain->cache_particle_format = FLUID_DOMAIN_FILE_OPENVDB;
- fmd->domain->cache_noise_format = FLUID_DOMAIN_FILE_OPENVDB;
-#else
+ /* Turn off incompatible options. */
+#ifndef WITH_OPENVDB
fmd->domain->cache_data_format = FLUID_DOMAIN_FILE_UNI;
fmd->domain->cache_particle_format = FLUID_DOMAIN_FILE_UNI;
fmd->domain->cache_noise_format = FLUID_DOMAIN_FILE_UNI;
#endif
+#ifndef WITH_OPENVDB_BLOSC
+ fmd->domain->openvdb_compression = VDB_COMPRESSION_ZIP;
+#endif
+
+ fmd->domain->effector_weights = BKE_effector_add_weights(NULL);
+ fmd->domain->fluid_mutex = BLI_rw_mutex_alloc();
+
char cache_name[64];
BKE_fluid_cache_new_name_for_current_session(sizeof(cache_name), cache_name);
BKE_modifier_path_init(
fmd->domain->cache_directory, sizeof(fmd->domain->cache_directory), cache_name);
- /* time options */
- fmd->domain->time_scale = 1.0;
- fmd->domain->cfl_condition = 4.0;
- fmd->domain->timesteps_minimum = 1;
- fmd->domain->timesteps_maximum = 4;
-
- /* display options */
- fmd->domain->slice_method = FLUID_DOMAIN_SLICE_VIEW_ALIGNED;
- fmd->domain->axis_slice_method = AXIS_SLICE_FULL;
- fmd->domain->slice_axis = 0;
- fmd->domain->interp_method = 0;
- fmd->domain->draw_velocity = false;
- fmd->domain->slice_per_voxel = 5.0f;
- fmd->domain->slice_depth = 0.5f;
- fmd->domain->display_thickness = 1.0f;
- fmd->domain->coba = NULL;
- fmd->domain->vector_scale = 1.0f;
- fmd->domain->vector_draw_type = VECTOR_DRAW_NEEDLE;
- fmd->domain->use_coba = false;
- fmd->domain->coba_field = FLUID_DOMAIN_FIELD_DENSITY;
-
- /* -- Deprecated / unsed options (below)-- */
-
/* pointcache options */
- BLI_listbase_clear(&fmd->domain->ptcaches[1]);
fmd->domain->point_cache[0] = BKE_ptcache_add(&(fmd->domain->ptcaches[0]));
fmd->domain->point_cache[0]->flag |= PTCACHE_DISK_CACHE;
fmd->domain->point_cache[0]->step = 1;
fmd->domain->point_cache[1] = NULL; /* Deprecated */
- fmd->domain->cache_comp = SM_CACHE_LIGHT;
- fmd->domain->cache_high_comp = SM_CACHE_LIGHT;
-
- /* OpenVDB cache options */
-#ifdef WITH_OPENVDB_BLOSC
- fmd->domain->openvdb_compression = VDB_COMPRESSION_BLOSC;
-#else
- fmd->domain->openvdb_compression = VDB_COMPRESSION_ZIP;
-#endif
- fmd->domain->clipping = 1e-6f;
- fmd->domain->openvdb_data_depth = 0;
}
else if (fmd->type & MOD_FLUID_TYPE_FLOW) {
if (fmd->flow) {
BKE_fluid_modifier_freeFlow(fmd);
}
- /* flow object data */
- fmd->flow = MEM_callocN(sizeof(FluidFlowSettings), "MantaFlow");
+ fmd->flow = DNA_struct_default_alloc(FluidFlowSettings);
fmd->flow->fmd = fmd;
- fmd->flow->mesh = NULL;
- fmd->flow->psys = NULL;
- fmd->flow->noise_texture = NULL;
-
- /* initial velocity */
- fmd->flow->verts_old = NULL;
- fmd->flow->numverts = 0;
- fmd->flow->vel_multi = 1.0f;
- fmd->flow->vel_normal = 0.0f;
- fmd->flow->vel_random = 0.0f;
- fmd->flow->vel_coord[0] = 0.0f;
- fmd->flow->vel_coord[1] = 0.0f;
- fmd->flow->vel_coord[2] = 0.0f;
-
- /* emission */
- fmd->flow->density = 1.0f;
- fmd->flow->color[0] = 0.7f;
- fmd->flow->color[1] = 0.7f;
- fmd->flow->color[2] = 0.7f;
- fmd->flow->fuel_amount = 1.0f;
- fmd->flow->temperature = 1.0f;
- fmd->flow->volume_density = 0.0f;
- fmd->flow->surface_distance = 1.5f;
- fmd->flow->particle_size = 1.0f;
- fmd->flow->subframes = 0;
-
- /* texture control */
- fmd->flow->source = FLUID_FLOW_SOURCE_MESH;
- fmd->flow->texture_size = 1.0f;
-
- fmd->flow->type = FLUID_FLOW_TYPE_SMOKE;
- fmd->flow->behavior = FLUID_FLOW_BEHAVIOR_GEOMETRY;
- fmd->flow->flags = FLUID_FLOW_ABSOLUTE | FLUID_FLOW_USE_PART_SIZE | FLUID_FLOW_USE_INFLOW;
}
else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
if (fmd->effector) {
BKE_fluid_modifier_freeEffector(fmd);
}
- /* effector object data */
- fmd->effector = MEM_callocN(sizeof(FluidEffectorSettings), "MantaEffector");
+ fmd->effector = DNA_struct_default_alloc(FluidEffectorSettings);
fmd->effector->fmd = fmd;
- fmd->effector->mesh = NULL;
- fmd->effector->verts_old = NULL;
- fmd->effector->numverts = 0;
- fmd->effector->surface_distance = 0.0f;
- fmd->effector->type = FLUID_EFFECTOR_TYPE_COLLISION;
- fmd->effector->flags = FLUID_EFFECTOR_USE_EFFEC;
-
- /* guide options */
- fmd->effector->guide_mode = FLUID_EFFECTOR_GUIDE_OVERRIDE;
- fmd->effector->vel_multi = 1.0f;
}
}
@@ -5147,7 +5006,9 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->particle_radius = fds->particle_radius;
tfds->particle_band_width = fds->particle_band_width;
tfds->fractions_threshold = fds->fractions_threshold;
+ tfds->fractions_distance = fds->fractions_distance;
tfds->sys_particle_maximum = fds->sys_particle_maximum;
+ tfds->simulation_method = fds->simulation_method;
/* diffusion options*/
tfds->surface_tension = fds->surface_tension;
@@ -5219,7 +5080,6 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->timesteps_maximum = fds->timesteps_maximum;
/* display options */
- tfds->slice_method = fds->slice_method;
tfds->axis_slice_method = fds->axis_slice_method;
tfds->slice_axis = fds->slice_axis;
tfds->interp_method = fds->interp_method;
@@ -5227,13 +5087,23 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->slice_per_voxel = fds->slice_per_voxel;
tfds->slice_depth = fds->slice_depth;
tfds->display_thickness = fds->display_thickness;
+ tfds->show_gridlines = fds->show_gridlines;
if (fds->coba) {
tfds->coba = MEM_dupallocN(fds->coba);
}
tfds->vector_scale = fds->vector_scale;
tfds->vector_draw_type = fds->vector_draw_type;
+ tfds->vector_field = fds->vector_field;
+ tfds->vector_scale_with_magnitude = fds->vector_scale_with_magnitude;
+ tfds->vector_draw_mac_components = fds->vector_draw_mac_components;
tfds->use_coba = fds->use_coba;
tfds->coba_field = fds->coba_field;
+ tfds->grid_scale = fds->grid_scale;
+ tfds->gridlines_color_field = fds->gridlines_color_field;
+ tfds->gridlines_lower_bound = fds->gridlines_lower_bound;
+ tfds->gridlines_upper_bound = fds->gridlines_upper_bound;
+ copy_v4_v4(tfds->gridlines_range_color, fds->gridlines_range_color);
+ tfds->gridlines_cell_filter = fds->gridlines_cell_filter;
/* -- Deprecated / unsed options (below)-- */