ROOT CAUSE FIX
The Doxyfile EXCLUDE_PATTERNS line contained `*/* 2.hpp` (note the
space — a stray glob from macOS-style "foo 2.hpp" duplicate files).
That pattern was silently matching ALL .hpp / .h files, so Doxygen was
indexing nothing under code/include/. The pre-existing 556 KB of HTML
output was effectively documenting only README.md, CLAUDE.md and a
small stub for std:: — not the C++ API at all.
After fixing the pattern (and properly escaping the space-prefixed
"foo 2.hpp / foo 2.h" macOS-dup patterns), Doxygen now extracts 141
compounds and emits 248 HTML pages from the public headers.
WHAT THIS PR ADDS
1. Doxyfile fix: correct EXCLUDE_PATTERNS; add GENERATE_XML for the
coverage measurement script; add MathJax for `$$...$$` math in
markdown; add the missing CGAL `\cgalParamNBegin/End/Description/
Default/...` aliases so CGAL-style param blocks render correctly.
2. New headers:
- code/include/CGAL/Conformal_map/doxygen_groups.h
defines `PkgConformalMap{,Ref,Concepts,NamedParameters}`,
resolving 17 prior "non-existing group" warnings.
- code/include/CGAL/Conformal_map/doxygen_namespaces.h
gives every namespace under `CGAL::` and `conformallab::` a
brief description.
3. New tool: scripts/doxygen-coverage.sh
Parses the XML output and reports % of public symbols (excluding
the `detail::` implementation namespaces by default) that have a
non-empty brief/detailed description. Supports `--list-undoc`
and `--threshold N` for CI integration.
4. Substantial docstring additions to the public CGAL headers:
`Conformal_map_traits.h`, `Discrete_circle_packing.h`,
`Discrete_inversive_distance.h`, `conformal_mesh.hpp`,
`Discrete_conformal_map.h` (Hyper_ideal_map_result fields).
5. Markdown housekeeping that the strict-warning Doxygen run surfaced:
tests.md (escape literal `#` in table cell),
locked-vs-flexible.md (broken section anchor),
overall_pipeline.md (replace `$$LaTeX$$` with inline-unicode math).
CURRENT NUMBERS
before: ~24% documented (public API; the prior "87%" claim was
based on the broken extraction)
after: 42% documented (165 of 396 public symbols)
warnings: 0 (was 27 spurious + a flood of bogus undocumented
warnings hidden by the buggy EXCLUDE pattern)
NEXT (in a follow-up commit on this branch)
The remaining 231 public symbols (mostly in `layout.hpp`,
`hyper_ideal_functional.hpp`, `spherical_functional.hpp`, the per-mode
functional/Hessian files) can be brought to ~100% with another pass of
short `///` brief descriptions. The coverage script is the gate; CI
can begin enforcing `--threshold 95` once the next pass lands.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
182 lines
8.8 KiB
C++
182 lines
8.8 KiB
C++
// Copyright (c) 2024-2026 Tarik Moussa.
|
||
// SPDX-License-Identifier: MIT
|
||
//
|
||
// Package: conformallab++ / Discrete_conformal_map (Phase 8 MVP, 2026-05-19)
|
||
|
||
/*!
|
||
\file CGAL/Conformal_map_traits.h
|
||
\ingroup PkgConformalMapRef
|
||
|
||
Defines the `ConformalMapTraits` concept and the default model
|
||
`Default_conformal_map_traits<TriangleMesh, K>` for the package.
|
||
|
||
The concept lists the types and property maps that the discrete-conformal
|
||
algorithms require from any backing data structure. By templatising the
|
||
algorithms on this concept, the package can run on any CGAL halfedge
|
||
mesh — `Surface_mesh`, `Polyhedron_3`, OpenMesh-adapter, pmp — without
|
||
changes to the algorithm code.
|
||
|
||
For Phase 8 MVP only the `Surface_mesh` specialisation is provided
|
||
(specialisation 8a.1). A generic `FaceGraph` specialisation is on the
|
||
roadmap as 8a.2.
|
||
|
||
\sa `CGAL::Discrete_conformal_map`
|
||
\sa `CGAL::parameters::vertex_curvature_map`
|
||
*/
|
||
|
||
#ifndef CGAL_CONFORMAL_MAP_TRAITS_H
|
||
#define CGAL_CONFORMAL_MAP_TRAITS_H
|
||
|
||
#include <CGAL/Surface_mesh.h>
|
||
#include <CGAL/Simple_cartesian.h>
|
||
#include <boost/graph/graph_traits.hpp>
|
||
|
||
namespace CGAL {
|
||
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
// \cgalConcept
|
||
//
|
||
// \concept ConformalMapTraits
|
||
// \ingroup PkgConformalMapConcepts
|
||
//
|
||
// The concept `ConformalMapTraits` describes the requirements that any
|
||
// Traits model must fulfil for the Discrete_conformal_map package.
|
||
//
|
||
// \cgalHasModelsBegin
|
||
// \cgalHasModels{CGAL::Default_conformal_map_traits<TriangleMesh, K>}
|
||
// \cgalHasModelsEnd
|
||
//
|
||
// \section RequiredTypes Required types
|
||
//
|
||
// | Type | Description |
|
||
// |------|-------------|
|
||
// | `Triangle_mesh` | A model of CGAL `FaceGraph` + `HalfedgeGraph`. |
|
||
// | `Kernel` | A CGAL kernel; defaults to `Simple_cartesian<double>`. |
|
||
// | `FT` | Field type used internally (typically `double`). |
|
||
// | `Vertex_descriptor` | `boost::graph_traits<Triangle_mesh>::vertex_descriptor`. |
|
||
// | `Halfedge_descriptor` | analogously. |
|
||
// | `Edge_descriptor` | analogously. |
|
||
// | `Face_descriptor` | analogously. |
|
||
//
|
||
// \section RequiredProperties Required property-map accessors
|
||
//
|
||
// The Traits class is responsible for *locating* the property maps that
|
||
// the algorithm reads from and writes to. The semantics follow the
|
||
// project conventions (see `doc/api/contracts.md` for the full table):
|
||
//
|
||
// | Property | Key | Value | Access | Used by |
|
||
// |----------------------|-------------------------|-------|---------|---------|
|
||
// | `vertex_points(m)` | `Vertex_descriptor` | `Point_3` | Read | input geometry |
|
||
// | `theta_map(m)` | `Vertex_descriptor` | `FT` | RW | target cone angle Θᵥ |
|
||
// | `vertex_index_map(m)`| `Vertex_descriptor` | `int` | RW | DOF index (−1 = pinned) |
|
||
// | `lambda0_map(m)` | `Edge_descriptor` | `FT` | RW | base log-length λ°ᵢⱼ |
|
||
//
|
||
// Each accessor is a `static` member that returns the map; it must be
|
||
// idempotent (calling twice yields the same map by name lookup).
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
|
||
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
// Default_conformal_map_traits — primary template (undefined)
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
//
|
||
// The undefined primary template forces specialisation per mesh type.
|
||
// MVP provides only the `Surface_mesh` specialisation below; further
|
||
// mesh types (Polyhedron_3, OpenMesh, pmp) are deferred to Phase 8a.2.
|
||
|
||
template <typename TriangleMesh,
|
||
typename Kernel_ = CGAL::Simple_cartesian<double>>
|
||
struct Default_conformal_map_traits;
|
||
|
||
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
// Specialisation: CGAL::Surface_mesh<K::Point_3>
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
|
||
/*!
|
||
\ingroup PkgConformalMapRef
|
||
|
||
Default traits for `CGAL::Surface_mesh`. Wraps the property maps that
|
||
the existing implementation (`code/include/euclidean_functional.hpp`)
|
||
attaches to a Surface_mesh under the `"ev:idx"`, `"ev:theta"`,
|
||
`"ee:lam0"` etc. names.
|
||
|
||
This specialisation is the only one available in Phase 8 MVP. It is
|
||
selected automatically when `TriangleMesh = CGAL::Surface_mesh<...>`.
|
||
|
||
\tparam K Any CGAL kernel. Defaults to `Simple_cartesian<double>`,
|
||
which is what `conformal_mesh.hpp` uses today.
|
||
*/
|
||
template <typename K>
|
||
struct Default_conformal_map_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
|
||
{
|
||
/// The CGAL kernel parameter; defaults to `Simple_cartesian<double>`.
|
||
using Kernel = K;
|
||
/// Field type used for all scalar conformal-map data (lengths, λ, Θ, …).
|
||
using FT = typename K::FT;
|
||
/// 3-D point type used for vertex coordinates.
|
||
using Point_3 = typename K::Point_3;
|
||
/// The triangle-mesh type this specialisation targets.
|
||
using Triangle_mesh = CGAL::Surface_mesh<Point_3>;
|
||
|
||
/// Boost-graph vertex descriptor for `Triangle_mesh`.
|
||
using Vertex_descriptor = typename boost::graph_traits<Triangle_mesh>::vertex_descriptor;
|
||
/// Boost-graph half-edge descriptor for `Triangle_mesh`.
|
||
using Halfedge_descriptor = typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor;
|
||
/// Boost-graph edge descriptor for `Triangle_mesh`.
|
||
using Edge_descriptor = typename boost::graph_traits<Triangle_mesh>::edge_descriptor;
|
||
/// Boost-graph face descriptor for `Triangle_mesh`.
|
||
using Face_descriptor = typename boost::graph_traits<Triangle_mesh>::face_descriptor;
|
||
|
||
// Property-map types — match the names used by setup_euclidean_maps().
|
||
|
||
/// Property map vertex → `Point_3` (the mesh's geometric embedding).
|
||
using Vertex_point_map = typename Triangle_mesh::template Property_map<Vertex_descriptor, Point_3>;
|
||
/// Property map vertex → target cone angle Θᵥ in radians (legacy name `ev:theta`).
|
||
using Theta_pmap = typename Triangle_mesh::template Property_map<Vertex_descriptor, FT>;
|
||
/// Property map vertex → contiguous integer index (legacy name `ev:idx`).
|
||
using Vertex_index_pmap = typename Triangle_mesh::template Property_map<Vertex_descriptor, int>;
|
||
/// Property map edge → log of original edge length λ⁰ (legacy name `ee:lam0`).
|
||
using Lambda0_pmap = typename Triangle_mesh::template Property_map<Edge_descriptor, FT>;
|
||
|
||
// ─── Property-map accessors ───────────────────────────────────────────
|
||
//
|
||
// Each accessor returns a property map under its canonical legacy name.
|
||
// If no such map exists yet it is created with sensible defaults — so
|
||
// calling either `setup_euclidean_maps(m)` first or the accessor first
|
||
// is equivalent.
|
||
|
||
/// Return the built-in vertex-point map of `m` (the geometric embedding).
|
||
static Vertex_point_map vertex_points(Triangle_mesh& m) {
|
||
return m.points();
|
||
}
|
||
|
||
/// Return (or create with default 2π) the target-angle property map.
|
||
static Theta_pmap theta_map(Triangle_mesh& m) {
|
||
auto [pm, created] = m.template add_property_map<Vertex_descriptor, FT>(
|
||
"ev:theta", FT(2.0 * 3.141592653589793238));
|
||
(void)created;
|
||
return pm;
|
||
}
|
||
|
||
/// Return (or create with default −1) the vertex-index property map.
|
||
static Vertex_index_pmap vertex_index_map(Triangle_mesh& m) {
|
||
auto [pm, created] = m.template add_property_map<Vertex_descriptor, int>(
|
||
"ev:idx", -1);
|
||
(void)created;
|
||
return pm;
|
||
}
|
||
|
||
/// Return (or create with default 0) the λ⁰ (initial log-length) property map.
|
||
static Lambda0_pmap lambda0_map(Triangle_mesh& m) {
|
||
auto [pm, created] = m.template add_property_map<Edge_descriptor, FT>(
|
||
"ee:lam0", FT(0));
|
||
(void)created;
|
||
return pm;
|
||
}
|
||
};
|
||
|
||
} // namespace CGAL
|
||
|
||
#endif // CGAL_CONFORMAL_MAP_TRAITS_H
|