| 402 | } |
| 403 | |
| 404 | auto MeshDecimator::computeQueueElement_( UndirectedEdgeId ue, bool optimizeVertexPos, |
| 405 | QuadraticForm3f * outCollapseForm, Vector3f * outCollapsePos ) const -> std::optional<QueueElement> |
| 406 | { |
| 407 | EdgeId e{ ue }; |
| 408 | const auto o = mesh_.topology.org( e ); |
| 409 | const auto d = mesh_.topology.dest( e ); |
| 410 | const auto po = mesh_.points[o]; |
| 411 | const auto pd = mesh_.points[d]; |
| 412 | const auto vo = (*pVertForms_)[o]; |
| 413 | const auto vd = (*pVertForms_)[d]; |
| 414 | |
| 415 | std::optional<QueueElement> res; |
| 416 | // prepares res; checks flip metric; returns true if the edge does not collpase and function can return |
| 417 | auto earlyReturn = [&]( float errSq ) |
| 418 | { |
| 419 | EdgeOp edgeOp = optimizeVertexPos ? EdgeOp::CollapseOptPos : EdgeOp::CollapseEnd; |
| 420 | if ( maxRemainingFlips_ > 0 && ( !settings_.notFlippable || !settings_.notFlippable->test( ue ) ) ) |
| 421 | { |
| 422 | float deviationSqAfterFlip = FLT_MAX; |
| 423 | if ( !checkDeloneQuadrangleInMesh( mesh_, ue, deloneSettings_, &deviationSqAfterFlip ) |
| 424 | && deviationSqAfterFlip < errSq ) |
| 425 | { |
| 426 | edgeOp = EdgeOp::Flip; |
| 427 | errSq = deviationSqAfterFlip; |
| 428 | } |
| 429 | } |
| 430 | if ( ( edgeOp == EdgeOp::Flip || !settings_.adjustCollapse ) && errSq > maxErrorSq_ ) |
| 431 | return true; |
| 432 | res.emplace(); |
| 433 | res->x.uedgeId = (int)ue; |
| 434 | res->x.edgeOp = edgeOp; |
| 435 | res->c = errSq; |
| 436 | return edgeOp == EdgeOp::Flip; |
| 437 | }; |
| 438 | |
| 439 | if ( settings_.strategy == DecimateStrategy::ShortestEdgeFirst ) |
| 440 | { |
| 441 | if ( earlyReturn( mesh_.edgeLengthSq( e ) ) ) |
| 442 | return res; |
| 443 | } |
| 444 | |
| 445 | QuadraticForm3f qf; |
| 446 | Vector3f pos; |
| 447 | if ( settings_.touchBdVerts // if boundary vertices can be moved ... |
| 448 | || ( settings_.notFlippable && settings_.notFlippable->test( ue ) ) ) // ... or this is a not-flippable edge (if you do not want such collapses then exclude it from settings_.edgesToCollapse) |
| 449 | { |
| 450 | std::tie( qf, pos ) = sum( vo, po, vd, pd, !optimizeVertexPos ); |
| 451 | } |
| 452 | else |
| 453 | { |
| 454 | const bool bdO = pBdVerts_->test( o ); |
| 455 | const bool bdD = pBdVerts_->test( d ); |
| 456 | if ( bdO ) |
| 457 | { |
| 458 | if ( bdD ) |
| 459 | qf.c = FLT_MAX; |
| 460 | else |
| 461 | qf = sumAt( vo, po, vd, pd, pos = po ); |
nothing calls this directly
no test coverage detected