Phase 8a MVP: CGAL traits + Discrete_conformal_map.h Euclidean entry #6

Merged
user2595 merged 2 commits from feature/phase-8a-mvp-traits into main 2026-05-19 20:54:32 +00:00
Owner

Summary

First concrete step of the Phase 8 Hybrid MVP strategy. Adds a thin CGAL-conformant public API layer on top of the existing implementation — validated by 7 acceptance tests.

CGAL test count: 176 → 183, 0 skipped.

What it provides

Public headers (new)

Header Role
CGAL/Conformal_map_traits.h ConformalMapTraits concept doc + Default_conformal_map_traits<Surface_mesh<P>, K>
CGAL/Discrete_conformal_map.h User-facing entry discrete_conformal_map_euclidean(mesh, np) + Conformal_map_result<FT>
CGAL/Conformal_map/internal/parameters.h 4 named-parameter tags

Usage

#include <CGAL/Discrete_conformal_map.h>

Mesh mesh = ...;
auto result = CGAL::discrete_conformal_map_euclidean(
    mesh,
    CGAL::parameters::gradient_tolerance(1e-12).max_iterations(500));
if (result.converged) {
    for (double u : result.u_per_vertex) { ... }
}

Architecture

3-layer wrapper as designed in doc/api/cgal-package.md:

Layer 3 (new):  CGAL/Conformal_map_traits.h, CGAL/Discrete_conformal_map.h
Layer 2 (new):  CGAL/Conformal_map/internal/parameters.h  (adapter, tags)
Layer 1 (no change):  code/include/*.hpp  (existing algorithms)

No algorithm duplication. The wrapper delegates internally to the existing setup_euclidean_maps, enforce_gauss_bonnet, newton_euclidean — same code path as before, just a CGAL-style public façade.

Tests (7 new)

Test What it verifies
DefaultTraitsTypes Compile-time type sanity (static_assert on all advertised types)
AccessorsReuseExistingMaps Traits accessors return identical property maps to setup_euclidean_maps()
SingleTriangleConverges, QuadStripConverges End-to-end Euclidean wrapper runs and converges
MaxIterationsTakesEffect parameters::max_iterations(...) is read
GradientToleranceTakesEffect parameters::gradient_tolerance(...) changes Newton end state
WrapperMatchesLegacyAPI Cross-API u-vector equality at 1e-10

All 7 pass. Full CGAL suite 183/183 passed, 0 skipped.

Strategy reminder

This is MVP scope by design. Deferred to later phases:

  • 8a.2: generic FaceGraph specialisation (trigger: Polyhedron_3 user)
  • 8b.2: _spherical() + _hyperbolic() entry functions (after Phase 9a validates the pattern)
  • 8c–e: User_manual, CGAL-format tests, YAML pipeline (only if/when submission is planned)

Next step: Phase 9a (Inversive-Distance functional) as the second new client of the trait API — the real acceptance test for the design.

## Summary First concrete step of the **Phase 8 Hybrid MVP** strategy. Adds a thin CGAL-conformant public API layer on top of the existing implementation — validated by 7 acceptance tests. **CGAL test count: 176 → 183, 0 skipped.** ## What it provides ### Public headers (new) | Header | Role | |---|---| | `CGAL/Conformal_map_traits.h` | `ConformalMapTraits` concept doc + `Default_conformal_map_traits<Surface_mesh<P>, K>` | | `CGAL/Discrete_conformal_map.h` | User-facing entry `discrete_conformal_map_euclidean(mesh, np)` + `Conformal_map_result<FT>` | | `CGAL/Conformal_map/internal/parameters.h` | 4 named-parameter tags | ### Usage ```cpp #include <CGAL/Discrete_conformal_map.h> Mesh mesh = ...; auto result = CGAL::discrete_conformal_map_euclidean( mesh, CGAL::parameters::gradient_tolerance(1e-12).max_iterations(500)); if (result.converged) { for (double u : result.u_per_vertex) { ... } } ``` ## Architecture 3-layer wrapper as designed in `doc/api/cgal-package.md`: ``` Layer 3 (new): CGAL/Conformal_map_traits.h, CGAL/Discrete_conformal_map.h Layer 2 (new): CGAL/Conformal_map/internal/parameters.h (adapter, tags) Layer 1 (no change): code/include/*.hpp (existing algorithms) ``` **No algorithm duplication.** The wrapper delegates internally to the existing `setup_euclidean_maps`, `enforce_gauss_bonnet`, `newton_euclidean` — same code path as before, just a CGAL-style public façade. ## Tests (7 new) | Test | What it verifies | |---|---| | `DefaultTraitsTypes` | Compile-time type sanity (`static_assert` on all advertised types) | | `AccessorsReuseExistingMaps` | Traits accessors return identical property maps to `setup_euclidean_maps()` | | `SingleTriangleConverges`, `QuadStripConverges` | End-to-end Euclidean wrapper runs and converges | | `MaxIterationsTakesEffect` | `parameters::max_iterations(...)` is read | | `GradientToleranceTakesEffect` | `parameters::gradient_tolerance(...)` changes Newton end state | | `WrapperMatchesLegacyAPI` | Cross-API u-vector equality at `1e-10` | All 7 pass. Full CGAL suite **183/183 passed, 0 skipped**. ## Strategy reminder This is **MVP scope** by design. Deferred to later phases: - 8a.2: generic `FaceGraph` specialisation (trigger: Polyhedron_3 user) - 8b.2: `_spherical()` + `_hyperbolic()` entry functions (after Phase 9a validates the pattern) - 8c–e: User_manual, CGAL-format tests, YAML pipeline (only if/when submission is planned) **Next step**: Phase 9a (Inversive-Distance functional) as the *second* new client of the trait API — the real acceptance test for the design.
user2595 added 1 commit 2026-05-19 20:07:51 +00:00
Phase 8a MVP: CGAL traits + Discrete_conformal_map.h Euclidean entry
Some checks failed
C++ Tests / test-fast (push) Successful in 2m42s
C++ Tests / test-fast (pull_request) Successful in 3m44s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 4m28s
a1e74c1370
First step of the Phase 8 Hybrid MVP. Adds a thin CGAL-conformant public
API layer over the existing implementation, validated by 7 acceptance
tests.  Total CGAL test count: 183 (was 176), 0 skipped.

New public headers
──────────────────
* code/include/CGAL/Conformal_map_traits.h
    - ConformalMapTraits concept documentation
    - Default_conformal_map_traits<Surface_mesh<P>, K> specialisation
    - Static property-map accessors: vertex_points, theta_map,
      vertex_index_map, lambda0_map

* code/include/CGAL/Discrete_conformal_map.h
    - User-facing entry: discrete_conformal_map_euclidean(mesh, np)
    - Conformal_map_result<FT> struct (u, iter, ‖G‖, converged flags)
    - Natural-theta default: x = 0 is the equilibrium when no Θ supplied
    - Honours user-provided Θ via vertex_curvature_map named parameter

* code/include/CGAL/Conformal_map/internal/parameters.h
    - 4 named-parameter tags in CGAL::Conformal_map::internal_np:
        vertex_curvature_map, gradient_tolerance,
        max_iterations,       fixed_vertex_map
    - User-facing helpers in CGAL::parameters::*

Tests (test_cgal_traits_mvp.cpp, 7 cases)
─────────────────────────────────────────
* DefaultTraitsTypes:       compile-time type sanity (static_assert)
* AccessorsReuseExistingMaps: traits accessors return identical pmaps
* SingleTriangleConverges,
  QuadStripConverges:       end-to-end Euclidean wrapper passes
* MaxIterationsTakesEffect: named parameter is read
* GradientToleranceTakesEffect: tolerance override changes Newton end-state
* WrapperMatchesLegacyAPI:  cross-API result equality at 1e-10

Architecture
────────────
3-layer wrapper as designed (doc/api/cgal-package.md):
  Layer 1: code/include/*.hpp           (existing algorithms, unchanged)
  Layer 2: CGAL/Conformal_map/internal/ (adapter, parameter tags)
  Layer 3: CGAL/Conformal_map_traits.h, CGAL/Discrete_conformal_map.h
                                         (user-facing)

No algorithm duplication.  Existing 176 + 36 tests untouched.

Next: Phase 9a (Inversive-Distance) as the second client of this API —
the real acceptance test for the trait design.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
user2595 added 1 commit 2026-05-19 20:50:48 +00:00
fixup: deduce kernel from mesh point type instead of hard-coding it
Some checks failed
C++ Tests / test-fast (push) Successful in 2m33s
C++ Tests / test-fast (pull_request) Successful in 2m0s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / test-cgal (pull_request) Failing after 2m30s
140f50f707
Removes the only architectural lock-in spotted in the MVP audit before
Phase 9a starts: the wrapper hard-coded Simple_cartesian<double> as the
kernel inside discrete_conformal_map_euclidean.  This would have broken
any Surface_mesh<P> where P came from a different kernel (e.g. EPIC).

Change
──────
* CGAL::Kernel_traits<typename TriangleMesh::Point>::Kernel is now used
  to deduce the kernel from the mesh's point type.
* The full Default_traits<...> instantiation is wrapped in
  internal_np::Lookup_named_param_def so a future `geom_traits(...)`
  named parameter can override the entire traits class without changes
  to the wrapper body (CGAL idiom, used by every CGAL package).
* New test `KernelIsDeducedFromMeshPointType` pins the contract
  explicitly with static_asserts.

Why now
───────
Phase 9a (Inversive-Distance) will copy this same template pattern.
Fixing the kernel deduction once here keeps the design free for any
user kernel; doing it after 9a would mean two parallel hard-coded
kernel sites to refactor.

Tests
─────
CGAL suite: 184/184 passed, 0 skipped  (was 183).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
user2595 merged commit e435e143c6 into main 2026-05-19 20:54:32 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: conformallab/ConformalLabpp#6
No description provided.