| 37 | } |
| 38 | |
| 39 | VertScalars findSignedDistances( |
| 40 | const Mesh& refMesh, |
| 41 | const VertCoords & testPoints, const VertBitSet * validTestPoints, |
| 42 | const MeshProjectionParameters & params, |
| 43 | IPointsToMeshProjector * projector ) |
| 44 | { |
| 45 | MR_TIMER; |
| 46 | |
| 47 | AffineXf3f testToRefXf; |
| 48 | if ( params.refXf ) |
| 49 | testToRefXf = params.refXf->inverse(); |
| 50 | if ( params.xf ) |
| 51 | testToRefXf = testToRefXf * ( *params.xf ); |
| 52 | |
| 53 | VertScalars res( testPoints.size(), std::sqrt( params.upDistLimitSq ) ); |
| 54 | |
| 55 | if ( projector ) |
| 56 | { |
| 57 | projector->updateMeshData( &refMesh ); |
| 58 | std::vector<MeshProjectionResult> mpRes( testPoints.size() ); |
| 59 | projector->findProjections( mpRes, testPoints.vec_, params.xf, params.refXf, params.upDistLimitSq, params.loDistLimitSq ); |
| 60 | |
| 61 | ParallelFor( 0_v, testPoints.endId(), [&] ( VertId v ) |
| 62 | { |
| 63 | if ( validTestPoints && !validTestPoints->test( v ) ) |
| 64 | return; |
| 65 | const auto& mpResV = mpRes[v.get()]; |
| 66 | if ( mpResV.mtp.e ) |
| 67 | res[v] = refMesh.signedDistance( testToRefXf( testPoints[v] ), mpResV ); |
| 68 | else |
| 69 | res[v] = std::sqrt( mpResV.distSq ); |
| 70 | } ); |
| 71 | } |
| 72 | else |
| 73 | { |
| 74 | // no projector is given, use fully CPU computation |
| 75 | ParallelFor( 0_v, testPoints.endId(), [&] ( VertId v ) |
| 76 | { |
| 77 | if ( validTestPoints && !validTestPoints->test( v ) ) |
| 78 | return; |
| 79 | const auto pt = testToRefXf( testPoints[v] ); |
| 80 | const auto mpResV = findProjection( pt, refMesh, params.upDistLimitSq, nullptr, params.loDistLimitSq ); |
| 81 | if ( mpResV.mtp.e ) |
| 82 | res[v] = refMesh.signedDistance( pt, mpResV ); |
| 83 | else |
| 84 | res[v] = std::sqrt( mpResV.distSq ); |
| 85 | } ); |
| 86 | } |
| 87 | return res; |
| 88 | } |
| 89 | |
| 90 | VertScalars findSignedDistances( |
| 91 | const Mesh& refMesh, |