MeshLib C++ Docs
Loading...
Searching...
No Matches
MREdgePathsBuilder.h
Go to the documentation of this file.
1#pragma once
2
3#include "MREdgePaths.h"
4#include "MRBitSet.h"
5#include "MRMesh.h"
6#include "MRRingIterator.h"
7#include "MRphmap.h"
8#include "MRMacros.h"
9#include <queue>
10
11namespace MR
12{
15
16
19
22{
24 EdgeId back;
26 float metric = FLT_MAX;
27
28 bool isStart() const { return !back.valid(); }
29};
30
33using VertPathInfoMap = HashMap<VertId, VertPathInfo>;
34
36template<class MetricToPenalty>
38{
39public:
40 EdgePathsBuilderT( const MeshTopology & topology, const EdgeMetric & metric );
41
42 explicit EdgePathsBuilderT( const MeshTopology & topology );
43
45 void reset( const EdgeMetric & metric );
46
49 bool addStart( VertId startVert, float startMetric );
50
53 {
54 VertId v;
55
57 EdgeId backward;
58
61 float penalty = FLT_MAX;
62
64 float metric = FLT_MAX;
65 };
66
69 ReachedVert reachNext();
70
73 bool addOrgRingSteps( const ReachedVert & rv );
74
76 ReachedVert growOneEdge();
77
78public:
80 bool done() const { return nextSteps_.empty(); }
81
83 float doneDistance() const { return nextSteps_.empty() ? FLT_MAX : nextSteps_.top().penalty; }
84
86 const VertPathInfoMap & vertPathInfoMap() const { return vertPathInfoMap_; }
87
89 const VertPathInfo * getVertInfo( VertId v ) const;
90
92 EdgePath getPathBack( VertId backpathStart ) const;
93
96 VertId trackPathBack( VertId backpathStart, EdgePath* res = nullptr ) const;
97
98protected:
100
101private:
102 const MeshTopology & topology_;
103 EdgeMetric metric_;
104 VertPathInfoMap vertPathInfoMap_;
105
106 struct CandidateVert
107 {
108 VertId v;
110 float penalty = FLT_MAX;
111
113 friend bool operator <( const CandidateVert & a, const CandidateVert & b )
114 {
115 return a.penalty > b.penalty;
116 }
117 };
118 std::priority_queue<CandidateVert> nextSteps_;
119
123 bool addNextStep_( const VertPathInfo & c );
124};
125
128{
129 float operator()( float metric, VertId ) const { return metric; }
130};
131
133
134template<class MetricToPenalty>
135EdgePathsBuilderT<MetricToPenalty>::EdgePathsBuilderT( const MeshTopology & topology, const EdgeMetric & metric )
136 : topology_( topology )
137 , metric_( metric )
138{
139}
140
141template<class MetricToPenalty>
143 : topology_( topology )
144{
145}
146
147template<class MetricToPenalty>
148void EdgePathsBuilderT<MetricToPenalty>::reset( const EdgeMetric & metric )
149{
150 metric_ = metric;
151 vertPathInfoMap_.clear();
152 while ( !nextSteps_.empty() )
153 nextSteps_.pop();
154}
155
156template<class MetricToPenalty>
157bool EdgePathsBuilderT<MetricToPenalty>::addStart( VertId startVert, float startMetric )
158{
159 auto & vi = vertPathInfoMap_[startVert];
160 if ( vi.metric > startMetric )
161 {
162 vi = { EdgeId{}, startMetric };
163 nextSteps_.push( CandidateVert{ startVert, metricToPenalty_( startMetric, startVert ) } );
164 return true;
165 }
166 return false;
167}
168
169template<class MetricToPenalty>
171{
172 auto it = vertPathInfoMap_.find( v );
173 return ( it != vertPathInfoMap_.end() ) ? &it->second : nullptr;
174}
175
176template<class MetricToPenalty>
178{
179 EdgePath res;
180 trackPathBack( v, &res );
181 return res;
182}
183
184template<class MetricToPenalty>
185VertId EdgePathsBuilderT<MetricToPenalty>::trackPathBack( VertId v, EdgePath* res ) const
186{
187 for (;;)
188 {
189 auto it = vertPathInfoMap_.find( v );
190 if ( it == vertPathInfoMap_.end() )
191 {
192 assert( false );
193 break;
194 }
195 auto & vi = it->second;
196 if ( vi.isStart() )
197 break;
198 if ( res )
199 res->push_back( vi.back );
200 v = topology_.dest( vi.back );
201 }
202 return v;
203}
204
205template<class MetricToPenalty>
207{
208 if ( !( c.metric < FLT_MAX ) )
209 return false;
210 const auto vert = topology_.org( c.back );
211 auto & vi = vertPathInfoMap_[vert];
212 if ( vi.metric > c.metric )
213 {
214 vi = c;
215 nextSteps_.push( CandidateVert{ vert, metricToPenalty_( c.metric, vert ) } );
216 return true;
217 }
218 return false;
219}
220
221template<class MetricToPenalty>
223{
224 bool aNextStepAdded = false;
225 if ( !rv.v )
226 {
227 assert( !rv.backward );
228 return aNextStepAdded;
229 }
230 const float orgMetric = rv.metric;
231 const EdgeId back = rv.backward ? rv.backward : topology_.edgeWithOrg( rv.v );
232 for ( EdgeId e : orgRing( topology_, back ) )
233 {
234 VertPathInfo c;
235 c.back = e.sym();
236 c.metric = orgMetric + metric_( e );
237 aNextStepAdded = addNextStep_( c ) || aNextStepAdded;
238 }
239 return aNextStepAdded;
240}
241
242template<class MetricToPenalty>
244{
245 while ( !nextSteps_.empty() )
246 {
247 const auto c = nextSteps_.top();
248 nextSteps_.pop();
249 auto & vi = vertPathInfoMap_[c.v];
250 if ( metricToPenalty_( vi.metric, c.v ) < c.penalty )
251 {
253 continue;
254 }
255 assert( metricToPenalty_( vi.metric, c.v ) == c.penalty );
256 return { .v = c.v, .backward = vi.back, .penalty = c.penalty, .metric = vi.metric };
257 }
258 return {};
259}
260
261template<class MetricToPenalty>
263{
264 auto res = reachNext();
265 addOrgRingSteps( res );
266 return res;
267}
268
272{
273 const VertCoords * points = nullptr;
274 Vector3f target;
275 float operator()( float metric, VertId v ) const
276 {
277 return metric + ( (*points)[v] - target ).length();
278 }
279};
280
283class EdgePathsAStarBuilder: public EdgePathsBuilderT<MetricToAStarPenalty>
284{
285public:
286 EdgePathsAStarBuilder( const Mesh & mesh, VertId target, VertId start ) :
287 EdgePathsBuilderT( mesh.topology, edgeLengthMetric( mesh ) )
288 {
290 metricToPenalty_.target = mesh.points[target];
291 addStart( start, 0 );
292 }
293 EdgePathsAStarBuilder( const Mesh & mesh, const MeshTriPoint & target, const MeshTriPoint & start ) :
294 EdgePathsBuilderT( mesh.topology, edgeLengthMetric( mesh ) )
295 {
297 metricToPenalty_.target = mesh.triPoint( target );
298 const auto startPt = mesh.triPoint( start );
299 mesh.topology.forEachVertex( start, [&]( VertId v )
300 {
301 addStart( v, ( mesh.points[v] - startPt ).length() );
302 } );
303 }
304};
305
307
308}
#define MR_NO_UNIQUE_ADDRESS
Definition MRMacros.h:42
Definition MREdgePathsBuilder.h:284
the class is responsible for finding smallest metric edge paths on a mesh
Definition MREdgePathsBuilder.h:38
Definition MRMeshTopology.h:22
float penalty
Definition MREdgePathsBuilder.h:61
Vector3f target
Definition MREdgePathsBuilder.h:274
ReachedVert growOneEdge()
the same as reachNext() + addOrgRingSteps()
Definition MREdgePathsBuilder.h:262
friend bool operator<(const CandidateVert &a, const CandidateVert &b)
smaller penalty to be the first
Definition MREdgePathsBuilder.h:113
float metric
best summed metric to reach this vertex
Definition MREdgePathsBuilder.h:26
bool done() const
returns true if further edge forest growth is impossible
Definition MREdgePathsBuilder.h:80
VertId v
Definition MREdgePathsBuilder.h:108
bool addStart(VertId startVert, float startMetric)
Definition MREdgePathsBuilder.h:157
ReachedVert reachNext()
Definition MREdgePathsBuilder.h:243
EdgeId backward
edge from this vertex to its predecessor in the forest (if this vertex is not start)
Definition MREdgePathsBuilder.h:57
EdgePathsAStarBuilder(const Mesh &mesh, VertId target, VertId start)
Definition MREdgePathsBuilder.h:286
EdgePathsBuilderT(const MeshTopology &topology)
Definition MREdgePathsBuilder.h:142
float doneDistance() const
returns path length till the next candidate vertex or maximum float value if all vertices have been r...
Definition MREdgePathsBuilder.h:83
bool addOrgRingSteps(const ReachedVert &rv)
Definition MREdgePathsBuilder.h:222
EdgeId back
edge from this vertex to its predecessor in the forest
Definition MREdgePathsBuilder.h:24
float metric
summed metric to reach this vertex
Definition MREdgePathsBuilder.h:64
void reset(const EdgeMetric &metric)
clears everything without freeing memory, and sets new metric
Definition MREdgePathsBuilder.h:148
MR_NO_UNIQUE_ADDRESS MetricToPenalty metricToPenalty_
Definition MREdgePathsBuilder.h:99
HashMap< VertId, VertPathInfo > VertPathInfoMap
Definition MREdgePathsBuilder.h:33
VertId trackPathBack(VertId backpathStart, EdgePath *res=nullptr) const
Definition MREdgePathsBuilder.h:185
EdgePathsBuilderT(const MeshTopology &topology, const EdgeMetric &metric)
Definition MREdgePathsBuilder.h:135
EdgePath getPathBack(VertId backpathStart) const
returns the path in the forest from given vertex to one of start vertices
Definition MREdgePathsBuilder.h:177
bool isStart() const
Definition MREdgePathsBuilder.h:28
void forEachVertex(const MeshTriPoint &p, T &&callback) const
Definition MRMeshTopology.h:602
IteratorRange< OrgRingIterator > orgRing(const MeshTopology &topology, EdgeId edge)
Definition MRRingIterator.h:68
float operator()(float metric, VertId) const
Definition MREdgePathsBuilder.h:129
const VertPathInfoMap & vertPathInfoMap() const
gives read access to the map from vertex to path to it
Definition MREdgePathsBuilder.h:86
VertId v
Definition MREdgePathsBuilder.h:54
float operator()(float metric, VertId v) const
Definition MREdgePathsBuilder.h:275
EdgePathsAStarBuilder(const Mesh &mesh, const MeshTriPoint &target, const MeshTriPoint &start)
Definition MREdgePathsBuilder.h:293
const VertPathInfo * getVertInfo(VertId v) const
returns one element from the map (or nullptr if the element is missing)
Definition MREdgePathsBuilder.h:170
float penalty
best penalty to reach this vertex
Definition MREdgePathsBuilder.h:110
const VertCoords * points
Definition MREdgePathsBuilder.h:273
length
Definition MRObjectDimensionsEnum.h:17
MRMESH_API EdgeMetric edgeLengthMetric(const Mesh &mesh)
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
information about just reached vertex (with final metric value)
Definition MREdgePathsBuilder.h:53
Definition MRMeshTriPoint.h:26
Definition MRMesh.h:23
MeshTopology topology
Definition MRMesh.h:24
Vector3f triPoint(const MeshTriPoint &p) const
computes coordinates of point given as face and barycentric representation
Definition MRMesh.h:103
VertCoords points
Definition MRMesh.h:25
Definition MREdgePathsBuilder.h:272
the vertices in the queue are ordered by their metric from a start location
Definition MREdgePathsBuilder.h:128
information associated with each vertex by the paths builder
Definition MREdgePathsBuilder.h:22