Phase 7.5: Doxygen infrastructure + Phase 8 design freeze
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>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -27,3 +27,7 @@ Testing/
|
|||||||
|
|
||||||
# Claude Code worktrees
|
# Claude Code worktrees
|
||||||
.claude/
|
.claude/
|
||||||
|
|
||||||
|
# Doxygen output
|
||||||
|
doc/doxygen/
|
||||||
|
*.dox.tmp
|
||||||
|
|||||||
18
CLAUDE.md
18
CLAUDE.md
@@ -249,7 +249,23 @@ Expected results: **36 non-CGAL tests pass**, **176 CGAL tests pass, 0 skipped**
|
|||||||
## Release state
|
## Release state
|
||||||
|
|
||||||
Current release: **v0.7.0** (tag on `origin/dev`, PR to `main` open).
|
Current release: **v0.7.0** (tag on `origin/dev`, PR to `main` open).
|
||||||
Phase 7 is complete. Phase 8 (CGAL package) is next.
|
Phase 7 is complete. Phase 7.5 (Doxygen) and Phase 8 (CGAL package) are next.
|
||||||
|
|
||||||
|
## Phase 8 strategic decisions (2026-05-19)
|
||||||
|
|
||||||
|
The CGAL-package architecture was frozen on 2026-05-19 after the end-of-Phase-7
|
||||||
|
docstring audit. Full design: [`doc/api/cgal-package.md`](doc/api/cgal-package.md).
|
||||||
|
Key decisions:
|
||||||
|
|
||||||
|
| Decision | Choice |
|
||||||
|
|---|---|
|
||||||
|
| Submission to upstream CGAL | **Pre-submission-ready, not bound.** 12+ months horizon. |
|
||||||
|
| License | **MIT preserved** (no LGPL switch). |
|
||||||
|
| Mesh-type flexibility | **Generic `FaceGraph + HalfedgeGraph`** — Surface_mesh, Polyhedron_3, OpenMesh-adapter, pmp. |
|
||||||
|
| Parameter style | **Named Parameters** (`CGAL::parameters::...`). |
|
||||||
|
| Default kernel | **`Simple_cartesian<double>`** (status quo). |
|
||||||
|
| Backward compatibility | **Dual-layer wrapper** — `code/include/*.hpp` stays as implementation, `include/CGAL/*.h` is thin wrapper. No algorithm duplication. |
|
||||||
|
| Phase-8a acceptance test | **Phase 9a (Inversive-Distance)** as the first new client of the new traits API. |
|
||||||
|
|
||||||
Root-level files added at v0.7.0:
|
Root-level files added at v0.7.0:
|
||||||
- `CITATION.cff` — machine-readable citation (Sechelmann 2016, Springborn 2020, Bobenko–Springborn 2004)
|
- `CITATION.cff` — machine-readable citation (Sechelmann 2016, Springborn 2020, Bobenko–Springborn 2004)
|
||||||
|
|||||||
126
Doxyfile
Normal file
126
Doxyfile
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# Doxyfile for conformallab++
|
||||||
|
#
|
||||||
|
# Phase 7.5 — minimal CGAL-style Doxygen configuration.
|
||||||
|
# Only non-default values are set; Doxygen ≥ 1.9.5 supplies the rest.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# doxygen Doxyfile # generates HTML into doc/doxygen/html/
|
||||||
|
# open doc/doxygen/html/index.html
|
||||||
|
#
|
||||||
|
# Or via CMake:
|
||||||
|
# cmake --build build --target doc
|
||||||
|
|
||||||
|
# ── Project identity ─────────────────────────────────────────────────────────
|
||||||
|
PROJECT_NAME = "conformallab++"
|
||||||
|
PROJECT_NUMBER = 0.7.0
|
||||||
|
PROJECT_BRIEF = "Discrete conformal maps on triangle meshes — C++17 reimplementation of ConformalLab (TU Berlin)"
|
||||||
|
PROJECT_LOGO =
|
||||||
|
OUTPUT_DIRECTORY = doc/doxygen
|
||||||
|
USE_MDFILE_AS_MAINPAGE = README.md
|
||||||
|
|
||||||
|
# ── Input ────────────────────────────────────────────────────────────────────
|
||||||
|
INPUT = README.md \
|
||||||
|
CLAUDE.md \
|
||||||
|
code/include \
|
||||||
|
doc/api \
|
||||||
|
doc/architecture \
|
||||||
|
doc/math
|
||||||
|
FILE_PATTERNS = *.hpp *.h *.cpp *.md
|
||||||
|
RECURSIVE = YES
|
||||||
|
EXCLUDE_PATTERNS = */build*/* \
|
||||||
|
*/deps/* \
|
||||||
|
*/.git/* \
|
||||||
|
*/test-reports/* \
|
||||||
|
*/* 2.hpp
|
||||||
|
EXCLUDE_SYMBOLS = Eigen::* boost::* std::*
|
||||||
|
|
||||||
|
# ── Source browsing ──────────────────────────────────────────────────────────
|
||||||
|
EXTRACT_ALL = YES
|
||||||
|
EXTRACT_PRIVATE = NO
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
STRIP_CODE_COMMENTS = NO
|
||||||
|
REFERENCED_BY_RELATION = YES
|
||||||
|
REFERENCES_RELATION = YES
|
||||||
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
|
# ── Build options ────────────────────────────────────────────────────────────
|
||||||
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
MARKDOWN_SUPPORT = YES
|
||||||
|
AUTOLINK_SUPPORT = YES
|
||||||
|
BUILTIN_STL_SUPPORT = YES
|
||||||
|
DISTRIBUTE_GROUP_DOC = YES
|
||||||
|
GROUP_NESTED_COMPOUNDS = YES
|
||||||
|
SUBGROUPING = YES
|
||||||
|
INLINE_GROUPED_CLASSES = NO
|
||||||
|
INLINE_SIMPLE_STRUCTS = NO
|
||||||
|
TYPEDEF_HIDES_STRUCT = NO
|
||||||
|
EXTENSION_MAPPING = h=C++ hpp=C++
|
||||||
|
|
||||||
|
# ── Warnings ─────────────────────────────────────────────────────────────────
|
||||||
|
QUIET = NO
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = NO
|
||||||
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
WARN_IF_INCOMPLETE_DOC = YES
|
||||||
|
WARN_NO_PARAMDOC = NO
|
||||||
|
WARN_AS_ERROR = NO
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE = doc/doxygen/doxygen-warnings.log
|
||||||
|
|
||||||
|
# ── HTML output ──────────────────────────────────────────────────────────────
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_COLORSTYLE = LIGHT
|
||||||
|
HTML_COLORSTYLE_HUE = 220
|
||||||
|
HTML_COLORSTYLE_SAT = 100
|
||||||
|
HTML_COLORSTYLE_GAMMA = 80
|
||||||
|
HTML_TIMESTAMP = NO
|
||||||
|
HTML_DYNAMIC_SECTIONS = YES
|
||||||
|
GENERATE_TREEVIEW = YES
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
ENUM_VALUES_PER_LINE = 1
|
||||||
|
TREEVIEW_WIDTH = 280
|
||||||
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
SEARCHENGINE = YES
|
||||||
|
SERVER_BASED_SEARCH = NO
|
||||||
|
|
||||||
|
# ── Disabled outputs (we only want HTML) ─────────────────────────────────────
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
GENERATE_XML = NO
|
||||||
|
GENERATE_DOCBOOK = NO
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
GENERATE_PERLMOD = NO
|
||||||
|
|
||||||
|
# ── Preprocessor ─────────────────────────────────────────────────────────────
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH = code/include
|
||||||
|
PREDEFINED = CGAL_DISABLE_GMP \
|
||||||
|
CGAL_DISABLE_MPFR \
|
||||||
|
DOXYGEN_RUNNING
|
||||||
|
|
||||||
|
# ── Diagrams ─────────────────────────────────────────────────────────────────
|
||||||
|
HAVE_DOT = NO
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
COLLABORATION_GRAPH = NO
|
||||||
|
GROUP_GRAPHS = YES
|
||||||
|
INCLUDE_GRAPH = NO
|
||||||
|
INCLUDED_BY_GRAPH = NO
|
||||||
|
CALL_GRAPH = NO
|
||||||
|
CALLER_GRAPH = NO
|
||||||
|
|
||||||
|
# ── Aliases (CGAL-style) ─────────────────────────────────────────────────────
|
||||||
|
ALIASES += "concept{1}=\xrefitem concept \"Concept\" \"Concepts\" \1"
|
||||||
|
ALIASES += "models{1}=\xrefitem models \"Models\" \"Models\" \1"
|
||||||
|
ALIASES += "cgalRequires{1}=\par Requirements: \n\1"
|
||||||
|
ALIASES += "cgalParam{2}=\param \1 \2"
|
||||||
@@ -34,6 +34,10 @@ ctest --test-dir build -R "^cgal\." --output-on-failure
|
|||||||
# Full build with CLI + viewer (requires Wayland/X11 dev headers)
|
# Full build with CLI + viewer (requires Wayland/X11 dev headers)
|
||||||
cmake -S code -B build -DWITH_CGAL=ON && cmake --build build -j$(nproc)
|
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
|
./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
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -140,3 +140,25 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
|
|||||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../CITATION.cff
|
${CMAKE_CURRENT_SOURCE_DIR}/../CITATION.cff
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/conformallab)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/conformallab)
|
||||||
|
|
||||||
|
# ── Doxygen documentation target (Phase 7.5) ──────────────────────────────────
|
||||||
|
# Generates HTML API documentation into doc/doxygen/html/.
|
||||||
|
# Usage:
|
||||||
|
# cmake --build build --target doc
|
||||||
|
# open doc/doxygen/html/index.html
|
||||||
|
#
|
||||||
|
# Optional dependency: install Doxygen via `brew install doxygen` (macOS) or
|
||||||
|
# `apt install doxygen graphviz` (Linux). The target is silently disabled
|
||||||
|
# if Doxygen is not found.
|
||||||
|
find_package(Doxygen QUIET)
|
||||||
|
if(DOXYGEN_FOUND)
|
||||||
|
set(DOXYGEN_PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||||
|
add_custom_target(doc
|
||||||
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_PROJECT_ROOT}/Doxyfile
|
||||||
|
WORKING_DIRECTORY ${DOXYGEN_PROJECT_ROOT}
|
||||||
|
COMMENT "Generating API documentation with Doxygen"
|
||||||
|
VERBATIM)
|
||||||
|
message(STATUS "Doxygen found: target 'doc' available (cmake --build build --target doc)")
|
||||||
|
else()
|
||||||
|
message(STATUS "Doxygen not found — 'doc' target unavailable (install: brew/apt install doxygen)")
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -1,77 +1,211 @@
|
|||||||
# Phase 8 — CGAL Package Design
|
# Phase 8 — CGAL Package Design
|
||||||
|
|
||||||
> **Status: planned.** This document describes the target architecture for Phase 8.
|
> **Status: design frozen, implementation planned.**
|
||||||
> No code has been written yet. The design is informed by the CGAL package submission
|
> This document captures the strategic decisions taken before the first
|
||||||
> guidelines at https://www.cgal.org/developers.html
|
> 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_processing` and `Surface_mesh_parameterization` packages.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Goal
|
## Strategic position
|
||||||
|
|
||||||
Integrate conformallab++ into the CGAL library as a proper CGAL package:
|
| Question | Decision | Rationale |
|
||||||
`Discrete_conformal_map`. The package must satisfy all CGAL submission requirements:
|
|---|---|---|
|
||||||
traits-class design, Doxygen documentation, CGAL-format test suite, and coverage of
|
| 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. |
|
||||||
the CGAL coding conventions.
|
| 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
|
## 8a — Traits class & concepts
|
||||||
|
|
||||||
The current code is tightly coupled to `CGAL::Surface_mesh<Point3>`. Phase 8a introduces
|
### `ConformalMapTraits` concept
|
||||||
a traits class that separates the mesh type from the algorithm:
|
|
||||||
|
The concept lists the types and operations every Traits model must provide.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// TODO(Phase 8a): implement this header
|
namespace CGAL {
|
||||||
// include/CGAL/Conformal_map_traits.h
|
|
||||||
|
|
||||||
template<
|
// Concept (documentation only; no code):
|
||||||
typename MeshType, // any CGAL halfedge mesh
|
struct ConformalMapTraits {
|
||||||
typename KernelType, // CGAL kernel
|
// Types
|
||||||
typename ScalarType = double
|
using Triangle_mesh = ...; // model of FaceGraph + HalfedgeGraph
|
||||||
>
|
using FT = ...; // typically double
|
||||||
struct Conformal_map_traits {
|
using Vertex_descriptor = boost::graph_traits<Triangle_mesh>::vertex_descriptor;
|
||||||
using Mesh = MeshType;
|
using Halfedge_descriptor = ...;
|
||||||
using Kernel = KernelType;
|
using Face_descriptor = ...;
|
||||||
using FT = ScalarType;
|
|
||||||
// ... vertex/edge/face descriptor types
|
// Read access (input geometry)
|
||||||
// ... property map access
|
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.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
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
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 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);
|
||||||
|
// ...
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Concept checks will ensure any user-provided mesh satisfies the halfedge mesh concept.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8b — Public header hierarchy
|
## 8b — Public CGAL header hierarchy
|
||||||
|
|
||||||
A clean public API separate from the internal implementation:
|
### User-facing entry
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 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<bool> | 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/
|
include/CGAL/
|
||||||
Discrete_conformal_map.h ← single user-facing include
|
├── Discrete_conformal_map.h ← user-facing entry (1 include for casual use)
|
||||||
Conformal_map_traits.h
|
├── Conformal_map_traits.h ← concept + Default_conformal_map_traits
|
||||||
Conformal_newton_solver.h
|
├── Conformal_map_concept_checks.h
|
||||||
Conformal_layout.h
|
├── Conformal_newton_solver.h ← standalone Newton (advanced users)
|
||||||
Conformal_cut_graph.h
|
├── Conformal_layout.h ← layout + holonomy
|
||||||
conformal_map_package.h ← PackageDescription
|
├── 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
|
||||||
```
|
```
|
||||||
|
|
||||||
All existing `include/*.hpp` headers remain as internal implementation details,
|
|
||||||
not part of the public CGAL API.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8c — CGAL-style documentation
|
## 8c — CGAL-style documentation
|
||||||
|
|
||||||
```
|
```
|
||||||
doc/Conformal_map/
|
doc/Conformal_map/
|
||||||
PackageDescription.txt
|
├── PackageDescription.txt ← CGAL Doxygen package file
|
||||||
User_manual.md
|
├── Conformal_map.txt ← Doxygen User_manual
|
||||||
Reference_manual.md
|
├── examples.txt ← linkable example code
|
||||||
fig/ ← pipeline diagrams, mathematical figures
|
├── dependencies ← textual list
|
||||||
|
└── fig/ ← pipeline diagrams, math figures
|
||||||
```
|
```
|
||||||
|
|
||||||
All public functions and concepts require Doxygen comments following the CGAL style.
|
All public functions, concepts, and types require Doxygen. See **Phase 7.5** (below).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -79,88 +213,113 @@ All public functions and concepts require Doxygen comments following the CGAL st
|
|||||||
|
|
||||||
```
|
```
|
||||||
test/Conformal_map/
|
test/Conformal_map/
|
||||||
CMakeLists.txt ← CGAL-format, uses find_package(CGAL)
|
├── CMakeLists.txt ← CGAL-format, uses find_package(CGAL)
|
||||||
test_euclidean_functional.cpp
|
├── test_euclidean_traits.cpp ← traits concept checks
|
||||||
test_newton_solver.cpp
|
├── test_polyhedron_3_backend.cpp ← tests with Polyhedron_3 as mesh
|
||||||
...
|
├── test_named_parameters.cpp
|
||||||
|
└── data/ ← test meshes
|
||||||
```
|
```
|
||||||
|
|
||||||
The existing GTest suite remains. CGAL-format tests are added alongside as a separate
|
The existing GTest suite at `code/tests/cgal/` remains; CGAL-format tests are
|
||||||
target, following the CGAL test infrastructure conventions.
|
added alongside as a separate target. CI runs both.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8e — Declarative YAML pipeline
|
## 8e — Declarative YAML pipeline
|
||||||
|
|
||||||
A lightweight YAML format for reproducible experiments. The CLI accepts
|
A lightweight YAML format for reproducible experiments. CLI accepts
|
||||||
`--pipeline experiment.yml`; the validator checks `require`/`provide` tokens
|
`--pipeline experiment.yml`; the validator checks `require`/`provide` tokens
|
||||||
before execution.
|
before execution.
|
||||||
|
|
||||||
**Full concept & design specification:** [doc/concepts/declarative-pipeline.md](../concepts/declarative-pipeline.md)
|
**Full spec:** [doc/concepts/declarative-pipeline.md](../concepts/declarative-pipeline.md)
|
||||||
— token vocabulary, validation algorithm, 5 complete examples, implementation plan.
|
— token vocabulary, validation algorithm, 5 complete examples.
|
||||||
|
|
||||||
Abbreviated example:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
pipeline:
|
pipeline:
|
||||||
name: flat_torus_period
|
name: flat_torus_period
|
||||||
geometry: euclidean
|
geometry: euclidean
|
||||||
|
input: { source: data/torus.off }
|
||||||
input:
|
|
||||||
source: data/torus.off
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- id: setup
|
- { id: setup, unit: setup_euclidean_maps, provide: [maps_initialised] }
|
||||||
unit: setup_euclidean_maps
|
- { id: gb, unit: enforce_gauss_bonnet, require: [maps_initialised], provide: [gauss_bonnet_satisfied] }
|
||||||
provide: [maps_initialised]
|
- { 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: gauss_bonnet
|
- { id: layout, unit: euclidean_layout, require: [x_converged, cut_graph], provide: [layout_uv, holonomy] }
|
||||||
unit: enforce_gauss_bonnet
|
- { id: period, unit: compute_period_matrix, require: [holonomy], provide: [tau] }
|
||||||
require: [maps_initialised]
|
|
||||||
provide: [gauss_bonnet_satisfied]
|
|
||||||
|
|
||||||
- id: solve
|
|
||||||
unit: newton_euclidean
|
|
||||||
require: [gauss_bonnet_satisfied]
|
|
||||||
params:
|
|
||||||
tol: 1.0e-10
|
|
||||||
max_iter: 200
|
|
||||||
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]
|
|
||||||
params:
|
|
||||||
normalise: true
|
|
||||||
provide: [layout_uv, holonomy]
|
|
||||||
|
|
||||||
- id: period
|
|
||||||
unit: compute_period_matrix
|
|
||||||
require: [holonomy]
|
|
||||||
provide: [tau]
|
|
||||||
|
|
||||||
output:
|
output:
|
||||||
layout: out/torus_layout.off
|
layout: out/torus_layout.off
|
||||||
json: out/torus_result.json
|
json: out/torus_result.json
|
||||||
tau: out/torus_tau.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The contract table in [contracts.md](contracts.md) defines the valid `require`/`provide`
|
|
||||||
token vocabulary.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## TODO
|
## Phase 7.5 — Doxygen infrastructure (prerequisite)
|
||||||
|
|
||||||
- [ ] Design `Conformal_map_traits.h` interface (8a)
|
Before any Phase 8 code, the existing API surface must be extractable.
|
||||||
- [ ] Define concept requirements for `MeshType` (8a)
|
This is the prerequisite that bridges Phase 7 → Phase 8.
|
||||||
- [ ] Create `include/CGAL/` header skeleton (8b)
|
|
||||||
- [ ] Write `PackageDescription.txt` (8c)
|
```
|
||||||
- [ ] Port GTest tests to CGAL format (8d)
|
Phase 7.5 — Doxygen infrastructure
|
||||||
- [ ] Implement YAML validator (8e)
|
──────────────────────────────────
|
||||||
- [ ] CLI: `--pipeline` flag (8e)
|
• 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:
|
||||||
|
|
||||||
|
1. `cgal.ConformalTraits.Polyhedron_3_works` passes.
|
||||||
|
2. `cgal.ConformalTraits.Surface_mesh_default_works` passes — identical results to the legacy API.
|
||||||
|
3. 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.
|
||||||
|
4. A user can write `#include <CGAL/Discrete_conformal_map.h>` and call `discrete_conformal_map_euclidean(mesh, parameters::vertex_curvature_map(theta))` against a `Polyhedron_3` and 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: `ConformalMapTraits` concept header
|
||||||
|
- [ ] 8a.1: `Default_conformal_map_traits<Surface_mesh, K>`
|
||||||
|
- [ ] 8a.2: Generic `FaceGraph` specialisation
|
||||||
|
- [ ] 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.h` wrappers
|
||||||
|
- [ ] 9a: `inversive_distance_functional.hpp` written 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 `--pipeline` flag
|
||||||
|
|||||||
Reference in New Issue
Block a user