[Bf-blender-cvs] [39eb8fa1a61] fluid-mantaflow: new method for levelset generation from mesh
Sebastián Barschkis
noreply at git.blender.org
Sat Aug 12 01:35:47 CEST 2017
Commit: 39eb8fa1a6118a37b36cb383f9599efe42e7c9a8
Author: Sebastián Barschkis
Date: Wed Aug 9 17:35:38 2017 +0200
Branches: fluid-mantaflow
https://developer.blender.org/rB39eb8fa1a6118a37b36cb383f9599efe42e7c9a8
new method for levelset generation from mesh
now considering planes as well
===================================================================
M intern/mantaflow/intern/strings/liquid_script.h
M source/blender/blenkernel/intern/smoke.c
===================================================================
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index 4ca8b0c61bd..a7a962fe344 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -154,7 +154,6 @@ def liquid_post_step_low_$ID$():\n\
# TODO (sebbas): liquid inflow\n\
#invel_s$ID$.clear()\n\
\n\
- phiIn_s$ID$.setConst(9999)\n\
phiObs_s$ID$.setConst(9999)\n\
phiOut_s$ID$.setConst(9999)\n\
phiOutIn_s$ID$.setConst(9999)\n\
@@ -183,8 +182,8 @@ def manta_step_$ID$(framenr):\n\
\n\
phiOut_s$ID$.join(phiOutIn_s$ID$)\n\
\n\
- updateFractions(flags=flags_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$, boundaryWidth=boundaryWidth_s$ID$)\n\
- setObstacleFlags(flags=flags_s$ID$, phiObs=phiObs_s$ID$, phiOut=phiOut_s$ID$, fractions=fractions_s$ID$)\n\
+ #updateFractions(flags=flags_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$, boundaryWidth=boundaryWidth_s$ID$)\n\
+ setObstacleFlags(flags=flags_s$ID$, phiObs=phiObs_s$ID$, phiOut=phiOut_s$ID$)#, fractions=fractions_s$ID$)\n\
\n\
sampleLevelsetWithParticles(phi=phiIn_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, discretization=particleNumber_s$ID$, randomness=randomness_s$ID$, refillEmpty=True)\n\
flags_s$ID$.updateFromLevelset(phi_s$ID$, phiObs_s$ID$)\n\
@@ -264,13 +263,13 @@ def liquid_step_$ID$():\n\
extrapolateVec3Simple(vel=obvelC_s$ID$, phi=phiObsIn_s$ID$, distance=3, inside=False)\n\
resampleVec3ToMac(source=obvelC_s$ID$, target=obvel_s$ID$)\n\
\n\
- extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=2, phiObs=phiObs_s$ID$, intoObs=True)\n\
- setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, fractions=fractions_s$ID$, phiObs=phiObs_s$ID$)#, obvel=obvel_s$ID$) # TODO: uncomment for obvel support (once fraction wallbcs works)\n\
+ #extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=2, phiObs=phiObs_s$ID$, intoObs=True)\n\
+ setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, phiObs=phiObs_s$ID$, obvel=obvel_s$ID$)#, fractions=fractions_s$ID$) # TODO: uncomment for obvel support (once fraction wallbcs works)\n\
\n\
- solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, phi=phi_s$ID$, fractions=fractions_s$ID$)\n\
+ solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, phi=phi_s$ID$)#, fractions=fractions_s$ID$)\n\
\n\
- extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=4, phiObs=phiObs_s$ID$, intoObs=True)\n\
- setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, fractions=fractions_s$ID$, phiObs=phiObs_s$ID$)#, obvel=obvel_s$ID$) # TODO: uncomment for obvel support (once fraction wallbcs works)\n\
+ #extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=4, phiObs=phiObs_s$ID$, intoObs=False)\n\
+ setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, phiObs=phiObs_s$ID$, obvel=obvel_s$ID$)#, fractions=fractions_s$ID$) # TODO: uncomment for obvel support (once fraction wallbcs works)\n\
\n\
if (dim_s$ID$==3):\n\
# mis-use phiParts as temp grid to close the mesh\n\
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index c1be6259f71..62e8ad57872 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1571,18 +1571,87 @@ static void emit_from_particles(
}
}
+//static void update_mesh_distances(int index, float *mesh_distances, BVHTreeFromMesh *treeData, const float ray_start[3]) {
+//
+// /* Calculate map of (minimum) distances to flow/obstacle surface. Distances outside mesh are positive, inside negative */
+// float min_dist = 9999;
+// float inv_ray[3] = {0.0f};
+// /* Raycasts in 14 directions (6 axis + 8 quadrant diagonals) are at least necessary */
+// float ray_dirs[14][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 }, { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f },
+// { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f },
+// { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } };
+// size_t ray_cnt = sizeof ray_dirs / sizeof ray_dirs[0];
+//
+// for (int i = 0; i < ray_cnt; i++) {
+// BVHTreeRayHit hit_tree = {0};
+// hit_tree.index = -1;
+// hit_tree.dist = 9999;
+//
+// BLI_bvhtree_ray_cast(treeData->tree, ray_start, ray_dirs[i], 0.0f, &hit_tree, treeData->raycast_callback, treeData);
+//
+// /* Save hit dist first time */
+// min_dist = normalize_v3(&hit_tree.dist);
+//
+// if (hit_tree.index != -1) {
+// /* Is dot > 0? Are we inside the mesh? */
+// if (dot_v3v3(ray_dirs[i], hit_tree.no) > 0) {
+//
+// /* Also cast a ray in opposite direction to make sure
+// * point is at least surrounded by two faces */
+// hit_tree.index = -1;
+// hit_tree.dist = 9999;
+//
+// negate_v3_v3(inv_ray, ray_dirs[i]);
+// BLI_bvhtree_ray_cast(treeData->tree, ray_start, inv_ray, 0.0f, &hit_tree, treeData->raycast_callback, treeData);
+//
+// /* Save hit dist second time */
+// min_dist = MIN2(min_dist, normalize_v3(&hit_tree.dist));
+//
+// if (hit_tree.index != -1) {
+// if (dot_v3v3(inv_ray, hit_tree.no) > 0) {
+// /* Current index is inside mesh, place negative mesh distance */
+// /* If map previously contained pos value (outside), use only neg min_dist to ensure neg inside mesh. Otherwise evaluate min2 as usual */
+// mesh_distances[index] = (mesh_distances[index] > 0) ? -1.0f * min_dist : -1.0f * MIN2(fabsf(mesh_distances[index]), min_dist);
+// }
+// }
+// }
+// }
+// /* No negative, previously written distance at index,
+// * so just write positive value corresponding to outside distance into map */
+// if (mesh_distances[index] > 0) {
+// mesh_distances[index] = MIN2(mesh_distances[index], min_dist);
+// }
+//
+// // TODO (sebbas): liquid inflow
+// /* Ensure that planes also get setup */
+//// BVHTreeNearest nearest = {0};
+//// const float surface_distance = 0.5f;
+//// nearest.index = -1;
+//// nearest.dist_sq = surface_distance * surface_distance; /* find_nearest uses squared distance */
+////
+//// if (BLI_bvhtree_find_nearest(treeData->tree, ray_start, &nearest, treeData->nearest_callback, treeData) != -1) {
+//// mesh_distances[index] = - 5; // very small value at levelset border indicating inside region
+//// }
+// }
+//}
+
+/* Calculate map of (minimum) distances to flow/obstacle surface. Distances outside mesh are positive, inside negative */
static void update_mesh_distances(int index, float *mesh_distances, BVHTreeFromMesh *treeData, const float ray_start[3]) {
- /* Calculate map of (minimum) distances to flow/obstacle surface. Distances outside mesh are positive, inside negative */
float min_dist = 9999;
- float inv_ray[3] = {0.0f};
- /* Raycasts in 14 directions (6 axis + 8 quadrant diagonals) are at least necessary */
+
+ /* Raycasts in 14 directions (6 axis + 8 quadrant diagonals) */
float ray_dirs[14][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 }, { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f },
{ 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } };
size_t ray_cnt = sizeof ray_dirs / sizeof ray_dirs[0];
+ /* If stays true, a point is considered to be inside the mesh */
+ bool inside = true;
+
+ /* Check all ray directions */
for (int i = 0; i < ray_cnt; i++) {
BVHTreeRayHit hit_tree = {0};
hit_tree.index = -1;
@@ -1590,50 +1659,28 @@ static void update_mesh_distances(int index, float *mesh_distances, BVHTreeFromM
BLI_bvhtree_ray_cast(treeData->tree, ray_start, ray_dirs[i], 0.0f, &hit_tree, treeData->raycast_callback, treeData);
- /* Save hit dist first time */
- min_dist = normalize_v3(&hit_tree.dist);
+ /* Ray did not hit mesh. Current point definitely not inside mesh. */
+ if (hit_tree.index == -1) { inside = false; continue; }
- if (hit_tree.index != -1) {
- /* Is dot > 0? Are we inside the mesh? */
- if (dot_v3v3(ray_dirs[i], hit_tree.no) > 0) {
-
- /* Also cast a ray in opposite direction to make sure
- * point is at least surrounded by two faces */
- hit_tree.index = -1;
- hit_tree.dist = 9999;
+ /* Save new minimum hit dist */
+ min_dist = MIN2(min_dist, hit_tree.dist);
- negate_v3_v3(inv_ray, ray_dirs[i]);
- BLI_bvhtree_ray_cast(treeData->tree, ray_start, inv_ray, 0.0f, &hit_tree, treeData->raycast_callback, treeData);
+ /* Ray and normal are in opposing directions. Current point definitely not inside mesh. */
+ if (dot_v3v3(ray_dirs[i], hit_tree.no) < 0) { inside = false; }
+ }
- /* Save hit dist second time */
- min_dist = MIN2(min_dist, normalize_v3(&hit_tree.dist));
+ /* Update mesh distance in map */
+ mesh_distances[index] = MIN2(fabsf(mesh_distances[index]), min_dist);
- if (hit_tree.index != -1) {
- if (dot_v3v3(inv_ray, hit_tree.no) > 0) {
- /* Current index is inside mesh, place negative mesh distance */
- /* If map previously contained pos value (outside), use only neg min_dist to ensure neg inside mesh. Otherwise evaluate min2 as usual */
- mesh_distances[index] = (mesh_distances[index] > 0) ? -1.0f * min_dist : -1.0f * MIN2(fabsf(mesh_distances[index]), min_dist);
- }
- }
- }
- }
- /* No negative, previously written distance at index,
- * so just write positive value corresponding to outside distance into map */
- if (mesh_distances[index] > 0) {
- mesh_distances[index] = MIN2(mesh_distances[index], min_dist);
- }
+ /* If point is on surface it is also considered to be "inside" the mesh (negative levelset) */
+ BVHTreeNearest nearest = {0};
+ const float surface_distance = 0.5f;
+ nearest.index = -1;
+ nearest.dist_sq = surface_distance * surface_distance;
+ inside |= (BLI_bvhtree_find_nearest(treeData->tree, ray_start, &nearest, treeData->nearest_callback, treeD
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list