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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs