@@ -50,20 +50,21 @@ EdgeId collapseEdge( PolylineTopology & topology, const EdgeId e )
5050 return eNext != e ? eNext : EdgeId ();
5151}
5252
53+ template <typename V>
5354class PolylineDecimator
5455{
5556public:
56- PolylineDecimator ( Polyline2 & polyline, const DecimatePolylineSettings & settings );
57+ PolylineDecimator ( MR::Polyline<V> & polyline, const DecimatePolylineSettings<V> & settings );
5758 DecimatePolylineResult run ();
5859
5960 // returns true if the collapse of given edge is permitted by the region and settings
6061 bool isInRegion ( EdgeId e ) const ;
6162
6263private:
63- Polyline2 & polyline_;
64- const DecimatePolylineSettings & settings_;
64+ MR::Polyline<V> & polyline_;
65+ const DecimatePolylineSettings<V> & settings_;
6566 const float maxErrorSq_;
66- Vector<QuadraticForm2f , VertId> vertForms_;
67+ Vector<QuadraticForm<V> , VertId> vertForms_;
6768 struct QueueElement
6869 {
6970 float c = 0 ;
@@ -77,12 +78,13 @@ class PolylineDecimator
7778 class EdgeMetricCalc ;
7879
7980 void initializeQueue_ ();
80- QueueElement computeQueueElement_ ( UndirectedEdgeId ue, QuadraticForm2f * outCollapseForm = nullptr , Vector2f * outCollapsePos = nullptr ) const ;
81+ QueueElement computeQueueElement_ ( UndirectedEdgeId ue, QuadraticForm<V> * outCollapseForm = nullptr , V * outCollapsePos = nullptr ) const ;
8182 void addInQueueIfMissing_ ( UndirectedEdgeId ue );
82- VertId collapse_ ( EdgeId edgeToCollapse, const Vector2f & collapsePos );
83+ VertId collapse_ ( EdgeId edgeToCollapse, const V & collapsePos );
8384};
8485
85- PolylineDecimator::PolylineDecimator ( Polyline2 & polyline, const DecimatePolylineSettings & settings )
86+ template <typename V>
87+ PolylineDecimator<V>::PolylineDecimator( MR::Polyline<V> & polyline, const DecimatePolylineSettings<V> & settings )
8688 : polyline_( polyline )
8789 , settings_( settings )
8890 , maxErrorSq_( sqr( settings.maxError ) )
@@ -96,7 +98,8 @@ static bool isRegionEdge( const PolylineTopology & topology, EdgeId e, const Ver
9698 return region->test ( topology.org ( e ) ) && region->test ( topology.dest ( e ) );
9799}
98100
99- bool PolylineDecimator::isInRegion ( EdgeId e ) const
101+ template <typename V>
102+ bool PolylineDecimator<V>::isInRegion( EdgeId e ) const
100103{
101104 if ( !isRegionEdge ( polyline_.topology , e, settings_.region ) )
102105 return false ;
@@ -110,10 +113,11 @@ bool PolylineDecimator::isInRegion( EdgeId e ) const
110113 return true ;
111114}
112115
113- class PolylineDecimator ::EdgeMetricCalc
116+ template <typename V>
117+ class PolylineDecimator <V>::EdgeMetricCalc
114118{
115119public:
116- EdgeMetricCalc ( const PolylineDecimator & decimator ) : decimator_( decimator ) { }
120+ EdgeMetricCalc ( const PolylineDecimator<V> & decimator ) : decimator_( decimator ) { }
117121 EdgeMetricCalc ( EdgeMetricCalc & x, tbb::split ) : decimator_( x.decimator_ ) { }
118122 void join ( EdgeMetricCalc & y ) { auto yes = y.takeElements (); elems_.insert ( elems_.end (), yes.begin (), yes.end () ); }
119123
@@ -137,13 +141,14 @@ class PolylineDecimator::EdgeMetricCalc
137141 }
138142
139143public:
140- const PolylineDecimator & decimator_;
144+ const PolylineDecimator<V> & decimator_;
141145 std::vector<QueueElement> elems_;
142146};
143147
144- MR::QuadraticForm2f computeFormAtVertex ( const MR::Polyline2 & polyline, MR::VertId v, float stabilizer )
148+ template <typename V>
149+ MR::QuadraticForm<V> computeFormAtVertex ( const MR::Polyline<V> & polyline, MR::VertId v, float stabilizer )
145150{
146- QuadraticForm2f qf;
151+ QuadraticForm<V> qf;
147152
148153 const auto e = polyline.topology .edgeWithOrg ( v );
149154 qf.addDistToLine ( polyline.edgeVector ( e ).normalized () );
@@ -157,7 +162,8 @@ MR::QuadraticForm2f computeFormAtVertex( const MR::Polyline2 & polyline, MR::Ver
157162 return qf;
158163}
159164
160- void PolylineDecimator::initializeQueue_ ()
165+ template <typename V>
166+ void PolylineDecimator<V>::initializeQueue_()
161167{
162168 MR_TIMER;
163169
@@ -186,7 +192,8 @@ void PolylineDecimator::initializeQueue_()
186192 queue_ = std::priority_queue<QueueElement>{ std::less<QueueElement>(), calc.takeElements () };
187193}
188194
189- auto PolylineDecimator::computeQueueElement_ ( UndirectedEdgeId ue, QuadraticForm2f * outCollapseForm, Vector2f * outCollapsePos ) const -> QueueElement
195+ template <typename V>
196+ auto PolylineDecimator<V>::computeQueueElement_( UndirectedEdgeId ue, QuadraticForm<V> * outCollapseForm, V * outCollapsePos ) const -> QueueElement
190197{
191198 QueueElement res;
192199 res.uedgeId = ue;
@@ -203,7 +210,8 @@ auto PolylineDecimator::computeQueueElement_( UndirectedEdgeId ue, QuadraticForm
203210 return res;
204211}
205212
206- void PolylineDecimator::addInQueueIfMissing_ ( UndirectedEdgeId ue )
213+ template <typename V>
214+ void PolylineDecimator<V>::addInQueueIfMissing_( UndirectedEdgeId ue )
207215{
208216 EdgeId e{ ue };
209217 if ( !isInRegion ( e ) )
@@ -215,7 +223,8 @@ void PolylineDecimator::addInQueueIfMissing_( UndirectedEdgeId ue )
215223 queue_.push ( qe );
216224}
217225
218- VertId PolylineDecimator::collapse_ ( EdgeId edgeToCollapse, const Vector2f & collapsePos )
226+ template <typename V>
227+ VertId PolylineDecimator<V>::collapse_( EdgeId edgeToCollapse, const V & collapsePos )
219228{
220229 auto & topology = polyline_.topology ;
221230 const auto vo = topology.org ( edgeToCollapse );
@@ -236,7 +245,8 @@ VertId PolylineDecimator::collapse_( EdgeId edgeToCollapse, const Vector2f & col
236245 return topology.hasVert ( vo ) ? vo : VertId{};
237246}
238247
239- DecimatePolylineResult PolylineDecimator::run ()
248+ template <typename V>
249+ DecimatePolylineResult PolylineDecimator<V>::run()
240250{
241251 MR_TIMER;
242252
@@ -261,8 +271,8 @@ DecimatePolylineResult PolylineDecimator::run()
261271 continue ;
262272 }
263273
264- QuadraticForm2f collapseForm;
265- Vector2f collapsePos;
274+ QuadraticForm<V> collapseForm;
275+ V collapsePos;
266276 auto qe = computeQueueElement_ ( topQE.uedgeId , &collapseForm, &collapsePos );
267277
268278 if ( qe.c > topQE.c )
@@ -293,18 +303,40 @@ DecimatePolylineResult PolylineDecimator::run()
293303 return res_;
294304}
295305
296- DecimatePolylineResult decimatePolyline ( Polyline2 & polyline, const DecimatePolylineSettings & settings )
306+ DecimatePolylineResult decimatePolyline ( MR:: Polyline2 & polyline, const DecimatePolylineSettings2 & settings )
297307{
298308 MR_TIMER;
299309 // MR_POLYLINE_WRITER( polyline );
300- PolylineDecimator md ( polyline, settings );
310+ PolylineDecimator<Vector2f> md ( polyline, settings );
301311 return md.run ();
302312}
303313
304- DecimatePolylineResult decimateContour ( Contour2f& contour , const DecimatePolylineSettings & settings )
314+ DecimatePolylineResult decimatePolyline ( MR::Polyline3 & polyline , const DecimatePolylineSettings3 & settings )
305315{
306316 MR_TIMER;
307- Polyline2 p ( { contour } );
317+ // MR_POLYLINE_WRITER( polyline );
318+ PolylineDecimator<Vector3f> md ( polyline, settings );
319+ return md.run ();
320+ }
321+
322+ DecimatePolylineResult decimateContour ( Contour2f& contour, const DecimatePolylineSettings2& settings )
323+ {
324+ MR_TIMER;
325+ MR::Polyline2 p ( { contour } );
326+ auto res = decimatePolyline ( p, settings );
327+ auto resContours = p.contours ();
328+ assert ( p.contours ().size () == 1 );
329+ if ( !p.contours ().empty () )
330+ contour = p.contours ()[0 ];
331+ else
332+ contour.clear ();
333+ return res;
334+ }
335+
336+ DecimatePolylineResult decimateContour ( Contour3f& contour, const DecimatePolylineSettings3& settings )
337+ {
338+ MR_TIMER;
339+ MR::Polyline3 p ( { contour } );
308340 auto res = decimatePolyline ( p, settings );
309341 auto resContours = p.contours ();
310342 assert ( p.contours ().size () == 1 );
@@ -362,12 +394,12 @@ TEST( MRMesh, DecimatePolyline )
362394
363395 for ( auto & cont : testContours )
364396 {
365- DecimatePolylineSettings settings;
397+ DecimatePolylineSettings2 settings;
366398 settings.maxDeletedVertices = 3 ;
367399 settings.maxError = 100 .f ;
368400 settings.touchBdVertices = false ;
369401
370- Polyline2 pl ( { cont } );
402+ MR:: Polyline2 pl ( { cont } );
371403 auto plBack = pl;
372404 auto decRes = decimatePolyline ( pl, settings );
373405
0 commit comments