Skip to content

Commit

Permalink
rayMeshIntersect can find any intersection for better performance; ra…
Browse files Browse the repository at this point in the history
…yMultiMeshAnyIntersect added (#4)
  • Loading branch information
Fedr authored Jan 13, 2022
1 parent 50d521d commit 7a117c9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 11 deletions.
45 changes: 37 additions & 8 deletions source/MRMesh/MRMeshIntersect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace MR

template<typename T>
std::optional<MeshIntersectionResult> meshRayIntersect_( const MeshPart& meshPart, const Line3<T>& line,
T rayStart /*= 0.0f*/, T rayEnd /*= FLT_MAX */, const IntersectionPrecomputes<T>& prec )
T rayStart /*= 0.0f*/, T rayEnd /*= FLT_MAX */, const IntersectionPrecomputes<T>& prec, bool closestIntersect )
{
const auto& m = meshPart.mesh;
constexpr int maxTreeDepth = 32;
Expand All @@ -40,7 +40,7 @@ std::optional<MeshIntersectionResult> meshRayIntersect_( const MeshPart& meshPar

FaceId faceId;
TriPointf triP;
while( currentNode >= 0 )
while( currentNode >= 0 && ( closestIntersect || faceId ) )
{
if( currentNode >= maxTreeDepth ) // max depth exceeded
{
Expand Down Expand Up @@ -125,33 +125,62 @@ std::optional<MeshIntersectionResult> meshRayIntersect_( const MeshPart& meshPar
}

std::optional<MeshIntersectionResult> rayMeshIntersect( const MeshPart& meshPart, const Line3f& line,
float rayStart /*= 0.0f*/, float rayEnd /*= DBL_MAX */, const IntersectionPrecomputes<float>* prec /*= nullptr*/ )
float rayStart, float rayEnd, const IntersectionPrecomputes<float>* prec, bool closestIntersect )
{
if( prec )
{
return meshRayIntersect_<float>( meshPart, line, rayStart, rayEnd, *prec );
return meshRayIntersect_<float>( meshPart, line, rayStart, rayEnd, *prec, closestIntersect );
}
else
{
const IntersectionPrecomputes<float> precNew( line.d );
return meshRayIntersect_<float>( meshPart, line, rayStart, rayEnd, precNew );
return meshRayIntersect_<float>( meshPart, line, rayStart, rayEnd, precNew, closestIntersect );
}
}

std::optional<MeshIntersectionResult> rayMeshIntersect( const MeshPart& meshPart, const Line3d& line,
double rayStart /*= 0.0f*/, double rayEnd /*= DBL_MAX */, const IntersectionPrecomputes<double>* prec /*= nullptr*/ )
double rayStart, double rayEnd, const IntersectionPrecomputes<double>* prec, bool closestIntersect )
{
if( prec )
{
return meshRayIntersect_<double>( meshPart, line, rayStart, rayEnd, *prec );
return meshRayIntersect_<double>( meshPart, line, rayStart, rayEnd, *prec, closestIntersect );
}
else
{
const IntersectionPrecomputes<double> precNew( line.d );
return meshRayIntersect_<double>( meshPart, line, rayStart, rayEnd, precNew );
return meshRayIntersect_<double>( meshPart, line, rayStart, rayEnd, precNew, closestIntersect );
}
}

template<typename T>
std::optional<MultiMeshIntersectionResult> rayMultiMeshAnyIntersect_( const std::vector<Line3Mesh<T>> & lineMeshes,
T rayStart /*= 0.0f*/, T rayEnd /*= FLT_MAX */ )
{
std::optional<MultiMeshIntersectionResult> res;
for ( const auto & lm : lineMeshes )
{
assert( lm.mesh );
if ( auto r = meshRayIntersect_( { *lm.mesh, lm.region }, lm.line, rayStart, rayEnd, lm.prec, false ) )
{
res = MultiMeshIntersectionResult{ *r };
break;
}
}
return res;
}

std::optional<MultiMeshIntersectionResult> rayMultiMeshAnyIntersect( const std::vector<Line3fMesh> & lineMeshes,
float rayStart, float rayEnd )
{
return rayMultiMeshAnyIntersect_( lineMeshes, rayStart, rayEnd );
}

std::optional<MultiMeshIntersectionResult> rayMultiMeshAnyIntersect( const std::vector<Line3dMesh> & lineMeshes,
double rayStart, double rayEnd )
{
return rayMultiMeshAnyIntersect_( lineMeshes, rayStart, rayEnd );
}

template<typename T>
void rayMeshIntersectAll_( const MeshPart& meshPart, const Line3<T>& line, MeshIntersectionCallback callback,
T rayStart /*= 0.0f*/, T rayEnd /*= FLT_MAX */, const IntersectionPrecomputes<T>& prec )
Expand Down
31 changes: 28 additions & 3 deletions source/MRMesh/MRMeshIntersect.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,37 @@ struct MeshIntersectionResult
float distanceAlongLine = 0;
};

// Intersects ray with mesh. Finds the closest to origin intersection
// Intersects ray with mesh. Finds the closest to origin intersection (or any intersection for better performance if !closestIntersect)
MRMESH_API std::optional<MeshIntersectionResult> rayMeshIntersect( const MeshPart& meshPart, const Line3f& line,
float rayStart = 0.0f, float rayEnd = FLT_MAX, const IntersectionPrecomputes<float>* prec = nullptr );
float rayStart = 0.0f, float rayEnd = FLT_MAX, const IntersectionPrecomputes<float>* prec = nullptr, bool closestIntersect = true );
// Use double precision
MRMESH_API std::optional<MeshIntersectionResult> rayMeshIntersect( const MeshPart& meshPart, const Line3d& line,
double rayStart = 0.0, double rayEnd = DBL_MAX, const IntersectionPrecomputes<double>* prec = nullptr );
double rayStart = 0.0, double rayEnd = DBL_MAX, const IntersectionPrecomputes<double>* prec = nullptr, bool closestIntersect = true );

struct MultiMeshIntersectionResult : MeshIntersectionResult
{
// the intersection found in this mesh
const Mesh * mesh = nullptr;
};

template<typename T>
struct Line3Mesh
{
Line3<T> line; // in the reference frame of mesh
IntersectionPrecomputes<T> prec;
const Mesh * mesh = nullptr; // must be set a valid pointer before use
const AABBTree * tree = nullptr; // must be set a valid pointer before use
const FaceBitSet * region = nullptr; // may remain nullptr, meaning all mesh
};
using Line3fMesh = Line3Mesh<float>;
using Line3dMesh = Line3Mesh<double>;

// Intersects ray with many meshes. Finds any intersection (not the closest)
MRMESH_API std::optional<MultiMeshIntersectionResult> rayMultiMeshAnyIntersect( const std::vector<Line3fMesh> & lineMeshes,
float rayStart = 0.0f, float rayEnd = FLT_MAX );
// Use double precision
MRMESH_API std::optional<MultiMeshIntersectionResult> rayMultiMeshAnyIntersect( const std::vector<Line3dMesh> & lineMeshes,
double rayStart = 0.0, double rayEnd = DBL_MAX );

// this callback is envoked for each encountered ray-mesh intersection;
// if it returns false, then the search immediately terminates
Expand Down

0 comments on commit 7a117c9

Please sign in to comment.