Files
ConformalLabpp/doc/roadmap/porting-status.md
Tarik Moussa 039cc26e36
Some checks failed
C++ Tests / test-fast (push) Successful in 1m58s
C++ Tests / test-fast (pull_request) Successful in 2m33s
API Docs / doc-build (pull_request) Successful in 51s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m32s
Phase 8b-Lite: pipe-operator chaining for named parameters
Adds `operator|` in `namespace CGAL` so package-local named parameters
can be combined left-to-right without modifying CGAL upstream:

    auto p = CGAL::parameters::gradient_tolerance(1e-12)
           | CGAL::parameters::max_iterations(500)
           | CGAL::parameters::output_uv_map(uv);
    CGAL::discrete_conformal_map_euclidean(mesh, p);

Why not the canonical `.a().b().c()` syntax
───────────────────────────────────────────
CGAL's standard chaining mechanism requires registering each named
parameter as a member function on `Named_function_parameters` via the
`CGAL_add_named_parameter` macro in
`CGAL/STL_Extension/internal/parameters_interface.h` — a vendored
upstream file that conformallab++ deliberately treats as read-only.

Adding member-function chainers for our package-local tags would
require either forking CGAL or modifying the vendored copy.  Neither
is acceptable for a library that wants to remain portable across
future CGAL releases.

The pipe-operator achieves the same compositional semantics via a
free function in `namespace CGAL` (so ADL finds it for
`Named_function_parameters` operands).  Implementation: rebuild the
right-hand-side `Named_function_parameters` with the left-hand-side
as its `Base`, producing an indistinguishable chain that every entry
function accepts unchanged.

Implementation: `code/include/CGAL/Conformal_map/internal/parameters.h`
lines 158-187.  The operator is constrained to right-hand-sides with
`No_property` base (i.e. fresh single-parameter packs from the helper
functions), so it never collides with any future CGAL operator on the
same type.

Tests (2 new, total Phase-8b-Lite suite 15 → 17)
────────────────────────────────────────────────
* CGALPhase8bLite.NamedParamPipe_MultipleParamsTakeEffect
    Chain three parameters; verify all three take effect (tight
    tolerance respected + UV pmap populated + iteration cap honoured).
* CGALPhase8bLite.NamedParamPipe_TwoParams
    Chain two parameters; verify max_iterations(0) blocks the loop
    even when combined with another param.

Full CGAL suite: 234/234 PASSED, 0 SKIPPED (was 232).
Total: 257/257 PASSED, 0 SKIPPED (was 255).
scripts/check-test-counts.sh: OK.

Documentation updates
─────────────────────
* doc/tutorials/add-output-uv-map.md §3.4: "Current limitation: no
  chaining" → "Chaining: use the pipe operator `|`".  Explains why
  CGAL's `.member()` syntax isn't available and shows the `|`
  workaround with a working code example.
* doc/architecture/locked-vs-flexible.md §8: chaining now flagged as
  shipped via pipe; recommended posture says `.member()` chaining
  only if a user pushes for the CGAL-canonical syntax.
* doc/roadmap/porting-status.md §5: API limitations table updated.
* doc/api/tests.md: CGALPhase8bLite row 15 → 17, total 232 → 234.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:43:52 +02:00

251 lines
15 KiB
Markdown
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.

# Porting status overview
> **Snapshot date:** 2026-05-22 (commit graph at v0.9.0 + 2 open PRs).
>
> **Audience.** External collaborators evaluating whether to use, extend,
> or contribute to conformallab++. This document is the **operational
> truth** of which Java mathematics is reachable from C++ today, with
> what API, and with which caveats. For the longer plan see
> [`phases.md`](phases.md), for the formal port-vs-research classification
> see [`research-track.md`](research-track.md), for the cross-reference
> with the Java original see [`java-parity.md`](java-parity.md).
---
## 1. The 25 000 lines of Java in one table
```
de.varylab.discreteconformal
├── functional/ ~3 000 LoC ████████████░░░░ Phase 3 + 9a ✅
├── unwrapper/ ~3 500 LoC ████████░░░░░░░░ Phase 5/6/7 (basic 3 modes) ✅
│ residual: Stereographic, CircleDomain, Koebe, CirclePattern
├── util/ ~5 000 LoC ████░░░░░░░░░░░░ partial — main utilities ported
│ residual: Homology, Holomorphic / Harmonic forms,
│ FundamentalPolygon, Surgery, Cutting
├── heds/ (Co* data struct) ~3 000 LoC ░░░░░░░░░░░░░░░░ REPLACED by CGAL::Surface_mesh ❌ intentional
├── plugin/ ~7 000 LoC ░░░░░░░░░░░░░░░░ SKIP (Swing UI, GLSL viewer) ❌ intentional
├── numerics/ (PETSc glue) ~1 500 LoC ░░░░░░░░░░░░░░░░ REPLACED by Eigen ❌ intentional
├── math/, logging/, ... ~2 000 LoC ░░░░░░░░░░░░░░░░ REPLACED by std::* / Eigen ❌ intentional
└── total ~25 000 LoC
```
**Coverage of the mathematics:** about **4 500 of the 11 000 LoC** of
genuinely mathematical Java code is portrayed in C++ — **~41% of the
maths, ~75% of the "core math we actually want"** (Phase 17 + 9a + 9b
together cover the algorithmically central mass).
The remaining ~6 500 LoC of port-worthy maths is catalogued in
[`java-parity.md`](java-parity.md) and broken into Phases 9c / 10a /
10b / 10b' / 11.
---
## 2. Five DCE models — operational status matrix
The library supports **five** discrete-conformal-equivalence models on
the same `CGAL::Surface_mesh<P>`. All can be used from both the
legacy API (`code/include/*.hpp`) and the CGAL public API
(`<CGAL/Discrete_*.h>`).
| Model | Native space | DOF location | Java port? | Hessian | Newton | CGAL entry | UV out |
|------------------------|---------------|--------------|-----------|------------------|-----------|---------------------------------------------|----------|
| **Euclidean** | ℝ² | vertex | EuclideanCyclic 530 LoC | analytic (cot-Laplace) | ✅ | `discrete_conformal_map_euclidean` | ✅ Point_2 |
| **Spherical** | S² | vertex | Spherical 458 LoC | analytic | ✅ | `discrete_conformal_map_spherical` | ✅ Point_3 |
| **Hyper-ideal** | H² (Poincaré) | vertex + edge | HyperIdeal 311 LoC (no Hess) | block-FD (Phase 9b, 96× speed-up); analytic planned | ✅ | `discrete_conformal_map_hyper_ideal` | ✅ Point_2 |
| **CP-Euclidean** (BPS) | face circles | **face** | CPEuclidean 260 LoC | analytic 2×2-per-edge | ✅ | `discrete_circle_packing_euclidean` | ⛔ N/A |
| **Inversive Distance** | vertex circles| vertex | ❌ no Java (Luo 2004 + Glickenstein 2011 from literature) | FD (analytic planned) | ✅ | `discrete_inversive_distance_map` | ⛔ pending |
Total: 250+ tests covering all five models, 0 skipped. Per-suite
breakdown: [`doc/api/tests.md`](../api/tests.md).
### What "UV out" means
The `output_uv_map(pmap)` named parameter, when supplied, runs the
relevant `*_layout()` step internally and writes per-vertex coordinates
into `pmap` — no separate user code needed. See
[`doc/tutorials/add-output-uv-map.md`](../tutorials/add-output-uv-map.md).
* **Euclidean / Spherical / HyperIdeal**: shipped.
* **CP-Euclidean**: conceptually not applicable (face-based packing
produces face-circles, not per-vertex UV — needs a separate
`output_circle_map` design).
* **Inversive Distance**: requires `inversive_distance_layout()` using
Luo's edge-length formula `ℓ² = r_i² + r_j² + 2 I_ij r_i r_j`.
~3 days work, on the wishlist.
---
## 3. Topology infrastructure
| Feature | Status | Notes |
|------------------------------------------------|:-----:|-------|
| Mesh I/O (OFF / OBJ / PLY) | ✅ | `mesh_io.hpp` via CGAL::IO |
| GaussBonnet check & enforce | ✅ | `gauss_bonnet.hpp` |
| Cut graph (tree-cotree, EricksonWhittlesey) | ✅ | `cut_graph.hpp`, produces 2g seam edges |
| Layout / embedding (priority-BFS trilateration) | ✅ | ℝ² / S² / Poincaré disk |
| Halfedge UV (seam-aware texture atlas) | ✅ | `layout.hpp` |
| Möbius holonomy SU(1,1) | ✅ | for hyperbolic mode, genus 1 |
| Period matrix τ ∈ + SL(2,) reduction | ✅ | genus 1 only |
| Fundamental domain (parallelogram) | ✅ | genus 1 only |
| Fundamental domain (4g-polygon) | 🔲 | Phase 9c — biggest remaining Java-port item |
| Real mesh cuts (CuttingUtility ops) | 🔲 | Phase 9c prerequisite |
---
## 4. Solver infrastructure
| Feature | Status | Notes |
|-------------------------------------------------|:-----:|-------|
| Newton with line search | ✅ | `newton_solver.hpp`, all five solvers |
| SimplicialLDLT + SparseQR fallback | ✅ | gauge-singular meshes handled automatically |
| Block-FD Hessian framework | ✅ | shipped for HyperIdeal (Phase 9b); 96× speed-up |
| Analytic Hessian via Schläfli | 🔲 | Phase 9b-analytic; derivation in [`hyperideal-hessian-derivation.md`](../math/hyperideal-hessian-derivation.md) |
---
## 5. CGAL public API (`<CGAL/Discrete_*.h>`)
After Phase 8a MVP + 8b-Lite (both shipped in v0.9.0):
| Public header | Provides |
|--------------------------------------------------------------|----------|
| `<CGAL/Discrete_conformal_map.h>` | `discrete_conformal_map_euclidean / _spherical / _hyper_ideal` + `Conformal_map_result<FT>` |
| `<CGAL/Discrete_circle_packing.h>` | `Default_cp_euclidean_traits` + `discrete_circle_packing_euclidean` + `Circle_packing_result<FT>` |
| `<CGAL/Discrete_inversive_distance.h>` | `Default_inversive_distance_traits` + `discrete_inversive_distance_map` |
| `<CGAL/Conformal_layout.h>` | Thin re-exports of layout functions in the `CGAL::` namespace |
| `<CGAL/Conformal_map_traits.h>` | `ConformalMapTraits` concept + `Default_conformal_map_traits` |
| `<CGAL/Conformal_map/internal/parameters.h>` (private) | Named-parameter tags |
Named parameters available:
| Parameter | Effect |
|------------------------------------|--------|
| `vertex_curvature_map(pmap)` | Per-vertex Θ targets; if omitted, "natural-theta" makes x = 0 the equilibrium |
| `fixed_vertex_map(pmap)` | Gauge pin; if omitted, first vertex is pinned |
| `gradient_tolerance(eps)` | Newton stop threshold (default 1e-10) |
| `max_iterations(n)` | Newton iteration cap (default 200) |
| `output_uv_map(pmap)` | Run layout + write per-vertex coordinates |
| `normalise_layout(flag)` | Canonical post-layout normalisation (PCA / north-pole / Möbius) |
**Known limitations** (documented for the meeting):
1. **Chaining via pipe operator.** CGAL-style `.a().b().c()` is not yet
implemented for package-local tags (would require modifying CGAL
upstream). conformallab++ provides `operator|` instead — see
`code/include/CGAL/Conformal_map/internal/parameters.h` and the test
`CGALPhase8bLite.NamedParamPipe_MultipleParamsTakeEffect`. Example:
`gradient_tolerance(1e-12) | max_iterations(500) | output_uv_map(uv)`.
2. **Generic FaceGraph not yet supported.** All Default traits
specialise on `CGAL::Surface_mesh<P>` only. Adding `Polyhedron_3`,
`OpenMesh-adapter`, `pmp::SurfaceMesh` is Phase 8a.2 — speculative,
waiting on a concrete user request.
3. **CGAL submission-readiness incomplete.** User_manual /
PackageDescription.txt / CGAL-format tests are not yet written
(Phase 8c / 8d). Required for upstream submission, not for current
users.
---
## 6. What's reachable from the Java original today
Cross-reference between Java classes and their C++ port status. For
the full list see [`java-parity.md`](java-parity.md); the table below
gives the operational summary for a Java user wondering "where is X?".
### Direct ports
| Java | C++ |
|----------------------------------------------|-------------------------------------------------------------|
| `EuclideanCyclicFunctional` | `euclidean_functional.hpp` |
| `SphericalFunctional` | `spherical_functional.hpp` |
| `HyperIdealFunctional` | `hyper_ideal_functional.hpp` |
| `HyperIdealUtility`, `…Geometry` | `hyper_ideal_utility.hpp`, `hyper_ideal_geometry.hpp` |
| `HyperIdealHyperellipticUtility` | `hyper_ideal_visualization_utility.hpp` |
| `CPEuclideanFunctional` | `cp_euclidean_functional.hpp` |
| `Clausen` | `clausen.hpp` |
| `MeshIO` (jReality JRS) | `mesh_io.hpp` (CGAL::IO, OFF/OBJ/PLY) |
| `CuttingUtility::point_in_triangle_2d` | `geometry_utils.hpp` partial port |
| `ConvergenceUtility::circumradius` | `geometry_utils.hpp` |
| `HomologyUtility::compute_generators` | `cut_graph.hpp` (different algorithm: tree-cotree) |
| `PeriodMatrixUtility` (genus 1) | `period_matrix.hpp` |
| `UnwrapperUtility::EuclideanUnwrapper` | `newton_euclidean()` + `euclidean_layout()` |
| `UnwrapperUtility::SphericalUnwrapper` | `newton_spherical()` + `spherical_layout()` |
| `UnwrapperUtility::HyperbolicUnwrapper` | `newton_hyper_ideal()` + `hyper_ideal_layout()` |
### Not-yet-ported, in roadmap
| Java | Suggested phase | Lines | Notes |
|---------------------------------------------------|:----:|:----:|-------|
| `FundamentalPolygonUtility` + `CanonicalFormUtility` | 9c | 698+532 | genus > 1 fundamental domain |
| `CuttingUtility` + `SurgeryUtility` (full ops) | 9c | 584+217 | real mesh-cut operations |
| `DiscreteHarmonicFormUtility` | 10a | 657 | harmonic 1-forms |
| `DiscreteHolomorphicFormUtility` | 10a | 285 | holomorphic differentials |
| `CanonicalBasisUtility` | 10a | 337 | symplectic homology basis |
| `DualityUtility`, `HomologyUtility` (full) | 10a | 308+122 | primal/dual cohomology |
| `DiscreteRiemannUtility` | 10b | 186 | period matrix for genus > 1 |
| `HyperbolicCyclicFunctional` | 10bc | 530 | hyperbolic energy (different from hyper-ideal) |
| `QuasiisothermicUtility` + `SinConditionApplication` | 10b | ~1200 | Lawson correspondence |
| `StereographicUnwrapper` | 10b' | 266 | S² → atlas |
| `KoebePolyhedron` | 10c | 321 | KAT circle packing |
| `MobiusCenteringFunctional` | 10c | 289 | sphere pre-processing |
| `CircleDomainUnwrapper` | 11c | 570 | multiply-connected planar regions |
### Intentionally not ported
* **`CoHDS` (half-edge data structure)** — replaced by `CGAL::Surface_mesh`. ~3 000 Java LoC saved.
* **`plugin/*` Swing UI** — out of scope; C++ project is a library, not an application.
* **`unwrapper/numerics/*` PETSc/Tao wrappers** — replaced by Eigen, which is header-only and bundled.
* **`math/CP1`, `math/Cn`, …** — redundant with `std::complex`, `Eigen::Matrix`.
---
## 7. Things in C++ that the Java original does NOT have
These are conformallab++ contributions beyond porting — the
"research extensions" track ([`research-track.md`](research-track.md)).
| Item | Status |
|----------------------------------------------|:-----:|
| Block-FD HyperIdeal Hessian (96× speed-up) | ✅ shipped (Phase 9b) |
| HyperIdeal Hessian (any kind) | ✅ shipped — Java has `hasHessian()==false` |
| Inversive-Distance functional (Luo 2004) | ✅ shipped — implemented from paper, not from Java |
| `<CGAL/Discrete_*.h>` public-API surface | ✅ shipped (Phase 8a + 8b-Lite) |
| Cross-validation framework (4 acceptance criteria) | ✅ documented in `add-inversive-distance.md` |
| Genus-2 test mesh + brezel2.obj scalability | ✅ shipped |
| Memory-safe layout via `halfedge_uv` storage | ✅ shipped |
| `doc/release-policy.md` formal release policy | ✅ shipped (PR #13) |
| Analytic HyperIdeal Hessian via Schläfli | 🔲 derivation written (`hyperideal-hessian-derivation.md`); implementation Phase 9b-analytic |
| Output UV map integrated into wrappers | ✅ shipped (PR #14) for 3 of 5 models |
| Full uniformisation for genus g ≥ 2 | 🔲 Phase 10c — fully new research |
---
## 8. How to "use the library today"
The fastest path for a mathematician evaluating the library:
```bash
# Build + run the full test suite
git clone <repo> && cd ConformalLabpp
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
# Try the CGAL API on a mesh
./build/examples/example_layout my_mesh.off
```
To experiment with a new functional, follow
[`doc/tutorials/add-inversive-distance.md`](../tutorials/add-inversive-distance.md).
To extend the CGAL API with new named parameters, follow
[`doc/tutorials/add-output-uv-map.md`](../tutorials/add-output-uv-map.md).
To optimise an FD Hessian, follow
[`doc/tutorials/block-fd-hessian.md`](../tutorials/block-fd-hessian.md).
For the architectural commitments that constrain future contributions,
see [`doc/architecture/locked-vs-flexible.md`](../architecture/locked-vs-flexible.md).