[Bf-blender-cvs] [33317b46477] blender-v2.82-release: Fluid: Fixes for flow objects and initial velocities

Sebastián Barschkis noreply at git.blender.org
Wed Jan 29 19:22:42 CET 2020


Commit: 33317b4647771e2031722531c6f9e6b124255a74
Author: Sebastián Barschkis
Date:   Wed Jan 29 19:21:09 2020 +0100
Branches: blender-v2.82-release
https://developer.blender.org/rB33317b4647771e2031722531c6f9e6b124255a74

Fluid: Fixes for flow objects and initial velocities

This commit cleans up the flow emission code (i.e. the code that determines where flow is generated). It also addresses an issue with initial velocities.

Related issues (that might be fixed through this commit) are: T73422, T72949

===================================================================

M	intern/mantaflow/intern/strings/liquid_script.h
M	intern/mantaflow/intern/strings/smoke_script.h
M	source/blender/blenkernel/intern/fluid.c
M	source/blender/editors/physics/physics_fluid.c

===================================================================

diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index 6cbbf06f0d2..bb42b781c19 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -175,9 +175,6 @@ def liquid_adaptive_step_$ID$(framenr):\n\
         extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
         extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
     \n\
-    mantaMsg('Initializing fluid levelset')\n\
-    extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
-    extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
     phi_s$ID$.join(phiIn_s$ID$)\n\
     \n\
     if using_obstacle_s$ID$:\n\
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index 9277923fa7a..ad966503fd1 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -288,10 +288,6 @@ def smoke_adaptive_step_$ID$(framenr):\n\
         extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
         extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
     \n\
-    mantaMsg('Initializing fluid levelset')\n\
-    extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
-    extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
-    \n\
     if using_outflow_s$ID$:\n\
         phiOut_s$ID$.join(phiOutIn_s$ID$)\n\
     \n\
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index cb94a78e619..12c65027e25 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -630,9 +630,10 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
   ObstaclesFromDMData *data = userdata;
   FluidDomainSettings *mds = data->mds;
 
-  /* Distance from unit cube center to one of the vertices.
-   * I.e. half the cube diagonal or sqrt(3) * 0.5. */
-  const float surface_distance = 0.867f;
+  /* Distance between two opposing vertices in a unit cube.
+   * I.e. the unit cube diagonal or sqrt(3).
+   * This value is our nearest neighbour search distance. */
+  const float surface_distance = 1.732;
 
   for (int x = mds->res_min[0]; x < mds->res_max[0]; x++) {
     for (int y = mds->res_min[1]; y < mds->res_max[1]; y++) {
@@ -646,7 +647,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
                         surface_distance; /* find_nearest uses squared distance */
       bool has_inc_obj = false;
 
-      /* find the nearest point on the mesh */
+      /* Find the nearest point on the mesh. */
       if (BLI_bvhtree_find_nearest(
               data->tree->tree, ray_start, &nearest, data->tree->nearest_callback, data->tree) !=
           -1) {
@@ -1433,11 +1434,12 @@ static void update_mesh_distances(int index,
 {
   float min_dist = PHI_MAX;
 
-  /* Ensure that planes get initialized correctly. */
+  /* a) Planar initialization */
   if (use_plane_init) {
     BVHTreeNearest nearest = {0};
     nearest.index = -1;
-    nearest.dist_sq = surface_thickness;
+    nearest.dist_sq = surface_thickness *
+                      surface_thickness; /* find_nearest uses squared distance */
 
     if (BLI_bvhtree_find_nearest(
             tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) {
@@ -1445,12 +1447,14 @@ static void update_mesh_distances(int index,
       sub_v3_v3v3(ray, ray_start, nearest.co);
       min_dist = len_v3(ray);
       min_dist = (-1.0f) * fabsf(min_dist);
-      mesh_distances[index] = MIN2(mesh_distances[index], min_dist);
+      mesh_distances[index] = min_dist;
     }
     return;
   }
 
-  /* First pass: Ray-casts in 26 directions
+  /* b) Volumetric initialization: 1) Ray-casts around mesh object. */
+
+  /* Ray-casts in 26 directions.
    * (6 main axis + 12 quadrant diagonals (2D) + 8 octant diagonals (3D)). */
   float ray_dirs[26][3] = {
       {1.0f, 0.0f, 0.0f},   {0.0f, 1.0f, 0.0f},   {0.0f, 0.0f, 1.0f},  {-1.0f, 0.0f, 0.0f},
@@ -1462,8 +1466,9 @@ static void update_mesh_distances(int index,
       {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}};
   size_t ray_cnt = sizeof ray_dirs / sizeof ray_dirs[0];
 
-  /* Count for ray misses (no face hit) and cases where ray direction matches face normal
-   * direction. */
+  /* Count ray mesh misses (i.e. no face hit) and cases where the ray direction matches the face
+   * normal direction. From this information it can be derived whether a cell is inside or outside
+   * the mesh. */
   int miss_cnt = 0, dir_cnt = 0;
   min_dist = PHI_MAX;
 
@@ -1481,14 +1486,13 @@ static void update_mesh_distances(int index,
                          tree_data->raycast_callback,
                          tree_data);
 
-    /* Ray did not hit mesh. Current point definitely not inside mesh. Inside mesh all rays have to
-     * hit. */
+    /* Ray did not hit mesh.
+     * Current point definitely not inside mesh. Inside mesh as all rays have to hit. */
     if (hit_tree.index == -1) {
       miss_cnt++;
-      continue;
     }
 
-    /* Ray and normal are in pointing opposite directions. */
+    /* Ray and normal are pointing in opposite directions. */
     if (dot_v3v3(ray_dirs[i], hit_tree.no) <= 0) {
       dir_cnt++;
     }
@@ -1498,25 +1502,30 @@ static void update_mesh_distances(int index,
     }
   }
 
-  /* Point lies inside mesh. Use negative sign for distance value. */
+  /* Point lies inside mesh. Use negative sign for distance value.
+   * This "if statement" has 2 conditions that can be true for points outside mesh. */
   if (!(miss_cnt > 0 || dir_cnt == ray_cnt)) {
     min_dist = (-1.0f) * fabsf(min_dist);
   }
 
-  /* Update global distance array but ensure that older entries are not overridden. */
-  mesh_distances[index] = MIN2(mesh_distances[index], min_dist);
+  /* Update global distance array with distance value. */
+  mesh_distances[index] = min_dist;
 
-  /* Second pass: Use nearest neighbor search on mesh surface. */
+  /* b) Volumetric initialization: 2) Use nearest neighbor search on mesh surface. */
+
+  /* Distance between two opposing vertices in a unit cube.
+   * I.e. the unit cube diagonal or sqrt(3).
+   * This value is our nearest neighbour search distance. */
+  const float surface_distance = 1.732;
   BVHTreeNearest nearest = {0};
   nearest.index = -1;
-  nearest.dist_sq = 5;
+  nearest.dist_sq = surface_distance * surface_distance; /* find_nearest uses squared distance. */
 
   if (BLI_bvhtree_find_nearest(
           tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) {
     float ray[3] = {0};
     sub_v3_v3v3(ray, nearest.co, ray_start);
     min_dist = len_v3(ray);
-    //    CLAMP(min_dist, 0.5, min_dist);
 
     BVHTreeRayHit hit_tree = {0};
     hit_tree.index = -1;
@@ -1529,22 +1538,23 @@ static void update_mesh_distances(int index,
     /* Only proceed if casted ray hit the mesh surface. */
     if (hit_tree.index != -1) {
 
-      /* Ray and normal are in pointing same directions: Point must lie inside mesh. */
+      /* Ray and normal are pointing in the same direction: Point must lie inside mesh. */
       if (dot_v3v3(ray, hit_tree.no) > 0) {
         min_dist = (-1.0f) * fabsf(min_dist);
       }
 
-      /* Update distance value with more accurate one from this nearest neighbor search.
-       * Skip if new value would be outside and current value has inside value already. */
-      if (!(min_dist > 0 && mesh_distances[index] <= 0)) {
-        mesh_distances[index] = min_dist;
-      }
+      /* Update distance map with more accurate distance from this nearest neighbor search. */
+      mesh_distances[index] = min_dist;
     }
   }
 
+  /* Subtract optional surface thickness value and virtually increase the object size. */
   if (surface_thickness) {
     mesh_distances[index] -= surface_thickness;
   }
+
+  /* Sanity check: Ensure that distances don't explode. */
+  CLAMP(mesh_distances[index], -PHI_MAX, PHI_MAX);
 }
 
 static void sample_mesh(FluidFlowSettings *mfs,
@@ -1578,9 +1588,10 @@ static void sample_mesh(FluidFlowSettings *mfs,
   hit.dist = PHI_MAX;
   nearest.index = -1;
 
-  /* Distance from unit cube center to one of the vertices.
-   * I.e. half the cube diagonal or sqrt(3) * 0.5. */
-  const float surface_distance = 0.867f;
+  /* Distance between two opposing vertices in a unit cube.
+   * I.e. the unit cube diagonal or sqrt(3).
+   * This value is our nearest neighbour search distance. */
+  const float surface_distance = 1.732;
   nearest.dist_sq = surface_distance * surface_distance; /* find_nearest uses squared distance. */
 
   bool is_gas_flow = (mfs->type == FLUID_FLOW_TYPE_SMOKE || mfs->type == FLUID_FLOW_TYPE_FIRE ||
@@ -1625,22 +1636,13 @@ static void sample_mesh(FluidFlowSettings *mfs,
     int v1, v2, v3, f_index = nearest.index;
     float n1[3], n2[3], n3[3], hit_normal[3];
 
-    /* Emission from surface is based on UI configurable distance value. */
-    if (mfs->surface_distance) {
-      emission_strength = sqrtf(nearest.dist_sq) / mfs->surface_distance;
-      CLAMP(emission_strength, 0.0f, 1.0f);
-      emission_strength = pow(1.0f - emission_strength, 0.5f);
-    }
-    else {
-      emission_strength = 0.0f;
-    }
-
     /* Calculate barycentric weights for nearest point. */
     v1 = mloop[mlooptri[f_index].tri[0]].v;
     v2 = mloop[mlooptri[f_index].tri[1]].v;
     v3 = mloop[mlooptri[f_index].tri[2]].v;
     interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co);
 
+    /* Initial velocity of flow object. */
     if (mfs->flags & FLUID_FLOW_INITVELOCITY && velocity_map) {
       /* Apply normal directional velocity. */
       if (mfs->vel_normal) {
@@ -1674,40 +1676,54 @@ static void sample_mesh(FluidFlowSettings *mfs,
       velocity_map[index * 3 + 2] += mfs->vel_coord[2];
     }
 
-    /* Apply vertex group influence if it is being used. */
-    if (defgrp_index != -1 && dvert) {
-      float weight_mask = defvert_find_we

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list