Back
Meshing
Overview
The Mesh<N> class represents a triangulated surface mesh in N dimensions (2D or 3D).
It stores vertex positions and triangle connectivity, and supports per-vertex and per-triangle attributes
via embedded Dataframe objects. The module also provides contour extraction functions for
isoline/isosurface computation.
Mesh Class
Mesh Class Definition
template <size_t N>
class Mesh {
public:
// Constructors
Mesh() = default;
Mesh(const Serie<Vector<N>> &vertices,
const Serie<std::array<uint32_t, 3>> &triangles);
// Accessors
size_t vertexCount() const;
size_t triangleCount() const;
const Serie<Vector<N>> &vertices() const;
const Serie<std::array<uint32_t, 3>> &triangles() const;
// Attributes (stored as Dataframe)
Dataframe &vertexAttributes();
const Dataframe &vertexAttributes() const;
Dataframe &triangleAttributes();
const Dataframe &triangleAttributes() const;
// Add attributes
template <typename T>
void addVertexAttribute(const std::string &name, const Serie<T> &data);
template <typename T>
void addTriangleAttribute(const std::string &name, const Serie<T> &data);
// Topology queries
std::vector<std::vector<uint32_t>> neighbors() const;
std::vector<uint32_t> borderNodes() const;
// Validation
bool isValid() const;
};
// Type aliases
using Mesh2D = Mesh<2>;
using Mesh3D = Mesh<3>;
Mesh Example
// Create a simple 3D mesh
df::Serie<Vector<3>> vertices{
{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}
};
df::Serie<std::array<uint32_t, 3>> triangles{
{0, 1, 2}, {1, 3, 2}
};
df::Mesh3D mesh(vertices, triangles);
std::cout << "Vertices: " << mesh.vertexCount() << std::endl; // 4
std::cout << "Triangles: " << mesh.triangleCount() << std::endl; // 2
std::cout << "Valid: " << mesh.isValid() << std::endl; // true
// Add per-vertex scalar attribute
df::Serie<double> elevation{0.0, 0.5, 0.3, 0.8};
mesh.addVertexAttribute("elevation", elevation);
// Add per-triangle attribute
df::Serie<double> quality{0.95, 0.87};
mesh.addTriangleAttribute("quality", quality);
// Access attributes
auto elev = mesh.vertexAttributes().get<double>("elevation");
// Get border nodes
auto border = mesh.borderNodes();
// Get neighbor connectivity
auto nbrs = mesh.neighbors();
Contour Extraction
Contour Functions
// Iso-segment structure: a line segment on the mesh surface at a given iso-value
template <size_t N>
struct IsoSegment {
Vector<N> p1; // First endpoint
Vector<N> p2; // Second endpoint
double value; // Iso-value
};
// Extract contour lines at a given iso-value
template <size_t N>
std::vector<IsoSegment<N>> contours(
const Mesh<N> &mesh,
const std::string &attrName, // Vertex attribute name
double isoValue
);
// Generate iso-values evenly spaced by a given spacing
std::vector<double> generateIsosBySpacing(
double minVal, double maxVal, double spacing
);
// Generate a given number of evenly spaced iso-values
std::vector<double> generateIsosByNumber(
double minVal, double maxVal, size_t count
);
// Generate all contours for a set of iso-values
template <size_t N>
std::vector<IsoSegment<N>> generateIsos(
const Mesh<N> &mesh,
const std::string &attrName,
const std::vector<double> &isoValues
);
Contour Example
// Create a mesh with an elevation attribute
df::Mesh3D mesh(vertices, triangles);
mesh.addVertexAttribute("elevation", elevation);
// Extract a single contour at elevation = 0.5
auto iso_segments = df::contours(mesh, "elevation", 0.5);
for (const auto &seg : iso_segments) {
std::cout << "Segment from ("
<< seg.p1[0] << "," << seg.p1[1] << "," << seg.p1[2]
<< ") to ("
<< seg.p2[0] << "," << seg.p2[1] << "," << seg.p2[2]
<< ") at value " << seg.value << std::endl;
}
// Generate multiple contours by spacing
auto iso_vals = df::generateIsosBySpacing(0.0, 1.0, 0.1);
auto all_isos = df::generateIsos(mesh, "elevation", iso_vals);
// Or by count
auto iso_vals2 = df::generateIsosByNumber(0.0, 1.0, 10);
auto all_isos2 = df::generateIsos(mesh, "elevation", iso_vals2);
Complete Example
Mesh Processing Pipeline
#include <dataframe/Serie.h>
#include <dataframe/geo/mesh.h>
#include <dataframe/geo/geometry.h>
#include <iostream>
int main() {
// Generate a sphere mesh
auto [verts, tris] = df::geo::generateSphere(3, 1.0);
df::Mesh3D sphere(verts, tris);
// Compute normals and add as attribute
auto norms = df::geo::normals(verts, tris);
sphere.addTriangleAttribute("normals", norms);
// Add a scalar field (e.g., height = z-coordinate)
auto heights = verts | df::map([](const Vector<3> &v, size_t) {
return v[2];
});
sphere.addVertexAttribute("height", heights);
// Extract contour lines at the equator
auto equator = df::contours(sphere, "height", 0.0);
std::cout << "Sphere: " << sphere.vertexCount() << " vertices, "
<< sphere.triangleCount() << " triangles" << std::endl;
std::cout << "Equator segments: " << equator.size() << std::endl;
// Check border (sphere has no border)
auto border = sphere.borderNodes();
std::cout << "Border nodes: " << border.size() << std::endl; // 0
return 0;
}