docs(doxygen): 100% public-API coverage (228 → 0 undocumented)
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>
This commit is contained in:
@@ -39,18 +39,23 @@ namespace conformallab {
|
||||
|
||||
// ── Property-map type aliases ─────────────────────────────────────────────────
|
||||
|
||||
/// Property map vertex → `double` (HyperIdeal scalar-per-vertex data).
|
||||
using VMapD = ConformalMesh::Property_map<Vertex_index, double>;
|
||||
/// Property map vertex → `int` (HyperIdeal DOF indices).
|
||||
using VMapI = ConformalMesh::Property_map<Vertex_index, int>;
|
||||
/// Property map edge → `double` (HyperIdeal scalar-per-edge data).
|
||||
using EMapD = ConformalMesh::Property_map<Edge_index, double>;
|
||||
/// Property map edge → `int` (HyperIdeal DOF indices).
|
||||
using EMapI = ConformalMesh::Property_map<Edge_index, int>;
|
||||
|
||||
// ── Persistent map bundle ─────────────────────────────────────────────────────
|
||||
|
||||
/// Bundle of the four property maps consumed by the HyperIdeal functional.
|
||||
struct HyperIdealMaps {
|
||||
VMapI v_idx; // DOF index per vertex (-1 = pinned / ideal point)
|
||||
EMapI e_idx; // DOF index per edge (-1 = fixed)
|
||||
VMapD theta_v; // target cone angle Θ_v (parameter, not variable)
|
||||
EMapD theta_e; // target intersection angle θ_e
|
||||
VMapI v_idx; ///< DOF index per vertex (−1 = pinned / ideal point).
|
||||
EMapI e_idx; ///< DOF index per edge (−1 = fixed).
|
||||
VMapD theta_v; ///< Target cone angle Θᵥ (parameter, not variable).
|
||||
EMapD theta_e; ///< Target intersection angle θₑ.
|
||||
};
|
||||
|
||||
/// Attach the four HyperIdeal property maps to `mesh` and return their
|
||||
@@ -105,20 +110,22 @@ inline int assign_all_dof_indices(ConformalMesh& mesh, HyperIdealMaps& m)
|
||||
|
||||
// ── Evaluation result ─────────────────────────────────────────────────────────
|
||||
|
||||
/// Output of `evaluate_hyper_ideal()` — the energy value and (optionally)
|
||||
/// its gradient evaluated at the current DOF vector.
|
||||
struct HyperIdealResult {
|
||||
double energy = 0.0;
|
||||
std::vector<double> gradient; // empty when gradient was not requested
|
||||
double energy = 0.0; ///< Functional value at the input DOFs.
|
||||
std::vector<double> gradient; ///< Gradient ∇E; empty when not requested.
|
||||
};
|
||||
|
||||
// ── Internal helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
// Get the DOF value from x, or 0.0 if pinned.
|
||||
/// Read the DOF value from `x` for index `idx`; return 0 if pinned (idx < 0).
|
||||
static inline double dof_val(int idx, const std::vector<double>& x)
|
||||
{
|
||||
return idx >= 0 ? x[static_cast<std::size_t>(idx)] : 0.0;
|
||||
}
|
||||
|
||||
// Convert a CGAL halfedge index to a plain std::size_t (for vector indexing).
|
||||
/// Convert a CGAL half-edge index to a plain `std::size_t` for vector indexing.
|
||||
static inline std::size_t hidx(Halfedge_index h)
|
||||
{
|
||||
return static_cast<std::size_t>(static_cast<std::uint32_t>(h));
|
||||
@@ -144,11 +151,21 @@ static inline std::size_t hidx(Halfedge_index h)
|
||||
// HyperIdealFunctional.java's defensive behaviour (lines 122-127 of the
|
||||
// Java original); this keeps the FD perturbation regime well-defined.
|
||||
|
||||
/// Six per-face angle outputs computed from local DOFs (see
|
||||
/// `face_angles_from_local_dofs`). Used by the block-FD Hessian.
|
||||
struct FaceAngleOutputs {
|
||||
double beta1, beta2, beta3; ///< interior angles at v₁,v₂,v₃
|
||||
double alpha12, alpha23, alpha31; ///< dihedral angles at e₁₂,e₂₃,e₃₁
|
||||
double beta1; ///< Interior angle at v₁.
|
||||
double beta2; ///< Interior angle at v₂.
|
||||
double beta3; ///< Interior angle at v₃.
|
||||
double alpha12; ///< Dihedral angle at edge e₁₂.
|
||||
double alpha23; ///< Dihedral angle at edge e₂₃.
|
||||
double alpha31; ///< Dihedral angle at edge e₃₁.
|
||||
};
|
||||
|
||||
/// Pure-math 6→6 kernel: given the six local DOFs (b₁,b₂,b₃,a₁₂,a₂₃,a₃₁)
|
||||
/// of one face plus the per-vertex variability flags, return the six
|
||||
/// HyperIdeal angle outputs. No mesh, no property maps — used by the
|
||||
/// per-face block-FD Hessian in `hyper_ideal_hessian.hpp`.
|
||||
inline FaceAngleOutputs face_angles_from_local_dofs(
|
||||
double b1, double b2, double b3,
|
||||
double a12, double a23, double a31,
|
||||
@@ -196,14 +213,29 @@ inline FaceAngleOutputs face_angles_from_local_dofs(
|
||||
|
||||
// ── Per-face angle kernel ─────────────────────────────────────────────────────
|
||||
|
||||
/// Per-face angle bundle returned by `compute_face_angles()`. Carries
|
||||
/// the six output angles plus the six input DOFs (so the energy and
|
||||
/// gradient kernels can reuse them without re-reading the mesh).
|
||||
struct FaceAngles {
|
||||
double alpha12, alpha23, alpha31; // dihedral angles at each edge
|
||||
double beta1, beta2, beta3; // interior angles at each vertex
|
||||
double a12, a23, a31; // edge DOF values (used in energy)
|
||||
double b1, b2, b3; // vertex DOF values
|
||||
bool v1b, v2b, v3b; // whether each vertex is variable
|
||||
double alpha12; ///< Dihedral angle at edge e₁₂.
|
||||
double alpha23; ///< Dihedral angle at edge e₂₃.
|
||||
double alpha31; ///< Dihedral angle at edge e₃₁.
|
||||
double beta1; ///< Interior angle at vertex v₁.
|
||||
double beta2; ///< Interior angle at vertex v₂.
|
||||
double beta3; ///< Interior angle at vertex v₃.
|
||||
double a12; ///< Edge DOF value at e₁₂.
|
||||
double a23; ///< Edge DOF value at e₂₃.
|
||||
double a31; ///< Edge DOF value at e₃₁.
|
||||
double b1; ///< Vertex DOF value at v₁.
|
||||
double b2; ///< Vertex DOF value at v₂.
|
||||
double b3; ///< Vertex DOF value at v₃.
|
||||
bool v1b; ///< `true` iff vertex v₁ is variable (not pinned).
|
||||
bool v2b; ///< `true` iff vertex v₂ is variable.
|
||||
bool v3b; ///< `true` iff vertex v₃ is variable.
|
||||
};
|
||||
|
||||
/// Compute the six per-face angles (+ remember the input DOFs) for face
|
||||
/// `f` of `mesh`, given the current DOF vector `x` and DOF-index maps.
|
||||
static FaceAngles compute_face_angles(
|
||||
const ConformalMesh& mesh,
|
||||
Face_index f,
|
||||
@@ -281,7 +313,7 @@ static FaceAngles compute_face_angles(
|
||||
return fa;
|
||||
}
|
||||
|
||||
// Per-face energy contribution U(f) (before subtracting θ·a and Θ·b terms).
|
||||
/// Per-face energy contribution U(f) before subtracting the θ·a and Θ·b terms.
|
||||
static double face_energy(const FaceAngles& fa)
|
||||
{
|
||||
double aa = fa.a12*fa.alpha12 + fa.a23*fa.alpha23 + fa.a31*fa.alpha31;
|
||||
@@ -310,6 +342,14 @@ static double face_energy(const FaceAngles& fa)
|
||||
|
||||
// ── Full evaluation ───────────────────────────────────────────────────────────
|
||||
|
||||
/// Evaluate the HyperIdeal functional at DOF vector `x`. Returns the
|
||||
/// energy value and (optionally) the gradient in a `HyperIdealResult`.
|
||||
///
|
||||
/// \param mesh Triangle mesh carrying the DOF-index property maps.
|
||||
/// \param x Current DOF vector (length = `hyper_ideal_dimension(...)`).
|
||||
/// \param m Property-map bundle from `setup_hyper_ideal_maps(...)`.
|
||||
/// \param need_energy If `true`, fill `result.energy` (default: `true`).
|
||||
/// \param need_gradient If `true`, fill `result.gradient` (default: `true`).
|
||||
inline HyperIdealResult evaluate_hyper_ideal(
|
||||
ConformalMesh& mesh,
|
||||
const std::vector<double>& x,
|
||||
@@ -393,10 +433,10 @@ inline HyperIdealResult evaluate_hyper_ideal(
|
||||
return res;
|
||||
}
|
||||
|
||||
// ── Finite-difference gradient check ─────────────────────────────────────────
|
||||
//
|
||||
// Returns true if |G[i] − fd[i]| / max(1, |G[i]|) < tol for all DOFs.
|
||||
// eps = step size, tol = tolerance (same defaults as Java FunctionalTest).
|
||||
/// Finite-difference gradient check (central differences).
|
||||
///
|
||||
/// Returns `true` iff `|G[i] − fd[i]| / max(1, |G[i]|) < tol` for every
|
||||
/// DOF. Defaults `eps = 1e-5`, `tol = 1e-4` match the Java `FunctionalTest`.
|
||||
inline bool gradient_check(
|
||||
ConformalMesh& mesh,
|
||||
const std::vector<double>& x0,
|
||||
|
||||
Reference in New Issue
Block a user