Adds the Doxygen documentation pipeline as the bridge from Phase 7
(porting complete) to Phase 8 (CGAL package). Also captures the
strategic Phase 8 decisions taken on 2026-05-19.
Infrastructure
──────────────
* Doxyfile — CGAL-style minimal configuration, HTML-only,
INPUT=code/include + doc/, excludes deps/ and
macOS Finder duplicates
* code/CMakeLists — `doc` target via find_package(Doxygen QUIET);
silently disabled if Doxygen is not installed
* README — `cmake --build build --target doc` instructions
* .gitignore — exclude doc/doxygen/ output
Phase 8 strategic decisions (recorded in doc/api/cgal-package.md)
────────────────────────────────────────────────────────────────
* Submission to CGAL: pre-submission-ready, 12+ months horizon, MIT preserved
* Mesh-type flexibility: generic FaceGraph + HalfedgeGraph
* Parameter style: CGAL Named Parameters
* Default kernel: Simple_cartesian<double> (status quo)
* Architecture: 3-layer wrapper, no algorithm duplication
* Acceptance test: Phase 9a (Inversive-Distance) as first new client
CLAUDE.md updated with a compact Phase 8 decision table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
15 KiB
Phase 8 — CGAL Package Design
Status: design frozen, implementation planned. This document captures the strategic decisions taken before the first line of Phase 8 code is written. The decisions were taken on 2026-05-19 after the docstring/architecture audit at the end of Phase 7.
The design is informed by the CGAL package submission guidelines at https://www.cgal.org/developers.html and by reading the existing
Polygon_mesh_processingandSurface_mesh_parameterizationpackages.
Strategic position
| Question | Decision | Rationale |
|---|---|---|
| Submission to CGAL? | Pre-submission-ready, not submission-bound. 12+ months horizon, optional. | Keep design freedom, no editor-review pressure. Structure is valuable on its own. |
| License | MIT preserved. | CGAL submission would require LGPL — deferred. Current users (academic + industrial) profit from MIT. |
| Mesh-type flexibility | Generic FaceGraph + HalfedgeGraph. |
Maximum CGAL value: works with Surface_mesh, Polyhedron_3, OpenMesh-adapter, pmp. |
| Parameter style | Named Parameters (CGAL::parameters::vertex_curvature_map(...).max_iterations(50)). |
CGAL standard; identical UX to PMP::triangulate_*. |
| Default kernel | CGAL::Simple_cartesian<double>. |
Status quo. Conformal geometry does not require exact predicates. |
| Backward compatibility | Dual-layer wrapper. code/include/*.hpp stays as implementation; include/CGAL/*.h is thin wrapper. |
Existing 176 + 36 tests unchanged. New API gets new tests. |
| Algorithm code | No duplication. New CGAL headers delegate to existing code via property-map adapters. | Single source of truth; no parallel maintenance. |
Architecture
Three-layer model
┌──────────────────────────────────────────────────────────────────┐
│ Layer 3: Public CGAL API include/CGAL/*.h │
│ ───────────────────────── │
│ • Conformal_map_traits.h ← concept + default model │
│ • Discrete_conformal_map.h ← user-facing entry │
│ • Conformal_layout.h, ... │
│ Named parameters, generic over FaceGraph, Doxygen-documented. │
└──────────────────────────────────────────────────────────────────┘
▲
│ thin wrapper, no algorithm code
│
┌──────────────────────────────────────────────────────────────────┐
│ Layer 2: Adapter / Traits include/CGAL/Conformal_map/ │
│ ───────────────────────── │
│ • Default_traits.h ← maps generic FaceGraph to │
│ Surface_mesh property maps │
│ • Property_map_adapter.h ← read/write u, θ, α via │
│ boost::property_map traits │
└──────────────────────────────────────────────────────────────────┘
▲
│ uses existing algorithms as-is
│
┌──────────────────────────────────────────────────────────────────┐
│ Layer 1: Implementation code/include/*.hpp │
│ ───────────────────────── │
│ euclidean_functional.hpp, layout.hpp, newton_solver.hpp, ... │
│ Hardcoded to Surface_mesh + Simple_cartesian — unchanged. │
└──────────────────────────────────────────────────────────────────┘
8a — Traits class & concepts
ConformalMapTraits concept
The concept lists the types and operations every Traits model must provide.
namespace CGAL {
// Concept (documentation only; no code):
struct ConformalMapTraits {
// Types
using Triangle_mesh = ...; // model of FaceGraph + HalfedgeGraph
using FT = ...; // typically double
using Vertex_descriptor = boost::graph_traits<Triangle_mesh>::vertex_descriptor;
using Halfedge_descriptor = ...;
using Face_descriptor = ...;
// Read access (input geometry)
using Vertex_point_map = ...; // model of ReadablePropertyMap
// key: Vertex_descriptor
// value: K::Point_3
// Read/write access (conformal data)
using Lambda_pmap = ...; // u_v (scale factor) RW
using Theta_pmap = ...; // Θ_v (target curvature) R
using Vertex_index_pmap = ...; // DOF index (−1 = pinned) RW
using Edge_alpha_pmap = ...; // α_e (hyperbolic only) RW
using Face_type_pmap = ...; // geometry tag per face R
// Optional output
using UV_pmap = ...; // halfedge → (u, v) ∈ ℝ² W
using Holonomy_pmap = ...; // seam edge → ω ∈ ℂ W
};
}
Default_conformal_map_traits<TM>
The default model wraps Surface_mesh property maps so existing code keeps
working through the new public API.
template <class TriangleMesh,
class K = CGAL::Simple_cartesian<double>>
struct Default_conformal_map_traits;
// Specialisation for Surface_mesh:
template <class K>
struct Default_conformal_map_traits<CGAL::Surface_mesh<typename K::Point_3>, K> {
using Triangle_mesh = CGAL::Surface_mesh<typename K::Point_3>;
using FT = typename K::FT;
using Vertex_point_map = typename Triangle_mesh::Point_property_map;
using Lambda_pmap = typename Triangle_mesh::template Property_map<vertex_descriptor, FT>;
// ... etc, using "conformal:lambda" property names
};
// Generic specialisation for other FaceGraph models will be added in 8a.2.
Concept-checks
// include/CGAL/Conformal_map_concept_checks.h
template <class Traits>
struct Conformal_map_traits_check {
static_assert(boost::is_same<...>::value, "Traits::FT must be a floating-point type");
static_assert(is_face_graph<Traits::Triangle_mesh>::value);
// ...
};
8b — Public CGAL header hierarchy
User-facing entry
// include/CGAL/Discrete_conformal_map.h
namespace CGAL {
template <class TriangleMesh, class NamedParameters = parameters::Default_named_parameters>
bool discrete_conformal_map_euclidean(TriangleMesh& mesh,
const NamedParameters& np = parameters::default_values());
template <class TriangleMesh, class NamedParameters = ...>
bool discrete_conformal_map_spherical(TriangleMesh& mesh,
const NamedParameters& np = ...);
template <class TriangleMesh, class NamedParameters = ...>
bool discrete_conformal_map_hyperbolic(TriangleMesh& mesh,
const NamedParameters& np = ...);
} // namespace CGAL
Named parameter vocabulary
| Parameter | Type | Default | Meaning |
|---|---|---|---|
vertex_curvature_map(pmap) |
ReadablePropertyMap | 2π at interior, π at boundary |
Θᵥ values |
fixed_vertex_pmap(pmap) |
ReadablePropertyMap | First vertex pinned | Which vertices are pinned (gauge) |
max_iterations(n) |
int | 200 | Newton iteration limit |
gradient_tolerance(eps) |
FT | 1e-10 | ‖G‖∞ threshold |
vertex_index_map(pmap) |
LvaluePropertyMap | DOF auto-assigned | Allows user to override DOF assignment |
output_uv_map(pmap) |
WritablePropertyMap | none | If set, writes UV layout into pmap |
cut_graph(cg) |
Conformal_cut_graph |
auto-computed | Pre-computed seam edges (mandatory for closed surfaces) |
geom_traits(t) |
model of ConformalMapTraits | Default_* |
Custom traits |
Modular headers
include/CGAL/
├── Discrete_conformal_map.h ← user-facing entry (1 include for casual use)
├── Conformal_map_traits.h ← concept + Default_conformal_map_traits
├── Conformal_map_concept_checks.h
├── Conformal_newton_solver.h ← standalone Newton (advanced users)
├── Conformal_layout.h ← layout + holonomy
├── Conformal_cut_graph.h ← orthogonal algorithm
├── Conformal_period_matrix.h ← genus-1 τ (conformallab++ unique)
├── Conformal_holonomy.h ← Möbius holonomy (conformallab++ unique)
└── Conformal_map/ ← CGAL convention: implementation details
├── Default_traits.h
├── Property_map_adapter.h
├── Newton_iteration.h
└── Internal_helpers.h
8c — CGAL-style documentation
doc/Conformal_map/
├── PackageDescription.txt ← CGAL Doxygen package file
├── Conformal_map.txt ← Doxygen User_manual
├── examples.txt ← linkable example code
├── dependencies ← textual list
└── fig/ ← pipeline diagrams, math figures
All public functions, concepts, and types require Doxygen. See Phase 7.5 (below).
8d — CGAL test format
test/Conformal_map/
├── CMakeLists.txt ← CGAL-format, uses find_package(CGAL)
├── test_euclidean_traits.cpp ← traits concept checks
├── test_polyhedron_3_backend.cpp ← tests with Polyhedron_3 as mesh
├── test_named_parameters.cpp
└── data/ ← test meshes
The existing GTest suite at code/tests/cgal/ remains; CGAL-format tests are
added alongside as a separate target. CI runs both.
8e — Declarative YAML pipeline
A lightweight YAML format for reproducible experiments. CLI accepts
--pipeline experiment.yml; the validator checks require/provide tokens
before execution.
Full spec: doc/concepts/declarative-pipeline.md — token vocabulary, validation algorithm, 5 complete examples.
pipeline:
name: flat_torus_period
geometry: euclidean
input: { source: data/torus.off }
steps:
- { id: setup, unit: setup_euclidean_maps, provide: [maps_initialised] }
- { id: gb, unit: enforce_gauss_bonnet, require: [maps_initialised], provide: [gauss_bonnet_satisfied] }
- { id: solve, unit: newton_euclidean, require: [gauss_bonnet_satisfied], provide: [x_converged] }
- { id: cut, unit: compute_cut_graph, require: [mesh_closed], provide: [cut_graph] }
- { id: layout, unit: euclidean_layout, require: [x_converged, cut_graph], provide: [layout_uv, holonomy] }
- { id: period, unit: compute_period_matrix, require: [holonomy], provide: [tau] }
output:
layout: out/torus_layout.off
json: out/torus_result.json
Phase 7.5 — Doxygen infrastructure (prerequisite)
Before any Phase 8 code, the existing API surface must be extractable. This is the prerequisite that bridges Phase 7 → Phase 8.
Phase 7.5 — Doxygen infrastructure
──────────────────────────────────
• Doxyfile (CGAL-conform: INPUT=code/include + include/CGAL,
EXCLUDE_PATTERNS="* 2.hpp")
• doxygen-awesome-css as theme (matches CGAL house style)
• CMake target: cmake --build build --target doc
• CI job: doc-build → publishes to Codeberg Pages or gitea-pages
• Extract baseline once → snapshot what is actually exported today
• Top-5 central headers (3 functional + conformal_mesh + layout)
upgraded to Doxygen comments; the rest follows during Phase 8 implementation
The baseline snapshot doubles as the API-design review tool: before designing the public CGAL wrapper, we see exactly which functions, classes and free operators exist and need to be wrapped or hidden.
Validation criteria
Phase 8a is "done" when:
cgal.ConformalTraits.Polyhedron_3_workspasses.cgal.ConformalTraits.Surface_mesh_default_workspasses — identical results to the legacy API.- The Inversive-Distance functional (Phase 9a) is implementable as the first new client of the traits API without architectural changes — no breaking changes to the trait concept.
- A user can write
#include <CGAL/Discrete_conformal_map.h>and calldiscrete_conformal_map_euclidean(mesh, parameters::vertex_curvature_map(theta))against aPolyhedron_3and get a valid layout.
If any of these fail, the design is iterated before continuing.
Implementation order
1. Phase 7.5 Doxygen infrastructure + duplicate cleanup (½–1 day)
2. Phase 8a.1 ConformalMapTraits concept + Default_traits (2–3 days)
3. Phase 8a.2 Generic FaceGraph specialisation (2 days)
4. Phase 8b.1 Discrete_conformal_map.h entry point (2 days)
5. Phase 8b.2 Layout + cut graph wrappers (2 days)
6. Phase 9a Inversive-Distance against new traits = API test (3–5 days)
7. Phase 8c PackageDescription.txt + User_manual.md (2 days)
8. Phase 8d CGAL-format test directory (1–2 days)
9. Phase 8e YAML pipeline + CLI flag (3 days)
Total budget: 3–4 weeks net work, 6–8 weeks calendar.
TODO checklist
- Phase 7.5: Doxyfile + CMake doc target + duplicate cleanup
- 8a.1:
ConformalMapTraitsconcept header - 8a.1:
Default_conformal_map_traits<Surface_mesh, K> - 8a.2: Generic
FaceGraphspecialisation - 8a.2:
Conformal_map_concept_checks.h - 8b.1:
Discrete_conformal_map.h(3 entry functions) - 8b.1: Named-parameter vocabulary header
- 8b.2:
Conformal_layout.h,Conformal_cut_graph.hwrappers - 9a:
inversive_distance_functional.hppwritten against new traits - 8c:
doc/Conformal_map/PackageDescription.txt - 8c: User_manual + Reference_manual
- 8d:
test/Conformal_map/CGAL-style tests - 8e: YAML validator + CLI
--pipelineflag