Initial Codeberg Pages publish: Doxygen HTML for v0.9.x main
This commit is contained in:
541
md__c_l_a_u_d_e.html
Normal file
541
md__c_l_a_u_d_e.html
Normal file
@@ -0,0 +1,541 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
||||
<meta name="generator" content="Doxygen 1.17.0"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>conformallab++: CLAUDE.md</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<script type="text/javascript" src="codefolding.js"></script>
|
||||
<script type="text/javascript" src="clipboard.js"></script>
|
||||
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="navtreedata.js"></script>
|
||||
<script type="text/javascript" src="navtree.js"></script>
|
||||
<script type="text/javascript" src="cookie.js"></script>
|
||||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||
<script type="text/javascript" src="search/search.js"></script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
const theme = 'default';
|
||||
mermaid.initialize({ startOnLoad: true, theme: theme });
|
||||
</script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr id="projectrow">
|
||||
<td id="projectalign">
|
||||
<div id="projectname">conformallab++<span id="projectnumber"> 0.7.0</span>
|
||||
</div>
|
||||
<div id="projectbrief">Discrete conformal maps on triangle meshes — C++17 reimplementation of ConformalLab (TU Berlin)</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.17.0 -->
|
||||
<script type="text/javascript">
|
||||
let searchBox = new SearchBox("searchBox", "search/",'.html');
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', codefold.init);
|
||||
</script>
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initMenu('',true);
|
||||
init_search();
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav-mobile">
|
||||
<div class="sm sm-dox"><input id="main-menu-state" type="checkbox"/>
|
||||
<label class="main-menu-btn" for="main-menu-state">
|
||||
<span class="main-menu-btn-icon"></span> Toggle main menu visibility</label>
|
||||
<span id="searchBoxPos1" style="position:absolute;right:8px;top:8px;height:36px;"></span>
|
||||
</div>
|
||||
</div><!-- main-nav-mobile -->
|
||||
<div id="main-nav">
|
||||
<ul class="sm sm-dox" id="main-menu">
|
||||
<li id="searchBoxPos2" style="float:right">
|
||||
<div id="MSearchBox" class="MSearchBoxInactive">
|
||||
<span class="left">
|
||||
<span id="MSearchSelect" class="search-icon" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()"><span class="search-icon-dropdown"></span></span>
|
||||
<input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
|
||||
onfocus="searchBox.OnSearchFieldFocus(true)"
|
||||
onblur="searchBox.OnSearchFieldFocus(false)"
|
||||
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
||||
</span><span class="right">
|
||||
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><div id="MSearchCloseImg" class="close-icon"></div></a>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- main-nav -->
|
||||
</div><!-- top -->
|
||||
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||||
<div id="nav-tree">
|
||||
<div id="nav-tree-contents">
|
||||
<div id="nav-sync" class="sync"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="splitbar" style="-moz-user-select:none;"
|
||||
class="ui-resizable-handle">
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded',() => { initNavTree('md__c_l_a_u_d_e.html','',''); });
|
||||
</script>
|
||||
<div id="container">
|
||||
<div id="doc-content">
|
||||
<!-- window showing the filter options -->
|
||||
<div id="MSearchSelectWindow"
|
||||
onmouseover="return searchBox.OnSearchSelectShow()"
|
||||
onmouseout="return searchBox.OnSearchSelectHide()"
|
||||
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||||
</div>
|
||||
|
||||
<!-- iframe showing the search results (closed by default) -->
|
||||
<div id="MSearchResultsWindow">
|
||||
<div id="MSearchResults">
|
||||
<div class="SRPage">
|
||||
<div id="SRIndex">
|
||||
<div id="SRResults"></div>
|
||||
<div class="SRStatus" id="Loading">Loading...</div>
|
||||
<div class="SRStatus" id="Searching">Searching...</div>
|
||||
<div class="SRStatus" id="NoMatches">No Matches</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div><div class="header">
|
||||
<div class="headertitle"><div class="title">CLAUDE.md </div></div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock"><p><a class="anchor" id="autotoc_md13"></a></p>
|
||||
<p>This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md14"></a>
|
||||
Project purpose and long-term goal</h1>
|
||||
<p>conformallab++ is a C++17 reimplementation of <a href="https://github.com/varylab/conformallab">ConformalLab</a> — Stefan Sechelmann's Java research library for discrete conformal geometry (TU Berlin, ~850 commits, v1.0.0 2018). The algorithmic foundation is his dissertation:</p>
|
||||
<blockquote class="doxtable">
|
||||
<p>Stefan Sechelmann — <em>Variational Methods for Discrete Surface Parameterization: Applications and Implementation</em>, TU Berlin 2016. DOI: <a href="https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f">10.14279/depositonce-5415</a> · CC BY-SA 4.0 </p>
|
||||
</blockquote>
|
||||
<p><b>The long-term goal is a CGAL package</b> — a submission to the CGAL library that brings discrete conformal maps (hyper-ideal, spherical, Euclidean) to the CGAL ecosystem using <span class="tt">CGAL::Surface_mesh</span> as the underlying halfedge data structure, with a traits-class design compatible with arbitrary CGAL-conforming mesh types.</p>
|
||||
<p>The project has four distinct phase blocks (updated 2026-05-22):</p><ul>
|
||||
<li><b>Phase 1–7 (done, v0.7.0):</b> Direct port of the Java library algorithms to C++.</li>
|
||||
<li><b>Phase 8a MVP + 8b-Lite (done, v0.9.0):</b> CGAL public-API surface for all five DCE models via <span class="tt"><CGAL/Discrete_*.h></span>. Phase 8a.2 (generic FaceGraph), 8c (manuals), 8d (CGAL-test-format), 8e (YAML pipeline) deferred on-demand.</li>
|
||||
<li><b>Phase 9a + 9b (done, v0.9.0):</b> Two new functionals (CP-Euclidean port, Inversive-Distance research), two new Newton solvers, block-FD HyperIdeal Hessian.</li>
|
||||
<li><b>Phase 9b-analytic + 9c (planned):</b> Full analytic HyperIdeal Hessian via Schläfli identity (research, see <span class="tt">doc/roadmap/research-track.md</span>); 4g-polygon fundamental domain for genus g > 1 (mixed port + research).</li>
|
||||
<li><b>Phase 10+ (research):</b> Holomorphic differentials, Siegel period matrix Ω ∈ H_g, full uniformization for genus g ≥ 2.</li>
|
||||
</ul>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md15"></a>
|
||||
Language</h1>
|
||||
<p><b>All code, comments, documentation, commit messages, and test descriptions must be in English.</b> The project is intended for international collaboration and CGAL submission. Existing German-language comments in older files should be replaced with English when editing those files.</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md16"></a>
|
||||
Build commands</h1>
|
||||
<p>All source lives under <span class="tt">code/</span>. Three build modes:</p>
|
||||
<div class="fragment"><div class="line"># Mode 1 — fast tests, no CGAL, no Boost, no display (CI default)</div>
|
||||
<div class="line">cmake -S code -B build</div>
|
||||
<div class="line">cmake --build build --target conformallab_tests -j$(nproc)</div>
|
||||
<div class="line">ctest --test-dir build --output-on-failure</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"># Mode 2 — CGAL tests, headless (CI full, requires Boost headers only)</div>
|
||||
<div class="line"># macOS: brew install boost Linux: apt install libboost-dev</div>
|
||||
<div class="line">cmake -S code -B build -DWITH_CGAL_TESTS=ON</div>
|
||||
<div class="line">cmake --build build --target conformallab_cgal_tests -j$(nproc)</div>
|
||||
<div class="line">ctest --test-dir build -R "^cgal\." --output-on-failure</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"># Mode 3 — full local build: CLI app + viewer + examples (requires Wayland/X11)</div>
|
||||
<div class="line">cmake -S code -B build -DWITH_CGAL=ON</div>
|
||||
<div class="line">cmake --build build -j$(nproc)</div>
|
||||
</div><!-- fragment --><p><span class="tt">-DWITH_CGAL=ON</span> automatically enables <span class="tt">-DWITH_VIEWER=ON</span>, which pulls in GLFW and requires <span class="tt">wayland-scanner</span>. Never use this in headless CI.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md17"></a>
|
||||
Running a single test</h2>
|
||||
<div class="fragment"><div class="line"># By GTest suite/test name</div>
|
||||
<div class="line">./build/conformallab_cgal_tests --gtest_filter="NewtonSolver*"</div>
|
||||
<div class="line">./build/conformallab_tests --gtest_filter="Clausen*"</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"># By CTest regex (prefix "cgal." for all CGAL tests)</div>
|
||||
<div class="line">ctest --test-dir build -R "cgal.NewtonSolver" --output-on-failure</div>
|
||||
</div><!-- fragment --><h2 class="doxsection"><a class="anchor" id="autotoc_md18"></a>
|
||||
Rebuilding the CI Docker image</h2>
|
||||
<div class="fragment"><div class="line">docker buildx build \</div>
|
||||
<div class="line"> --platform linux/arm64 \</div>
|
||||
<div class="line"> -f .gitea/docker/Dockerfile.ci-cpp \</div>
|
||||
<div class="line"> -t git.eulernest.eu/conformallab/ci-cpp:latest \</div>
|
||||
<div class="line"> --push \</div>
|
||||
<div class="line"> .gitea/docker/</div>
|
||||
</div><!-- fragment --><h1 class="doxsection"><a class="anchor" id="autotoc_md19"></a>
|
||||
Architecture</h1>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md20"></a>
|
||||
Everything is header-only</h2>
|
||||
<p>All algorithms live in <span class="tt">code/include/*.hpp</span>. There is no compiled library. The three CMake targets (<span class="tt">conformallab_tests</span>, <span class="tt">conformallab_cgal_tests</span>, <span class="tt">conformallab_core</span>) compile headers directly from their <span class="tt">.cpp</span> entry points. To add a new algorithm: create a <span class="tt">.hpp</span> in <span class="tt">code/include/</span>, add a test in <span class="tt">code/tests/cgal/</span>, and register the test file in <span class="tt">code/tests/cgal/CMakeLists.txt</span>.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md21"></a>
|
||||
Central type: <span class="tt">ConformalMesh</span></h2>
|
||||
<p><span class="tt">conformal_mesh.hpp</span> defines the core type: </p><div class="fragment"><div class="line"><span class="keyword">using </span>ConformalMesh = CGAL::Surface_mesh<Point3>; <span class="comment">// CGAL::Simple_cartesian<double></span></div>
|
||||
</div><!-- fragment --><p>This replaces the Java <span class="tt">CoHDS</span> (half-edge data structure) and its intrusive <span class="tt">CoVertex</span>/<span class="tt">CoEdge</span>/<span class="tt">CoFace</span> types. Data is attached via named CGAL property maps instead of intrusive fields:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Property map name </th><th class="markdownTableHeadNone">Type </th><th class="markdownTableHeadNone">Meaning </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">"v:lambda"</span> </td><td class="markdownTableBodyNone"><span class="tt">double</span> per vertex </td><td class="markdownTableBodyNone">log scale factor (conformal variable uᵢ) </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">"v:theta"</span> </td><td class="markdownTableBodyNone"><span class="tt">double</span> per vertex </td><td class="markdownTableBodyNone">target cone angle Θᵥ </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">"v:idx"</span> </td><td class="markdownTableBodyNone"><span class="tt">int</span> per vertex </td><td class="markdownTableBodyNone">solver DOF index; <span class="tt">-1</span> = pinned/boundary </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">"e:alpha"</span> </td><td class="markdownTableBodyNone"><span class="tt">double</span> per edge </td><td class="markdownTableBodyNone">intersection angle αᵢⱼ (hyperbolic only) </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">"f:type"</span> </td><td class="markdownTableBodyNone"><span class="tt">int</span> per face </td><td class="markdownTableBodyNone">geometry type (0=Euclidean, 1=Hyperbolic, 2=Spherical) </td></tr>
|
||||
</table>
|
||||
<p><span class="tt">CGAL_DISABLE_GMP</span> and <span class="tt">CGAL_DISABLE_MPFR</span> are defined for all CGAL targets — the library deliberately uses <span class="tt">Simple_cartesian<double></span> (floating-point, no exact arithmetic) because conformal geometry does not require exact predicates.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md22"></a>
|
||||
The five DCE models</h2>
|
||||
<p>Each model has its own Maps struct that bundles all property maps, plus a functional, optional Hessian, Newton solver, and (since v0.9.0) a CGAL public-API entry function:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Model </th><th class="markdownTableHeadNone">Space </th><th class="markdownTableHeadNone">DOFs </th><th class="markdownTableHeadNone">Maps struct </th><th class="markdownTableHeadNone">Key headers </th><th class="markdownTableHeadNone">Newton function </th><th class="markdownTableHeadNone">CGAL entry </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Euclidean </td><td class="markdownTableBodyNone">ℝ² </td><td class="markdownTableBodyNone">vertex </td><td class="markdownTableBodyNone"><span class="tt">EuclideanMaps</span> </td><td class="markdownTableBodyNone"><span class="tt">euclidean_functional.hpp</span>, <span class="tt">euclidean_hessian.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">newton_euclidean()</span> </td><td class="markdownTableBodyNone"><span class="tt">discrete_conformal_map_euclidean()</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Spherical </td><td class="markdownTableBodyNone">S² </td><td class="markdownTableBodyNone">vertex </td><td class="markdownTableBodyNone"><span class="tt">SphericalMaps</span> </td><td class="markdownTableBodyNone"><span class="tt">spherical_functional.hpp</span>, <span class="tt">spherical_hessian.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">newton_spherical()</span> </td><td class="markdownTableBodyNone"><span class="tt">discrete_conformal_map_spherical()</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Hyper-ideal </td><td class="markdownTableBodyNone">H² (Poincaré disk) </td><td class="markdownTableBodyNone">vertex + edge </td><td class="markdownTableBodyNone"><span class="tt">HyperIdealMaps</span> </td><td class="markdownTableBodyNone"><span class="tt">hyper_ideal_functional.hpp</span>, <span class="tt">hyper_ideal_hessian.hpp</span> (block-FD, Phase 9b) </td><td class="markdownTableBodyNone"><span class="tt">newton_hyper_ideal()</span> </td><td class="markdownTableBodyNone"><span class="tt">discrete_conformal_map_hyper_ideal()</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">CP-Euclidean (BPS 2010) </td><td class="markdownTableBodyNone">face-based circle packing </td><td class="markdownTableBodyNone"><b>face</b> </td><td class="markdownTableBodyNone"><span class="tt">CPEuclideanMaps</span> </td><td class="markdownTableBodyNone"><span class="tt">cp_euclidean_functional.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">newton_cp_euclidean()</span> </td><td class="markdownTableBodyNone"><span class="tt">discrete_circle_packing_euclidean()</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Inversive-Distance (Luo 2004) </td><td class="markdownTableBodyNone">vertex-based circle packing </td><td class="markdownTableBodyNone">vertex </td><td class="markdownTableBodyNone"><span class="tt">InversiveDistanceMaps</span> </td><td class="markdownTableBodyNone"><span class="tt">inversive_distance_functional.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">newton_inversive_distance()</span> </td><td class="markdownTableBodyNone"><span class="tt">discrete_inversive_distance_map()</span> </td></tr>
|
||||
</table>
|
||||
<p>DOF-assignment patterns:</p><ul>
|
||||
<li><b>Vertex-only models</b> (Euclidean, Spherical, Inversive-Distance): pin one vertex manually (<span class="tt">maps.v_idx[first_vertex] = -1</span>) then assign sequential indices. The CGAL public entries do this automatically with the "natural-theta" trick (so calling them with no arguments returns x = 0 as the equilibrium).</li>
|
||||
<li><b>HyperIdeal</b>: <span class="tt">assign_all_dof_indices(mesh, maps)</span> assigns vertex + edge DOFs automatically.</li>
|
||||
<li><b>CP-Euclidean</b>: face-based — <span class="tt">assign_cp_euclidean_face_dof_indices(mesh, maps, pinned_face)</span> pins one face and indexes the rest.</li>
|
||||
</ul>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md23"></a>
|
||||
The full pipeline</h2>
|
||||
<div class="fragment"><div class="line">load_mesh() → ConformalMesh (OFF/OBJ/PLY)</div>
|
||||
<div class="line">setup_*_maps(mesh) → *Maps (property maps created, all zero)</div>
|
||||
<div class="line">compute_*_lambda0_from_mesh(mesh, m) → λ° initialised from 3-D edge lengths</div>
|
||||
<div class="line">DOF assignment → v_idx[v] set; -1 = pinned</div>
|
||||
<div class="line">check_gauss_bonnet(mesh, maps) → throws if Σ(2π−Θᵥ) ≠ 2π·χ(M)</div>
|
||||
<div class="line">enforce_gauss_bonnet(mesh, maps) → redistributes angle defect uniformly</div>
|
||||
<div class="line">newton_*(mesh, x0, maps) → NewtonResult{x*, iterations, converged}</div>
|
||||
<div class="line">compute_cut_graph(mesh) → CutGraph (2g seam edges, tree-cotree)</div>
|
||||
<div class="line">*_layout(mesh, x*, maps, &cg, &hol) → Layout2D/3D + HolonomyData</div>
|
||||
<div class="line">normalise_*(layout) → canonical position (PCA / Möbius / Rodrigues)</div>
|
||||
<div class="line">compute_period_matrix(hol) → PeriodData{τ∈ℍ} (genus 1 flat torus)</div>
|
||||
<div class="line">compute_fundamental_domain(hol) → FundamentalDomain{vertices, generators}</div>
|
||||
<div class="line">tiling_neighbourhood(layout, hol) → vector of translated layout copies</div>
|
||||
<div class="line">save_result_json/xml() → serialised result</div>
|
||||
</div><!-- fragment --><p>After <span class="tt">compute_*_lambda0_from_mesh()</span> the original vertex positions are no longer used — all subsequent computation is in log-length/scale-factor space.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md24"></a>
|
||||
Newton solver (<span class="tt">newton_solver.hpp</span>)</h2>
|
||||
<p>Gradient sign convention differs across the five models:</p><ul>
|
||||
<li><b>Euclidean / Spherical / Inversive-Distance:</b> <span class="tt">G_v = Θ_v − actual_angle_sum</span> (target minus actual).</li>
|
||||
<li><b>HyperIdeal:</b> <span class="tt">G_v = actual_angle_sum − Θ_v</span> (actual minus target).</li>
|
||||
<li><b>CP-Euclidean:</b> <span class="tt">G_f = φ_f − Σ_{h:face(h)=f} (p(θ*,Δρ) + θ*)</span> (face-based; see <span class="tt">cp_euclidean_functional.hpp</span> header for the full formula).</li>
|
||||
</ul>
|
||||
<p>Hessian sign and solver per model:</p><ul>
|
||||
<li><b>Euclidean:</b> H is PSD (cotangent Laplacian) → <span class="tt">SimplicialLDLT(H)</span>.</li>
|
||||
<li><b>Spherical:</b> H is NSD (concave energy) → <span class="tt">SimplicialLDLT(−H)</span> (sign flip inside <span class="tt">newton_spherical</span>).</li>
|
||||
<li><b>HyperIdeal:</b> H is PSD (strictly convex) → <span class="tt">SimplicialLDLT(H)</span>. Phase 9b uses a <b>block-FD Hessian</b> (per-face 6×6 local block, ~96× speed-up vs full FD on V=200). Full analytic Hessian via the chain <span class="tt">(bᵢ, aₑ) → lᵢⱼ → ζ₁₃/ζ₁₄/ζ₁₅ → αᵢⱼ/βᵢ</span> is planned research — see <span class="tt">doc/roadmap/research-track.md</span> Phase 9b-analytic.</li>
|
||||
<li><b>CP-Euclidean:</b> analytic 2×2-per-edge <span class="tt">h_jk = sin θ / (cosh Δρ − cos θ)</span> (BPS 2010), strictly convex → <span class="tt">SimplicialLDLT(H)</span>.</li>
|
||||
<li><b>Inversive-Distance:</b> FD Hessian (inline in <span class="tt">newton_inversive_distance</span>). Analytic via Glickenstein 2011 eq. (4.6) is planned research (Phase 9a.2-analytic).</li>
|
||||
</ul>
|
||||
<p>When <span class="tt">SimplicialLDLT</span> fails (rank-deficient H — gauge mode on a closed mesh without pinned vertex/face), the solver automatically retries with <span class="tt">Eigen::SparseQR</span> to find the minimum-norm step orthogonal to the null space. Public API: <span class="tt">solve_linear_system(H, rhs, &used_fallback)</span>.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md25"></a>
|
||||
Layout and holonomy (<span class="tt">layout.hpp</span>)</h2>
|
||||
<p>BFS-trilateration with a <b>priority min-heap on BFS depth</b> (<span class="tt">depth = max(depth[src], depth[tgt]) + 1</span>). Root face = largest 3-D area face. This minimises trilateration error accumulation compared to simple BFS.</p>
|
||||
<p>Key output fields:</p><ul>
|
||||
<li><span class="tt">layout.uv[v.idx()]</span> — primary UV (first/shallowest BFS visit per vertex)</li>
|
||||
<li><span class="tt">layout.halfedge_uv[h.idx()]</span> — UV of <span class="tt">source(h)</span> as seen from <span class="tt">face(h)</span>; at seam halfedges the two opposite halfedges carry <em>different</em> UV values, enabling proper GPU texture atlasing without vertex duplication</li>
|
||||
<li><span class="tt">hol.translations[i]</span> — lattice generator ωᵢ ∈ ℂ (Euclidean/spherical)</li>
|
||||
<li><span class="tt">hol.mobius_maps[i]</span> — Möbius isometry Tᵢ ∈ SU(1,1) (hyperbolic, Poincaré disk)</li>
|
||||
</ul>
|
||||
<p><span class="tt">MobiusMap</span> is defined in <span class="tt">layout.hpp</span>: T(z) = (az+b)/(cz+d). Key methods: <span class="tt">from_three()</span> (fit to 3 point correspondences via 3×3 complex linear system), <span class="tt">compose()</span>, <span class="tt">inverse()</span>, <span class="tt">apply(Vector2d)</span>.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md26"></a>
|
||||
Key mathematical reference for each header</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Header </th><th class="markdownTableHeadNone">Java original </th><th class="markdownTableHeadNone">Key reference </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">hyper_ideal_geometry.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">HyperIdealGeometry.java</span> </td><td class="markdownTableBodyNone">Springborn (2020) — ζ₁₃/ζ₁₄/ζ₁₅ functions </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">euclidean_hessian.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">EuclideanHessian.java</span> </td><td class="markdownTableBodyNone">Pinkall & Polthier (1993) — cotangent Laplacian </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">spherical_hessian.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">SphericalHessian.java</span> </td><td class="markdownTableBodyNone">∂α/∂u from spherical law of cosines </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">cut_graph.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">CuttingUtility.java</span> </td><td class="markdownTableBodyNone">Erickson & Whittlesey (SODA 2005) — tree-cotree </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">period_matrix.hpp</span> </td><td class="markdownTableBodyNone"><span class="tt">PeriodMatrixUtility.java</span> </td><td class="markdownTableBodyNone">Sechelmann (2016) §4 — SL(2,ℤ) reduction </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">gauss_bonnet.hpp</span> </td><td class="markdownTableBodyNone">(distributed across Java) </td><td class="markdownTableBodyNone">Gauss–Bonnet: Σ(2π−Θᵥ) = 2π·χ(M) </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md27"></a>
|
||||
Java features not yet ported (Phase 9)</h2>
|
||||
<p>The Java library under <span class="tt">de.varylab.discreteconformal</span> contains these items not yet in C++:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Java class </th><th class="markdownTableHeadNone">Planned C++ header </th><th class="markdownTableHeadNone">Phase </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">InversiveDistanceFunctional</span> </td><td class="markdownTableBodyNone"><span class="tt">inversive_distance_functional.hpp</span> </td><td class="markdownTableBodyNone">9a </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Analytic HyperIdeal Hessian </td><td class="markdownTableBodyNone"><span class="tt">hyper_ideal_hessian.hpp</span> (replace FD) </td><td class="markdownTableBodyNone">9b </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">4g-polygon boundary walk in <span class="tt">FundamentalDomainUtility</span> </td><td class="markdownTableBodyNone"><span class="tt">fundamental_domain.hpp</span> (extend) </td><td class="markdownTableBodyNone">9c </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">DiscreteHarmonicFormUtility</span> </td><td class="markdownTableBodyNone">Phase 10a prerequisite </td><td class="markdownTableBodyNone">10 </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">DiscreteHolomorphicFormUtility</span> </td><td class="markdownTableBodyNone">Phase 10a </td><td class="markdownTableBodyNone">10 </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">HomologyUtility</span>, <span class="tt">CanonicalBasisUtility</span> </td><td class="markdownTableBodyNone">Phase 10 </td><td class="markdownTableBodyNone">10 </td></tr>
|
||||
</table>
|
||||
<p>When porting a Java class, locate the original in <span class="tt">de.varylab.discreteconformal.*</span> at <a href="https://github.com/varylab/conformallab">github.com/varylab/conformallab</a> and use it as the reference implementation.</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md28"></a>
|
||||
Test design patterns</h1>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md29"></a>
|
||||
"Natural theta" — constructing a known equilibrium at x* = 0</h2>
|
||||
<div class="fragment"><div class="line"><span class="comment">// Evaluate gradient at x=0; set target angles = actual angle sums → x*=0 by definition</span></div>
|
||||
<div class="line">std::vector<double> x0(n_dofs, 0.0);</div>
|
||||
<div class="line"><span class="keyword">auto</span> G0 = euclidean_gradient(mesh, x0, maps);</div>
|
||||
<div class="line"><span class="keywordflow">for</span> (<span class="keyword">auto</span> v : mesh.vertices())</div>
|
||||
<div class="line"> <span class="keywordflow">if</span> (maps.v_idx[v] >= 0)</div>
|
||||
<div class="line"> maps.theta_v[v] -= G0[maps.v_idx[v]]; <span class="comment">// shift so G(x=0) = 0</span></div>
|
||||
</div><!-- fragment --><p>This is used in virtually every Newton convergence test — it avoids hardcoding specific angle values.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md30"></a>
|
||||
Gradient check pattern</h2>
|
||||
<div class="fragment"><div class="line"><span class="comment">// Copy from any test_*_functional.cpp — GradientCheck_* test suite</span></div>
|
||||
<div class="line"><span class="keywordtype">double</span> eps = 1e-5;</div>
|
||||
<div class="line"><span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < n; ++i) {</div>
|
||||
<div class="line"> xp[i] += eps; <span class="keyword">auto</span> Gp = euclidean_gradient(mesh, xp, maps);</div>
|
||||
<div class="line"> xm[i] -= eps; <span class="keyword">auto</span> Gm = euclidean_gradient(mesh, xm, maps);</div>
|
||||
<div class="line"> <span class="keywordtype">double</span> fd = (energy(xp) - energy(xm)) / (2*eps);</div>
|
||||
<div class="line"> EXPECT_NEAR(G[i], fd, 1e-7);</div>
|
||||
<div class="line"> xp[i] = xm[i] = x0[i];</div>
|
||||
<div class="line">}</div>
|
||||
</div><!-- fragment --><p>All new functionals must have a gradient-check test before being considered complete.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md31"></a>
|
||||
Halfedge traversal</h2>
|
||||
<div class="fragment"><div class="line"><span class="keywordflow">for</span> (<span class="keyword">auto</span> f : mesh.faces()) {</div>
|
||||
<div class="line"> <span class="keyword">auto</span> h0 = mesh.halfedge(f); <span class="comment">// canonical halfedge of face</span></div>
|
||||
<div class="line"> <span class="keyword">auto</span> h1 = mesh.next(h0);</div>
|
||||
<div class="line"> <span class="keyword">auto</span> h2 = mesh.next(h1);</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"> Vertex_index v1 = mesh.source(h0); <span class="comment">// = mesh.target(h2)</span></div>
|
||||
<div class="line"> Vertex_index v2 = mesh.source(h1);</div>
|
||||
<div class="line"> Vertex_index v3 = mesh.source(h2);</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"> <span class="comment">// Angle at v3 is opposite to h0 (edge v1–v2)</span></div>
|
||||
<div class="line"> <span class="comment">// h_alpha[h0] = α₃, h_alpha[h1] = α₁, h_alpha[h2] = α₂</span></div>
|
||||
<div class="line"> </div>
|
||||
<div class="line"> <span class="keywordtype">bool</span> is_boundary = mesh.is_border(mesh.opposite(h0));</div>
|
||||
<div class="line">}</div>
|
||||
</div><!-- fragment --><h2 class="doxsection"><a class="anchor" id="autotoc_md32"></a>
|
||||
Attaching custom data to the mesh</h2>
|
||||
<div class="fragment"><div class="line"><span class="keyword">auto</span> [my_map, created] = mesh.add_property_map<Vertex_index, <span class="keywordtype">double</span>>(<span class="stringliteral">"v:my_data"</span>, 0.0);</div>
|
||||
<div class="line">my_map[v] = 3.14;</div>
|
||||
</div><!-- fragment --><h1 class="doxsection"><a class="anchor" id="autotoc_md33"></a>
|
||||
CI pipeline</h1>
|
||||
<p>Two jobs in <span class="tt">.gitea/workflows/cpp-tests.yml</span>:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Job </th><th class="markdownTableHeadNone">CMake flags </th><th class="markdownTableHeadNone">Deps </th><th class="markdownTableHeadNone">Triggers on </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">test-fast</span> </td><td class="markdownTableBodyNone"><em>(none)</em> </td><td class="markdownTableBodyNone">Eigen + GTest only </td><td class="markdownTableBodyNone">all branches </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><span class="tt">test-cgal</span> </td><td class="markdownTableBodyNone"><span class="tt">-DWITH_CGAL_TESTS=ON</span> </td><td class="markdownTableBodyNone">+ Boost </td><td class="markdownTableBodyNone">pull requests only </td></tr>
|
||||
</table>
|
||||
<p>Runner: <span class="tt">eulernest</span> — self-hosted Raspberry Pi, ARM64, Ubuntu 22.04. Docker image: <span class="tt">git.eulernest.eu/conformallab/ci-cpp:latest</span>. <span class="tt">test-cgal</span> needs <span class="tt">test-fast</span> to pass first (<span class="tt">needs: test-fast</span>).</p>
|
||||
<p>Expected results: full test suite passing, 0 skipped, 0 failed. The canonical counts live in <span class="tt">doc/api/tests.md</span> — do not hardcode them anywhere else (see <a href="doc/release-policy.md"><span class="tt">doc/release-policy.md</span></a>).</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md34"></a>
|
||||
Release state</h1>
|
||||
<p>Current release: <b>v0.9.0</b> (tag on <span class="tt">main</span>, released 2026-05-22). Phases 1–9a complete, Phase 8b-Lite CGAL API surface complete (all 5 DCE models reachable via <span class="tt"><CGAL/Discrete_*.h></span>), Phase 9b block-FD HyperIdeal Hessian shipped (~96× speed-up). Next planned milestones: Phase 9c (4g-polygon, genus g > 1) and Phase 9b-analytic (Schläfli identity). See <span class="tt">doc/release-policy.md</span> for the version-tag policy and <span class="tt">doc/roadmap/phases.md</span> for the phase plan.</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md35"></a>
|
||||
Phase 8 strategic decisions (2026-05-19)</h1>
|
||||
<p>The CGAL-package architecture was frozen on 2026-05-19. Full design: <a href="doc/api/cgal-package.md"><span class="tt">doc/api/cgal-package.md</span></a>. Key decisions:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Decision </th><th class="markdownTableHeadNone">Choice </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Submission to upstream CGAL </td><td class="markdownTableBodyNone"><b>Pre-submission-ready, not bound.</b> 12+ months horizon. </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">License </td><td class="markdownTableBodyNone"><b>MIT preserved</b> (no LGPL switch). </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Mesh-type flexibility </td><td class="markdownTableBodyNone"><b>Generic <span class="tt">FaceGraph + HalfedgeGraph</span></b> in target design; MVP starts Surface_mesh-only. </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Parameter style </td><td class="markdownTableBodyNone"><b>Named Parameters</b> (<span class="tt">CGAL::parameters::...</span>). </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Default kernel </td><td class="markdownTableBodyNone"><b><span class="tt">Simple_cartesian<double></span></b> (status quo). </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Backward compatibility </td><td class="markdownTableBodyNone"><b>Dual-layer wrapper</b> — <span class="tt">code/include/*.hpp</span> stays as implementation, <span class="tt">include/CGAL/*.h</span> is thin wrapper. No algorithm duplication. </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Implementation strategy </td><td class="markdownTableBodyNone"><b>Hybrid MVP</b> — minimum Phase 8 (traits + one wrapper) first, then Phase 9 in full, then Phase 8 extensions only on concrete demand. </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Phase-8 MVP acceptance test </td><td class="markdownTableBodyNone"><b>Phase 9a (Inversive-Distance)</b> as the first new client of the new traits API. </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md36"></a>
|
||||
Implementation sequence (committed)</h2>
|
||||
<div class="fragment"><div class="line">1. Phase 7.5 Doxygen + cleanup done ✅</div>
|
||||
<div class="line">2. Phase 8 MVP — traits + one euclidean wrapper 3–5 days</div>
|
||||
<div class="line">3. Phase 9a — Inversive-Distance against new traits 3–5 days</div>
|
||||
<div class="line">4. Phase 9b — analytic HyperIdeal Hessian 1 week</div>
|
||||
<div class="line">5. Phase 9c — 4g-polygon for genus g > 1 1 week</div>
|
||||
<div class="line"> → port really complete, v0.9.0 release</div>
|
||||
</div><!-- fragment --><p>Phase 8 extensions (8a.2 generic FaceGraph, 8c full Doxygen manuals, 8d CGAL-format tests, 8e YAML pipeline) are deferred to on-demand status — no speculative architecture for an uncertain submission.</p>
|
||||
<p>Root-level files added at v0.7.0:</p><ul>
|
||||
<li><span class="tt">CITATION.cff</span> — machine-readable citation (Sechelmann 2016, Springborn 2020, Bobenko–Springborn 2004)</li>
|
||||
<li><span class="tt">CONTRIBUTING.md</span> — short root-level pointer to <span class="tt">doc/contributing.md</span></li>
|
||||
<li><span class="tt">scripts/try_it.sh</span> — one-script quickstart: build → 209 tests → example run</li>
|
||||
<li>CMake install target: <span class="tt">cmake --install build --prefix /usr/local</span> → headers land in <span class="tt">include/conformallab/</span></li>
|
||||
</ul>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md37"></a>
|
||||
Port-vs-research maintenance rule (2026-05-21 audit)</h1>
|
||||
<p>Before claiming something "ports X from Java", <b>verify empirically</b>:</p>
|
||||
<div class="fragment"><div class="line">find /Users/tarikmoussa/Desktop/conformallab -iname "*X*"</div>
|
||||
<div class="line">grep -r "ClassName" /Users/tarikmoussa/Desktop/conformallab/src</div>
|
||||
</div><!-- fragment --><p>If zero matches, the work is <b>new research</b> — add it to <span class="tt">doc/roadmap/research-track.md</span> with primary literature citations, <b>not</b> to <span class="tt">doc/roadmap/java-parity.md</span>.</p>
|
||||
<p>The 2026-05-21 audit found four pre-existing mis-labels:</p>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Item </th><th class="markdownTableHeadNone">Wrong claim </th><th class="markdownTableHeadNone">Reality </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><span class="tt">InversiveDistanceFunctional</span> </td><td class="markdownTableBodyNone">"Java port (Luo 2004)" </td><td class="markdownTableBodyNone">No such Java class exists </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">HyperIdeal Hessian (FD) </td><td class="markdownTableBodyNone">"Phase 4a" </td><td class="markdownTableBodyNone">Research — Java has <span class="tt">hasHessian()==false</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">HyperIdeal Hessian (analytic) </td><td class="markdownTableBodyNone">"Phase 9b port" </td><td class="markdownTableBodyNone">Research — derivation via Schläfli 1858 </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Tutorial framing </td><td class="markdownTableBodyNone">"ports `InversiveDistanceFunctional.java`" </td><td class="markdownTableBodyNone">Implementation from Luo 2004 + Glickenstein 2011 </td></tr>
|
||||
</table>
|
||||
<p>All four are corrected as of this commit. Future contributors must follow the empirical verification rule above before any new claim.</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md38"></a>
|
||||
Documentation map</h1>
|
||||
<p>24 documents across 6 categories. Read the relevant one before reasoning from scratch — do not hallucinate content that is already written down.</p>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md39"></a>
|
||||
Mathematics & theory</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">What problem does this library solve mathematically? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/discrete-conformal-theory.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">How do the three geometry modes differ (Euclidean/Spherical/HyperIdeal)? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/geometry-modes.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">What analytic invariants can be used to validate correctness? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/validation.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">What are the exact ctest commands with expected terminal output? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/validation-protocol.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">What is the O() complexity and how does it scale with mesh size? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/complexity.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Which papers are referenced by which header? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/references.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">How does conformallab++ compare to libigl, CGAL, geometry-central, pmp-library? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/software-landscape.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">What is unique about conformallab++ (novelty, target audience)? </td><td class="markdownTableBodyNone"><span class="tt">doc/math/novelty-statement.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md40"></a>
|
||||
Architecture & design</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Full pipeline diagram and data-flow overview </td><td class="markdownTableBodyNone"><span class="tt">doc/architecture/overall_pipeline.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Directory tree, build targets, file organisation </td><td class="markdownTableBodyNone"><span class="tt">doc/architecture/project-structure.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Key architectural decisions and their rationale </td><td class="markdownTableBodyNone"><span class="tt">doc/architecture/design-decisions.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Detailed comparison with geometry-central (CMU): overlap, adoption, scientific value </td><td class="markdownTableBodyNone"><span class="tt">doc/architecture/geometry-central-comparison.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Phase 9a validation report (CP-Euclidean port + Luo-inversive-distance literature check) </td><td class="markdownTableBodyNone"><span class="tt">doc/architecture/phase-9a-validation.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md41"></a>
|
||||
API & extension</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">All 24 public headers with descriptions </td><td class="markdownTableBodyNone"><span class="tt">doc/api/headers.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Full pipeline API for all three geometries </td><td class="markdownTableBodyNone"><span class="tt">doc/api/pipeline.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">What does each processing unit require/provide (contracts)? </td><td class="markdownTableBodyNone"><span class="tt">doc/api/contracts.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">How to add a new functional / geometry mode / port from Java </td><td class="markdownTableBodyNone"><span class="tt">doc/api/extending.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Per-suite breakdown and counts (single source of truth) </td><td class="markdownTableBodyNone"><span class="tt">doc/api/tests.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Phase 8 CGAL package design + Declarative YAML pipeline spec </td><td class="markdownTableBodyNone"><span class="tt">doc/api/cgal-package.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md42"></a>
|
||||
Concepts & specs</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Declarative YAML pipeline: token vocabulary, 5 examples, validation algorithm </td><td class="markdownTableBodyNone"><span class="tt">doc/concepts/declarative-pipeline.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md43"></a>
|
||||
Roadmap & porting</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Phases 1–10 with status and sub-tasks </td><td class="markdownTableBodyNone"><span class="tt">doc/roadmap/phases.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Which Java classes are ported, which are planned, which are skipped? </td><td class="markdownTableBodyNone"><span class="tt">doc/roadmap/java-parity.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">New research items (beyond Java) — citations, acceptance criteria </td><td class="markdownTableBodyNone"><span class="tt">doc/roadmap/research-track.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md44"></a>
|
||||
Tutorials & onboarding</h2>
|
||||
<table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Question </th><th class="markdownTableHeadNone">Document </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Build modes, single-test invocation, CLI, Docker image rebuild </td><td class="markdownTableBodyNone"><span class="tt">doc/getting-started.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Step-by-step: port the Inversive Distance functional (Phase 9a template) </td><td class="markdownTableBodyNone"><span class="tt">doc/tutorials/add-inversive-distance.md</span> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Language policy, test standards, release flow </td><td class="markdownTableBodyNone"><span class="tt">doc/contributing.md</span> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Versioning rules + release process + single-source-of-truth list </td><td class="markdownTableBodyNone"><span class="tt">doc/release-policy.md</span> </td></tr>
|
||||
</table>
|
||||
<h2 class="doxsection"><a class="anchor" id="autotoc_md45"></a>
|
||||
geometry-central context</h2>
|
||||
<p><b>geometry-central</b> (Keenan Crane, CMU) implements the same discrete conformal equivalence problem (Gillespie, Springborn & Crane, SIGGRAPH 2021) but uses Ptolemaic flips on intrinsic triangulations instead of Newton on the original mesh. It has no period matrix, holonomy, or spherical geometry mode. The shared mathematical core (Springborn 2020) means cross-validation is meaningful. Full analysis: <span class="tt">doc/architecture/geometry-central-comparison.md</span>. Optional adoption roadmap (GC-1/2/3): <span class="tt">doc/roadmap/phases.md</span> (Optional section).</p>
|
||||
<h1 class="doxsection"><a class="anchor" id="autotoc_md46"></a>
|
||||
Known quirks</h1>
|
||||
<ul>
|
||||
<li><b>No GTEST_SKIP stubs remain</b> (since v0.9.0): the three stale HDS-port stub files were removed because the CGAL test suite covers the same functionality with real tests. The pure-math <span class="tt">conformallab_tests</span> target now only contains active tests.</li>
|
||||
<li><b>Boost is header-only</b>: CGAL 6.x uses only Boost headers (<span class="tt">Boost.Config</span>, <span class="tt">Boost.Graph</span>). No compiled Boost libraries are needed. <span class="tt">find_package(Boost REQUIRED)</span> only locates the include path.</li>
|
||||
<li><b><span class="tt">main</span> branch is protected</b> on <span class="tt">origin</span> (Gitea). Push to <span class="tt">dev</span>, then merge via pull request. Codeberg <span class="tt">main</span> can be pushed to directly.</li>
|
||||
<li><b>Both remotes must stay in sync</b>: <span class="tt">origin</span> = <span class="tt">git.eulernest.eu</span> (CI runs here), <span class="tt">codeberg</span> = <span class="tt">codeberg.org/TMoussa/ConformalLabpp</span> (public mirror). Push to both after every significant change. </li>
|
||||
</ul>
|
||||
</div></div><!-- contents -->
|
||||
</div><!-- PageDoc -->
|
||||
</div><!-- doc-content -->
|
||||
<div id="page-nav" class="page-nav-panel">
|
||||
<div id="page-nav-resize-handle"></div>
|
||||
<div id="page-nav-tree">
|
||||
<div id="page-nav-contents">
|
||||
</div><!-- page-nav-contents -->
|
||||
</div><!-- page-nav-tree -->
|
||||
</div><!-- page-nav -->
|
||||
</div><!-- container -->
|
||||
<!-- start footer part -->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.17.0 </li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user