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 <unordered_map>
7#include <vector>
8
9#include <glm/vec2.hpp>
10#include <glm/vec3.hpp>
11#include <glm/vec4.hpp>
12
13#include "highmap/array.hpp"
14
15namespace hmap
16{
17
19{
20public:
22 {
23 glm::vec2 min;
24 glm::vec2 max;
25
26 bool contains(const glm::vec2 &p) const;
27 glm::vec2 clamp(const glm::vec2 &p) const;
28 };
29
30 struct Edge
31 {
32 size_t v0, v1;
33 Edge(size_t a, size_t b) : v0(std::min(a, b)), v1(std::max(a, b))
34 {
35 }
36 bool operator==(const Edge &other) const
37 {
38 return v0 == other.v0 && v1 == other.v1;
39 }
40 };
41
42 struct EdgeHash
43 {
44 std::size_t operator()(const Edge &e) const
45 {
46 return std::hash<size_t>()(e.v0) ^ (std::hash<size_t>()(e.v1) << 1);
47 }
48 };
49
50 struct Triangle
51 {
52 size_t a, b, c;
53 };
54
55 struct Neighbor
56 {
57 size_t index;
59 };
60
62 {
63 std::vector<std::vector<Neighbor>> adjacency;
64
65 void clear()
66 {
67 adjacency.clear();
68 }
69
70 void resize(size_t n)
71 {
72 adjacency.resize(n);
73 }
74 };
75
76public:
77 TerrainTriMesh() = default;
78 TerrainTriMesh(const std::vector<glm::vec3> &ref_points);
79 TerrainTriMesh(const std::vector<float> &x,
80 const std::vector<float> &y,
81 const std::vector<float> &z);
82
83 // --- Core processing ---
84
85 // in this order...
87 void compute_neighbors();
88 void compute_gradients();
89
90 // --- Geometry ops ---
91
92 void relax_xy(float lambda = 0.5f,
93 int iterations = 1,
94 bool preserve_chull = true);
95
96 void relax_xyz(float lambda = 0.5f,
97 int iterations = 1,
98 bool preserve_chull = true);
99
100 void relax_xyz_taubin(float lambda = 0.5f,
101 float mu = -0.55f,
102 int iterations = 1,
103 bool preserve_chull = true);
104
105 void remap_z(float vmin = 0.f, float vmax = 1.f);
106
107 void slope_limiter(float max_slope, int iterations = 10, float sigma = 0.1f);
108 void slope_limiter(const std::vector<float> &max_slope,
109 int iterations = 10,
110 float sigma = 0.1f);
111
112 void subdivise();
113
114 // --- Triangle walk and interp ---
115
116 bool barycentric(const glm::vec2 &p,
117 size_t i0,
118 size_t i1,
119 size_t i2,
120 float &w0,
121 float &w1,
122 float &w2) const;
123
124 int find_triangle(const glm::vec2 &p,
125 int start_tri = 0,
126 bool linear_search = false) const;
127 int neighbor_triangle(int tri_index, int edge_index) const;
128
129 float interpolate_z_linear(const glm::vec2 &p,
130 int &last_tri,
131 float fill_value = 0.f) const;
132 float interpolate_z_linear_gradient(const glm::vec2 &p,
133 int &last_tri,
134 float fill_value = 0.f,
135 float gradient_scaling = 1.f) const;
136 float interpolate_z_nearest(const glm::vec2 &p) const;
137 float interpolate_z_nearest_approx(const glm::vec2 &p,
138 int &last_tri,
139 float fill_value = 0.f) const;
140
141 // --- Metrics ---
142
144 glm::vec2 get_range_z() const;
145 glm::vec3 get_reference_lengths() const;
146 std::vector<float> get_vertex_areas(bool normalized) const;
147
148 float get_reference_area_xy() const;
149 float get_reference_area() const;
150
151 size_t size() const;
152
153 // --- Accessors ---
154
155 const std::vector<glm::vec3> &get_points() const;
156 std::vector<glm::vec3> &get_points();
157 const std::vector<Triangle> &get_triangles() const;
158 const std::vector<size_t> &get_convex_hull() const;
159 const NeighborData &get_neighbors() const;
160
161 // --- IO ---
162
163 bool export_obj(const std::string &filepath) const;
164 std::string info_string() const;
165 void print_info() const;
166 Array to_array(const glm::ivec2 &shape,
167 const std::vector<float> &values = {},
168 const glm::vec4 &bbox = {0.f, 1.f, 0.f, 1.f}) const;
169 void to_csv(const std::string &fname) const;
170
171private:
172 std::vector<glm::vec3> points;
173 std::vector<Triangle> triangles;
174 std::vector<size_t> halfedges;
175 std::vector<size_t> convex_hull;
176 NeighborData neighbors;
177 std::vector<glm::vec2> gradients;
178
179private:
180 glm::vec2 to_xy(const glm::vec3 &p) const;
181};
182
183// --- FUNCTIONS
184
185std::vector<float> cubic_pulse(const TerrainTriMesh &mesh);
186
187TerrainTriMesh generate_terrain_tri_mesh_from_heightmap(const Array &z,
188 float max_error,
189 int max_triangles = 0,
190 int max_points = 0);
191
192} // 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:19
const std::vector< size_t > & get_convex_hull() const
Definition terrain_tri_mesh.cpp:282
float get_reference_area() const
Definition terrain_tri_mesh.cpp:324
std::string info_string() const
Definition terrain_tri_mesh.cpp:429
void slope_limiter(float max_slope, int iterations=10, float sigma=0.1f)
Definition terrain_tri_mesh.cpp:817
void triangulate_delaunay()
Definition terrain_tri_mesh.cpp:931
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:511
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:68
float get_reference_area_xy() const
Definition terrain_tri_mesh.cpp:345
int neighbor_triangle(int tri_index, int edge_index) const
Definition terrain_tri_mesh.cpp:612
float interpolate_z_nearest(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:553
void print_info() const
Definition terrain_tri_mesh.cpp:618
void to_csv(const std::string &fname) const
Definition terrain_tri_mesh.cpp:908
void relax_xy(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:655
void subdivise()
Definition terrain_tri_mesh.cpp:823
const std::vector< glm::vec3 > & get_points() const
Definition terrain_tri_mesh.cpp:298
size_t size() const
Definition terrain_tri_mesh.cpp:771
void compute_neighbors()
Definition terrain_tri_mesh.cpp:167
void relax_xyz_taubin(float lambda=0.5f, float mu=-0.55f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:758
std::vector< float > get_vertex_areas(bool normalized) const
Definition terrain_tri_mesh.cpp:394
TerrainTriMesh()=default
TerrainTriMesh::BoundingBox get_bbox() const
Definition terrain_tri_mesh.cpp:264
void relax_xyz(float lambda=0.5f, int iterations=1, bool preserve_chull=true)
Definition terrain_tri_mesh.cpp:696
float interpolate_z_nearest_approx(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Definition terrain_tri_mesh.cpp:574
float interpolate_z_linear(const glm::vec2 &p, int &last_tri, float fill_value=0.f) const
Definition terrain_tri_mesh.cpp:487
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:861
const NeighborData & get_neighbors() const
Definition terrain_tri_mesh.cpp:287
int find_triangle(const glm::vec2 &p, int start_tri=0, bool linear_search=false) const
Definition terrain_tri_mesh.cpp:219
void compute_gradients()
Definition terrain_tri_mesh.cpp:98
const std::vector< Triangle > & get_triangles() const
Definition terrain_tri_mesh.cpp:388
void remap_z(float vmin=0.f, float vmax=1.f)
Definition terrain_tri_mesh.cpp:623
glm::vec3 get_reference_lengths() const
Definition terrain_tri_mesh.cpp:364
glm::vec2 get_range_z() const
Definition terrain_tri_mesh.cpp:308
bool export_obj(const std::string &filepath) const
Definition terrain_tri_mesh.cpp:198
Definition algebra.hpp:23
Array cubic_pulse(glm::ivec2 shape)
Generates a cubic pulse kernel array.
Definition kernels.cpp:97
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:1012
Definition terrain_tri_mesh.hpp:22
glm::vec2 clamp(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:38
glm::vec2 max
Definition terrain_tri_mesh.hpp:24
bool contains(const glm::vec2 &p) const
Definition terrain_tri_mesh.cpp:32
glm::vec2 min
Definition terrain_tri_mesh.hpp:23
Definition terrain_tri_mesh.hpp:43
std::size_t operator()(const Edge &e) const
Definition terrain_tri_mesh.hpp:44
Definition terrain_tri_mesh.hpp:31
bool operator==(const Edge &other) const
Definition terrain_tri_mesh.hpp:36
Edge(size_t a, size_t b)
Definition terrain_tri_mesh.hpp:33
size_t v0
Definition terrain_tri_mesh.hpp:32
size_t v1
Definition terrain_tri_mesh.hpp:32
Definition terrain_tri_mesh.hpp:62
void clear()
Definition terrain_tri_mesh.hpp:65
void resize(size_t n)
Definition terrain_tri_mesh.hpp:70
std::vector< std::vector< Neighbor > > adjacency
Definition terrain_tri_mesh.hpp:63
Definition terrain_tri_mesh.hpp:56
size_t index
Definition terrain_tri_mesh.hpp:57
float distance2d
Definition terrain_tri_mesh.hpp:58
Definition terrain_tri_mesh.hpp:51
size_t a
Definition terrain_tri_mesh.hpp:52
size_t c
Definition terrain_tri_mesh.hpp:52
size_t b
Definition terrain_tri_mesh.hpp:52