Completes the work begun in the previous commit on this branch. Every
public symbol under code/include/ now carries a brief Doxygen comment
(0 undocumented per scripts/doxygen-coverage.sh, with the `detail::`
implementation namespaces excluded as before).
Trajectory on this branch:
start (after Doxyfile fix): 24.0 % (165 / 437 in the no-detail set
was 105 / 437 when detail counted)
after PR #17 base commit : 42.4 % (165 / 396)
this commit : 100.0 % (396 / 396)
Files touched (all .hpp / .h headers under code/include/):
* cgal/Conformal_map_traits.h
* clausen.hpp, conformal_mesh.hpp, constants.hpp (already docd)
* cp_euclidean_functional.hpp, cut_graph.hpp, discrete_elliptic_utility.hpp
* euclidean_functional.hpp, euclidean_geometry.hpp, euclidean_hessian.hpp
* fundamental_domain.hpp, gauss_bonnet.hpp
* hyper_ideal_{functional,geometry,hessian,utility,visualization_utility}.hpp
* inversive_distance_functional.hpp, layout.hpp
* matrix_utility.hpp, mesh_builder.hpp, mesh_io.hpp
* newton_solver.hpp, p2_utility.hpp, period_matrix.hpp, projective_math.hpp
* serialization.hpp, spherical_functional.hpp, spherical_geometry.hpp
* spherical_hessian.hpp, viewer_utils.h
CI:
.gitea/workflows/doxygen-pages.yml now enforces
`scripts/doxygen-coverage.sh --threshold 100`, so any future regression
(a new public function landed without a `///` brief) fails the build
before the Doxygen HTML is published to Codeberg Pages.
Doxygen warnings remain at 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
185 lines
8.8 KiB
C++
185 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)
|
||
// ════════════════════════════════════════════════════════════════════════════
|
||
//
|
||
/*!
|
||
\ingroup PkgConformalMapConcepts
|
||
\brief Primary `ConformalMapTraits` template — undefined, must be
|
||
specialised per mesh type. The MVP only ships 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
|