| 11 | { |
| 12 | |
| 13 | std::optional<float> signedDistanceToMesh( const MeshPart& mp, const Vector3f& p, const SignedDistanceToMeshOptions& op ) |
| 14 | { |
| 15 | assert( op.signMode != SignDetectionMode::OpenVDB ); |
| 16 | |
| 17 | auto minDistSq = op.minDistSq; |
| 18 | auto maxDistSq = op.maxDistSq; |
| 19 | if ( !op.nullOutsideMinMax && op.signMode == SignDetectionMode::ProjectionNormal ) |
| 20 | { |
| 21 | // if the sign is determined by the normal at projection point then projection point must be found precisely |
| 22 | minDistSq = 0; |
| 23 | maxDistSq = FLT_MAX; |
| 24 | } |
| 25 | const auto proj = findProjection( p, mp, maxDistSq, nullptr, minDistSq ); |
| 26 | if ( !proj && op.signMode == SignDetectionMode::ProjectionNormal ) |
| 27 | return {}; // no projection point found |
| 28 | |
| 29 | if ( op.nullOutsideMinMax && ( proj.distSq < minDistSq || proj.distSq >= maxDistSq ) ) // note that proj.distSq == minDistSq (e.g. == 0) is a valid situation |
| 30 | return {}; // distance is too small or too large, discard them |
| 31 | |
| 32 | float dist = std::sqrt( proj.distSq ); |
| 33 | switch ( op.signMode ) |
| 34 | { |
| 35 | case SignDetectionMode::ProjectionNormal: |
| 36 | if ( !mp.mesh.isOutsideByProjNorm( p, proj, mp.region ) ) |
| 37 | dist = -dist; |
| 38 | break; |
| 39 | |
| 40 | case SignDetectionMode::WindingRule: |
| 41 | { |
| 42 | const Line3d ray( Vector3d( p ), Vector3d::plusX() ); |
| 43 | int count = 0; |
| 44 | rayMeshIntersectAll( mp, ray, [&count] ( auto&& ) { ++count; return true; } ); |
| 45 | if ( count % 2 == 1 ) // inside |
| 46 | dist = -dist; |
| 47 | break; |
| 48 | } |
| 49 | |
| 50 | case SignDetectionMode::HoleWindingRule: |
| 51 | assert( !mp.region ); |
| 52 | if ( !mp.mesh.isOutside( p, op.windingNumberThreshold, op.windingNumberBeta ) ) |
| 53 | dist = -dist; |
| 54 | break; |
| 55 | |
| 56 | default: ; //nothing |
| 57 | } |
| 58 | return dist; |
| 59 | } |
| 60 | |
| 61 | void processCloseTriangles( const MeshPart& mp, const Triangle3f & t, float rangeSq, const TriangleCallback & call ) |
| 62 | { |
no test coverage detected