| 293 | |
| 294 | template<typename V> |
| 295 | DecimatePolylineResult PolylineDecimator<V>::run() |
| 296 | { |
| 297 | MR_TIMER; |
| 298 | |
| 299 | initializeQueue_(); |
| 300 | |
| 301 | res_.errorIntroduced = settings_.maxError; |
| 302 | while ( !queue_.empty() ) |
| 303 | { |
| 304 | auto topQE = queue_.top(); |
| 305 | assert( presentInQueue_.test( topQE.uedgeId ) ); |
| 306 | queue_.pop(); |
| 307 | if( res_.vertsDeleted >= settings_.maxDeletedVertices ) |
| 308 | { |
| 309 | res_.errorIntroduced = std::sqrt( topQE.c ); |
| 310 | break; |
| 311 | } |
| 312 | |
| 313 | if ( polyline_.topology.isLoneEdge( topQE.uedgeId ) ) |
| 314 | { |
| 315 | // edge has been deleted by this moment |
| 316 | presentInQueue_.reset( topQE.uedgeId ); |
| 317 | continue; |
| 318 | } |
| 319 | |
| 320 | QuadraticForm<V> collapseForm; |
| 321 | V collapsePos; |
| 322 | auto qe = computeQueueElement_( topQE.uedgeId, &collapseForm, &collapsePos ); |
| 323 | if ( !qe ) |
| 324 | { |
| 325 | presentInQueue_.reset( topQE.uedgeId ); |
| 326 | continue; |
| 327 | } |
| 328 | |
| 329 | if ( qe->c > topQE.c ) |
| 330 | { |
| 331 | queue_.push( *qe ); |
| 332 | continue; |
| 333 | } |
| 334 | |
| 335 | presentInQueue_.reset( topQE.uedgeId ); |
| 336 | VertId collapseVert = collapse_( topQE.uedgeId, collapsePos ); |
| 337 | if ( !collapseVert ) |
| 338 | continue; |
| 339 | |
| 340 | vertForms_[collapseVert] = collapseForm; |
| 341 | |
| 342 | EdgeId e = polyline_.topology.edgeWithOrg( collapseVert ); |
| 343 | addInQueueIfMissing_( e.undirected() ); |
| 344 | EdgeId eNext = polyline_.topology.next( e ); |
| 345 | if ( e != eNext ) |
| 346 | addInQueueIfMissing_( eNext.undirected() ); |
| 347 | } |
| 348 | |
| 349 | if ( settings_.vertForms ) |
| 350 | *settings_.vertForms = std::move( vertForms_ ); |
| 351 | return res_; |
| 352 | } |
no test coverage detected