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
20{
21public:
23 {
24 glm::vec2 min;
25 glm::vec2 max;
26
27 bool contains(const glm::vec2 &p) const;
28 glm::vec2 clamp(const glm::vec2 &p) const;
29 };
30
31 struct Edge
32 {
33 size_t v0, v1;
34 Edge(size_t a, size_t b) : v0(std::min(a, b)), v1(std::max(a, b))
35 {
36 }
37 bool operator==(const Edge &other) const
38 {
39 return v0 == other.v0 && v1 == other.v1;
40 }
41 };
42
43 struct EdgeHash
44 {
45 std::size_t operator()(const Edge &e) const
46 {
47 return std::hash<size_t>()(e.v0) ^ (std::hash<size_t>()(e.v1) << 1);
48 }
49 };
50
51 struct Triangle
52 {
53 size_t a, b, c;
54 };
55
56 struct Neighbor
57 {
58 size_t index;
60 };
61
63 {
64 std::vector<std::vector<Neighbor>> adjacency;
65
66 void clear()
67 {
68 adjacency.clear();
69 }
70
71 void resize(size_t n)
72 {
73 adjacency.resize(n);
74 }
75 };
76
77public:
78 TerrainTriMesh() = default;
79 TerrainTriMesh(const std::vector<glm::vec3> &ref_points);
80 TerrainTriMesh(const std::vector<float> &x,
81 const std::vector<float> &y,
82 const std::vector<float> &z);
83
84 // --- Core processing ---
85
86 // in this order...
88 void compute_neighbors();
89 void compute_gradients();
90
91 // --- Geometry ops ---
92
93 void relax_xy(float lambda = 0.5f,
94 int iterations = 1,
95 bool preserve_chull = true);
96
97 void relax_xyz(float lambda = 0.5f,
98 int iterations = 1,
99 bool preserve_chull = true);
100
101 void relax_xyz_taubin(float lambda = 0.5f,
102 float mu = -0.55f,
103 int iterations = 1,
104 bool preserve_chull = true);
105
106 void remap_z(float vmin = 0.f, float vmax = 1.f);
107
108 void slope_limiter(float max_slope, int iterations = 10, float sigma = 0.1f);
109 void slope_limiter(const std::vector<float> &max_slope,
110 int iterations = 10,
111 float sigma = 0.1f);
112
113 void subdivise();
114
115 // --- Triangle walk and interp ---
116
117 bool barycentric(const glm::vec2 &p,
118 size_t i0,
119 size_t i1,
120 size_t i2,
121 float &w0,
122 float &w1,
123 float &w2) const;
124
125 int find_triangle(const glm::vec2 &p,
126 int start_tri = 0,
127 bool linear_search = false) const;
128 int neighbor_triangle(int tri_index, int edge_index) const;
129
130 float interpolate_z_linear(const glm::vec2 &p,
131 int &last_tri,
132 float fill_value = 0.f) const;
133 float interpolate_z_linear_gradient(const glm::vec2 &p,
134 int &last_tri,
135 float fill_value = 0.f,
136 float gradient_scaling = 1.f) const;
137 float interpolate_z_nearest(const glm::vec2 &p) const;
138 float interpolate_z_nearest_approx(const glm::vec2 &p,
139 int &last_tri,
140 float fill_value = 0.f) const;
141
142 // --- Metrics ---
143
145 glm::vec2 get_range_z() const;
146 glm::vec3 get_reference_lengths() const;
147 std::vector<float> get_vertex_areas(bool normalized) const;
148
149 float get_reference_area_xy() const;
150 float get_reference_area() const;
151
152 size_t size() const;
153
154 // --- Accessors ---
155
156 const std::vector<glm::vec3> &get_points() const;
157 std::vector<glm::vec3> &get_points();
158 const std::vector<Triangle> &get_triangles() const;
159 const std::vector<size_t> &get_convex_hull() const;
160 const NeighborData &get_neighbors() const;
161
162 // --- IO ---
163
164 bool export_obj(const std::string &filepath) const;
165 std::string info_string() const;
166 void print_info() const;
167 Array to_array(const glm::ivec2 &shape,
168 const std::vector<float> &values = {},
169 const glm::vec4 &bbox = {0.f, 1.f, 0.f, 1.f}) const;
170 void to_csv(const std::string &fname) const;
171
172private:
173 std::vector<glm::vec3> points;
174 std::vector<Triangle> triangles;
175 std::vector<size_t> halfedges;
176 std::vector<size_t> convex_hull;
177 NeighborData neighbors;
178 std::vector<glm::vec2> gradients;
179
180private:
181 glm::vec2 to_xy(const glm::vec3 &p) const;
182};
183
184// --- FUNCTIONS
185
186std::vector<float> cubic_pulse(const TerrainTriMesh &mesh);
187
188TerrainTriMesh generate_terrain_tri_mesh_from_heightmap(const Array &z,
189 float max_error,
190 int max_triangles = 0,
191 int max_points = 0);
192
193} // 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
Definition terrain_tri_mesh.hpp:20
const std::vector< size_t > & get_convex_hull() const
Definition terrain_tri_mesh.cpp:292
float get_reference_area() const
Definition terrain_tri_mesh.cpp:334
std::string info_string() const
Definition terrain_tri_mesh.cpp:439
void slope_limiter(float max_slope, int iterations=10, float sigma=0.1f)
Definition terrain_tri_mesh.cpp:827
void triangulate_delaunay()
Definition terrain_tri_mesh.cpp:941
float interpolate_z_linear_gradient(const glm::vec2 &p, int &last_tri, float fill_value=0.f, float gradient_scaling=1.f) const
Definition terrain_tri_mesh.cpp:521
bool barycentric(const glm::vec2 &p, size_t i0, size_t i1, size_t i2, float &w0, float &w1, float &w2) const
Definition terrain_tri_mesh.cpp:72
float get_reference_area_xy() const
Definition terrain_tri_mesh.cpp:355
int neighbor_triangle(int tri_index, int edge_index) const
Definition terrain_tri_mesh.cpp:622
float interpolate_z_nearest(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:563
void print_info() const
Definition terrain_tri_mesh.cpp:628
void to_csv(const std::string &fname) const
Definition terrain_tri_mesh.cpp:918
void relax_xy(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:665
void subdivise()
Definition terrain_tri_mesh.cpp:833
const std::vector< glm::vec3 > & get_points() const
Definition terrain_tri_mesh.cpp:308
size_t size() const
Definition terrain_tri_mesh.cpp:781
void compute_neighbors()
Definition terrain_tri_mesh.cpp:171
void relax_xyz_taubin(float lambda=0.5f, float mu=-0.55f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:768
std::vector< float > get_vertex_areas(bool normalized) const
Definition terrain_tri_mesh.cpp:404
TerrainTriMesh()=default
TerrainTriMesh::BoundingBox get_bbox() const
Definition terrain_tri_mesh.cpp:274
void relax_xyz(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:706
float interpolate_z_nearest_approx(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Definition terrain_tri_mesh.cpp:584
float interpolate_z_linear(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Definition terrain_tri_mesh.cpp:497
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
Definition terrain_tri_mesh.cpp:871
const NeighborData & get_neighbors() const
Definition terrain_tri_mesh.cpp:297
int find_triangle(const glm::vec2 &p, int start_tri=0, bool linear_search=false) const
Definition terrain_tri_mesh.cpp:223
void compute_gradients()
Definition terrain_tri_mesh.cpp:102
const std::vector< Triangle > & get_triangles() const
Definition terrain_tri_mesh.cpp:398
void remap_z(float vmin=0.f, float vmax=1.f)
Definition terrain_tri_mesh.cpp:633
glm::vec3 get_reference_lengths() const
Definition terrain_tri_mesh.cpp:374
glm::vec2 get_range_z() const
Definition terrain_tri_mesh.cpp:318
bool export_obj(const std::string &filepath) const
Definition terrain_tri_mesh.cpp:202
Definition algebra.hpp:23
Array cubic_pulse(glm::ivec2 shape)
Generates a cubic pulse kernel array.
Definition kernels.cpp:98
Array normalized(const Array &array, NormalizationMethod method)
Returns a normalized copy of an array.
Definition normalize.cpp:48
TerrainTriMesh generate_terrain_tri_mesh_from_heightmap(const Array &z, float max_error, int max_triangles=0, int max_points=0)
Definition terrain_tri_mesh.cpp:1022
Definition terrain_tri_mesh.hpp:23
glm::vec2 clamp(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:42
glm::vec2 max
Definition terrain_tri_mesh.hpp:25
bool contains(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:36
glm::vec2 min
Definition terrain_tri_mesh.hpp:24
Definition terrain_tri_mesh.hpp:44
std::size_t operator()(const Edge &e) const
Definition terrain_tri_mesh.hpp:45
Definition terrain_tri_mesh.hpp:32
bool operator==(const Edge &other) const
Definition terrain_tri_mesh.hpp:37
Edge(size_t a, size_t b)
Definition terrain_tri_mesh.hpp:34
size_t v0
Definition terrain_tri_mesh.hpp:33
size_t v1
Definition terrain_tri_mesh.hpp:33
Definition terrain_tri_mesh.hpp:63
void clear()
Definition terrain_tri_mesh.hpp:66
void resize(size_t n)
Definition terrain_tri_mesh.hpp:71
std::vector< std::vector< Neighbor > > adjacency
Definition terrain_tri_mesh.hpp:64
Definition terrain_tri_mesh.hpp:57
size_t index
Definition terrain_tri_mesh.hpp:58
float distance2d
Definition terrain_tri_mesh.hpp:59
Definition terrain_tri_mesh.hpp:52
size_t a
Definition terrain_tri_mesh.hpp:53
size_t c
Definition terrain_tri_mesh.hpp:53
size_t b
Definition terrain_tri_mesh.hpp:53