Skip to content

Commit f91a2c2

Browse files
authored
findDirMinMaxBruteForce functions (#4478)
1 parent 5e70467 commit f91a2c2

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

source/MRMesh/MRDirMaxBruteForce.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,57 @@ VertId findDirMaxBruteForce( const Vector3f & dir, const MeshPart & mp )
7777
return pv.v;
7878
}
7979

80+
MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const VertCoords & points, const VertBitSet * region )
81+
{
82+
MR_TIMER;
83+
84+
return parallel_reduce( tbb::blocked_range( 0_v, points.endId(), 1024 ), MinMaxArg<float, VertId>{},
85+
[&] ( const auto & range, MinMaxArg<float, VertId> curr )
86+
{
87+
for ( VertId v = range.begin(); v < range.end(); ++v )
88+
{
89+
if ( !contains( region, v ) )
90+
continue;
91+
curr.include( dot( points[v], dir ), v );
92+
}
93+
return curr;
94+
},
95+
[] ( MinMaxArg<float, VertId> a, const MinMaxArg<float, VertId> & b ) { a.include( b ); return a; }
96+
);
97+
}
98+
99+
MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const PointCloud & cloud )
100+
{
101+
return findDirMinMaxBruteForce( dir, cloud.points, &cloud.validPoints );
102+
}
103+
104+
MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const Polyline3 & polyline )
105+
{
106+
return findDirMinMaxBruteForce( dir, polyline.points, &polyline.topology.getValidVerts() );
107+
}
108+
109+
MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const MeshPart & mp )
110+
{
111+
if ( !mp.region )
112+
return findDirMinMaxBruteForce( dir, mp.mesh.points, &mp.mesh.topology.getValidVerts() );
113+
114+
MR_TIMER;
115+
return parallel_reduce( tbb::blocked_range( 0_f, FaceId( mp.mesh.topology.faceSize() ), 1024 ), MinMaxArg<float, VertId>{},
116+
[&] ( const auto & range, MinMaxArg<float, VertId> curr )
117+
{
118+
for ( FaceId f = range.begin(); f < range.end(); ++f )
119+
{
120+
if ( !mp.region->test( f ) )
121+
continue;
122+
VertId vs[3];
123+
mp.mesh.topology.getTriVerts( f, vs );
124+
for ( auto v : vs )
125+
curr.include( dot( mp.mesh.points[v], dir ), v );
126+
}
127+
return curr;
128+
},
129+
[] ( MinMaxArg<float, VertId> a, const MinMaxArg<float, VertId> & b ) { a.include( b ); return a; }
130+
);
131+
}
132+
80133
} //namespace MR

source/MRMesh/MRDirMaxBruteForce.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#pragma once
22

33
#include "MRMeshFwd.h"
4+
#include "MRMinMaxArg.h"
45

56
namespace MR
67
{
78

8-
/// finds the points having the largest projection on given direction by traversing all region points
9+
/// finds the point having the largest projection on given direction by traversing all region points
910
[[nodiscard]] MRMESH_API VertId findDirMaxBruteForce( const Vector3f & dir, const VertCoords & points, const VertBitSet * region = nullptr );
1011

1112
/// finds the point in the cloud having the largest projection on given direction by traversing all valid points
@@ -17,4 +18,16 @@ namespace MR
1718
/// finds the vertex in the mesh part having the largest projection on given direction by traversing all (region) faces
1819
[[nodiscard]] MRMESH_API VertId findDirMaxBruteForce( const Vector3f & dir, const MeshPart & mp );
1920

21+
/// finds the points having the smallest and the largest projections on given direction by traversing all region points
22+
[[nodiscard]] MRMESH_API MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const VertCoords & points, const VertBitSet * region = nullptr );
23+
24+
/// finds the points in the cloud having the smallest and the largest projections on given direction by traversing all valid points
25+
[[nodiscard]] MRMESH_API MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const PointCloud & cloud );
26+
27+
/// finds the vertex in the polyline having the smallest and the largest projections on given direction by traversing all valid vertices
28+
[[nodiscard]] MRMESH_API MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const Polyline3 & polyline );
29+
30+
/// finds the vertices in the mesh part having the smallest and the largest projections on given direction by traversing all (region) faces
31+
[[nodiscard]] MRMESH_API MinMaxArg<float, VertId> findDirMinMaxBruteForce( const Vector3f & dir, const MeshPart & mp );
32+
2033
} //namespace MR

source/MRMesh/MRMinMaxArg.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <limits>
4+
#include <utility>
45

56
namespace MR
67
{
@@ -13,6 +14,46 @@ struct MinMaxArg
1314
T min = std::numeric_limits<T>::max();
1415
T max = std::numeric_limits<T>::lowest();
1516
I minArg, maxArg;
17+
18+
auto minPair() const { return std::make_pair( min, minArg ); }
19+
auto maxPair() const { return std::make_pair( max, maxArg ); }
20+
21+
/// changes min(Arg) and max(Arg) if necessary to include given point
22+
void include( const std::pair<T,I>& p )
23+
{
24+
if ( p < minPair() )
25+
{
26+
min = p.first;
27+
minArg = p.second;
28+
}
29+
if ( p > maxPair() )
30+
{
31+
max = p.first;
32+
maxArg = p.second;
33+
}
34+
}
35+
36+
/// changes min(Arg) and max(Arg) if necessary to include given point
37+
void include( T v, I arg )
38+
{
39+
return include( std::make_pair( v, arg ) );
40+
}
41+
42+
/// changes min(Arg) and max(Arg) if necessary to include given segment
43+
void include( const MinMaxArg & s )
44+
{
45+
// it shall work with default initialized this and s
46+
if ( s.minPair() < minPair() )
47+
{
48+
min = s.min;
49+
minArg = s.minArg;
50+
}
51+
if ( s.maxPair() > maxPair() )
52+
{
53+
max = s.max;
54+
maxArg = s.maxArg;
55+
}
56+
}
1657
};
1758

1859
} //namespace MR

0 commit comments

Comments
 (0)