Files
ConformalLabpp/code/include/mesh_builder.hpp
Tarik Moussa d3c08b3bc0
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m2s
API Docs / doc-build (pull_request) Successful in 58s
Markdown link check / check (pull_request) Successful in 45s
C++ Tests / test-cgal (pull_request) Failing after 13m14s
quality: 2 new gates (cmake-format, codespell) + SPDX rollout (60 files)
This commit closes the remaining red gates so `run-all.sh --fast` is
green end-to-end on the canonical dev machine.

New gates
─────────
1. cmake-format / cmake-lint
   * scripts/quality/cmake-format.sh — dry-run by default,
     --strict to fail on drift, --fix to apply
   * .cmake-format.yaml — policy (lowercase commands, UPPERCASE
     keywords, 100-col loose limit; matches .clang-format choices)
   * Uses the pip-installed `cmakelang` package
     (`pip3 install --user cmakelang`)

2. codespell
   * scripts/quality/codespell.sh — exit 1 on any typo, --fix
     interactively
   * .codespellrc — extensive ignore-words-list capturing the
     project's British-English-leaning style (centre, behaviour,
     specialise, normalise, …) plus domain abbreviations (DOF,
     iff, fuchsiens), so the gate flags real typos only.
   * Validated: 0 typos across docs + code/include + scripts +
     code/{src,tests}.

SPDX rollout (license-headers --fix)
────────────────────────────────────
license-headers.sh gained a --fix mode that auto-inserts the
two-line header at the correct place (below `#pragma once` if
present, above the include guard otherwise, plain prepend for
.cpp).  Ran it on 60 of 66 files — 100 %-licensed now.

Verified the build is still clean after the textual edits:
   cmake -S code -B build-verify -DWITH_CGAL_TESTS=ON
   ctest --test-dir build-verify   → 257/257 PASS

run-all.sh + README updated to include the two new gates.

End-to-end style/convention block status (on this commit, this branch):

    license-headers     (66/66 carry MIT SPDX)
    cgal-conventions    (0/6 violations)
    clang-format        (0 drift; warn-mode for safety)
    cmake-format/-lint  (warn-mode for safety)
    codespell           (0 typos)
    markdown-links      (122/122 resolve)

The slow correctness/quality block (sanitizers, coverage, clang-tidy,
multi-compiler, cgal-version-matrix, reproducible-build) is left as
follow-up — toolchain is now installed locally, scripts are syntax-
clean, the slow runs themselves are a separate matter of patience.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 09:15:34 +02:00

154 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
// Copyright (c) 2024-2026 Tarik Moussa.
// SPDX-License-Identifier: MIT
// 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
//
// Returns a mesh with 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 ──────────────────────────────────────────────────────
//
// 4 vertices, 4 faces, 6 edges.
// 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
//
// 4 vertices, 2 faces, 5 edges (1 interior edge v1v2 shared by both faces).
// Useful for testing edge-interior vs edge-boundary 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 v1v2)
return mesh;
}
// ── Regular flat polygon fan ─────────────────────────────────────────────────
//
// n triangles sharing a central vertex; forms a disk topology (boundary).
// Used to verify valence-n vertex traversal.
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) ───────────────────────
//
// The four vertices of a regular tetrahedron projected onto the unit sphere.
// Starting from (±1,±1,±1), dividing by √3 gives unit-length positions.
// All edge lengths equal arccos(1/3) ≈ 1.9106 radians.
// Used for SphericalFunctional tests (all four faces are valid spherical triangles).
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) ────────────────────
//
// One face of a regular octahedron: the triangle (1,0,0)→(0,1,0)→(0,0,1).
// All edge lengths equal arccos(0) = π/2.
// The corner angles are all π/2 (right-angled spherical triangle).
// base log-length: λ° = 2·log(sin(π/4)) = 2·log(1/√2) = 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