| 30 | { |
| 31 | |
| 32 | WatershedGraph::WatershedGraph( const Mesh & mesh, const Vector<int, FaceId> & face2basin, int numBasins ) |
| 33 | : mesh_( mesh ) |
| 34 | , face2iniBasin_( face2basin ) |
| 35 | { |
| 36 | MR_TIMER; |
| 37 | assert( numBasins >= 0 ); |
| 38 | basins_.clear(); |
| 39 | bds_.clear(); |
| 40 | |
| 41 | Vector<BasinVolumeCalculator, Graph::VertId> volumeCalcs( numBasins ); |
| 42 | |
| 43 | outsideId_ = Graph::VertId( numBasins ); |
| 44 | ++numBasins; |
| 45 | basins_.resize( numBasins ); |
| 46 | Graph::NeighboursPerVertex neighboursPerVertex( numBasins ); |
| 47 | parentBasin_.clear(); |
| 48 | parentBasin_.reserve( numBasins ); |
| 49 | for ( Graph::VertId v( 0 ); v < numBasins; ++v ) |
| 50 | parentBasin_.push_back( v ); |
| 51 | Graph::EndsPerEdge endsPerEdge; |
| 52 | |
| 53 | HashMap<Graph::EndVertices, Graph::EdgeId> neiBasins2edge; |
| 54 | |
| 55 | for ( auto v : mesh_.topology.getValidVerts() ) |
| 56 | { |
| 57 | const auto h = getHeightAt( v ); |
| 58 | bool bdVert = false; |
| 59 | Graph::VertId basin0; |
| 60 | for ( auto e : orgRing( mesh_.topology, v ) ) |
| 61 | { |
| 62 | auto l = mesh_.topology.left( e ); |
| 63 | Graph::VertId basin( l ? face2basin[l] : outsideId_ ); |
| 64 | if ( !basin0 ) |
| 65 | { |
| 66 | basin0 = basin; |
| 67 | continue; |
| 68 | } |
| 69 | if ( basin != basin0 ) |
| 70 | { |
| 71 | bdVert = true; |
| 72 | break; |
| 73 | } |
| 74 | } |
| 75 | if ( !bdVert ) |
| 76 | { |
| 77 | if ( basin0 ) |
| 78 | { |
| 79 | auto & info0 = basins_[basin0]; |
| 80 | if ( h < info0.lowestLevel ) |
| 81 | { |
| 82 | info0.lowestVert = v; |
| 83 | info0.lowestLevel = h; |
| 84 | } |
| 85 | } |
| 86 | continue; |
| 87 | } |
| 88 | for ( auto e : orgRing( mesh_.topology, v ) ) |
| 89 | { |
nothing calls this directly
no test coverage detected