| 214 | |
| 215 | template <typename V> |
| 216 | UndirectedEdgeBitSet getLargestComponent( const Polyline<V>& polyline, float minLength, int* numSmallerComponents ) |
| 217 | { |
| 218 | MR_TIMER; |
| 219 | |
| 220 | auto& topology = polyline.topology; |
| 221 | auto unionFindStruct = getUnionFindStructure( topology ); |
| 222 | |
| 223 | UndirectedEdgeBitSet region( topology.lastNotLoneUndirectedEdge() + 1 ); |
| 224 | for ( auto e : undirectedEdges( topology ) ) |
| 225 | region.set( e ); |
| 226 | |
| 227 | UndirectedEdgeBitSet maxLengthComponent; |
| 228 | const auto& allRoots = unionFindStruct.roots(); |
| 229 | auto [uniqueRootsMap, k] = getUniqueRootIds( allRoots, region ); |
| 230 | if ( k <= 0 ) |
| 231 | { |
| 232 | if ( numSmallerComponents ) |
| 233 | *numSmallerComponents = 0; |
| 234 | return maxLengthComponent; |
| 235 | } |
| 236 | |
| 237 | auto maxLength = std::numeric_limits<float>::lowest(); |
| 238 | int maxI = 0; |
| 239 | std::vector<float> lengths( k, 0.f ); |
| 240 | for ( auto e : region ) |
| 241 | { |
| 242 | auto index = uniqueRootsMap[e]; |
| 243 | auto& length = lengths[index]; |
| 244 | length += polyline.edgeLength( EdgeId( e ) ); |
| 245 | if ( length > maxLength ) |
| 246 | { |
| 247 | maxI = index; |
| 248 | maxLength = length; |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | if ( maxLength < minLength ) |
| 253 | { |
| 254 | if ( numSmallerComponents ) |
| 255 | *numSmallerComponents = k; |
| 256 | return maxLengthComponent; |
| 257 | } |
| 258 | if ( numSmallerComponents ) |
| 259 | *numSmallerComponents = k - 1; |
| 260 | |
| 261 | maxLengthComponent.resize( topology.lastNotLoneUndirectedEdge() + 1 ); |
| 262 | for ( auto e : region ) |
| 263 | { |
| 264 | auto index = uniqueRootsMap[e]; |
| 265 | if ( index != maxI ) |
| 266 | continue; |
| 267 | maxLengthComponent.set( e ); |
| 268 | } |
| 269 | return maxLengthComponent; |
| 270 | } |
| 271 | |
| 272 | template MRMESH_API UndirectedEdgeBitSet getLargestComponent<Vector2f>( const Polyline2& polyline, float minLength, int* numSmallerComponents ); |
| 273 | template MRMESH_API UndirectedEdgeBitSet getLargestComponent<Vector3f>( const Polyline3& polyline, float minLength, int* numSmallerComponents ); |
no test coverage detected