Mark all Phase 3 sub-phases (3a–3g) as done in the roadmap. Add euclidean_hessian and spherical_hessian to the feature table. Update status banner: 62 tests, Phase 4 is next. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
12 KiB
conformallab++
conformallab++ is a modern C++ reimplementation of the ConformalLab software by Stefan Sechelmann for experiments in discrete conformal geometry and related mesh transformations.
The long-term goal is a CGAL package that brings discrete conformal maps (hyper-ideal, spherical, Euclidean) to the CGAL ecosystem using CGAL::Surface_mesh as the underlying half-edge data structure.
Status: Phase 3 vollständig abgeschlossen. Alle drei Kern-Geometrien (Hyper-Ideal, Sphärisch, Euklidisch) plus analytische Hessians (Kotangenten-Laplace) sind auf
ConformalMeshportiert. 62 Tests, 3 skipped. Nächster Schritt: Phase 4 (Newton-Solver) — siehe Roadmap.
Features
| Area | Status |
|---|---|
| Clausen / Lobachevsky / ImLi₂ functions | ✅ Phase 1 |
| Hyper-ideal geometry (ζ, lᵢⱼ, αᵢⱼ, σᵢ, σᵢⱼ) | ✅ Phase 2 |
| Hyper-ideal functional (energy + gradient, CGAL mesh) | ✅ Phase 3b |
| Spherical functional (energy + gradient, CGAL mesh) | ✅ Phase 3c |
CGAL Surface_mesh infrastructure + mesh builders |
✅ Phase 3a |
| Euclidean functional (energy + gradient, CGAL mesh) | ✅ Phase 3d |
| Spherical gauge-fix (scale gauge for closed surfaces) | ✅ Phase 3e |
| Euclidean Hessian (cotangent-Laplace operator) | ✅ Phase 3f |
| Spherical Hessian (∂α/∂u from law of cosines) | ✅ Phase 3f |
| Solvers (Newton, gradient flow) | 🔜 Phase 4 |
| XML serialisation / mesh I/O | 🔜 Phase 5 |
| Full CLI app | 🔜 Phase 5 |
Build modes
| Mode | CMake flag | What gets built | CI |
|---|---|---|---|
| Tests only (default) | (none) | conformallab_tests · Eigen + GTest |
✅ runs automatically |
| CGAL tests | -DWITH_CGAL=ON |
conformallab_cgal_tests · above + CGAL + system Boost |
local only |
| Viewer | -DWITH_VIEWER=ON |
viewer library · libigl / GLFW / GLAD |
local only |
| Full app | -DWITH_CGAL=ON |
conformallab_core CLI · all of the above |
local only |
External dependencies are bundled as tarballs in code/deps/tarballs/ and extracted lazily at CMake configure time (GTest is fetched from GitHub via FetchContent).
Note on Boost: -DWITH_CGAL=ON requires a system-installed Boost (header-only use by CGAL). The default Tests only mode needs no Boost.
Prerequisites
| Tool | Minimum version |
|---|---|
| C++ compiler (GCC or Clang) | C++17 |
| CMake | 3.20 |
| Boost headers | 1.70 (only with -DWITH_CGAL=ON) |
Getting started
git clone https://codeberg.org/TMoussa/ConformalLabpp
cd ConformalLabpp
Tests only (CI default — no system deps needed)
cmake -S code -B build
cmake --build build --target conformallab_tests -j$(nproc)
ctest --test-dir build --output-on-failure
CGAL mesh + functional tests (requires system Boost)
cmake -S code -B build -DWITH_CGAL=ON
cmake --build build --target conformallab_cgal_tests -j$(nproc)
ctest --test-dir build -R "^cgal\." --output-on-failure
Expected output: 45 tests pass, 3 skipped (the three @Ignore Hessian stubs, one per functional).
Full CLI app (CGAL + viewer)
cmake -S code -B build -DWITH_CGAL=ON
cmake --build build -j$(nproc)
./code/bin/conformallab_core --input data/off/example.off --show
Public headers (code/include/)
| Header | Description |
|---|---|
clausen.hpp |
Clausen integral Cl₂, Lobachevsky Л, ImLi₂ |
hyper_ideal_geometry.hpp |
Pure-math ζ functions, lᵢⱼ, αᵢⱼ, σᵢ, σᵢⱼ |
hyper_ideal_utility.hpp |
Tetrahedron volume (Meyerhoff / Kolpakov–Mednykh) |
hyper_ideal_functional.hpp |
Hyper-ideal energy + gradient on ConformalMesh |
spherical_geometry.hpp |
Spherical arc length, half-angle angle formula |
spherical_functional.hpp |
Spherical energy + gradient + gauge-fix on ConformalMesh |
euclidean_geometry.hpp |
Euclidean corner-angle formula (t-value / atan2) |
euclidean_functional.hpp |
Euclidean energy + gradient on ConformalMesh |
conformal_mesh.hpp |
ConformalMesh = CGAL::Surface_mesh<Point3>, index types, property-map helpers |
mesh_builder.hpp |
Factory meshes: triangle, tetrahedron, quad strip, fan, spherical tetrahedron, octahedron face |
discrete_elliptic_utility.hpp |
Discrete elliptic integrals |
matrix_utility.hpp |
Small linear-algebra helpers |
projective_math.hpp |
Projective geometry utilities |
Project structure
code/
├── include/
│ ├── conformal_mesh.hpp # CGAL mesh type + property-map helpers
│ ├── mesh_builder.hpp # make_triangle / make_tetrahedron / …
│ ├── hyper_ideal_geometry.hpp # ζ, lᵢⱼ, αᵢⱼ — pure math
│ ├── hyper_ideal_functional.hpp # HyperIdealFunctional on ConformalMesh
│ ├── spherical_geometry.hpp # spherical arc length + angles
│ ├── spherical_functional.hpp # SphericalFunctional + gauge-fix on ConformalMesh
│ ├── euclidean_geometry.hpp # Euclidean corner-angle formula (t-value)
│ ├── euclidean_functional.hpp # EuclideanCyclicFunctional on ConformalMesh
│ ├── clausen.hpp # Clausen / Lobachevsky / ImLi₂
│ └── hyper_ideal_utility.hpp # Tetrahedron volumes
├── src/
│ ├── apps/v0/ # conformallab_core CLI (requires WITH_CGAL)
│ └── viewer/ # simple_viewer (requires WITH_VIEWER)
├── tests/
│ ├── CMakeLists.txt
│ ├── *.cpp # conformallab_tests (no CGAL)
│ └── cgal/
│ ├── CMakeLists.txt
│ ├── test_conformal_mesh.cpp # 14 mesh infrastructure tests
│ ├── test_hyper_ideal_functional.cpp # 6 hyper-ideal gradient checks
│ ├── test_spherical_functional.cpp # 11 spherical gradient + gauge-fix checks
│ └── test_euclidean_functional.cpp # 11 Euclidean gradient checks
└── deps/
├── tarballs/ # bundled dependency archives
├── eigen-3.4.0/ # header-only linear algebra (always extracted)
├── CGAL-6.1.1/ # header-only geometry (extracted with WITH_CGAL)
├── libigl-2.6.0/ # header-only viewer toolkit (extracted with WITH_VIEWER)
├── glfw-3.4/ # windowing (extracted with WITH_VIEWER)
├── libigl-glad/ # OpenGL loader (extracted with WITH_VIEWER)
└── single_includes/ # CLI11, json.hpp
Test suites
conformallab_tests (always built, runs in CI)
Pure-math tests requiring only Eigen:
- Clausen function, Lobachevsky function, ImLi₂
- Hyper-ideal geometry (ζ₁₃, ζ₁₄, ζ₁₅, lᵢⱼ, αᵢⱼ)
- Tetrahedron volume formulas (Meyerhoff, Kolpakov–Mednykh)
conformallab_cgal_tests (built with -DWITH_CGAL=ON)
CGAL Surface_mesh tests (test prefix cgal.):
| Suite | Tests | Description |
|---|---|---|
ConformalMeshTopology |
4 | Euler characteristic, vertex/edge/face counts |
ConformalMeshTraversal |
4 | Halfedge iteration, valence, opposite-halfedge |
ConformalMeshProperties |
5 | Property maps: λ, θ, idx, α, geometry type |
ConformalMeshValidity |
1 | CGAL validity check for all factory meshes |
HyperIdealFunctional |
6 | Finite-difference gradient checks on triangle, tetrahedron, quad strip, fan |
SphericalFunctional |
11 | Angle formula + gradient checks on spherical meshes + 3 gauge-fix tests |
EuclideanFunctional |
11 | Angle formula + gradient checks on Euclidean meshes (triangle, quad strip, fan, tetrahedron) |
Key design decisions
CGAL as CoHDS replacement. CGAL::Surface_mesh<Point3> replaces the Java CoHDS half-edge data structure. Vertex/edge/face/halfedge descriptors are Vertex_index, Edge_index, Face_index, Halfedge_index (typed integers, not raw handles).
Property maps. mesh.add_property_map<Vertex_index, double>("v:lambda", 0.0) replaces the Java adapter/decorator pattern. Multiple maps can be attached to one mesh without subclassing.
Energy parameterisation. Both functionals use a DOF vector x indexed by v_idx[v] / e_idx[e] (−1 = pinned). This matches the Java FunctionalTest gradient-check convention.
Spherical edge gradient. For the spherical parameterisation where Λᵢⱼ = λ°ᵢⱼ + uᵢ + uⱼ + λₑ (additive edge DOF), the Schläfli identity gives ∂E/∂λₑ = (2α_opp − S_f)/2 per face (Euclidean limit: S_f = π, recovering the familiar α_opp⁺ + α_opp⁻ − π).
CI
Tests run automatically on push to main, dev, and claude/** branches via a self-hosted Gitea Actions runner (eulernest, ARM64 Raspberry Pi). The pipeline uses a minimal Docker image (git.eulernest.eu/conformallab/ci-cpp:latest) with cmake, g++, git, and Node.js 20 pre-installed. Only conformallab_tests runs in CI (no Boost/CGAL dependency in the CI image).
The Dockerfile for the CI image lives in .gitea/docker/Dockerfile.ci-cpp. Build and push it once whenever the image needs updating:
docker buildx build \
--platform linux/arm64 \
-f .gitea/docker/Dockerfile.ci-cpp \
-t git.eulernest.eu/conformallab/ci-cpp:latest \
--push \
.gitea/docker/
Roadmap
Phase 3 ist vollständig abgeschlossen. Phase 4 (Newton-Solver) ist der nächste Schritt. Die Zeitangaben sind grobe Schätzungen.
Phase 3a CGAL Surface_mesh Infrastruktur ✅ abgeschlossen
→ conformal_mesh.hpp, mesh_builder.hpp
→ 14 Tests: Topologie, Traversal, Properties, Validity
Phase 3b HyperIdealFunctional portieren ✅ abgeschlossen
→ hyper_ideal_functional.hpp: Energie + Gradient
→ 6 Tests (1 skipped): Gradient-Checks, FD-Tests
Phase 3c SphericalFunctional portieren ✅ abgeschlossen
→ spherical_functional.hpp: Energie + Gradient
→ Tests: Winkelformel, Gradient-Checks
Phase 3d EuclideanCyclicFunctional portieren ✅ abgeschlossen
→ euclidean_functional.hpp: Energie + Gradient auf ConformalMesh
→ Tests: Winkelformel, Gradient-Checks, NaN-Test, Fan, Mixed-Pinned
Phase 3e Gauge-Fix für SphericalFunctional ✅ abgeschlossen
→ spherical_gauge_shift() + apply_spherical_gauge() in
spherical_functional.hpp — Newton + Backtracking
→ Tests: ZerosSumGv, ApplyInPlace, AlreadyAtGauge
Phase 3f Analytische Hessians ✅ abgeschlossen
→ euclidean_hessian.hpp: Kotangenten-Laplace (Pinkall–Polthier 1993)
mit korrektem 1/2-Normierungsfaktor; 8 Tests
→ spherical_hessian.hpp: ∂α_i/∂u_j direkt aus sphärischem
Cosinussatz abgeleitet + Chain-Rule mit ∂l/∂λ = tan(l/2); 8 Tests
→ Erkenntnis: Sphärische Energie ist konkav (H ist NSD), nicht konvex
Phase 3g PI-Konstante konsolidieren ✅ abgeschlossen
→ constants.hpp mit conformallab::PI und TWO_PI
→ 5 Dateien bereinigt; PI_SPHER-Alias rückwärtskompatibel
Phase 4a Minimaler Newton-Solver (1–2 Tage)
→ Eigen SimplicialLDLT (bereits Projektabhängigkeit)
→ Newton-Schritt: Δx = −H⁻¹·g mit Hessian aus 3f
→ Kein externer PETSc-Solver nötig für erste Tests
→ Konvergenzkriterium: ||g||∞ < tol
Phase 4b CGAL::IO für Mesh-Import/Export (< 1 Tag)
→ CGAL::IO::read_OBJ / write_OBJ auf Surface_mesh:
null Eigenentwicklung, sofort nutzbar
→ Ermöglicht Round-Trip-Tests gegen Java-Referenz-Meshes
→ Mittelfristig: CGAL::IO::read_OFF für .off-Dateien
(ersetzt Java-XML-Serialisierung für Testzwecke)
License
conformallab++ is released under the MIT License (see LICENSE).