Six concrete next steps toward Phase 3 completion and Phase 4 (solver): 3d EuclideanCyclicFunctional — most critical missing functional 3e Spherical gauge-fix (1D Brent along additive u constant) 3f Analytic Hessian via CGAL::Weights::cotangent_weight() 3g Consolidate duplicate PI constant 4a Minimal Newton solver with Eigen SimplicialLDLT 4b CGAL::IO read/write OBJ for mesh round-trip testing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
11 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 abgeschlossen. Kern-Geometrie (Clausen, Hyper-Ideal, Sphärisch) und CGAL-Mesh-Infrastruktur sind vorhanden. Zum Abschluss von Phase 3 und als Vorbereitung für Phase 4 stehen noch sechs konkrete Schritte aus — 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 | 🔜 Phase 4 |
| 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: 30 tests pass, 2 skipped (the two @Ignore Hessian stubs).
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 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 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 # 8 spherical 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 |
8 | Angle formula correctness + gradient checks on spherical meshes |
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
Die Phasen 1–3 sind abgeschlossen. Die folgenden Schritte schließen Phase 3 ab und bereiten Phase 4 (Solver) vor. Die Zeitangaben sind grobe Schätzungen.
Phase 3d EuclideanCyclicFunctional portieren (2–3 Tage)
→ Wichtigster fehlender Baustein: Euklidische Uniformisierung
(genus-0 Flachparameterisierung, Kotangenten-Laplace)
→ Energie + Gradient auf ConformalMesh
→ Entsperrt die verbleibenden HDS-blockierten Tests
→ Voraussetzung für jeden end-to-end Optimiererlauf
Phase 3e Gauge-Fix für SphericalFunctional (1 Tag)
→ Java-Äquivalent: maximizeInNegativeDirection() vor jeder
Auswertung — 1D-Liniensuche (Brent) entlang der
globalen Additionskonstante in u_v
→ Ohne Gauge-Fix ist die Energie auf geschlossenen Flächen
nach unten unbeschränkt; kein Optimierer kann konvergieren
Phase 3f Hessian (Sphärisch → Euklidisch) (2–3 Tage)
→ Analytischer Hessian = Kotangenten-Laplace-Operator
→ CGAL::Weights::cotangent_weight() als Basis für
die Kantenbeiträge nutzen (bereits in CGAL 6.0 enthalten)
→ Entsperrt Newton-/Trust-Region-Verfahren
→ Reihenfolge: Sphärisch zuerst (kleinster Hessian),
dann Euklidisch
Phase 3g PI-Konstante konsolidieren (< 1 Stunde)
→ conformallab::PI in hyper_ideal_geometry.hpp und
lokales pi in hyper_ideal_utility.hpp zusammenführen
→ Einzelne constants.hpp oder in conformal_mesh.hpp
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).