Completes the work begun in the previous commit on this branch. Every
public symbol under code/include/ now carries a brief Doxygen comment
(0 undocumented per scripts/doxygen-coverage.sh, with the `detail::`
implementation namespaces excluded as before).
Trajectory on this branch:
start (after Doxyfile fix): 24.0 % (165 / 437 in the no-detail set
was 105 / 437 when detail counted)
after PR #17 base commit : 42.4 % (165 / 396)
this commit : 100.0 % (396 / 396)
Files touched (all .hpp / .h headers under code/include/):
* cgal/Conformal_map_traits.h
* clausen.hpp, conformal_mesh.hpp, constants.hpp (already docd)
* cp_euclidean_functional.hpp, cut_graph.hpp, discrete_elliptic_utility.hpp
* euclidean_functional.hpp, euclidean_geometry.hpp, euclidean_hessian.hpp
* fundamental_domain.hpp, gauss_bonnet.hpp
* hyper_ideal_{functional,geometry,hessian,utility,visualization_utility}.hpp
* inversive_distance_functional.hpp, layout.hpp
* matrix_utility.hpp, mesh_builder.hpp, mesh_io.hpp
* newton_solver.hpp, p2_utility.hpp, period_matrix.hpp, projective_math.hpp
* serialization.hpp, spherical_functional.hpp, spherical_geometry.hpp
* spherical_hessian.hpp, viewer_utils.h
CI:
.gitea/workflows/doxygen-pages.yml now enforces
`scripts/doxygen-coverage.sh --threshold 100`, so any future regression
(a new public function landed without a `///` brief) fails the build
before the Doxygen HTML is published to Codeberg Pages.
Doxygen warnings remain at 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
149 lines
5.1 KiB
C++
149 lines
5.1 KiB
C++
#pragma once
|
||
// mesh_builder.hpp
|
||
//
|
||
// Factory functions that build simple reference meshes for testing and examples.
|
||
// All functions return a ConformalMesh (CGAL::Surface_mesh<Point3>).
|
||
//
|
||
// Replaces Java mesh generators:
|
||
// CoHDS generators (convex hull, hyper-ideal generator) come later (Phase 3c/4).
|
||
// These builders cover the minimal meshes needed for functional unit tests.
|
||
|
||
#include "conformal_mesh.hpp"
|
||
#include "constants.hpp"
|
||
#include <cmath>
|
||
#include <vector>
|
||
|
||
namespace conformallab {
|
||
|
||
// ── Single triangle ──────────────────────────────────────────────────────────
|
||
//
|
||
// v2
|
||
// | \
|
||
// | \
|
||
// v0 ─ v1
|
||
//
|
||
/// Build a single right-angle triangle in the xy-plane (1 face, 3 vertices, 3 edges).
|
||
// The triangle lies in the xy-plane with a right angle at v0.
|
||
inline ConformalMesh make_triangle(
|
||
double x0=0, double y0=0,
|
||
double x1=1, double y1=0,
|
||
double x2=0, double y2=1)
|
||
{
|
||
ConformalMesh mesh;
|
||
auto v0 = mesh.add_vertex(Point3(x0, y0, 0));
|
||
auto v1 = mesh.add_vertex(Point3(x1, y1, 0));
|
||
auto v2 = mesh.add_vertex(Point3(x2, y2, 0));
|
||
mesh.add_face(v0, v1, v2);
|
||
return mesh;
|
||
}
|
||
|
||
// ── Regular tetrahedron ──────────────────────────────────────────────────────
|
||
//
|
||
/// Build a regular tetrahedron (4 vertices, 4 faces, 6 edges; sphere topology).
|
||
// Euler characteristic: V - E + F = 4 - 6 + 4 = 2 (sphere topology).
|
||
// Used to test closed-surface traversal.
|
||
inline ConformalMesh make_tetrahedron()
|
||
{
|
||
ConformalMesh mesh;
|
||
|
||
// Vertices of a regular tetrahedron centred at origin, edge length √2·2
|
||
auto v0 = mesh.add_vertex(Point3( 1, 1, 1));
|
||
auto v1 = mesh.add_vertex(Point3( 1, -1, -1));
|
||
auto v2 = mesh.add_vertex(Point3(-1, 1, -1));
|
||
auto v3 = mesh.add_vertex(Point3(-1, -1, 1));
|
||
|
||
// 4 outward-facing triangles (consistent winding)
|
||
mesh.add_face(v0, v2, v1); // bottom (z=-1 side)
|
||
mesh.add_face(v0, v1, v3); // front (y=-1 side)
|
||
mesh.add_face(v0, v3, v2); // left (x=-1 side)
|
||
mesh.add_face(v1, v2, v3); // back
|
||
|
||
return mesh;
|
||
}
|
||
|
||
// ── Two-triangle strip ───────────────────────────────────────────────────────
|
||
//
|
||
// v2 ─ v3
|
||
// | \ |
|
||
// v0 ─ v1
|
||
//
|
||
/// Build a two-triangle strip (4 vertices, 2 faces, 5 edges; 1 interior edge).
|
||
/// Useful for testing interior- vs boundary-edge distinction.
|
||
inline ConformalMesh make_quad_strip()
|
||
{
|
||
ConformalMesh mesh;
|
||
auto v0 = mesh.add_vertex(Point3(0, 0, 0));
|
||
auto v1 = mesh.add_vertex(Point3(1, 0, 0));
|
||
auto v2 = mesh.add_vertex(Point3(0, 1, 0));
|
||
auto v3 = mesh.add_vertex(Point3(1, 1, 0));
|
||
|
||
mesh.add_face(v0, v1, v2); // lower-left triangle
|
||
mesh.add_face(v1, v3, v2); // upper-right triangle (shares edge v1–v2)
|
||
|
||
return mesh;
|
||
}
|
||
|
||
// ── Regular flat polygon fan ─────────────────────────────────────────────────
|
||
//
|
||
/// Build a regular flat polygon fan: `n` triangles sharing a central
|
||
/// vertex, with rim vertices on the unit circle (disk topology).
|
||
inline ConformalMesh make_fan(int n)
|
||
{
|
||
CGAL_precondition(n >= 3);
|
||
ConformalMesh mesh;
|
||
|
||
auto center = mesh.add_vertex(Point3(0, 0, 0));
|
||
|
||
const double dtheta = TWO_PI / n;
|
||
std::vector<Vertex_index> rim(n);
|
||
for (int i = 0; i < n; ++i) {
|
||
double a = i * dtheta;
|
||
rim[i] = mesh.add_vertex(Point3(std::cos(a), std::sin(a), 0));
|
||
}
|
||
|
||
for (int i = 0; i < n; ++i)
|
||
mesh.add_face(center, rim[i], rim[(i+1) % n]);
|
||
|
||
return mesh;
|
||
}
|
||
|
||
// ── Spherical tetrahedron (vertices on the unit sphere) ───────────────────────
|
||
//
|
||
/// Build a regular tetrahedron with vertices on the unit sphere.
|
||
/// All edge lengths equal `arccos(−1/3) ≈ 1.9106 rad`; used by the
|
||
/// SphericalFunctional tests.
|
||
inline ConformalMesh make_spherical_tetrahedron()
|
||
{
|
||
ConformalMesh mesh;
|
||
const double s = 1.0 / std::sqrt(3.0);
|
||
|
||
auto v0 = mesh.add_vertex(Point3( s, s, s));
|
||
auto v1 = mesh.add_vertex(Point3( s, -s, -s));
|
||
auto v2 = mesh.add_vertex(Point3(-s, s, -s));
|
||
auto v3 = mesh.add_vertex(Point3(-s, -s, s));
|
||
|
||
mesh.add_face(v0, v2, v1);
|
||
mesh.add_face(v0, v1, v3);
|
||
mesh.add_face(v0, v3, v2);
|
||
mesh.add_face(v1, v2, v3);
|
||
|
||
return mesh;
|
||
}
|
||
|
||
// ── Octahedron face triangle (vertices on the unit sphere) ────────────────────
|
||
//
|
||
/// Build one face of a regular octahedron `(1,0,0)→(0,1,0)→(0,0,1)`:
|
||
/// a right-angled spherical triangle with edge length `π/2` and base
|
||
/// log-length `λ° = −log 2 ≈ −0.6931`.
|
||
inline ConformalMesh make_octahedron_face()
|
||
{
|
||
ConformalMesh mesh;
|
||
auto v0 = mesh.add_vertex(Point3(1, 0, 0));
|
||
auto v1 = mesh.add_vertex(Point3(0, 1, 0));
|
||
auto v2 = mesh.add_vertex(Point3(0, 0, 1));
|
||
mesh.add_face(v0, v1, v2);
|
||
return mesh;
|
||
}
|
||
|
||
} // namespace conformallab
|