template<
typename T,
class MeshType = HalfEdgeMesh<T>,
class Solver = Eigen::ConjugateGradient<Eigen::SparseMatrix<T>, Eigen::Lower | Eigen::Upper>, std::enable_if_t< std::is_floating_point_v< T >,
bool > = true>
class OpenABF::HierarchicalLSCM< T, MeshType, Solver, >
Compute parameterized mesh using Hierarchical LSCM.
Implements the HLSCM algorithm from Ray & Lévy, "Hierarchical Least Squares
Conformal Map" (2003) [3]. Uses cascadic multigrid to accelerate LSCM convergence: the mesh is decimated into a hierarchy, LSCM is solved on the coarsest level, and the solution is prolongated and refined at each finer level using conjugate gradient with the prolongated UVs as initial guess.
For small meshes the hierarchy has a single level and HLSCM degrades gracefully to a standard LSCM solve.
- Template Parameters
-
| T | Floating-point type |
| MeshType | HalfEdgeMesh type which implements the default mesh traits |
| Solver | An Eigen iterative or direct solver. Iterative solvers (ConjugateGradient, LeastSquaresConjugateGradient) support warm- starting from the coarser-level solution; direct solvers ignore the initial guess. Defaults to ConjugateGradient<SparseMatrix<T>, Lower|Upper>, which solves the normal equations (AᵀA x = Aᵀb) of the overdetermined LSCM system. The Lower|Upper flag enables OpenMP-parallelized SpMV on the symmetric AᵀA matrix, giving the best multi-thread performance. LeastSquaresConjugateGradient is a valid alternative; it operates on the same normal equations internally but without the OpenMP benefit. |
- Note
- Solver default differs from AngleBasedLSCM. AngleBasedLSCM defaults to SparseLU (a direct solver); HierarchicalLSCM defaults to ConjugateGradient so it can warm-start from the coarser-level solution. Using a direct solver via the
Solver template parameter is valid but disables warm-starting — the initial guess is ignored.
-
Single-level fallback. When the mesh is too small to decimate (all vertices are boundary, or minCoarseVertices is already reached), HLSCM falls back to a standard LSCM solve using this class's
Solver template parameter, not AngleBasedLSCM's default (SparseLU). The result is numerically equivalent but may differ in convergence behavior from a plain AngleBasedLSCM call.