[Bf-blender-cvs] [a5c4a44df67] master: Fluid: Bounding boxes for effector objects

Sebastián Barschkis noreply at git.blender.org
Wed Mar 4 18:47:59 CET 2020


Commit: a5c4a44df67ed69844a433179629d861cf10f438
Author: Sebastián Barschkis
Date:   Wed Mar 4 18:44:23 2020 +0100
Branches: master
https://developer.blender.org/rBa5c4a44df67ed69844a433179629d861cf10f438

Fluid: Bounding boxes for effector objects

This commit adds bounding box support for emission objects - similarly to flow objects. Before, each effector object had to iterate over the entire domain. Bake times of scenes with multiple obstacles improved significantly with this optimization.

Other improvements that were implemented alongside the bbox feature:
- Option for subframe sampling for effector objects
- Option to enable / disable effectors (can be animated)
- Optimization for static objects. If a flow or effector object does not move and the adaptive domain is not in use, the bake time will be optimized further by reusing the flow / effector grids from the previous frame (no recalculation).

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

M	intern/mantaflow/extern/manta_fluid_API.h
M	intern/mantaflow/intern/MANTA_main.cpp
M	intern/mantaflow/intern/MANTA_main.h
M	intern/mantaflow/intern/manta_fluid_API.cpp
M	intern/mantaflow/intern/strings/fluid_script.h
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/makesdna/DNA_fluid_types.h
M	source/blender/makesrna/intern/rna_fluid.c

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

diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h
index 249eb2b4780..5ed94d99edd 100644
--- a/intern/mantaflow/extern/manta_fluid_API.h
+++ b/intern/mantaflow/extern/manta_fluid_API.h
@@ -93,7 +93,9 @@ int manta_get_res_x(struct MANTA *fluid);
 int manta_get_res_y(struct MANTA *fluid);
 int manta_get_res_z(struct MANTA *fluid);
 float *manta_get_phi_in(struct MANTA *fluid);
+float *manta_get_phistatic_in(struct MANTA *fluid);
 float *manta_get_phiobs_in(struct MANTA *fluid);
+float *manta_get_phiobsstatic_in(struct MANTA *fluid);
 float *manta_get_phiout_in(struct MANTA *fluid);
 
 /* Smoke functions */
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 34efe7a8c2d..4759888e234 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -130,6 +130,7 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
 
   // Fluid low res grids
   mPhiIn = nullptr;
+  mPhiStaticIn = nullptr;
   mPhiOutIn = nullptr;
   mPhi = nullptr;
 
@@ -140,6 +141,7 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
 
   // Fluid obstacle
   mPhiObsIn = nullptr;
+  mPhiObsStaticIn = nullptr;
   mNumObstacle = nullptr;
   mObVelocityX = nullptr;
   mObVelocityY = nullptr;
@@ -3007,6 +3009,7 @@ void MANTA::updatePointers()
 
   mFlags = (int *)pyObjectToPointer(callPythonFunction("flags" + solver_ext, func));
   mPhiIn = (float *)pyObjectToPointer(callPythonFunction("phiIn" + solver_ext, func));
+  mPhiStaticIn = (float *)pyObjectToPointer(callPythonFunction("phiSIn" + solver_ext, func));
   mVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_vel" + solver_ext, func));
   mVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_vel" + solver_ext, func));
   mVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_vel" + solver_ext, func));
@@ -3019,6 +3022,8 @@ void MANTA::updatePointers()
   }
   if (mUsingObstacle) {
     mPhiObsIn = (float *)pyObjectToPointer(callPythonFunction("phiObsIn" + solver_ext, func));
+    mPhiObsStaticIn = (float *)pyObjectToPointer(
+        callPythonFunction("phiObsSIn" + solver_ext, func));
     mObVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_obvel" + solver_ext, func));
     mObVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_obvel" + solver_ext, func));
     mObVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_obvel" + solver_ext, func));
diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h
index 8c99a64bf03..dd003d13f51 100644
--- a/intern/mantaflow/intern/MANTA_main.h
+++ b/intern/mantaflow/intern/MANTA_main.h
@@ -376,10 +376,18 @@ struct MANTA {
   {
     return mPhiIn;
   }
+  inline float *getPhiStaticIn()
+  {
+    return mPhiStaticIn;
+  }
   inline float *getPhiObsIn()
   {
     return mPhiObsIn;
   }
+  inline float *getPhiObsStaticIn()
+  {
+    return mPhiObsStaticIn;
+  }
   inline float *getPhiGuideIn()
   {
     return mPhiGuideIn;
@@ -823,7 +831,9 @@ struct MANTA {
 
   // Liquid grids
   float *mPhiIn;
+  float *mPhiStaticIn;
   float *mPhiObsIn;
+  float *mPhiObsStaticIn;
   float *mPhiGuideIn;
   float *mPhiOutIn;
   float *mPhi;
diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp
index 47a643928e9..7e3e4520485 100644
--- a/intern/mantaflow/intern/manta_fluid_API.cpp
+++ b/intern/mantaflow/intern/manta_fluid_API.cpp
@@ -332,10 +332,18 @@ float *manta_get_phi_in(MANTA *fluid)
 {
   return fluid->getPhiIn();
 }
+float *manta_get_phistatic_in(MANTA *fluid)
+{
+  return fluid->getPhiStaticIn();
+}
 float *manta_get_phiobs_in(MANTA *fluid)
 {
   return fluid->getPhiObsIn();
 }
+float *manta_get_phiobsstatic_in(MANTA *fluid)
+{
+  return fluid->getPhiObsStaticIn();
+}
 float *manta_get_phiout_in(MANTA *fluid)
 {
   return fluid->getPhiOutIn();
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index 4d0909d9464..abfc1eff566 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -230,6 +230,7 @@ y_vel_s$ID$       = s$ID$.create(RealGrid)\n\
 z_vel_s$ID$       = s$ID$.create(RealGrid)\n\
 pressure_s$ID$    = s$ID$.create(RealGrid)\n\
 phiObs_s$ID$      = s$ID$.create(LevelsetGrid)\n\
+phiSIn_s$ID$      = s$ID$.create(LevelsetGrid) # helper for static flow objects\n\
 phiIn_s$ID$       = s$ID$.create(LevelsetGrid)\n\
 phiOut_s$ID$      = s$ID$.create(LevelsetGrid)\n\
 forces_s$ID$      = s$ID$.create(Vec3Grid)\n\
@@ -252,6 +253,7 @@ const std::string fluid_alloc_obstacle =
     "\n\
 mantaMsg('Allocating obstacle data')\n\
 numObs_s$ID$     = s$ID$.create(RealGrid)\n\
+phiObsSIn_s$ID$  = s$ID$.create(LevelsetGrid) # helper for static obstacles\n\
 phiObsIn_s$ID$   = s$ID$.create(LevelsetGrid)\n\
 obvel_s$ID$      = s$ID$.create(MACGrid)\n\
 obvelC_s$ID$     = s$ID$.create(Vec3Grid)\n\
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index 2226eabe55f..1c3f576f1fa 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -174,6 +174,7 @@ def liquid_adaptive_step_$ID$(framenr):\n\
     \n\
     if using_obstacle_s$ID$:\n\
         mantaMsg('Initializing obstacle levelset')\n\
+        phiObsIn_s$ID$.join(phiObsSIn_s$ID$) # Join static obstacle map\n\
         phiObsIn_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
         extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=6, inside=True)\n\
         extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=3, inside=False)\n\
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index 719ebbfef3e..04f03100cb9 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -277,6 +277,7 @@ def smoke_adaptive_step_$ID$(framenr):\n\
     \n\
     if using_obstacle_s$ID$:\n\
         mantaMsg('Initializing obstacle levelset')\n\
+        phiObsIn_s$ID$.join(phiObsSIn_s$ID$) # Join static obstacle map\n\
         phiObsIn_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
         extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=6, inside=True)\n\
         extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=3, inside=False)\n\
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 6fc732687d1..cfbbd6ea858 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -564,19 +564,19 @@ static bool BKE_fluid_modifier_init(
 static void manta_smoke_calc_transparency(FluidDomainSettings *mds, ViewLayer *view_layer);
 static float calc_voxel_transp(
     float *result, float *input, int res[3], int *pixel, float *t_ray, float correct);
-static void update_mesh_distances(int index,
-                                  float *mesh_distances,
-                                  BVHTreeFromMesh *tree_data,
-                                  const float ray_start[3],
-                                  float surface_thickness,
-                                  int use_plane_init);
+static void update_distances(int index,
+                             float *mesh_distances,
+                             BVHTreeFromMesh *tree_data,
+                             const float ray_start[3],
+                             float surface_thickness,
+                             int use_plane_init);
 
 static int get_light(ViewLayer *view_layer, float *light)
 {
   Base *base_tmp = NULL;
   int found_light = 0;
 
-  // try to find a lamp, preferably local
+  /* Try to find a lamp, preferably local. */
   for (base_tmp = FIRSTBASE(view_layer); base_tmp; base_tmp = base_tmp->next) {
     if (base_tmp->object->type == OB_LAMP) {
       Light *la = base_tmp->object->data;
@@ -595,25 +595,357 @@ static int get_light(ViewLayer *view_layer, float *light)
   return found_light;
 }
 
+static void clamp_bounds_in_domain(FluidDomainSettings *mds,
+                                   int min[3],
+                                   int max[3],
+                                   float *min_vel,
+                                   float *max_vel,
+                                   int margin,
+                                   float dt)
+{
+  int i;
+  for (i = 0; i < 3; i++) {
+    int adapt = (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) ? mds->adapt_res : 0;
+    /* Add some margin. */
+    min[i] -= margin;
+    max[i] += margin;
+
+    /* Adapt to velocity. */
+    if (min_vel && min_vel[i] < 0.0f) {
+      min[i] += (int)floor(min_vel[i] * dt);
+    }
+    if (max_vel && max_vel[i] > 0.0f) {
+      max[i] += (int)ceil(max_vel[i] * dt);
+    }
+
+    /* Clamp within domain max size. */
+    CLAMP(min[i], -adapt, mds->base_res[i] + adapt);
+    CLAMP(max[i], -adapt, mds->base_res[i] + adapt);
+  }
+}
+
+static bool is_static_object(Object *ob)
+{
+
+  /* Check if the object has modifiers that might make the object "dynamic". */
+  ModifierData *md = ob->modifiers.first;
+  for (; md; md = md->next) {
+    if (ELEM(md->type,
+             eModifierType_Cloth,
+             eModifierType_DynamicPaint,
+             eModifierType_Explode,
+             eModifierType_Ocean,
+             eModifierType_ShapeKey,
+             eModifierType_Softbody)) {
+      return false;
+    }
+  }
+
+  /* Finally, check if the object has animation data. If so, it is considered dynamic. */
+  return !BKE_object_moves_in_time(ob, true);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Obstacles
+/** \name Bounding Box
  * \{ */
 
+typedef struct EmissionMap {
+  float *influence;
+  float *velocity;
+  float *distances;
+  float *numobjs;
+  int min[3], max[3], res[3];
+  int hmin[3], hmax[3], hres[3];
+  int total_cells, valid;
+} EmissionMap;
+
+static void em_boundInsert(EmissionMap *em, float point[3])
+{
+  int i = 0;
+  if (!em->valid) {
+    for (; i < 3; i++) {
+      em->min[i] = (int)floor(point[i]);
+      em

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list