Two complementary improvements aimed at reducing recurring maintenance
overhead:
1. **Test-count centralisation** — `doc/api/tests.md` is now the
single source of truth for the test counts. All other docs
(README, CLAUDE.md, doc/contributing.md, doc/getting-started.md,
doc/math/validation.md, doc/math/validation-protocol.md,
scripts/try_it.sh) use qualitative phrasing + a link instead of
hardcoded numbers. The previous regime had eight places with
"227 CGAL tests, 23 non-CGAL tests" that drifted apart across
releases (the v0.9.0 release-prep needed to touch nine files).
2. **Versioning policy** — `doc/release-policy.md` (new, ~250 lines)
formalises:
* SemVer rules for the pre-1.0 and post-1.0 phases.
* Phase-milestone → MINOR-bump mapping (v0.10.0 → Phase 9c, …).
* Single-source-of-truth table for moving numbers (test counts,
version, date).
* Step-by-step release process (the recipe that worked for v0.9.0
after the false-start with PR #11/#12).
* Hotfix policy + post-1.0 deprecation policy.
* Known failure modes and how to recover from them.
Plus a small CI gate:
3. **scripts/check-test-counts.sh** — verifies the totals in
doc/api/tests.md match `ctest` output. Re-uses existing build-cgal/
if present. Exit 0 on match, 1 on divergence with recovery hints.
Cheap enough (~30 s) to run on every PR.
Other cleanups
──────────────
* code/tests/cgal/CMakeLists.txt — stale "Test 7 (genus-2 homology)
as GTEST_SKIP stub until Phase 8" comment removed; that test landed
as HomologyGenerators.Genus2_FourCutEdges in Phase 7.
* CLAUDE.md — "test-fast also runs stubs" Known Quirks entry updated
to reflect the v0.9.0 stub cleanup (no GTEST_SKIPs remain).
* CLAUDE.md doc map — new entry for doc/release-policy.md.
Stubs audit
───────────
Zero GTEST_SKIP() calls remain in the codebase as of this commit.
The only references to stubs are in historical documentation
(CHANGELOG.md v0.7.0 entry, doc/roadmap/* "deferred to research-track"
notes) — those are intended.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
139 lines
7.4 KiB
Markdown
139 lines
7.4 KiB
Markdown
# conformallab++
|
||
|
||
[](https://git.eulernest.eu/conformallab/ConformalLabpp/actions)
|
||
[](LICENSE)
|
||
[](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f)
|
||
|
||
C++17 reimplementation of [ConformalLab](https://github.com/varylab/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](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f) · CC BY-SA 4.0 ·
|
||
> [Java original](https://github.com/varylab/conformallab) · [sechel.de](https://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`](doc/api/tests.md) for the per-suite breakdown.
|
||
|
||
---
|
||
|
||
## Quick start
|
||
|
||
```bash
|
||
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)
|
||
./bin/conformallab_core -i input.off -g euclidean -o layout.off -j result.json
|
||
|
||
# API documentation (requires doxygen: brew/apt install doxygen)
|
||
cmake --build build --target doc
|
||
open doc/doxygen/html/index.html
|
||
```
|
||
|
||
---
|
||
|
||
## Minimal usage
|
||
|
||
```cpp
|
||
#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
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Getting started** — build modes, single-test invocation, CLI, Docker | [doc/getting-started.md](doc/getting-started.md) |
|
||
| **Pipeline API** — all three geometries, holonomy, serialisation | [doc/api/pipeline.md](doc/api/pipeline.md) |
|
||
| **Public headers** — all 24 headers with descriptions | [doc/api/headers.md](doc/api/headers.md) |
|
||
| **Test suites** — per-suite breakdown and counts (single source of truth) | [doc/api/tests.md](doc/api/tests.md) |
|
||
| **Extending** — new functionals, geometry modes, porting from Java | [doc/api/extending.md](doc/api/extending.md) |
|
||
| **Processing unit contracts** — preconditions / provides table | [doc/api/contracts.md](doc/api/contracts.md) |
|
||
| **CGAL package design** — Phase 8 target, YAML pipeline | [doc/api/cgal-package.md](doc/api/cgal-package.md) |
|
||
| **Architecture & pipeline diagram** | [doc/architecture/overall_pipeline.md](doc/architecture/overall_pipeline.md) |
|
||
| **geometry-central comparison** — shared core, demarcation, adoption candidates, scientific added value | [doc/architecture/geometry-central-comparison.md](doc/architecture/geometry-central-comparison.md) |
|
||
| **Design decisions** — key architectural choices + rationale | [doc/architecture/design-decisions.md](doc/architecture/design-decisions.md) |
|
||
| **Project structure** — directory tree + build targets | [doc/architecture/project-structure.md](doc/architecture/project-structure.md) |
|
||
| **Discrete conformal theory** — mathematical background for collaborators | [doc/math/discrete-conformal-theory.md](doc/math/discrete-conformal-theory.md) |
|
||
| **Validation** — known analytic results + how to verify them | [doc/math/validation.md](doc/math/validation.md) |
|
||
| **Validation protocol** — concrete commands with expected outputs | [doc/math/validation-protocol.md](doc/math/validation-protocol.md) |
|
||
| **Tutorial: add a new functional** — step-by-step Inversive-Distance port | [doc/tutorials/add-inversive-distance.md](doc/tutorials/add-inversive-distance.md) |
|
||
| **Declarative YAML pipeline** — concept, token vocabulary, 5 examples | [doc/concepts/declarative-pipeline.md](doc/concepts/declarative-pipeline.md) |
|
||
| **Geometry modes** — Euclidean / Spherical / HyperIdeal comparison | [doc/math/geometry-modes.md](doc/math/geometry-modes.md) |
|
||
| **References** — all papers by module | [doc/math/references.md](doc/math/references.md) |
|
||
| **Software landscape** — how conformallab++ relates to libigl, CGAL, geometry-central | [doc/math/software-landscape.md](doc/math/software-landscape.md) |
|
||
| **Novelty statement** — unique features, target audience, what this is not | [doc/math/novelty-statement.md](doc/math/novelty-statement.md) |
|
||
| **Complexity & scalability** — O() analysis, measured timings on real meshes, HyperIdeal bottleneck | [doc/math/complexity.md](doc/math/complexity.md) |
|
||
| **Roadmap** — Phases 1–10 | [doc/roadmap/phases.md](doc/roadmap/phases.md) |
|
||
| **Java parity table** — what is ported, what is planned | [doc/roadmap/java-parity.md](doc/roadmap/java-parity.md) |
|
||
| **Contributing** — language policy, test standards, release flow | [doc/contributing.md](doc/contributing.md) |
|
||
| **Claude Code context** | [CLAUDE.md](CLAUDE.md) |
|
||
|
||
---
|
||
|
||
## Citing
|
||
|
||
If you use conformallab++ in your research, please cite it using the metadata
|
||
in [`CITATION.cff`](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](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f)
|
||
|
||
---
|
||
|
||
## Bugs & questions
|
||
|
||
- **Bug reports / feature requests:** [Gitea Issues](https://git.eulernest.eu/conformallab/ConformalLabpp/issues)
|
||
- **Code mirror (read-only):** [Codeberg](https://codeberg.org/TMoussa/ConformalLabpp)
|
||
- **Contact:** Tarik Moussa · Tarik.moussa95@gmail.com
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
conformallab++ is released under the MIT License (see [LICENSE](LICENSE)).
|
||
Copyright © 2024–2026 Tarik Moussa.
|
||
The dissertation (Sechelmann 2016) is CC BY-SA 4.0.
|