HighMap library (C++)
Loading...
Searching...
No Matches
drainage_basin.hpp
Go to the documentation of this file.
1/* Copyright (c) 2026 Otto Link. Distributed under the terms of the GNU General
2 Public License. The full license is in the file LICENSE, distributed with
3 this software. */
4
12#pragma once
13#include <cstddef>
14#include <memory>
15#include <string>
16#include <utility>
17#include <vector>
18
19#include <glm/glm.hpp>
20
21#include "highmap/array.hpp"
23
24#include <unordered_map>
25
26namespace hmap
27{
28
40{
41public:
46 DrainageBasin(std::vector<glm::vec3> xyz_);
47
52 const std::vector<glm::vec3> &get_xyz() const;
53
58 size_t size() const;
59
64 void to_csv(const std::string &filename) const;
65
66 // --- Geometry / Mesh ---
67
72 const TerrainTriMesh &get_mesh() const;
73
79
84 std::vector<float> compute_vertex_areas() const;
85
92 void remap(float zmin = 0.f, float zmax = 1.f);
93
94 // --- Flow graph construction ---
95
99 void compute_receivers();
100
108 void compute_receivers(unsigned int seed, float noise_strength = 0.25f);
109
115 void update_stream_tree(unsigned int seed, float noise_strength);
116
120 void update_stream_tree();
121
125 void update_traversals();
126
131 std::vector<size_t> &get_outlets() const;
132
137 void set_outlets(const std::vector<size_t> &outlet_indices);
138
143 const std::vector<size_t> &get_receivers() const;
144
149 void invert_receiver_map();
150
151 // --- Basin topology utilities ---
152
157 std::vector<bool> compute_is_ridge_node() const;
158
163 std::vector<size_t> compute_strahler_order() const;
164
170 std::pair<std::vector<size_t>, bool> find_subroots();
171
177 std::vector<std::vector<size_t>> get_main_channels() const;
178
183 void remove_lakes(const std::vector<size_t> &subroot);
184
185 // --- Hydrology computations ---
186
194 std::vector<float> compute_response_times(
195 const std::vector<float> &area_acc,
196 const std::vector<float> &erodibility,
197 float m_exp) const;
198
202 void flow_breach();
203
208 std::vector<std::vector<glm::vec3>> flow_breach_paths();
209
217 float update_elevations(const std::vector<float> &response_times,
218 float uplift_rate,
219 const std::vector<float> &max_slope);
220
226 void accumulate_area_by_outlet(const std::vector<float> &area,
227 std::vector<float> &acc) const;
228
229 // --- Traversal helpers ---
230
237 const std::vector<size_t> &for_each_upstream(size_t outlet) const;
238
244 auto for_each_downstream(size_t outlet) const
245 {
246 const auto &t = traversals.at(outlet);
247 return std::make_pair(t.rbegin(), t.rend());
248 }
249
250private:
251 // --- Geometry ---
252
253 TerrainTriMesh mesh;
254
255 // --- Flow graph ---
256
257 std::vector<size_t> receivers;
258 std::vector<size_t> roots; // basin ID
259 std::vector<std::vector<size_t>> children;
260 std::vector<bool> outlets_mask;
261 mutable std::vector<size_t> cached_outlets;
262 mutable bool outlets_dirty = true;
263 int tick = 0;
264
265 // --- Traversal cache ---
266
267 std::unordered_map<size_t, std::vector<size_t>> traversals;
268
269 // --- Constants ---
270
271 const size_t invalid_index = size_t(-1);
272};
273
274// --- FUNCTIONS
275
282std::vector<size_t> find_border_minima(const std::vector<glm::vec3> &xyz,
283 float eps = 1e-6f);
284
291std::vector<size_t> find_border_sinks(TerrainTriMesh &mesh, float eps = 1e-6f);
292
302std::vector<glm::vec3> heightmap_retopology(const Array &z,
303 float max_error,
304 int max_triangles = 0,
305 int max_points = 0);
306
313std::vector<size_t> sample_border_points(const std::vector<glm::vec3> &xyz,
314 size_t nb);
315
316} // namespace hmap
Declaration of the Array class for 2D floating-point arrays with various mathematical operations and ...
Represents a drainage basin network constructed on a 3D terrain mesh.
Definition drainage_basin.hpp:40
std::vector< size_t > & get_outlets() const
Get the indices of the outlets in the basin.
Definition drainage_basin.cpp:452
void to_csv(const std::string &filename) const
Export the drainage basin data to a CSV file.
Definition drainage_basin.cpp:638
std::pair< std::vector< size_t >, bool > find_subroots()
Find subroots of the flow network.
Definition drainage_basin.cpp:273
void invert_receiver_map()
Invert the receiver map to build a map of children/downstream receivers.
Definition drainage_basin.cpp:476
std::vector< bool > compute_is_ridge_node() const
Compute whether each vertex is a ridge node (no upstream flow).
Definition drainage_basin.cpp:60
const std::vector< size_t > & get_receivers() const
Get the receiver index of each vertex.
Definition drainage_basin.cpp:466
auto for_each_downstream(size_t outlet) const
Get the cached downstream traversal order from a specific outlet.
Definition drainage_basin.hpp:244
void compute_receivers()
Compute the flow receiver for each vertex deterministically.
Definition drainage_basin.cpp:82
std::vector< std::vector< glm::vec3 > > flow_breach_paths()
Compute the breaching paths for depressions.
Definition drainage_basin.cpp:353
float update_elevations(const std::vector< float > &response_times, float uplift_rate, const std::vector< float > &max_slope)
Update terrain elevations based on response times and uplift.
Definition drainage_basin.cpp:671
const std::vector< glm::vec3 > & get_xyz() const
Get the 3D coordinates of the terrain vertices.
Definition drainage_basin.cpp:471
void accumulate_area_by_outlet(const std::vector< float > &area, std::vector< float > &acc) const
Accumulate contributing area down the network by outlet.
Definition drainage_basin.cpp:42
void flow_breach()
Perform flow breaching to resolve depressions.
Definition drainage_basin.cpp:324
void remap(float zmin=0.f, float zmax=1.f)
Remap the elevation (z) values of the mesh vertices to a target range.
Definition drainage_basin.cpp:492
const std::vector< size_t > & for_each_upstream(size_t outlet) const
Get the cached upstream traversal order from a specific outlet.
Definition drainage_basin.cpp:400
void remove_lakes(const std::vector< size_t > &subroot)
Remove lakes by draining local depressions.
Definition drainage_basin.cpp:521
const TerrainTriMesh & get_mesh() const
Get the underlying terrain tri mesh (const).
Definition drainage_basin.cpp:442
std::vector< float > compute_vertex_areas() const
Compute the area of each vertex in the mesh.
Definition drainage_basin.cpp:246
std::vector< float > compute_response_times(const std::vector< float > &area_acc, const std::vector< float > &erodibility, float m_exp) const
Compute response times of the basin vertices.
Definition drainage_basin.cpp:205
void update_traversals()
Update cached traversal orders for upstream/downstream computations.
Definition drainage_basin.cpp:743
void set_outlets(const std::vector< size_t > &outlet_indices)
Set the outlets of the basin.
Definition drainage_basin.cpp:623
void update_stream_tree()
Update the stream tree deterministically.
Definition drainage_basin.cpp:734
std::vector< size_t > compute_strahler_order() const
Compute the Strahler stream order for each vertex.
Definition drainage_basin.cpp:176
std::vector< std::vector< size_t > > get_main_channels() const
Get the main channel paths of the flow network.
Definition drainage_basin.cpp:405
size_t size() const
Get the number of vertices in the basin.
Definition drainage_basin.cpp:633
Triangle mesh representation of a terrain surface.
Definition terrain_tri_mesh.hpp:26
Definition algebra.hpp:23
std::vector< glm::vec3 > heightmap_retopology(const Array &z, float max_error, int max_triangles=0, int max_points=0)
Performs retopology of a heightmap to generate a 3D point cloud.
Definition drainage_basin.cpp:948
std::vector< size_t > find_border_minima(const std::vector< glm::vec3 > &xyz, float eps=1e-6f)
Find local minima along the border of a set of 3D coordinates.
Definition drainage_basin.cpp:783
std::vector< size_t > find_border_sinks(TerrainTriMesh &mesh, float eps=1e-6f)
Find sinks along the border of a terrain tri mesh.
Definition drainage_basin.cpp:842
std::vector< size_t > sample_border_points(const std::vector< glm::vec3 > &xyz, size_t nb)
Sample a specified number of points along the border.
Definition drainage_basin.cpp:888