| 217 | } |
| 218 | |
| 219 | Graph::VertId WatershedGraph::merge( Graph::VertId v0, Graph::VertId v1 ) |
| 220 | { |
| 221 | MR_TIMER; |
| 222 | assert( v0 && v1 ); |
| 223 | assert( v0 != outsideId_ && v1 != outsideId_ ); |
| 224 | assert( graph_.valid( v0 ) && graph_.valid( v1 ) ); |
| 225 | if ( v0 == v1 ) |
| 226 | return v0; |
| 227 | |
| 228 | assert( parentBasin_[v1] == v1 ); |
| 229 | parentBasin_[v1] = v0; |
| 230 | |
| 231 | auto & info0 = basins_[v0]; |
| 232 | auto & info1 = basins_[v1]; |
| 233 | assert( info0.accVolume == info0.maxVolume ); |
| 234 | assert( info1.accVolume == info1.maxVolume ); |
| 235 | assert( !info0.overflowVia ); |
| 236 | assert( info0.lowestBdLevel == info1.lowestBdLevel ); |
| 237 | if ( info1.lowestLevel < info0.lowestLevel ) |
| 238 | { |
| 239 | info0.lowestVert = info1.lowestVert; |
| 240 | info0.lowestLevel = info1.lowestLevel; |
| 241 | } |
| 242 | |
| 243 | graph_.merge( v0, v1, [&]( Graph::EdgeId eremnant, Graph::EdgeId edead ) |
| 244 | { |
| 245 | if ( getHeightAt( bds_[edead].lowestVert ) < getHeightAt( bds_[eremnant].lowestVert ) ) |
| 246 | bds_[eremnant].lowestVert = bds_[edead].lowestVert; |
| 247 | } ); |
| 248 | |
| 249 | info0.lastMergeLevel = info0.lowestBdLevel; |
| 250 | info0.lowestBdLevel = FLT_MAX; |
| 251 | for ( auto bd : graph_.neighbours( v0 ) ) |
| 252 | { |
| 253 | const auto& bdInfo = bds_[bd]; |
| 254 | info0.lowestBdLevel = std::min( info0.lowestBdLevel, getHeightAt( bdInfo.lowestVert ) ); |
| 255 | } |
| 256 | info0.accVolume = info0.lastMergeVolume = info0.maxVolume + info1.maxVolume; |
| 257 | info0.maxVolume = std::max( info0.lastMergeVolume, ( float )computeBasinVolume( v0, info0.lowestBdLevel ) ); |
| 258 | |
| 259 | return v0; |
| 260 | } |
| 261 | |
| 262 | Graph::VertId WatershedGraph::mergeViaBd( Graph::EdgeId bd ) |
| 263 | { |
nothing calls this directly
no test coverage detected