Add bit-for-bit (1e-12) golden-value oracle tests pinning the C++ pure-math and functional cores against the compiled upstream Java library (openjdk 17): - HyperIdealGoldenJava: Clausen/Л/ImLi2, ζ13/14/15/ζ, both tetrahedron-volume formulas (real de.varylab…Clausen / HyperIdealUtility). - EuclideanGoldenJava / SphericalGoldenJava: angle formulas + β relations + Л energy terms, plus FULL-MESH oracles driving the real EuclideanCyclicFunctional / SphericalFunctional on a shared tetrahedron — per-vertex gradient (Θ−Σα) and ΔE = E(x)−E(0) (C++ Gauss-Legendre path integral vs Java closed form). - SphericalGoldenJava.FullMeshEdgeDofGradient: edge-DOF gradient (vertex + edge components, α_opp⁺+α_opp⁻−θ_e) vs raw conformalEnergyAndGradient — locks Finding 3 at the solution level (audit items 4 & 5). - PeriodMatrix.NormalizeModulus_GoldenJava: τ-reduction fold convention vs the real DiscreteEllipticUtility.normalizeModulus (audit items 7 & 8). Subtlety documented: the spherical oracles call Java's raw conformalEnergyAndGradient, not evaluate() (which pre-runs a Brent gauge maximization that C++ factors into the Newton solver's spherical_gauge_shift). Also: - P1-2 (layout.hpp): Euclidean holonomy now uses a per-cut-edge rigid-motion fit g(z)=a·z+b, exposing residual_rotation = |arg(a)| as a diagnostic; non- regressive (flat case a=1 reduces to the old midpoint formula). - P1-3 (period_matrix.hpp): is_in_fundamental_domain fixed to the correct half-open SL(2,ℤ) domain (−½ ≤ Re < ½). Updated the now-exposed ComputePeriodMatrix_ReducedTau_InFD to assert the normalizeModulus domain (closed +½ edge) instead. Test counts (single source of truth = doc/api/tests.md): 272/272 pass, 0 skipped (26 non-CGAL + 246 CGAL). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
conformallab++
C++17 reimplementation of ConformalLab — Stefan Sechelmann's Java research library for discrete conformal geometry (TU Berlin). The long-term goal is a CGAL package for discrete conformal maps.
Algorithmic foundation:
Stefan Sechelmann — Variational Methods for Discrete Surface Parameterization: Applications and Implementation, TU Berlin 2016. DOI: 10.14279/depositonce-5415 · CC BY-SA 4.0 · Java original · sechel.de
Status: v0.9.0 — Phases 1–9a complete, Phase 8b-Lite CGAL API surface. Newton solvers for five DCE models (Euclidean / Spherical / HyperIdeal / CP-Euclidean / Inversive-Distance), priority-BFS layout in ℝ²/S²/Poincaré disk, Gauss–Bonnet, tree-cotree cut graph, Möbius holonomy, period matrix (genus 1), fundamental domain, halfedge_uv texture atlas, JSON/XML serialisation, CLI app. Full test suite passing, 0 skipped — see doc/api/tests.md for the per-suite breakdown.
Quick start
git clone https://codeberg.org/TMoussa/ConformalLabpp && cd ConformalLabpp
# Fast tests — no system dependencies
cmake -S code -B build && cmake --build build --target conformallab_tests -j$(nproc)
ctest --test-dir build --output-on-failure
# CGAL tests headless (apt install libboost-dev / brew install boost)
cmake -S code -B build -DWITH_CGAL_TESTS=ON
cmake --build build --target conformallab_cgal_tests -j$(nproc)
ctest --test-dir build -R "^cgal\." --output-on-failure
# Full build with CLI + viewer (requires Wayland/X11 dev headers)
cmake -S code -B build -DWITH_CGAL=ON && cmake --build build -j$(nproc)
# Conformal flattening (Θ_v = 2π target). Closed meshes pin one vertex +
# enforce Gauss-Bonnet; open meshes pin the boundary and flatten the interior.
./bin/conformallab_core -i code/data/off/torus_8x8.off -g euclidean -v \
-o layout.off -j result.json
# topology: closed, free DOFs=63, genus=1
# Euclidean: converged=yes iter=3 |grad|_inf≈5e-15
./bin/conformallab_core -i code/data/obj/cathead.obj -g euclidean -v -o cat.off
# topology: open (boundary pinned), free DOFs=119
# Euclidean: converged=yes iter=4
# API documentation (requires doxygen: brew/apt install doxygen)
cmake --build build --target doc
open doc/doxygen/html/index.html
Compile-time workflow modes
The default build (PCH + Unity Build + Dense→Core trims) takes ~47 s clean for the full CGAL test target. Five opt-in modes cover other iteration scenarios:
# Configure-only, no compile. ~1 s configure, 0 s build — emits
# compile_commands.json for IDE / clangd; skips the GTest fetch.
cmake -S code -B build -DBUILD_TESTING=OFF
# Header smoke check: per-public-header isolated compile. ~12 s full,
# ~0.1 s after touching one header. "Does my refactor still parse?"
cmake -S code -B build -DBUILD_TESTING=OFF -DCONFORMALLAB_HEADERS_CHECK=ON
cmake --build build --target headers_check
# Dev iteration: PCH on, Unity off. Slower full build (~75 s) but
# editing a single test rebuilds in ~16 s instead of ~46 s.
cmake -S code -B build -DWITH_CGAL_TESTS=ON -DCONFORMALLAB_DEV_BUILD=ON
# Fast CI tests: -O0 -g for the test executables only (library /
# install targets keep -O3). Linux + g++ typically ~40 % faster
# build at the cost of 5–15× slower test RUN. Neutral on macOS.
cmake -S code -B build -DWITH_CGAL_TESTS=ON -DCONFORMALLAB_FAST_TEST_BUILD=ON
# Pristine measurement: disable both performance levers, e.g. for
# scripts/quality/coverage.sh that needs every TU compiled fresh.
cmake -S code -B build -DWITH_CGAL_TESTS=ON \
-DCONFORMALLAB_USE_PCH=OFF -DCMAKE_UNITY_BUILD=OFF
ccache is detected automatically when present on PATH; disable with
-DCONFORMALLAB_USE_CCACHE=OFF. Full mode matrix + measurements in
doc/architecture/compile-time.md.
Minimal usage
#include "conformal_mesh.hpp"
#include "mesh_io.hpp"
#include "euclidean_functional.hpp"
#include "gauss_bonnet.hpp"
#include "newton_solver.hpp"
#include "layout.hpp"
using namespace conformallab;
ConformalMesh mesh = load_mesh("input.off");
EuclideanMaps maps = setup_euclidean_maps(mesh);
compute_euclidean_lambda0_from_mesh(mesh, maps);
// Assign DOFs — pin first vertex (gauge fix)
auto vit = mesh.vertices().begin();
maps.v_idx[*vit++] = -1;
int idx = 0;
for (; vit != mesh.vertices().end(); ++vit) maps.v_idx[*vit] = idx++;
// Natural equilibrium target: x* = 0 by construction
std::vector<double> x0(idx, 0.0);
auto G0 = euclidean_gradient(mesh, x0, maps);
for (auto v : mesh.vertices())
if (maps.v_idx[v] >= 0) maps.theta_v[v] -= G0[maps.v_idx[v]];
check_gauss_bonnet(mesh, maps);
NewtonResult res = newton_euclidean(mesh, x0, maps);
Layout2D layout = euclidean_layout(mesh, res.x, maps);
Documentation
| API reference (Doxygen HTML) — every public class, function and named-parameter helper | https://tmoussa.codeberg.page/ConformalLabpp/ |
| Getting started — build modes, single-test invocation, CLI, Docker | doc/getting-started.md |
| Pipeline API — all three geometries, holonomy, serialisation | doc/api/pipeline.md |
| Public headers — all public headers with descriptions | doc/api/headers.md |
| Test suites — per-suite breakdown and counts (single source of truth) | doc/api/tests.md |
| Extending — new functionals, geometry modes, porting from Java | doc/api/extending.md |
| Processing unit contracts — preconditions / provides table | doc/api/contracts.md |
| CGAL package design — Phase 8 target, YAML pipeline | doc/api/cgal-package.md |
| Architecture & pipeline diagram | doc/architecture/overall_pipeline.md |
| geometry-central comparison — shared core, demarcation, adoption candidates, scientific added value | doc/architecture/geometry-central-comparison.md |
| Design decisions — key architectural choices + rationale | doc/architecture/design-decisions.md |
| Project structure — directory tree + build targets | doc/architecture/project-structure.md |
| Discrete conformal theory — mathematical background for collaborators | doc/math/discrete-conformal-theory.md |
| Validation — known analytic results + how to verify them | doc/math/validation.md |
| Validation protocol — concrete commands with expected outputs | doc/math/validation-protocol.md |
| Tutorial: add a new functional — step-by-step Inversive-Distance port | doc/tutorials/add-inversive-distance.md |
| Declarative YAML pipeline — concept, token vocabulary, 5 examples | doc/concepts/declarative-pipeline.md |
| Geometry modes — Euclidean / Spherical / HyperIdeal comparison | doc/math/geometry-modes.md |
| References — all papers by module | doc/math/references.md |
| Software landscape — how conformallab++ relates to libigl, CGAL, geometry-central | doc/math/software-landscape.md |
| Novelty statement — unique features, target audience, what this is not | doc/math/novelty-statement.md |
| Complexity & scalability — O() analysis, measured timings on real meshes, HyperIdeal bottleneck | doc/math/complexity.md |
| Roadmap — Phases 1–10 | doc/roadmap/phases.md |
| Java parity table — what is ported, what is planned | doc/roadmap/java-parity.md |
| Contributing — language policy, test standards, release flow | doc/contributing.md |
| Claude Code context | CLAUDE.md |
Citing
If you use conformallab++ in your research, please cite it using the metadata
in CITATION.cff. GitHub and Codeberg show a "Cite this repository"
button that generates BibTeX and APA automatically.
The primary algorithmic source is:
Stefan Sechelmann — Variational Methods for Discrete Surface Parameterization: Applications and Implementation, TU Berlin 2016. DOI: 10.14279/depositonce-5415
Bugs & questions
- Bug reports / feature requests: Gitea Issues
- Code mirror (read-only): Codeberg
- Contact: Tarik Moussa · Tarik.moussa95@gmail.com
License
conformallab++ is released under the MIT License (see LICENSE).
Copyright © 2024–2026 Tarik Moussa.
The dissertation (Sechelmann 2016) is CC BY-SA 4.0.