[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