Some checks failed
C++ Tests / test-fast (push) Successful in 2m8s
C++ Tests / test-fast (pull_request) Successful in 2m20s
API Docs / doc-build (pull_request) Successful in 47s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 10m45s
Closes the UX gap identified in the Phase-8b-Lite design discussion:
the four classical-DCE CGAL entries now optionally run their `*_layout()`
step internally if the caller supplies `CGAL::parameters::output_uv_map(pmap)`.
Before this PR, the workflow was:
auto res = CGAL::discrete_conformal_map_euclidean(mesh);
// ... user has to re-set up maps, re-pin vertex, then ...
auto layout = euclidean_layout(mesh, res.x, maps);
// ... and copy coordinates into a property map manually.
After this PR:
auto uv = mesh.add_property_map<Vertex_index, K::Point_2>("uv", ...).first;
CGAL::discrete_conformal_map_euclidean(
mesh, CGAL::parameters::output_uv_map(uv));
// ... uv now populated for every vertex.
Coverage
────────
* `discrete_conformal_map_euclidean` — `Point_2` per vertex.
* `discrete_conformal_map_spherical` — `Point_3` per vertex (on S²).
* `discrete_conformal_map_hyper_ideal` — `Point_2` per vertex (Poincaré disk).
CP-Euclidean and Inversive-Distance entries do not yet support
`output_uv_map` — face-based packing has no per-vertex UV concept, and
inversive-distance needs a dedicated layout routine that uses Luo's
edge-length formula (planned follow-up).
New named parameters (`code/include/CGAL/Conformal_map/internal/parameters.h`)
─────────────────────────────────────────────────────────────────────────────
* `output_uv_map(pmap)` — write coordinates into pmap after layout.
* `normalise_layout(bool)` — apply post-layout canonical normalisation
(PCA centroid for Euclidean, north-pole alignment for Spherical,
Möbius centring for Hyper-ideal).
Both follow the existing Phase-8a-MVP named-parameter convention.
Chained syntax (`.output_uv_map(...).normalise_layout(true)`) is not
yet supported — pass them one at a time.
Tests (5 new in test_cgal_phase8b_lite.cpp)
───────────────────────────────────────────
* `OutputUvMap_Euclidean_PopulatesPmap` — UVs are finite + non-trivial.
* `OutputUvMap_Spherical_PopulatesXyz` — every output on unit S².
* `OutputUvMap_HyperIdeal_PointsInPoincareDisk` — |p|² ≤ 1 if converged.
* `OutputUvMap_Absent_DoesNotRunLayout` — no parameter ⇒ no layout.
* `OutputUvMap_NormaliseLayout_TakesEffect` — both raw + norm calls
return finite UVs (named-parameter chaining limitation documented).
All five pass. Full CGAL suite: 232/232, 0 skipped (was 227).
doc/api/tests.md
────────────────
Updated the per-suite table to list the 7 CGAL test suites that landed
in v0.9.0 (8a MVP + 9a + 9b + 8b-Lite) but had not yet been added to the
canonical table. Total: 227 → 232. This brings the doc back in sync
with `ctest` output and unblocks future `scripts/check-test-counts.sh`
runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
5.7 KiB
Markdown
88 lines
5.7 KiB
Markdown
# Test Suites
|
||
|
||
## `conformallab_tests` — always built (no CGAL)
|
||
|
||
Pure-math tests, only Eigen required. Covers Java utilities ported in Phase 1–2.
|
||
|
||
| File | What it tests |
|
||
|---|---|
|
||
| `test_clausen.cpp` | Clausen Cl₂, Lobachevsky Л, ImLi₂ — values at known points |
|
||
| `test_hyper_ideal_utility.cpp` | Tetrahedron volumes (Meyerhoff / Kolpakov–Mednykh) |
|
||
| `test_matrix_utility.cpp` | Matrix helpers |
|
||
| `test_surface_curve_utility.cpp` | Surface curve utilities |
|
||
| `test_discrete_elliptic_utility.cpp` | Discrete elliptic functions |
|
||
| `test_p2_utility.cpp` | P2 projective utilities |
|
||
| `test_hyper_ideal_visualization_utility.cpp` | Poincaré disk projection, circumcircle |
|
||
|
||
**Total: 23 tests, 0 skipped.**
|
||
|
||
---
|
||
|
||
## `conformallab_cgal_tests` — built with `-DWITH_CGAL_TESTS=ON` or `-DWITH_CGAL=ON`
|
||
|
||
All tests have CTest prefix `cgal.` (set via `TEST_PREFIX "cgal."` in CMakeLists).
|
||
|
||
| Suite | File | Tests | What is verified |
|
||
|---|---|---:|---|
|
||
| `ConformalMeshTopology` | `test_conformal_mesh.cpp` | 4 | Euler characteristic, vertex/edge/face counts |
|
||
| `ConformalMeshTraversal` | `test_conformal_mesh.cpp` | 4 | Halfedge iteration, valence, opposite |
|
||
| `ConformalMeshProperties` | `test_conformal_mesh.cpp` | 5 | Property maps (λ, θ, idx, α, geometry type) |
|
||
| `ConformalMeshValidity` | `test_conformal_mesh.cpp` | 1 | CGAL validity for all factory meshes |
|
||
| `HyperIdealFunctional` | `test_hyper_ideal_functional.cpp` | 7 | FD gradient checks + Hessian symmetry |
|
||
| `SphericalFunctional` | `test_spherical_functional.cpp` | 12 | Angle formula + gradient + gauge-fix + cross-module Hessian check |
|
||
| `EuclideanFunctional` | `test_euclidean_functional.cpp` | 12 | Angle formula + gradient + cross-module Hessian check |
|
||
| `EuclideanHessian` | `test_euclidean_hessian.cpp` | 9 | Cotangent Laplacian structure, FD agreement, PSD, null space |
|
||
| `SphericalHessian` | `test_spherical_hessian.cpp` | 8 | Derivative correctness, NSD at equilibrium |
|
||
| `NewtonSolver` | `test_newton_solver.cpp` | 11 | Convergence: Euclidean ×3, Spherical ×4, HyperIdeal ×4 |
|
||
| `SparseQRFallback` | `test_newton_solver.cpp` | 3 | Full-rank LDLT · singular matrix → QR · closed mesh gauge mode |
|
||
| `MeshIO` | `test_mesh_io.cpp` | 6 | OFF/OBJ round-trips, error handling |
|
||
| `Pipeline` | `test_pipeline.cpp` | 5 | End-to-end: build → setup → solve → export → reload |
|
||
| `Layout` | `test_layout.cpp` | 6 | Edge-length preservation (Eucl./Spher.), Poincaré disk layout |
|
||
| `Serialization` | `test_layout.cpp` | 2 | JSON and XML round-trips (DOF vector + layout UVs) |
|
||
| `GaussBonnet` | `test_phase6.cpp` | 12 | χ, genus, sum/RHS, deficit, check, enforce |
|
||
| `CutGraph` | `test_phase6.cpp` | 6 | Tree-cotree, open/closed meshes, flag–index consistency |
|
||
| `HyperbolicTrilateration` | `test_phase6.cpp` | 4 | Möbius + law of cosines: exact distances, disk interior, off-origin |
|
||
| `Normalisation` | `test_phase6.cpp` | 4 | Euclidean centroid, length ratios, Möbius centring |
|
||
| `MobiusMap` | `test_phase7.cpp` | 8 | Identity, inverse, compose, `from_three`, `apply(Vector2d)` |
|
||
| `BestRootFace` | `test_phase7.cpp` | 2 | Valid root face selection, interior bonus |
|
||
| `HalfedgeUV` | `test_phase7.cpp` | 4 | Size = #halfedges, seam consistency, boundary halfedges = 0 |
|
||
| `PriorityBFS` | `test_phase7.cpp` | 3 | Success, no seam on open meshes, all vertices placed |
|
||
| `NormaliseEuclidean` | `test_phase7.cpp` | 2 | UV centroid = 0, halfedge_uv centroid = 0 |
|
||
| `PeriodMatrix` | `test_phase7.cpp` | 7 | τ ∈ ℍ, SL(2,ℤ) reduction, exception outside ℍ |
|
||
| `FundamentalDomain` | `test_phase7.cpp` | 7 | Genus-1 parallelogram CCW, generators, g > 1 empty |
|
||
| `TilingCopy/Neighbourhood` | `test_phase7.cpp` | 4 | Translation correct, tile count |
|
||
| `CuttingUtility` | `test_geometry_utils.cpp` | 3 | `point_in_triangle_2d`: false, true, unit triangle (Java CuttingUtilityTest) |
|
||
| `UnwrapUtility` | `test_geometry_utils.cpp` | 2 | Corner angle: collinear → π, equilateral → π/3 (Java UnwrapUtilityTest) |
|
||
| `ConvergenceUtility` | `test_geometry_utils.cpp` | 6 | Circumradius + scale-invariant R_f/√A (Java ConvergenceUtilityTests) |
|
||
| `EuclideanLayout` | `test_geometry_utils.cpp` | 2 | Euclidean layout round-trip edge lengths |
|
||
| `SphericalLayout` | `test_geometry_utils.cpp` | 1 | Spherical layout on unit sphere |
|
||
| `HomologyGenerators` | `test_geometry_utils.cpp` | 1 | Genus-2 cut graph: χ = −2, 4 cut edges (`brezel2.obj`) |
|
||
| `SmokeEuclidean` | `test_scalability_smoke.cpp` | 3 | Smoke tests on real meshes: CatHead (open), Brezel genus-1, Brezel2 genus-2 |
|
||
| `CGALConformalTraits` | `test_cgal_traits_mvp.cpp` | 2 | Phase 8a MVP traits + Default model |
|
||
| `CGALDiscreteConformalMap` | `test_cgal_traits_mvp.cpp` | 6 | Phase 8a MVP wrapper smoke tests |
|
||
| `CPEuclideanFunctional` | `test_cp_euclidean_functional.cpp` | 10 | Phase 9a.1 — BPS-2010 face-based packing (Java parity) |
|
||
| `InversiveDistanceFunctional` | `test_inversive_distance_functional.cpp` | 11 | Phase 9a.2 — Luo-2004 vertex-based packing (from literature) |
|
||
| `HyperIdealHessian` | `test_hyper_ideal_hessian.cpp` | 7 | Phase 9b — block-FD vs full-FD cross-validation + PSD + speed-up |
|
||
| `NewtonPhase9a` | `test_newton_phase9a.cpp` | 7 | Phase 9a-Newton — convergence for the two new circle-packing solvers |
|
||
| `CGALPhase8bLite` | `test_cgal_phase8b_lite.cpp` | 13 | Phase 8b-Lite — CGAL entries for all 5 DCE models + `output_uv_map` |
|
||
|
||
**Total: 232 tests, 0 skipped.**
|
||
|
||
---
|
||
|
||
## Running tests
|
||
|
||
```bash
|
||
# All CGAL tests
|
||
ctest --test-dir build -R "^cgal\." --output-on-failure
|
||
|
||
# One suite
|
||
./build/conformallab_cgal_tests --gtest_filter="PeriodMatrix*"
|
||
|
||
# One specific test
|
||
./build/conformallab_cgal_tests --gtest_filter="PeriodMatrix.TauInUpperHalfPlane"
|
||
|
||
# Verbose output with timing
|
||
./build/conformallab_cgal_tests --gtest_filter="NewtonSolver*" --gtest_print_time=1
|
||
```
|