| 229 | } |
| 230 | |
| 231 | Expected<FaceBitSet> expandToComponents( const MeshPart& mp, const FaceBitSet& seeds, const ExpandToComponentsParams& params /*= {} */ ) |
| 232 | { |
| 233 | if ( params.coverRatio > 1.0f ) |
| 234 | return FaceBitSet(); |
| 235 | if ( params.coverRatio <= 0.0f ) |
| 236 | return getComponents( mp, seeds, params.incidence, params.isCompBd ); |
| 237 | |
| 238 | MR_TIMER; |
| 239 | |
| 240 | auto res = seeds; |
| 241 | auto compMapRes = MeshComponents::getAllComponentsMap( mp, params.incidence, params.isCompBd ); |
| 242 | const auto& compMap = compMapRes.first; |
| 243 | int numComps = compMapRes.second; |
| 244 | |
| 245 | if ( !reportProgress( params.cb, 0.3f ) ) |
| 246 | return unexpectedOperationCanceled(); |
| 247 | |
| 248 | RegionBitSet compsWithSeeds( numComps ); |
| 249 | for ( auto f : res ) |
| 250 | compsWithSeeds.set( compMap[f] ); |
| 251 | |
| 252 | if ( !reportProgress( params.cb, 0.6f ) ) |
| 253 | return unexpectedOperationCanceled(); |
| 254 | |
| 255 | const auto& region = mp.mesh.topology.getFaceIds( mp.region ); |
| 256 | |
| 257 | struct AreaCounter |
| 258 | { |
| 259 | float seedArea = 0.0f; |
| 260 | float totalArea = 0.0f; |
| 261 | }; |
| 262 | Vector<AreaCounter, RegionId> areas( numComps ); |
| 263 | for ( auto f : region ) |
| 264 | { |
| 265 | auto rId = compMap[f]; |
| 266 | if ( !compsWithSeeds.test( rId ) ) |
| 267 | continue; |
| 268 | auto area = mp.mesh.area( f ); |
| 269 | areas[rId].totalArea += area; |
| 270 | if ( res.test( f ) ) |
| 271 | areas[rId].seedArea += area; |
| 272 | } |
| 273 | |
| 274 | if ( !reportProgress( params.cb, 0.9f ) ) |
| 275 | return unexpectedOperationCanceled(); |
| 276 | |
| 277 | auto largeSeedsCompsBs = compsWithSeeds; |
| 278 | for ( auto rId : compsWithSeeds ) |
| 279 | { |
| 280 | if ( areas[rId].seedArea / areas[rId].totalArea < params.coverRatio ) |
| 281 | largeSeedsCompsBs.reset( rId ); |
| 282 | } |
| 283 | res.resize( region.size() ); |
| 284 | BitSetParallelFor( region, [&] ( FaceId f ) |
| 285 | { |
| 286 | res.set( f, largeSeedsCompsBs.test( compMap[f] ) ); |
| 287 | } ); |
| 288 | if ( !reportProgress( params.cb, 1.0f ) ) |
nothing calls this directly
no test coverage detected