docs(doxygen): fix critical extraction bug; baseline 24% → 42% on public API

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>
This commit is contained in:
Tarik Moussa
2026-05-23 23:44:54 +02:00
parent 8869ead3c9
commit e04515c423
13 changed files with 425 additions and 19 deletions

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2024-2026 Tarik Moussa.
// SPDX-License-Identifier: MIT
//
// This header contains only Doxygen \defgroup commands. It is included
// nowhere in the build; its sole purpose is to register the package's
// Doxygen group hierarchy so that `@ingroup Pkg...` references in the
// other public headers resolve cleanly.
#ifndef CGAL_CONFORMAL_MAP_DOXYGEN_GROUPS_H
#define CGAL_CONFORMAL_MAP_DOXYGEN_GROUPS_H
/*!
\defgroup PkgConformalMap CGAL Discrete Conformal Map package
\brief Discrete conformal maps on triangulated surfaces — five DCE models
(Euclidean, Spherical, Hyper-Ideal, Circle-Packing Euclidean,
Inversive-Distance).
This package provides the C++ implementation of the variational discrete
conformal equivalence solvers from Springborn 2020, Bobenko/Pinkall/Springborn
2010, and Luo 2004, together with a CGAL-style named-parameter API.
See `doc/api/cgal-package.md` for the full design rationale.
*/
/*!
\defgroup PkgConformalMapRef Reference manual
\ingroup PkgConformalMap
\brief Public C++ API: entry functions, traits, layout helpers.
*/
/*!
\defgroup PkgConformalMapConcepts Concepts
\ingroup PkgConformalMap
\brief C++ concepts and traits classes consumed by the entry functions.
*/
/*!
\defgroup PkgConformalMapNamedParameters Named function parameters
\ingroup PkgConformalMap
\brief Package-specific named-parameter helpers in `CGAL::parameters::*`,
plus the pipe-operator chaining convention.
*/
#endif // CGAL_CONFORMAL_MAP_DOXYGEN_GROUPS_H

View File

@@ -0,0 +1,88 @@
// Copyright (c) 2024-2026 Tarik Moussa.
// SPDX-License-Identifier: MIT
//
// Doxygen namespace documentation only — no declarations. Centralised
// here so that each namespace gets a single, consistent description in
// the generated HTML, regardless of which header is parsed first.
#ifndef CGAL_CONFORMAL_MAP_DOXYGEN_NAMESPACES_H
#define CGAL_CONFORMAL_MAP_DOXYGEN_NAMESPACES_H
/*!
\namespace CGAL
\brief Root namespace of the CGAL library; conformallab++ adds its
public entry points (`discrete_conformal_map_*`, `Conformal_map_traits`,
…) directly into this namespace, matching CGAL package conventions.
*/
/*!
\namespace CGAL::Conformal_map
\brief Implementation-detail namespace for the Discrete Conformal Map
package. Users normally do not need to enter this namespace; all
public entry points are re-exported into `CGAL::`.
*/
/*!
\namespace CGAL::Conformal_map::internal_np
\brief Tag types backing the package-local named-function parameters
(`vertex_curvature_map_t`, `gradient_tolerance_t`, `output_uv_map_t`, …).
Users invoke them via the helpers in `CGAL::parameters::*`.
*/
/*!
\namespace CGAL::parameters
\brief CGAL named-function-parameter helpers — both upstream CGAL's and
the conformallab++ package extensions (`vertex_curvature_map(...)`,
`gradient_tolerance(...)`, `output_uv_map(...)`, `normalise_layout(...)`).
Also home of the pipe-operator chaining convention; see
`doc/tutorials/add-output-uv-map.md` §3.4.
*/
/*!
\namespace conformallab
\brief Core math/algorithm namespace of conformallab++. Holds the five
DCE functionals (Euclidean / Spherical / HyperIdeal / CP-Euclidean /
Inversive-Distance), the Newton solver, layout helpers, mesh-property
typedefs, and serialisation utilities. Lives under
`code/include/*.hpp` and is consumed both by the standalone CLI and
by the thin CGAL wrappers under `CGAL::`.
*/
/*!
\namespace conformallab::detail
\brief Implementation-private helpers for the `conformallab` namespace.
Not part of the stable public API.
*/
/*!
\namespace conformallab::cp_detail
\brief Implementation-private helpers for the Circle-Packing Euclidean
functional (see `cp_euclidean_functional.hpp`).
*/
/*!
\namespace conformallab::id_detail
\brief Implementation-private helpers for the Inversive-Distance
functional (see `inversive_distance_functional.hpp`).
*/
/*!
\namespace conformallab::detail_xml
\brief Implementation-private XML helpers for the (de)serialisation
layer (see `serialization.hpp`).
*/
/*!
\namespace mesh_utils
\brief Small, opinion-free mesh utilities (loaders, validators,
property-map registration) used by both the standalone tools and the
CGAL wrappers.
*/
/*!
\namespace viewer_utils
\brief libigl-based interactive viewer helpers; built only when
`WITH_VIEWER=ON`. Not part of the headless / CGAL public surface.
*/
#endif // CGAL_CONFORMAL_MAP_DOXYGEN_NAMESPACES_H

View File

@@ -198,11 +198,8 @@ inline auto normalise_layout(bool flag)
// operator on the same type.
// ════════════════════════════════════════════════════════════════════════════
/*!
\addtogroup PkgConformalMapNamedParameters
\{
*/
// Close the PkgConformalMapNamedParameters group block that was opened
// above the helper functions (see \addtogroup at the top of this section).
/// \}
} // namespace parameters

View File

@@ -110,20 +110,33 @@ selected automatically when `TriangleMesh = CGAL::Surface_mesh<...>`.
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 ───────────────────────────────────────────
@@ -133,10 +146,12 @@ struct Default_conformal_map_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
// 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));
@@ -144,6 +159,7 @@ struct Default_conformal_map_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
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);
@@ -151,6 +167,7 @@ struct Default_conformal_map_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
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));

View File

@@ -38,26 +38,51 @@ namespace CGAL {
// ── Default traits for CP-Euclidean ───────────────────────────────────────────
/*!
\ingroup PkgConformalMapConcepts
\brief Traits class for `discrete_circle_packing_euclidean()` —
declares the kernel, mesh and property-map types used by the
BPS-2010 face-based circle-packing functional.
Primary template; specialise it for non-`Surface_mesh` triangle meshes.
*/
template <typename TriangleMesh,
typename Kernel_ = CGAL::Simple_cartesian<double>>
struct Default_cp_euclidean_traits;
/*!
\ingroup PkgConformalMapConcepts
\brief Specialisation for `CGAL::Surface_mesh<P>`; the only one shipped
in Phase 8b-Lite.
*/
template <typename K>
struct Default_cp_euclidean_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
{
/// CGAL kernel parameter (defaults to `Simple_cartesian<double>`).
using Kernel = K;
/// Scalar field type used for all CP-Euclidean DOFs (`ρ_f`, `θ_e`, `φ_f`).
using FT = typename K::FT;
/// 3-D point type (vertex coordinates).
using Point_3 = typename K::Point_3;
/// 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;
// CP-Euclidean property maps — note the *face* DOF index map.
/// Property map face → contiguous integer DOF index (legacy `cf:idx`).
using Face_index_pmap = typename Triangle_mesh::template Property_map<Face_descriptor, int>;
/// Property map edge → intersection angle θₑ (legacy `ce:theta`).
using Theta_e_pmap = typename Triangle_mesh::template Property_map<Edge_descriptor, FT>;
/// Property map face → target angle sum φ_f (legacy `cf:phi`).
using Phi_f_pmap = typename Triangle_mesh::template Property_map<Face_descriptor, FT>;
};
@@ -75,8 +100,11 @@ struct Circle_packing_result
/// Face DOFs `ρ_f = log R_f` (length = num_faces(mesh); pinned face = 0).
std::vector<FT> rho_per_face;
/// Newton iterations actually performed (≤ `max_iterations`).
int iterations = 0;
/// Final infinity-norm of the gradient (Newton stopping criterion).
FT gradient_norm = FT(0);
/// `true` iff `gradient_norm < gradient_tolerance` at exit.
bool converged = false;
};

View File

@@ -449,8 +449,11 @@ struct Hyper_ideal_map_result
/// Edge DOFs `a_e` (length = num_edges(mesh); pinned edges = 0).
std::vector<FT> a_per_edge;
/// Newton iterations actually performed (≤ `max_iterations`).
int iterations = 0;
/// Final infinity-norm of the gradient (Newton stopping criterion).
FT gradient_norm = FT(0);
/// `true` iff `gradient_norm < gradient_tolerance` at exit.
bool converged = false;
};

View File

@@ -47,25 +47,49 @@ namespace CGAL {
// ── Default traits for Inversive-Distance ────────────────────────────────────
/*!
\ingroup PkgConformalMapConcepts
\brief Traits class for `discrete_inversive_distance_map()` — declares
the kernel, mesh and property-map types used by Luo's 2004 vertex-based
inversive-distance circle packing.
Primary template; specialise it for non-`Surface_mesh` triangle meshes.
*/
template <typename TriangleMesh,
typename Kernel_ = CGAL::Simple_cartesian<double>>
struct Default_inversive_distance_traits;
/*!
\ingroup PkgConformalMapConcepts
\brief Specialisation for `CGAL::Surface_mesh<P>`; the only one shipped
in Phase 8b-Lite.
*/
template <typename K>
struct Default_inversive_distance_traits<CGAL::Surface_mesh<typename K::Point_3>, K>
{
/// CGAL kernel parameter (defaults to `Simple_cartesian<double>`).
using Kernel = K;
/// Scalar field type used for all inversive-distance DOFs.
using FT = typename K::FT;
/// 3-D point type (vertex coordinates).
using Point_3 = typename K::Point_3;
/// 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 edge descriptor for `Triangle_mesh`.
using Edge_descriptor = typename boost::graph_traits<Triangle_mesh>::edge_descriptor;
// Inversive-distance specific property maps.
/// Property map vertex → contiguous integer DOF index (legacy `iv:idx`).
using Vertex_index_pmap = typename Triangle_mesh::template Property_map<Vertex_descriptor, int>;
/// Property map vertex → target cone angle Θᵥ in radians (legacy `iv:theta`).
using Theta_v_pmap = typename Triangle_mesh::template Property_map<Vertex_descriptor, FT>;
/// Property map vertex → initial radius r⁰ᵥ (legacy `iv:r0`).
using R0_pmap = typename Triangle_mesh::template Property_map<Vertex_descriptor, FT>;
/// Property map edge → inversive distance Iᵢⱼ (legacy `ie:I`).
using I_e_pmap = typename Triangle_mesh::template Property_map<Edge_descriptor, FT>;
};