| 305 | } |
| 306 | |
| 307 | void smoothRegionBoundary( Mesh & mesh, const FaceBitSet & regionFaces, int numIters ) |
| 308 | { |
| 309 | MR_TIMER; |
| 310 | assert( numIters > 0 ); |
| 311 | if ( !regionFaces.any() || numIters <= 0 ) |
| 312 | return; |
| 313 | |
| 314 | // value 1 for out-of-region vertices |
| 315 | VertScalars scalarField( mesh.topology.vertSize(), 1 ); |
| 316 | |
| 317 | const auto regionVerts = getIncidentVerts( mesh.topology, regionFaces ); |
| 318 | // value -1 for in-region vertices |
| 319 | for( auto v : regionVerts ) |
| 320 | scalarField[v] = -1; |
| 321 | |
| 322 | /// free vertices must have both in-region and out-of-region neighbor faces |
| 323 | VertBitSet freeVerts = getIncidentVerts( mesh.topology, mesh.topology.getValidFaces() - regionFaces ) & regionVerts; |
| 324 | |
| 325 | for ( const auto & cc : MeshComponents::getAllComponentsVerts( mesh ) ) |
| 326 | { |
| 327 | auto freeCC = cc & freeVerts; |
| 328 | auto numfree = freeCC.count(); |
| 329 | auto numCC = cc.count(); |
| 330 | assert( numfree <= numCC ); |
| 331 | if ( numfree <= 0 ) |
| 332 | continue; // too small connected component |
| 333 | if ( numfree < numCC ) |
| 334 | continue; // at least one fixed vertex in the component |
| 335 | |
| 336 | // all component vertices are free, just fix them all (to -1) to avoid under-determined system of equations |
| 337 | freeVerts -= cc; |
| 338 | } |
| 339 | |
| 340 | // change topology: eliminate not boundary edges joining two boundary vertices |
| 341 | for ( auto v : freeVerts ) |
| 342 | { |
| 343 | mesh.topology.flipEdgesOut( v, [&]( EdgeId e ) |
| 344 | { |
| 345 | assert( mesh.topology.org( e ) == v ); |
| 346 | if ( regionFaces.test( mesh.topology.left( e ) ) != regionFaces.test( mesh.topology.right( e ) ) ) |
| 347 | return false; |
| 348 | |
| 349 | auto c = mesh.topology.dest( e ); |
| 350 | |
| 351 | if ( !freeVerts.test( c ) ) |
| 352 | return false; |
| 353 | |
| 354 | auto b = mesh.topology.dest( mesh.topology.prev( e ) ); |
| 355 | auto d = mesh.topology.dest( mesh.topology.next( e ) ); |
| 356 | if ( freeVerts.test( b ) && freeVerts.test( c ) ) |
| 357 | return false; |
| 358 | |
| 359 | if ( mesh.topology.findEdge( d, b ) ) |
| 360 | return false; // multiple edges between b and d will appear |
| 361 | |
| 362 | auto ap = mesh.points[v]; |
| 363 | auto bp = mesh.points[b]; |
| 364 | auto cp = mesh.points[c]; |
nothing calls this directly
no test coverage detected