Skip to content

Commit

Permalink
Local Triangulations: compute oppositely oriented; fix orientLocalTri…
Browse files Browse the repository at this point in the history
…angulations (MeshInspector#2217)
  • Loading branch information
Fedr authored Feb 12, 2024
1 parent 16399f1 commit aa1c621
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 20 deletions.
43 changes: 29 additions & 14 deletions source/MRMesh/MRLocalTriangulations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void orientLocalTriangulations( AllLocalTriangulations & triangs, const VertCoor
const auto next = triangs.neighbors[n + 1 < nend ? n + 1 : nbeg];
if ( curr == bd )
{
otherBd = bd;
otherBd = next;
continue;
}
const auto d = dot( normals[c], cross( coords[next] - cp, coords[curr] - cp ) );
Expand All @@ -130,11 +130,19 @@ void orientLocalTriangulations( AllLocalTriangulations & triangs, const VertCoor
} );
}

static ParallelHashMap<UnorientedTriangle, int, UnorientedTriangleHasher> makeTriangleHashMap( const AllLocalTriangulations & triangs )
struct Repetitions
{
unsigned char sameOriented : 4 = 0;
unsigned char oppositeOriented : 4 = 0;
};

static_assert( sizeof( Repetitions ) == 1 );

static ParallelHashMap<UnorientedTriangle, Repetitions, UnorientedTriangleHasher> makeTriangleHashMap( const AllLocalTriangulations & triangs )
{
MR_TIMER

ParallelHashMap<UnorientedTriangle, int, UnorientedTriangleHasher> map;
ParallelHashMap<UnorientedTriangle, Repetitions, UnorientedTriangleHasher> map;
ParallelFor( size_t(0), map.subcnt(), [&]( size_t myPartId )
{
for ( VertId v = 0_v; v + 1 < triangs.fanRecords.size(); ++v )
Expand All @@ -147,47 +155,54 @@ static ParallelHashMap<UnorientedTriangle, int, UnorientedTriangleHasher> makeTr
if ( triangs.neighbors[n] == border )
continue;
const auto next = triangs.neighbors[n + 1 < nend ? n + 1 : nbeg];
const UnorientedTriangle triplet({ v, next, triangs.neighbors[n] });
bool flippped = false;
const UnorientedTriangle triplet( { v, next, triangs.neighbors[n] }, &flippped );
const auto hashval = map.hash( triplet );
const auto idx = map.subidx( hashval );
if ( idx != myPartId )
continue;
auto [it, inserted] = map.insert( { triplet, 0 } );
if ( !inserted )
++it->second;
Repetitions & r = map[triplet];
if ( flippped )
++r.oppositeOriented;
else
++r.sameOriented;
}
}
} );
return map;
}

VotesForTriangles computeTrianglesRepetitions( const AllLocalTriangulations & triangs )
TrianglesRepetitions computeTrianglesRepetitions( const AllLocalTriangulations & triangs )
{
MR_TIMER

const auto map = makeTriangleHashMap( triangs );

VotesForTriangles res{};
TrianglesRepetitions res{};
for ( auto & [key, val] : map )
{
assert( val >= 0 && val <= 2 );
++res[val];
int c = val.sameOriented + val.oppositeOriented;
assert( c >= 1 && c <= 3 );
++res[c];
if ( val.sameOriented >= 1 && val.oppositeOriented >= 1 )
++res[0];
}
return res;
}

std::vector<UnorientedTriangle> findRepeatedTriangles( const AllLocalTriangulations & triangs, int repetitions )
{
MR_TIMER
assert( repetitions >= 0 && repetitions <= 2 );
assert( repetitions >= 1 && repetitions <= 3 );

const auto map = makeTriangleHashMap( triangs );

std::vector<UnorientedTriangle> res;
for ( auto & [key, val] : map )
{
assert( val >= 0 && val <= 2 );
if ( val == repetitions )
int c = val.sameOriented + val.oppositeOriented;
assert( c >= 1 && c <= 3 );
if ( c == repetitions )
res.push_back( key );
}
return res;
Expand Down
13 changes: 7 additions & 6 deletions source/MRMesh/MRLocalTriangulations.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ struct AllLocalTriangulations
/// orient neighbors around each point so they will be in clockwise order if look from the top of target normal
MRMESH_API void orientLocalTriangulations( AllLocalTriangulations & triangs, const VertCoords & coords, const VertNormals & normals );

/// TrianglesRepetitions[0] contains the number of unoriented triangles that appear in one local triangulation only
/// TrianglesRepetitions[1] contains the number of unoriented triangles that appear in exactly two local triangulations
/// TrianglesRepetitions[2] contains the number of unoriented triangles that appear in three local triangulations
using VotesForTriangles = std::array<int, 3>;
/// TrianglesRepetitions[0] contains the number of triangles that appear in different local triangulations with opposite orientations
/// TrianglesRepetitions[1] contains the number of unoriented triangles that appear in one local triangulation only
/// TrianglesRepetitions[2] contains the number of unoriented triangles that appear in exactly two local triangulations
/// TrianglesRepetitions[3] contains the number of unoriented triangles that appear in three local triangulations
using TrianglesRepetitions = std::array<int, 4>;

/// computes statistics about the number of triangle repetitions in local triangulations
[[nodiscard]] MRMESH_API VotesForTriangles computeTrianglesRepetitions( const AllLocalTriangulations & triangs );
[[nodiscard]] MRMESH_API TrianglesRepetitions computeTrianglesRepetitions( const AllLocalTriangulations & triangs );

/// from local triangulations returns all unoriented with given number of repetitions each in [0,2]
/// from local triangulations returns all unoriented with given number of repetitions each in [1,3]
[[nodiscard]] MRMESH_API std::vector<UnorientedTriangle> findRepeatedTriangles( const AllLocalTriangulations & triangs, int repetitions );

} //namespace MR

0 comments on commit aa1c621

Please sign in to comment.