HighMap library (C++)
Loading...
Searching...
No Matches
terrain_tri_mesh.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#pragma once
5#include <optional>
6#include <vector>
7
8#include <glm/vec2.hpp>
9#include <glm/vec3.hpp>
10#include <glm/vec4.hpp>
11
12#include "highmap/array.hpp"
13
14#include <unordered_map>
15
16namespace hmap
17{
18
26{
27public:
30 {
31 glm::vec2 min;
32 glm::vec2 max;
33
35 bool contains(const glm::vec2 &p) const;
36
38 glm::vec2 clamp(const glm::vec2 &p) const;
39 };
40
42 struct Edge
43 {
44 size_t v0, v1;
45 Edge(size_t a, size_t b) : v0(std::min(a, b)), v1(std::max(a, b))
46 {
47 }
48 bool operator==(const Edge &other) const
49 {
50 return v0 == other.v0 && v1 == other.v1;
51 }
52 };
53
55 struct EdgeHash
56 {
57 std::size_t operator()(const Edge &e) const
58 {
59 return std::hash<size_t>()(e.v0) ^ (std::hash<size_t>()(e.v1) << 1);
60 }
61 };
62
64 struct Triangle
65 {
66 size_t a, b, c;
67 };
68
70 struct Neighbor
71 {
72 size_t index;
74 };
75
78 {
79 std::vector<std::vector<Neighbor>> adjacency;
80
81 void clear()
82 {
83 adjacency.clear();
84 }
85
86 void resize(size_t n)
87 {
88 adjacency.resize(n);
89 }
90 };
91
94 {
95 std::vector<float> distance;
96 std::vector<size_t> parent;
97 };
98
99public:
101 TerrainTriMesh() = default;
102
104 TerrainTriMesh(const std::vector<glm::vec3> &ref_points);
105
107 TerrainTriMesh(const std::vector<float> &x,
108 const std::vector<float> &y,
109 const std::vector<float> &z);
110
113
115 void compute_neighbors();
116
118 void compute_gradients();
119
121 void relax_xy(float lambda = 0.5f,
122 int iterations = 1,
123 bool preserve_chull = true);
124
126 void relax_xyz(float lambda = 0.5f,
127 int iterations = 1,
128 bool preserve_chull = true);
129
131 void relax_xyz_taubin(float lambda = 0.5f,
132 float mu = -0.55f,
133 int iterations = 1,
134 bool preserve_chull = true);
135
137 void remap_z(float vmin = 0.f, float vmax = 1.f);
138
140 void slope_limiter(float max_slope, int iterations = 10, float sigma = 0.1f);
141
143 void slope_limiter(const std::vector<float> &max_slope,
144 int iterations = 10,
145 float sigma = 0.1f);
146
148 void subdivise();
149
151 void flow_breach(float epsilon, float uphill_tolerance = 0.f);
152
154 bool barycentric(const glm::vec2 &p,
155 size_t i0,
156 size_t i1,
157 size_t i2,
158 float &w0,
159 float &w1,
160 float &w2) const;
161
163 int find_triangle(const glm::vec2 &p,
164 int start_tri = 0,
165 bool linear_search = false) const;
166
168 int neighbor_triangle(int tri_index, int edge_index) const;
169
171 float interpolate_z_linear(const glm::vec2 &p,
172 int &last_tri,
173 float fill_value = 0.f) const;
174
176 float interpolate_z_linear_gradient(const glm::vec2 &p,
177 int &last_tri,
178 float fill_value = 0.f,
179 float gradient_scaling = 1.f) const;
180
182 float interpolate_z_nearest(const glm::vec2 &p) const;
183
185 float interpolate_z_nearest_approx(const glm::vec2 &p,
186 int &last_tri,
187 float fill_value = 0.f) const;
188
190 BoundingBox get_bbox() const;
191
193 glm::vec2 get_range_z() const;
194
196 glm::vec3 get_reference_lengths() const;
197
199 std::vector<float> get_vertex_areas(bool normalized) const;
200
202 float get_reference_area_xy() const;
203
205 float get_reference_area() const;
206
208 size_t size() const;
209
212 bool use_delta_z = false,
213 float elevation_weight = 1.f) const;
214
217 bool use_delta_z = false,
218 float elevation_weight = 1.f) const;
219
221 std::vector<size_t> shortest_path(size_t start,
222 size_t end,
223 bool use_delta_z = false,
224 float elevation_weight = 1.f) const;
225
227 std::vector<size_t> path_to_hull(size_t start,
228 const ShortestPathResult &result) const;
229
231 const std::vector<glm::vec3> &get_points() const;
232
234 std::vector<glm::vec3> &get_points();
235
237 const std::vector<Triangle> &get_triangles() const;
238
240 const std::vector<size_t> &get_convex_hull() const;
241
243 const NeighborData &get_neighbors() const;
244
246 bool export_obj(const std::string &filepath) const;
247
249 std::string info_string() const;
250
252 void print_info() const;
253
255 Array to_array(const glm::ivec2 &shape,
256 const std::vector<float> &values = {},
257 const glm::vec4 &bbox = {0.f, 1.f, 0.f, 1.f}) const;
258
260 void to_csv(const std::string &fname) const;
261
262private:
263 std::vector<glm::vec3> points;
264 std::vector<Triangle> triangles;
265 std::vector<size_t> halfedges;
266 std::vector<size_t> convex_hull;
267 NeighborData neighbors;
268 std::vector<glm::vec2> gradients;
269
270private:
271 glm::vec2 to_xy(const glm::vec3 &p) const;
272};
273
275std::vector<float> cubic_pulse(const TerrainTriMesh &mesh);
276
278TerrainTriMesh generate_terrain_tri_mesh_from_heightmap(const Array &z,
279 float max_error,
280 int max_triangles = 0,
281 int max_points = 0);
282
285 const Array &z,
286 int control_points_count,
287 std::uint32_t seed);
288
289} // namespace hmap
Declaration of the Array class for 2D floating-point arrays with various mathematical operations and ...
Array class, helper to manipulate 2D float array with "(i, j)" indexing.
Definition array.hpp:32
Triangle mesh representation of a terrain surface.
Definition terrain_tri_mesh.hpp:26
const std::vector< size_t > & get_convex_hull() const
Return convex hull vertex indices.
Definition terrain_tri_mesh.cpp:295
float get_reference_area() const
Return the mesh surface area.
Definition terrain_tri_mesh.cpp:337
void flow_breach(float epsilon, float uphill_tolerance=0.f)
Breach terrain depressions for flow routing.
Definition flow_breach.cpp:12
std::string info_string() const
Return a mesh summary string.
Definition terrain_tri_mesh.cpp:442
void slope_limiter(float max_slope, int iterations=10, float sigma=0.1f)
Limit terrain slopes.
Definition terrain_tri_mesh.cpp:830
void triangulate_delaunay()
Build the Delaunay triangulation.
Definition terrain_tri_mesh.cpp:946
float interpolate_z_linear_gradient(const glm::vec2 &p, int &last_tri, float fill_value=0.f, float gradient_scaling=1.f) const
Gradient-enhanced linear interpolation.
Definition terrain_tri_mesh.cpp:524
bool barycentric(const glm::vec2 &p, size_t i0, size_t i1, size_t i2, float &w0, float &w1, float &w2) const
Compute barycentric coordinates.
Definition terrain_tri_mesh.cpp:75
float get_reference_area_xy() const
Return the projected mesh area.
Definition terrain_tri_mesh.cpp:358
int neighbor_triangle(int tri_index, int edge_index) const
Return the neighboring triangle across an edge.
Definition terrain_tri_mesh.cpp:625
float interpolate_z_nearest(const glm::vec2 &p) const
Nearest-neighbor interpolation.
Definition terrain_tri_mesh.cpp:566
ShortestPathResult compute_shortest_paths_to_hull(bool use_delta_z=false, float elevation_weight=1.f) const
Compute shortest paths to the convex hull.
Definition shortest_path.cpp:80
void print_info() const
Print mesh information.
Definition terrain_tri_mesh.cpp:631
void to_csv(const std::string &fname) const
Export vertices to CSV.
Definition terrain_tri_mesh.cpp:923
void relax_xy(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Relax vertex positions in the XY plane.
Definition terrain_tri_mesh.cpp:668
void subdivise()
Subdivide mesh triangles.
Definition terrain_tri_mesh.cpp:836
const std::vector< glm::vec3 > & get_points() const
Return mesh vertices.
Definition terrain_tri_mesh.cpp:311
size_t size() const
Return the number of vertices.
Definition terrain_tri_mesh.cpp:784
void compute_neighbors()
Compute vertex adjacency.
Definition terrain_tri_mesh.cpp:174
void relax_xyz_taubin(float lambda=0.5f, float mu=-0.55f, int iterations=1, bool preserve_chull=true)
Apply Taubin smoothing.
Definition terrain_tri_mesh.cpp:771
std::vector< float > get_vertex_areas(bool normalized) const
Compute vertex areas.
Definition terrain_tri_mesh.cpp:407
TerrainTriMesh()=default
Construct an empty mesh.
ShortestPathResult compute_shortest_paths(size_t start, bool use_delta_z=false, float elevation_weight=1.f) const
Compute shortest paths from a source vertex.
Definition shortest_path.cpp:18
BoundingBox get_bbox() const
Return the mesh bounding box.
Definition terrain_tri_mesh.cpp:277
void relax_xyz(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Relax vertex positions in 3D.
Definition terrain_tri_mesh.cpp:709
float interpolate_z_nearest_approx(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Approximate nearest-neighbor interpolation.
Definition terrain_tri_mesh.cpp:587
float interpolate_z_linear(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Linearly interpolate elevation.
Definition terrain_tri_mesh.cpp:500
Array to_array(const glm::ivec2 &shape, const std::vector< float > &values={}, const glm::vec4 &bbox={0.f, 1.f, 0.f, 1.f}) const
Rasterize the mesh into an array.
Definition terrain_tri_mesh.cpp:874
std::vector< size_t > path_to_hull(size_t start, const ShortestPathResult &result) const
Reconstruct a path to the convex hull.
Definition shortest_path.cpp:166
const NeighborData & get_neighbors() const
Return vertex neighbors.
Definition terrain_tri_mesh.cpp:300
int find_triangle(const glm::vec2 &p, int start_tri=0, bool linear_search=false) const
Find the triangle containing a point.
Definition terrain_tri_mesh.cpp:226
std::vector< size_t > shortest_path(size_t start, size_t end, bool use_delta_z=false, float elevation_weight=1.f) const
Compute the shortest path between two vertices.
Definition shortest_path.cpp:141
void compute_gradients()
Compute vertex gradients.
Definition terrain_tri_mesh.cpp:105
const std::vector< Triangle > & get_triangles() const
Return mesh triangles.
Definition terrain_tri_mesh.cpp:401
void remap_z(float vmin=0.f, float vmax=1.f)
Remap elevation values.
Definition terrain_tri_mesh.cpp:636
glm::vec3 get_reference_lengths() const
Return reference mesh dimensions.
Definition terrain_tri_mesh.cpp:377
glm::vec2 get_range_z() const
Return the elevation range.
Definition terrain_tri_mesh.cpp:321
bool export_obj(const std::string &filepath) const
Export the mesh as an OBJ file.
Definition terrain_tri_mesh.cpp:205
Definition algebra.hpp:23
Array cubic_pulse(glm::ivec2 shape)
Generates a cubic pulse kernel array.
Definition kernels.cpp:107
Array normalized(const Array &array, NormalizationMethod method)
Returns a normalized copy of an array.
Definition normalize.cpp:51
TerrainTriMesh generate_terrain_tri_mesh_from_heightmap_random(const Array &z, int control_points_count, std::uint32_t seed)
Generate a random terrain mesh from a heightmap.
Definition terrain_tri_mesh.cpp:1058
TerrainTriMesh generate_terrain_tri_mesh_from_heightmap(const Array &z, float max_error, int max_triangles=0, int max_points=0)
Generate a terrain mesh from a heightmap.
Definition terrain_tri_mesh.cpp:1028
Axis-aligned 2D bounding box.
Definition terrain_tri_mesh.hpp:30
glm::vec2 clamp(const glm::vec2 &p) const
Clamp a point to the box.
Definition terrain_tri_mesh.cpp:45
glm::vec2 max
Definition terrain_tri_mesh.hpp:32
bool contains(const glm::vec2 &p) const
Check whether a point lies inside the box.
Definition terrain_tri_mesh.cpp:39
glm::vec2 min
Definition terrain_tri_mesh.hpp:31
Hash functor for Edge.
Definition terrain_tri_mesh.hpp:56
std::size_t operator()(const Edge &e) const
Definition terrain_tri_mesh.hpp:57
Undirected edge between two vertices.
Definition terrain_tri_mesh.hpp:43
bool operator==(const Edge &other) const
Definition terrain_tri_mesh.hpp:48
Edge(size_t a, size_t b)
Definition terrain_tri_mesh.hpp:45
size_t v0
Definition terrain_tri_mesh.hpp:44
size_t v1
Definition terrain_tri_mesh.hpp:44
Vertex adjacency lists.
Definition terrain_tri_mesh.hpp:78
void clear()
Definition terrain_tri_mesh.hpp:81
void resize(size_t n)
Definition terrain_tri_mesh.hpp:86
std::vector< std::vector< Neighbor > > adjacency
Definition terrain_tri_mesh.hpp:79
Neighbor vertex information.
Definition terrain_tri_mesh.hpp:71
size_t index
Definition terrain_tri_mesh.hpp:72
float distance2d
Definition terrain_tri_mesh.hpp:73
Result of a shortest-path computation.
Definition terrain_tri_mesh.hpp:94
std::vector< size_t > parent
Definition terrain_tri_mesh.hpp:96
std::vector< float > distance
Definition terrain_tri_mesh.hpp:95
Triangle defined by three vertex indices.
Definition terrain_tri_mesh.hpp:65
size_t a
Definition terrain_tri_mesh.hpp:66
size_t c
Definition terrain_tri_mesh.hpp:66
size_t b
Definition terrain_tri_mesh.hpp:66