MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / getNLargeByLengthComponents

Function getNLargeByLengthComponents

source/MRMesh/MRPolylineComponents.cpp:143–210  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

141
142template <typename V>
143std::vector<UndirectedEdgeBitSet> getNLargeByLengthComponents( const Polyline<V>& polyline, const LargeByLengthComponentsSettings& settings )
144{
145 MR_TIMER;
146 std::vector<UndirectedEdgeBitSet> res;
147
148 assert( settings.maxLargeComponents > 0 );
149 if ( settings.maxLargeComponents <= 0 )
150 {
151 if ( settings.numSmallerComponents )
152 *settings.numSmallerComponents = -1; //unknown
153 return res;
154 }
155 if ( settings.maxLargeComponents == 1 )
156 {
157 res.push_back( getLargestComponent( polyline, settings.minLength, settings.numSmallerComponents ) );
158 return res;
159 }
160
161 auto unionFind = getUnionFindStructure( polyline.topology );
162 const auto& roots = unionFind.roots();
163
164 HashMap<UndirectedEdgeId, float> root2length;
165 for ( auto ue : undirectedEdges( polyline.topology ) )
166 root2length[roots[ue]] += polyline.edgeLength( EdgeId( ue ) );
167
168 struct LengthRoot
169 {
170 float length = 0;
171 UndirectedEdgeId root;
172 constexpr auto operator <=>( const LengthRoot& ) const = default;
173 };
174
175 std::vector<LengthRoot> lengthRootVec;
176 lengthRootVec.reserve( root2length.size() );
177 // fill it with not too small components
178 for ( const auto& [root, length] : root2length )
179 {
180 if ( length >= settings.minLength )
181 lengthRootVec.push_back( { length, root } );
182 }
183
184 // leave at most given number of roots sorted in descending by area order
185 if ( lengthRootVec.size() <= settings.maxLargeComponents )
186 {
187 if ( settings.numSmallerComponents )
188 *settings.numSmallerComponents = 0;
189 std::sort( lengthRootVec.begin(), lengthRootVec.end(), std::greater() );
190 }
191 else
192 {
193 if ( settings.numSmallerComponents )
194 *settings.numSmallerComponents = int( lengthRootVec.size() - settings.maxLargeComponents );
195 std::partial_sort( lengthRootVec.begin(), lengthRootVec.begin() + settings.maxLargeComponents, lengthRootVec.end(), std::greater() );
196 lengthRootVec.resize( settings.maxLargeComponents );
197 }
198
199 res.resize( lengthRootVec.size() );
200 ParallelFor( res, [&] ( size_t i )

Callers

nothing calls this directly

Calls 13

getUnionFindStructureFunction · 0.85
ParallelForFunction · 0.85
push_backMethod · 0.80
getLargestComponentFunction · 0.70
undirectedEdgesFunction · 0.70
edgeLengthMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
resizeMethod · 0.45
undirectedEdgeSizeMethod · 0.45

Tested by

no test coverage detected