Commit Graph

218 Commits

Author SHA1 Message Date
Tarik Moussa
26405be149 docs: add CLAUDE.md — context file for Claude Code
Some checks failed
C++ Tests / test-fast (push) Successful in 2m29s
C++ Tests / test-cgal (push) Failing after 1m51s
Covers build commands (all three modes), single-test invocation,
header-only architecture, the three geometry modes, Newton solver
sign conventions, layout BFS design, test patterns, CI structure,
and known quirks (Finder ` 2.hpp` duplicates, CGAL compile flags).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 20:47:01 +02:00
Tarik Moussa
9c35c2cb71 fix(ci): entferne WITH_CGAL_TESTS=ON aus test-fast — Job braucht kein Boost
Some checks failed
C++ Tests / test-fast (push) Successful in 2m51s
C++ Tests / test-cgal (push) Failing after 2m10s
test-fast ist der schnelle, abhängigkeitsfreie Job: nur Eigen + GTest.
WITH_CGAL_TESTS=ON in test-fast triggert unnötigerweise find_package(Boost)
und konfiguriert das CGAL-Test-Verzeichnis.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 20:39:32 +02:00
Tarik Moussa
4e8213f9aa fix(ci): cpp-tests.yml bereinigt — WITH_CGAL_TESTS=ON in test-fast, Boost-Kommentar aktuell
Some checks failed
C++ Tests / test-fast (push) Failing after 2m31s
C++ Tests / test-cgal (push) Has been skipped
- test-fast konfiguriert jetzt mit -DWITH_CGAL_TESTS=ON (Boost im Image)
- Kommentar aktualisiert (Boost kein Runtime-Install mehr nötig)
- Konsistenz zwischen test-fast und test-cgal hergestellt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 20:34:52 +02:00
4a036b8214 Update .gitea/workflows/mirror-to-codeberg.yml
Some checks failed
C++ Tests / test-fast (push) Successful in 2m48s
Mirror to Codeberg / mirror (push) Successful in 28s
C++ Tests / test-cgal (push) Failing after 2m3s
C++ Tests / test-fast (pull_request) Successful in 2m18s
C++ Tests / test-cgal (pull_request) Failing after 1m46s
2026-05-15 08:59:06 +00:00
28d05f5863 Update .gitea/workflows/cpp-tests.yml
Some checks failed
C++ Tests / test-fast (push) Successful in 2m30s
Mirror to Codeberg / mirror (push) Has been cancelled
C++ Tests / test-cgal (push) Failing after 2m1s
Del Boot Installation
2026-05-15 08:52:50 +00:00
Tarik Moussa
6886803a29 fix(ci): decouple CGAL tests from viewer — add WITH_CGAL_TESTS flag
Some checks failed
C++ Tests / test-fast (push) Successful in 2m12s
Mirror to Codeberg / mirror (push) Failing after 1s
C++ Tests / test-cgal (push) Failing after 1m52s
Root cause: -DWITH_CGAL=ON implied -DWITH_VIEWER=ON, which pulled in
GLFW, which requires wayland-scanner — not present in the headless CI
container (ubuntu:22.04 ARM64).

Fix: new CMake option -DWITH_CGAL_TESTS=ON builds conformallab_cgal_tests
without touching the viewer, GLFW, libigl, or any display dependency.
Only Boost headers are required (already in the Docker image).

Changes
───────
code/CMakeLists.txt
  - Add WITH_CGAL_TESTS option (OFF by default)
  - find_package(Boost REQUIRED) now shared between WITH_CGAL and WITH_CGAL_TESTS
  - WITH_CGAL still implies WITH_VIEWER (for local full builds)
  - Remove duplicate find_package(Boost) inside the WITH_CGAL block

code/tests/CMakeLists.txt
  - cgal/ subdirectory added for WITH_CGAL OR WITH_CGAL_TESTS

.gitea/workflows/cpp-tests.yml
  - test-cgal job: -DWITH_CGAL=ON → -DWITH_CGAL_TESTS=ON

README.md
  - Build modes table: three rows (default / CGAL_TESTS / CGAL full)
  - Quick-start: separate headless and full-local sections
  - Prerequisite table updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 13:50:56 +02:00
Tarik Moussa
78d13bf561 release: merge dev into main — v0.2.0
Some checks failed
C++ Tests / test-fast (push) Successful in 2m26s
Mirror to Codeberg / mirror (push) Failing after 2s
C++ Tests / test-cgal (push) Failing after 56s
Java-port vollständig abgeschlossen (Phase 1–7).

New since v0.1.0
────────────────
Phase 3   CGAL Surface_mesh infrastructure, all three functionals
          (Euclidean, Spherical, HyperIdeal) + analytical Hessians
Phase 4   Newton solver: SimplicialLDLT + SparseQR fallback for gauge modes
          Mesh I/O (OFF/OBJ/PLY), end-to-end pipeline tests, example programs
Phase 5   Priority-BFS layout (ℝ², S², Poincaré disk), CLI app,
          JSON + XML serialisation
Phase 6   Gauss–Bonnet check/enforce, tree-cotree cut graph (2g seam edges),
          exact hyperbolic trilateration (Möbius + law of cosines),
          layout normalisation (PCA / weighted Möbius / Rodrigues)
Phase 7   MobiusMap T(z)=(az+b)/(cz+d), halfedge_uv texture atlas,
          Möbius holonomy (SU(1,1)), period matrix τ∈ℍ + SL(2,ℤ) reduction,
          fundamental domain parallelogram + tiling — Java-parity complete

Infrastructure
──────────────
- CI: two-job pipeline (test-fast 36 tests + test-cgal 158 tests)
- Dockerfile: libboost-dev added for CGAL mode
- README + architecture doc fully rewritten with roadmap
  (Phase 8 CGAL package / Phase 9 porting / Phase 10+ new research)

Test count: 158 CGAL + 36 non-CGAL = 194 total, 2 intentional skips
v0.2.0
2026-05-14 13:22:10 +02:00
Tarik Moussa
c0e421e5af release: merge feature/phase7-layout-java-parity into dev
Some checks failed
C++ Tests / test-fast (push) Successful in 2m0s
Mirror to Codeberg / mirror (push) Failing after 2s
C++ Tests / test-cgal (push) Failing after 1m18s
Completes the full Java-port (Phase 1–7):
- Phase 3  CGAL Surface_mesh infrastructure + all three functionals
- Phase 4  Newton solver (SimplicialLDLT + SparseQR fallback) + mesh I/O
- Phase 5  Priority-BFS layout + CLI + JSON/XML serialisation
- Phase 6  Gauss–Bonnet, tree-cotree cut graph, exact hyperbolic trilateration,
           layout normalisation
- Phase 7  MobiusMap, halfedge_uv, Möbius holonomy, period matrix (genus 1),
           fundamental domain, tiling — Java-parity complete
- CI       two-job pipeline: test-fast (36) + test-cgal (158 tests)
- Docs     README + architecture doc fully rewritten with roadmap
           (Phase 8 CGAL package / Phase 9 porting / Phase 10+ research)

158 CGAL tests, 36 non-CGAL tests, 2 intentional skips.
2026-05-14 13:21:54 +02:00
Tarik Moussa
f8686a073c docs: add phase roadmap with porting/research boundary to README and architecture doc
All checks were successful
C++ Tests / test-fast (push) Successful in 2m12s
C++ Tests / test-cgal (push) Has been skipped
Structured the development roadmap into four blocks with an explicit
boundary marker separating direct Java ports (Phase 1–7) from
infrastructure (Phase 8), remaining porting (Phase 9), and new
research territory (Phase 10+).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 13:18:21 +02:00
Tarik Moussa
a937edcafe docs: Dissertation, GitHub-Repo, Website und LinkedIn von Stefan Sechelmann ergänzt
All checks were successful
C++ Tests / test-fast (push) Successful in 2m5s
C++ Tests / test-cgal (push) Has been skipped
README:
- Neuer Einstieg mit vollständiger Dissertation-Referenz (Titel, TU Berlin 2016,
  DOI 10.14279/depositonce-5415, CC BY-SA 4.0)
- Links zu Original-Java-Repo, sechel.de und linkedin.com/in/sechel
- Neuer Abschnitt "Ursprung & Danksagung" vor der Lizenz

doc/architecture/overall_pipeline.md:
- Neuer "Origin"-Abschnitt ganz oben mit vollständiger Quellenangabe
- Literaturabschnitt erweitert: Dissertation als "Primary source" hervorgehoben,
  Java-Original-Repo als direkter Port-Bezug dokumentiert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:33:30 +02:00
Tarik Moussa
9c61c9fc40 docs(architecture): overall_pipeline.md vollständig neu geschrieben
All checks were successful
C++ Tests / test-fast (push) Successful in 2m12s
C++ Tests / test-cgal (push) Has been skipped
Ersetzt den generischen Geometry-Framework-Entwurf durch eine präzise
Beschreibung der tatsächlichen konformen Geometrie-Pipeline:

- Klare Positionierung: spezialisiertes Werkzeug für diskrete konforme
  Abbildungen, kein generisches Mesh-Processing-Framework
- Korrigiertes Mermaid-Diagramm: alle 3 Phasen mit realen Komponenten
  (load_mesh → setup_maps → GB-check → Newton → CutGraph → Layout →
   halfedge_uv → Holonomie → Periodenmatrix → Fundamentalbereich → Export)
- Preconditions/Capabilities-Tabelle für alle Processing-Units
- Drei Geometrie-Modi (Euklidisch/Sphärisch/Hyper-ideal) im Vergleich
- MobiusMap, halfedge_uv, Priority-BFS, SL(2,ℤ)-Reduktion dokumentiert
- Realistischer YAML-Pipeline-Entwurf als Phase-8-Ziel (Tokens statt Prosa)
- Erweiterungspunkte: neues Funktional, neue Geometrie, neues Unit
- Alle Literaturverweise direkt auf Implementierungsstellen gemappt
- "Nice To Have but maybe too much" komplett entfernt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:19:59 +02:00
Tarik Moussa
a4438c9a1a test: Java-Geometrie-Utility-Tests portiert (Tests 1–6) + Genus-2-TODO-Stub
All checks were successful
C++ Tests / test-fast (push) Successful in 2m4s
C++ Tests / test-cgal (push) Has been skipped
Portiert aus CuttinUtilityTest, UnwrapUtilityTest, ConvergenceUtilityTests
und HomologyTest (Java-Quelldatei unifgeo/test). Jetzt 170 CGAL-Tests.

Neue Suiten in test_geometry_utils.cpp:
  CuttingUtility       — point_in_triangle_2d (3 Tests, Java-Test 1–2)
  UnwrapUtility        — Eckwinkel law-of-cosines (2 Tests, Java-Test 3)
  ConvergenceUtility   — circumradius + scale-invariant R_f/sqrt(A) (6 Tests, Java-Test 4–6)
  HomologyGenerators   — GTEST_SKIP-Stub für Genus-2 (Java-Test 7, Phase 8)

Der Stub dokumentiert genau was fehlt (Genus-2-Mesh), welcher Code nötig ist
(compute_cut_graph → 4 cut edges) und die Java-Herkunft.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:09:27 +02:00
Tarik Moussa
62e2875c30 ci: Zwei-Job-Pipeline — test-fast + test-cgal (158 CGAL-Tests)
All checks were successful
C++ Tests / test-fast (push) Successful in 2m16s
C++ Tests / test-cgal (push) Has been skipped
test-fast (alle Branches, < 1 s):
  Unverändert — reine Mathe-Tests ohne CGAL/Boost.

test-cgal (main / dev / Pull Requests):
  Läuft nach erfolgreichem test-fast (needs: test-fast).
  Baut conformallab_cgal_tests mit -DWITH_CGAL=ON und führt
  alle 158 CGAL-Tests (Phase 3–7) aus.
  Übergangs-Schritt: apt-get libboost-dev zur Laufzeit, bis das
  Docker-Image neu gebaut wird (Dockerfile bereits aktualisiert).

Dockerfile.ci-cpp:
  libboost-dev ergänzt — für den nächsten manuellen Image-Rebuild.
  Danach entfällt der apt-get-Schritt im Workflow automatisch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:47:35 +02:00
Tarik Moussa
5333ed143a docs: README vollständig überarbeitet — Phase 7 aktuell, Redundanzen entfernt
- Status-Banner: Phase 7 , 158 Tests (war: Phase 6, 121 Tests)
- Features-Tabelle: Phase 7 Zeilen ergänzt (Priority-BFS, MobiusMap,
  halfedge_uv, Möbius-Holonomie, Periodenmatrix, Fundamentalbereich)
- Bibliotheks-Nutzung: Holonomie/Periodenmatrix/Fundamentalbereich-Beispiele
- Öffentliche Header: period_matrix.hpp + fundamental_domain.hpp ergänzt
- Projektstruktur: neue Dateien + korrigierte Testzahlen
- Test-Suiten: 12 neue Suiten (Phase 7), Gesamt 158
- Mathematischer Umfang:  für Holonomie, Periodenmatrix Genus-1,
  halfedge_uv, exakte Trilateration, Schnittgraph
- Veraltete Abschnitte entfernt: "Porting the Java uniformization pipeline"
  Roadmap (Schritte 1-5 alle umgesetzt), Layout-Vergleich-Codeblöcke
  mit vorgeschlagenen Implementierungen (jetzt live)
- Roadmap: Phase 7  mit Details, Phase 8 geplant
- Sprache: auf Deutsch vereinheitlicht (war gemischt DE/EN)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:34:24 +02:00
Tarik Moussa
e7dfaed56c feat(phase7): Java-parity layout — priority BFS, halfedge_uv, Möbius holonomy, period matrix, fundamental domain — 158 tests
Phase 7 adds seven features ported from the original Java ConformalLab:

  layout.hpp
  - Priority BFS (min-heap on BFS depth) replaces FIFO queue, minimising
    trilateration error accumulation from the root face outward.
  - MobiusMap struct: T(z)=(az+b)/(cz+d), identity/inverse/compose,
    from_three (3×3 complex least-squares fit), apply(Vector2d).
  - halfedge_uv[h.idx()] = UV of source(h) in face(h); seam halfedges
    carry the virtual unfolded position, enabling proper GPU texture atlases.
  - Hyperbolic holonomy stored as MobiusMap per cut edge (SU(1,1) isometry).
  - best_root_face: largest 3-D area face, 1.5× interior bonus.
  - normalise_euclidean also transforms halfedge_uv (centroid + PCA).
  - Face-area-weighted iterative Möbius centering (Fréchet mean, Phase 7).

  period_matrix.hpp  (new)
  - PeriodData: lattice generators ω_i as complex numbers, τ = ω₂/ω₁ ∈ ℍ.
  - reduce_to_fundamental_domain: SL(2,ℤ) reduction via alternating S/T steps.
  - is_in_fundamental_domain, compute_period_matrix.
  - NOTE: Siegel matrix Ω for genus g>1 intentionally deferred.

  fundamental_domain.hpp  (new)
  - FundamentalDomain: CCW parallelogram {0, ω₁, ω₁+ω₂, ω₂} for genus 1.
  - edge_identifications, generators stored.
  - 4g-polygon boundary-walk for g>1 marked TODO(Phase 8) with full algorithm
    outline and literature references.
  - tiling_copy / tiling_neighbourhood for universal cover visualisation.

  Tests: 121 → 158 (+37 Phase 7 tests covering all new features).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 07:57:13 +02:00
Tarik Moussa
4fc48b39f0 feat(phase6): exact hyperbolic layout, Gauss–Bonnet, cut graph, normalisation — 121 tests
New files:
- gauss_bonnet.hpp: euler_characteristic, genus, Σ(2π-Θ_v) sum/rhs/deficit,
  check_gauss_bonnet (throws), enforce_gauss_bonnet (correct sign: Δ=(lhs-rhs)/V)
- cut_graph.hpp: CutGraph struct + compute_cut_graph (tree-cotree, Erickson–Whittlesey
  2005); boundary edges correctly excluded from cut set
- test_phase6.cpp: 26 new tests (GaussBonnet ×8, CutGraph ×6, HyperbolicTrilateration
  ×4, Normalisation ×4 — all pass)

layout.hpp (Phase 6 rewrite):
- detail::trilaterate_hyp: exact Möbius + hyperbolic law of cosines replacing old tanh(d/2)
- detail::center_poincare_disk: Möbius centering for hyperbolic normalisation
- normalise_euclidean: centroid → origin + PCA major-axis rotation
- normalise_hyperbolic: Möbius centering in the Poincaré disk
- normalise_spherical: Rodrigues rotation → north pole
- euclidean_layout / hyper_ideal_layout: optional CutGraph* + HolonomyData* + normalise

Bug fixes caught by new tests:
- gauss_bonnet.hpp: enforce_gauss_bonnet had wrong sign for delta
- cut_graph.hpp: boundary edges were incorrectly marked as cut edges

121 tests pass, 2 skipped (Hessian stubs).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 01:15:41 +02:00
Tarik Moussa
24f7607b2d docs: detailed layout comparison + uniformization porting roadmap
Mathematical scope section:
- Expanded layout comparison table with 4 concrete differences:
  (1) hyperbolic trilateration exact vs. tanh(d/2) approximation
  (2) closed mesh handling: holonomy/period matrices vs. seam flag
  (3) layout normalisation: Möbius vs. raw BFS output
  (4) Gauss–Bonnet pre-check: Java has it, C++ does not
- Added Möbius trilateration code snippet showing exact implementation path
- Added 10-row Java vs. C++ summary matrix

For mathematicians section:
- New subsection: "Porting the Java uniformization pipeline"
  Step 1: Gauss–Bonnet check (~30 lines, complete implementation template)
  Step 2: Homological basis / fundamental polygon cut (CutGraph struct + BFS hook)
  Step 3: Holonomy tracking (EuclideanHolonomy + MöbiusElement structs)
  Step 4: Period matrix extraction (genus 1 via holonomy translations, genus ≥ 2 via Fuchsian group)
  Step 5: Layout normalisation (canonical Möbius post-processing)
  Priority table: 6 steps, estimated effort, C++ hook location

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 00:53:47 +02:00
Tarik Moussa
b7593e3f6d feat(phase5): Layout, CLI, JSON/XML serialisation — 95 tests
Phase 5 complete:

layout.hpp
  - euclidean_layout(): BFS unfolding in ℝ² using trilaterate_2d
  - spherical_layout(): BFS on S² using trilaterate_sph (spherical law of cosines)
  - hyper_ideal_layout(): BFS in Poincaré disk (tanh(d/2) Euclidean approx)
  - save_layout_off(): convenience OFF writer for 2-D and 3-D layouts

serialization.hpp
  - save/load_result_json(): nlohmann/json; stores DOF vector + uv/pos layout
  - save/load_result_xml(): hand-written writer/parser; same schema

conformallab_cli.cpp (rewritten)
  - CLI11 interface: -i/-o/-g/-j/-x/-s/-v
  - Dispatches to euclidean / spherical / hyper_ideal pipeline
  - Runs Newton, computes layout, saves OFF + JSON + XML

examples/example_layout.cpp
  - Full round-trip demo: solve → layout → JSON/XML → reload → verify

tests/cgal/test_layout.cpp (8 tests)
  - Euclidean_PreservesEdgeLengths, CorrectVertexCount, TriangleIsNonDegenerate
  - Spherical_PreservesArcLengths, PositionsOnUnitSphere
  - HyperIdeal_SuccessAndFinitePositions
  - Serialization.JSON_RoundTrip, XML_RoundTrip

All 95 CGAL tests pass (2 skipped — Hessian stubs unchanged).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 00:53:47 +02:00
Tarik Moussa
3f124eb071 feat(phase4): HyperIdeal Newton solver, SparseQR fallback, examples, docs
Phase 4 complete — 87 CGAL tests pass, 2 skipped.

Newton solver (phase4a):
- hyper_ideal_hessian.hpp: symmetric FD Hessian (O(ε²), PSD by convexity)
- newton_hyper_ideal(): Newton + backtracking for the HyperIdeal functional
- detail::solve_with_fallback(): optional bool* fallback_used parameter
- solve_linear_system(): public API exposing LDLT→SparseQR fallback

SparseQR fallback tests (SparseQRFallback.*):
- FullRankSystem_CorrectSolution: LDLT path, fallback_used=false
- SingularMatrix_FallbackActivated: zero-pivot → QR activated, fallback_used=true
- Euclidean_ClosedMeshNoPinConverges: gauge-mode null space handled via QR

HyperIdeal Newton tests (NewtonSolver.HyperIdeal_*):
- ConvergesTriangleAllVariable, ResultFieldsConsistent,
  ConvergesTetrahedron, SparseQRFallbackNoCrash
- Natural-target base point (b=1.0, a=0.5) — x=0 is degenerate in log-space

Pipeline tests (test_pipeline.cpp):
- End-to-end: all three geometries, mesh I/O round-trip, solve+export

Example programs (code/examples/):
- example_euclidean.cpp:   headless Euclidean pipeline
- example_hyper_ideal.cpp: headless HyperIdeal pipeline
- example_viewer.cpp:      interactive libigl viewer with jet colour map

README:
- Mathematical scope table: C++ vs Java original (18 rows)
- "For mathematicians" section: mental model, step-by-step new-functional
  guide, half-edge traversal snippets, recommended reading

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 00:11:25 +02:00
Tarik Moussa
e70689d29f feat(phase4a+4b): Newton solver + CGAL mesh I/O
Phase 4a — newton_solver.hpp:
  - newton_euclidean(): SimplicialLDLT on H (PSD); solves H·Δx = −G
  - newton_spherical(): SimplicialLDLT on −H (NSD→PSD); solves (−H)·Δx = G
  - Backtracking line search (halving α up to 20×) for global convergence
  - NewtonResult struct: x, iterations, grad_inf_norm, converged
  - 7 tests: 4 spherical (convergence, few iters, large perturbation,
    field consistency) + 3 Euclidean (triangle pinned, quad pinned,
    mixed pinned — all with natural-theta equilibrium at x=0)

Phase 4b — mesh_io.hpp:
  - read_mesh() / write_mesh(): CGAL::IO::read/write_polygon_mesh wrappers
  - load_mesh() / save_mesh(): throwing convenience versions
  - Supports OFF, OBJ, PLY (format detected by file extension)
  - 6 tests: OFF round-trip (tet + quad), OBJ round-trip, missing-file throw,
    vertex-position preservation, save/load convenience wrappers

All 75 cgal tests pass (3 skipped as before).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-12 17:35:00 +02:00
Tarik Moussa
5841646017 docs: update README — Phase 3 vollständig abgeschlossen (62 Tests)
Mark all Phase 3 sub-phases (3a–3g) as done in the roadmap.
Add euclidean_hessian and spherical_hessian to the feature table.
Update status banner: 62 tests, Phase 4 is next.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-12 17:25:26 +02:00
Tarik Moussa
194effba97 feat(phase3f+3g): analytical Hessians + PI consolidation
Phase 3g — constants.hpp:
  - Introduce conformallab::PI and TWO_PI in a single constants.hpp
  - Remove scattered local PI/pi definitions from hyper_ideal_geometry.hpp,
    hyper_ideal_utility.hpp, euclidean_functional.hpp, mesh_builder.hpp,
    spherical_geometry.hpp (backward-compatible PI_SPHER alias kept)

Phase 3f — Euclidean Hessian (euclidean_hessian.hpp):
  - Cotangent-Laplace operator (Pinkall–Polthier 1993)
  - euclidean_cot_weights() helper + euclidean_hessian() + hessian_check_euclidean()
  - Correct Pinkall–Polthier 1/2 normalization factor
  - 8 tests: cot weights, symmetry, null-space (H·1=0), PSD, FD × 4 meshes

Phase 3f — Spherical Hessian (spherical_hessian.hpp):
  - Derives ∂α_i/∂u_j directly from the spherical law of cosines:
      ∂α1/∂l_opp  = sin(l_opp) / [sin(l_a)·sin(l_b)·sin(α1)]
      ∂α1/∂l_adj  = [cot(l_adj)·cos(α1) − cot(l_other)] / sin(α1)
    then chains with ∂l/∂λ = tan(l/2)
  - spherical_cot_weights() kept as a standalone helper (tested separately)
  - 8 tests: cot weights, symmetry, correct null-space & sign-convention
    (H·1 ≠ 0; H is NSD at equilibrium), FD × 3 meshes

All 62 cgal tests pass (3 skipped as before).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-12 17:22:28 +02:00
Tarik Moussa
8c353bb884 feat(phase3d+3e): port EuclideanCyclicFunctional + add SphericalFunctional gauge-fix
Phase 3d — EuclideanCyclicFunctional:
  • euclidean_geometry.hpp: t-value / atan2 corner-angle formula with
    centering trick (μ = (Λ̃₁₂+Λ̃₂₃+Λ̃₃₁)/6) for numerical stability
  • euclidean_functional.hpp: EuclideanMaps bundle, gradient (G_v = Θ_v − Σα_v,
    G_e = α_opp⁺ + α_opp⁻ − φ_e), 10-point GL path-integral energy,
    gradient_check_euclidean — identical halfedge convention to SphericalFunctional
  • test_euclidean_functional.cpp: 11 tests (1 skip) covering angle formula,
    right-isosceles triangle, angle sum = π, degenerate detection, gradient
    checks on triangle/quad-strip/tetrahedron/fan-5/mixed-pinned, NaN check

Phase 3e — Spherical gauge-fix:
  • spherical_gauge_shift(): Newton + backtracking line search to find t*
    where ΣG_v(x + t·1) = 0 (maximises E along the global scale direction);
    bisection used when sign change is detectable, Newton+backtrack otherwise
  • apply_spherical_gauge(): in-place wrapper
  • 3 new tests: GaugeFix_SpherTetVertexZerosSumGv, GaugeFix_ApplyInPlace,
    GaugeFix_AlreadyAtGaugeReturnsTNearZero

Total: 45 cgal tests pass, 3 skipped (@Ignore Hessian stubs, one per functional)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 07:39:14 +02:00
Tarik Moussa
dc0d3ca005 docs: add Phase 3d–4b roadmap to README
Six concrete next steps toward Phase 3 completion and Phase 4 (solver):
  3d  EuclideanCyclicFunctional — most critical missing functional
  3e  Spherical gauge-fix (1D Brent along additive u constant)
  3f  Analytic Hessian via CGAL::Weights::cotangent_weight()
  3g  Consolidate duplicate PI constant
  4a  Minimal Newton solver with Eigen SimplicialLDLT
  4b  CGAL::IO read/write OBJ for mesh round-trip testing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 00:25:36 +02:00
Tarik Moussa
a4c2a89e7e feat(phase3c): port SphericalFunctional onto ConformalMesh; update README
New headers:
- spherical_geometry.hpp: spherical arc length l(λ) and half-angle formula
  for interior angles of a spherical triangle (SphericalFaceAngles struct)
- spherical_functional.hpp: SphericalMaps bundle, setup/assign DOF helpers,
  compute_lambda0_from_mesh(), gradient (Θ_v − Σα_v; Schläfli edge formula),
  energy via 10-point Gauss-Legendre path integral, gradient_check_spherical()

Updated:
- mesh_builder.hpp: add make_spherical_tetrahedron() (vertices on unit sphere)
  and make_octahedron_face() (single right-angled spherical triangle)
- tests/cgal/CMakeLists.txt: enable test_spherical_functional.cpp
- README.md: rewrite for CGAL-package goal, two test targets, all headers,
  updated project tree, Phase progress table, key design decisions

Tests (cgal.SphericalFunctional.*): 8 active + 1 skip
- OctaFaceAnglesAreRightAngles, SpherTetAngleSumExceedsPi
- GradientCheck_{OctaFaceVertex, SpherTetVertex, SpherTetAllDofs,
  SpherFan4Vertex, MixedPinnedVertices}
- AnglesFiniteAtKnownPoint
All 30 cgal.* tests pass (2 @Ignore skips).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 00:01:24 +02:00
Tarik Moussa
516ac89bd8 feat(phase3b): port HyperIdealFunctional energy + gradient onto ConformalMesh
Implements the hyper-ideal discrete conformal map functional on
CGAL::Surface_mesh. The energy and analytic gradient are ported directly
from HyperIdealFunctional.java; correctness is verified via a
finite-difference gradient check (same eps=1E-5 / tol=1E-4 as Java).

New files:
  include/hyper_ideal_geometry.hpp    — ζ, ζ₁₃, ζ₁₄, ζ₁₅, lij, αij, σi, σij
  include/hyper_ideal_functional.hpp  — HyperIdealMaps, evaluate_hyper_ideal,
                                        gradient_check
  tests/cgal/test_hyper_ideal_functional.cpp  — 6 tests (1 skipped @Ignore)

Test results (local, -DWITH_CGAL=ON):
  conformallab_cgal_tests: 21 registered | 20 passed | 1 skipped | 0 failed
    - GradientCheck_AllHyperIdealTriangle   ✓
    - GradientCheck_ExtendedDomain          ✓
    - GradientCheck_TetrahedronAllVariable  ✓
    - EnergyFiniteAtTestPoint               ✓
    - GradientCheck_MixedIdealHyperIdeal    ✓
    - GradientCheck_Fan6AllVariable         ✓

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 23:10:23 +02:00
Tarik Moussa
bf9c323d60 feat(phase3a): introduce CGAL Surface_mesh as ConformalMesh foundation
Replaces the Java CoHDS with CGAL::Surface_mesh<Point3> (Simple_cartesian
kernel). Adds domain-specific property maps for lambda/theta/idx/alpha and
face geometry type — the direct C++ equivalent of CoVertex/CoEdge adapters.

New files:
  include/conformal_mesh.hpp   — ConformalMesh type + property-map helpers
  include/mesh_builder.hpp     — mesh factories (triangle, tetrahedron,
                                 quad-strip, fan) for tests and examples
  tests/cgal/                  — second test executable (conformallab_cgal_tests)
                                 built only with -DWITH_CGAL=ON

Test results (local, -DWITH_CGAL=ON):
  conformallab_tests:      36 registered | 23 passed | 13 skipped | 0 failed
  conformallab_cgal_tests: 14 registered | 14 passed |  0 skipped | 0 failed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 18:36:21 +02:00
Tarik Moussa
ae5db7216e tests: port HyperIdealVisualizationPlugin circle-projection tests
All checks were successful
C++ Tests / test (push) Successful in 2m29s
Mirror to Codeberg / mirror (push) Successful in 26s
Implements getEuclideanCircleFromHyperbolic() in C++ (hyperboloid model
→ Poincaré disk via Lorentz boost + circumcircle). Ports the 2 Java tests
that were the only remaining candidates not requiring HDS or a solver.

All other unported tests (DataTypesTest, SchottkyIOTest,
UniformizationDataTest, BranchedCoverTorusTest) are blocked by XML
serialization or HDS – stubs remain for Phase 4.

Test totals: 36 registered | 23 passed | 13 skipped | 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:23:15 +02:00
Tarik Moussa
c5a86cb30a tests: port DiscreteEllipticUtility + P2 tests; stub HDS-blocked tests
All checks were successful
C++ Tests / test (push) Successful in 2m39s
Mirror to Codeberg / mirror (push) Successful in 24s
Fully ported (pure math, no HDS required):
  test_discrete_elliptic_utility.cpp  – 2 tests
    normalizeModulus: move tau into SL(2,Z) fundamental domain
  test_p2_utility.cpp                 – 3 tests
    P2 projective geometry (perpendicularBisector, pointFromLines,
    makeDirectIsometryFromFrames double vs long double precision)

New headers:
  include/discrete_elliptic_utility.hpp  – normalizeModulus
  include/p2_utility.hpp                 – P2 Euclidean geometry (templated
    on scalar type so double and long double share one implementation)

Stubs (GTEST_SKIP, blocked until HDS port – Phase 4):
  test_hyper_ideal_functional.cpp          – 5 tests (1 @Ignore in Java)
  test_hyper_ideal_hyperelliptic_utility.cpp – 3 tests
  test_spherical_functional.cpp            – 5 tests
  All use CoHDS + HalfEdgeUtils which are not yet ported to C++.

Result: 34 tests total | 21 passed | 13 skipped | 0 failed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 17:15:18 +02:00
Tarik Moussa
9ab4fba9ed release: merge dev into main – v0.1.0
All checks were successful
C++ Tests / test (push) Successful in 1m55s
Mirror to Codeberg / mirror (push) Successful in 28s
Highlights:
- Three CMake build modes: tests-only (default), WITH_VIEWER, WITH_CGAL
- Boost removed as bundled dep; CGAL mode uses system Boost via find_package
- 16 GTest unit tests ported from Java (Clausen, HyperIdeal, Matrix, SurfaceCurve)
- Gitea Actions CI pipeline with custom ARM64 Docker image (ci-cpp:latest)
- Automatic Codeberg mirror on push to main/dev
- Dockerfile for CI image: .gitea/docker/Dockerfile.ci-cpp

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.0
2026-05-10 00:46:42 +02:00
Tarik Moussa
b66525039d fix: gitignore – update CMakeLists.txt exception + ignore macOS duplicates
All checks were successful
C++ Tests / test (push) Successful in 2m13s
Mirror to Codeberg / mirror (push) Successful in 25s
- Exception updated to match renamed CMakeLists.txt (capital M)
- Add "* 2.*" / "* 3.*" patterns to suppress iCloud Drive duplicate
  files (e.g. "clausen 2.hpp") from appearing in git status

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 00:22:53 +02:00
Tarik Moussa
6a70309a30 fix: rename deps/Cmakelists.txt → CMakeLists.txt (case-sensitive Linux fix)
Some checks failed
C++ Tests / test (push) Has started running
Mirror to Codeberg / mirror (push) Has been cancelled
macOS filesystem is case-insensitive so both spellings worked locally,
but the Linux container (CI) could not find the file and failed with
"does not contain a CMakeLists.txt file".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 00:22:16 +02:00
Tarik Moussa
42dd815591 cmake: add find_package(Boost) for WITH_CGAL mode
Some checks failed
C++ Tests / test (push) Failing after 41s
Mirror to Codeberg / mirror (push) Successful in 35s
CGAL 6.x still unconditionally includes boost/config.hpp in its
config.h, so Boost headers are required even with CGAL_DISABLE_GMP/MPFR.

Use system Boost via find_package instead of the removed 211 MB tarball.
Tests-only mode remains completely dependency-free.

Install: brew install boost  (macOS)
         apt install libboost-dev  (Debian/Ubuntu)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 00:20:38 +02:00
Tarik Moussa
b9f739319f ci: fix mirror workflow – remove actions/checkout (needs Node.js)
Some checks failed
C++ Tests / test (push) Failing after 1m12s
Replace JS action with plain git clone --bare + push --mirror.
No Node.js required → runs directly on the Pi host without a container.
Also upgrades from single-branch push to a full mirror of all refs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 00:15:43 +02:00
Tarik Moussa
488223f75d docker: replace g++ + make with build-essential
Some checks failed
Mirror to Codeberg / mirror (push) Failing after 2s
C++ Tests / test (push) Has started running
build-essential pulls gcc, g++, make and libc-dev together.
CMake declares LANGUAGES C CXX so it needs a C compiler (cc) too –
individual g++ install can leave gaps that build-essential covers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 23:03:25 +02:00
Tarik Moussa
c9c9320907 docker: add make to ci-cpp image (CMake build program was missing)
Some checks failed
C++ Tests / test (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 23:02:17 +02:00
Tarik Moussa
f65d000227 ci: re-enable ci-cpp container (arm64 image now in registry)
Some checks failed
C++ Tests / test (push) Failing after 36s
Mirror to Codeberg / mirror (push) Failing after 3s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:59:44 +02:00
Tarik Moussa
076d1b30d0 ci: fix pipeline – remove container until arm64 image is rebuilt
Some checks failed
C++ Tests / test (push) Failing after 2s
Mirror to Codeberg / mirror (push) Failing after 2s
The ci-cpp image was likely built for linux/amd64; the eulernest runner
is linux/arm64 (Raspberry Pi), so the container exited immediately
without running any steps (task 102 log: 10 lines, no step output).

Fix: run directly on the host runner and install cmake/g++ via apt-get
(same approach as the previously working workflow).

Also pin --platform=linux/arm64 in Dockerfile.ci-cpp so the next
image build produces the correct architecture. Once the image is pushed,
re-add the container: block to the workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:41:47 +02:00
Tarik Moussa
9889c4d811 ci: add mirror-to-codeberg workflow
Some checks failed
C++ Tests / test (push) Failing after 53s
Automatically pushes main and dev to the Codeberg mirror
(codeberg.org/TMoussa/ConformalLabpp) after every push to eulernest.
Requires CODEBERG_TOKEN secret in the eulernest repo settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:04:32 +02:00
Tarik Moussa
54c455449b merge feature/cgal-eigen-visualizer into dev
Some checks failed
C++ Tests / test (push) Failing after 1s
- cmake: three build modes (tests-only / WITH_VIEWER / WITH_CGAL)
- deps: Boost removed (unused, 211 MB), conditional dep extraction
- ci: Dockerfile.ci-cpp + container-based workflow
- docs: README rewritten to reflect current state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:01:06 +02:00
Tarik Moussa
e59f79a8e2 docs + ci: update README, add ci-cpp Docker image, use container in workflow
README:
- Remove stale Boost mention (unused dep, removed yesterday)
- Document three build modes (tests-only / WITH_VIEWER / WITH_CGAL)
  with a comparison table and per-mode cmake commands
- Add project structure overview
- Fix C++20 → C++17 (actual standard used)
- Fix clone URL and getting-started commands
- Add CI section with Dockerfile build instructions

CI:
- Add .gitea/docker/Dockerfile.ci-cpp — ubuntu:22.04 with cmake,
  g++, git, and Node.js 20 pre-installed (Node.js needed for
  actions/checkout@v4 inside containers)
- Update cpp-tests.yml to use ci-cpp container instead of installing
  build tools on every run; add JUnit XML output and summary step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 21:49:44 +02:00
Tarik Moussa
cd7b7a8fd8 cmake: add WITH_CGAL / WITH_VIEWER modes, remove unused Boost
Restructures the CMake build into three clearly separated modes:

  (default)        tests only – Eigen + GTest, no heavy deps
  -DWITH_VIEWER=ON builds viewer lib (libigl / GLFW / GLAD)
  -DWITH_CGAL=ON   builds conformallab_core CLI app;
                   implies WITH_VIEWER automatically

Changes:
- code/CMakeLists.txt: viewer and core targets are now guarded by
  option() flags; GTest / tests target is always built
- code/deps/Cmakelists.txt: CGAL, libigl, glfw, glad are only
  extracted when the corresponding mode is enabled; Eigen always
- Remove Boost (211 MB tarball, 0 usages in the codebase – CGAL 6.x
  does not require Boost for Simple_cartesian / Surface_mesh / basic IO)
- Remove code/src/main.cpp (dead file, not referenced in CMake)

All 16 C++ tests pass in tests-only mode (verified locally).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 21:42:43 +02:00
Tarik Moussa
5337a9e5a7 ci: use eulernest runner (Raspberry Pi, ARM64)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:51:45 +02:00
Tarik Moussa
d909683a5b add Gitea Actions workflow for C++ tests
Runs conformallab_tests (GTest) on every push to main/dev/claude/**
using ubuntu-latest + cmake + g++. Only the test binary is built,
not the full app (no CGAL/Boost compilation needed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:35:23 +02:00
Tarik Moussa
a2876b9cbf port MatrixUtility and SurfaceCurveUtility tests to C++
- include/matrix_utility.hpp: 4x4 mapping matrix R·from=to (Eigen)
- include/projective_math.hpp: dehomogenize, hyperbolicDistance,
  isOnSegment (collinearity + betweenness via 3D cross/dot),
  getPointOnCorrespondingSegment (parameter by arc-length ratio)
- test_matrix_utility.cpp: port of MatrixUtilityTest (1 test)
- test_surface_curve_utility.cpp: port of SurfaceCurveUtilityTest
  testIsBetween and testGetPointOnSegment_SegmentEdge (2 tests)
- tolerance adjusted to 1e-12 for matrix inversion (2.7e-15 rounding
  from Eigen vs jReality's LU; both well within meaningful accuracy)

Total: 16/16 tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:15:35 +02:00
Tarik Moussa
c30d540521 add GTest infrastructure and port first mathematical tests from Java
- Add Google Test via CMake FetchContent (v1.14.0)
- Add clausen.hpp: Clausen integral, Lobachevsky function, Im(Li2)
- Add hyper_ideal_utility.hpp: generalized and ideal-vertex hyperbolic
  tetrahedron volume formulas using Eigen for the 4x4 Gram determinant
- Port ClausenTest (5 tests) and HyperIdealUtilityTest (8 tests) from
  Java/JUnit — all 13 pass with same tolerances as the Java originals
- Fix pre-existing VIEWER/viewer case mismatch in CMakeLists.txt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 01:07:19 +02:00
Tarik Moussa
94533514fc fix typo 2026-03-17 21:25:33 +02:00
Tarik Moussa
e150cf6ef3 add new compile target for viewer 2026-03-17 21:18:59 +02:00
Tarik Moussa
2479aedeee ad simple visualization 2026-03-16 17:47:48 +02:00
Tarik Moussa
1ce993f296 ad simple visualization 2026-03-16 17:20:15 +02:00