505dd4b0a5
Merge pull request 'refactor(api): consistent naming for spherical + hyper-ideal helpers (A1–A3)' ( #36 ) from refactor/api-naming-a1-a3 into main
C++ Tests / test-fast (push) Failing after 2m2s
C++ Tests / quality-gates (push) Has been skipped
API Docs / doc-build (push) Has been skipped
Markdown link check / check (push) Has been skipped
Mirror to Codeberg / mirror (push) Successful in 28s
C++ Tests / test-cgal (push) Has been skipped
2026-05-31 17:43:42 +00:00
Tarik Moussa
65fc8ac816
refactor(api): consistent naming for spherical + hyper-ideal helpers (A1–A3)
...
C++ Tests / test-fast (pull_request) Successful in 2m20s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
Standardize the low-level free-function API on <verb>_<geom>_<rest>,
matching the already-consistent setup_<geom>_maps. Old names kept as
[[deprecated]] inline aliases for one release; all internal call sites
migrated.
Renames:
assign_vertex_dof_indices -> assign_spherical_vertex_dof_indices
assign_all_spherical_dof_indices -> assign_spherical_all_dof_indices
assign_all_dof_indices -> assign_hyper_ideal_all_dof_indices
compute_lambda0_from_mesh -> compute_spherical_lambda0_from_mesh
gradient_check -> gradient_check_hyper_ideal
A4/A5 (public CGAL API) intentionally deferred pending the license/
provenance decision (see CGAL submission audit G0/G1).
Verified: 277/277 CGAL tests pass, no deprecation warnings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-05-31 10:37:06 +02:00
Tarik Moussa
37b538aae4
docs: Layout2D index semantics, CLI table, CLI roadmap (U9+U10+U11)
...
C++ Tests / test-fast (push) Has been cancelled
C++ Tests / test-cgal (push) Has been cancelled
C++ Tests / quality-gates (push) Has been cancelled
API Docs / doc-build (push) Has been cancelled
Markdown link check / check (push) Has been cancelled
C++ Tests / test-fast (pull_request) Successful in 2m10s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
U9 (layout.hpp + example_layout.cpp)
Layout2D.uv and .halfedge_uv now have explicit Doxygen docs stating:
- indexing: v.idx() / h.idx() (raw integer index)
- length: mesh.number_of_vertices() / number_of_halfedges()
- precondition: no vertex removal / collect_garbage() after loading
- access pattern example in the doc comment
example_layout.cpp: access site comment + static_cast<size_t>(v.idx())
U10 (getting-started.md)
New 'CLI parameter reference' table (7 rows) added directly below the
CLI usage examples; cross-references --help as the canonical source
U11 (doc/roadmap/phases.md)
New Phase 9h 'CLI usability extensions' section inserted before Phase 10:
9h.1 --tol / --max-iter solver-tuning params (~30 min, no deps)
9h.2 -g cp_euclidean / -g inversive_distance (~2-4 h, needs 9a ✅ )
Each sub-task has effort estimate, implementation sketch, and
acceptance criteria so a future session can pick it up cold.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 01:51:04 +02:00
Tarik Moussa
ccbfd852b2
docs(examples): use gauge-vertex overload everywhere (U6)
...
Finding-U6 from doc/reviewer/usability-audit-2026-05-31.md.
The Finding-D fix (external-audit-2026-05-30) added a clean one-call
gauge-vertex overload:
assign_euclidean_vertex_dof_indices(mesh, maps, gauge_vertex)
But all user-facing code still showed the old verbose manual loop:
auto vit = mesh.vertices().begin();
maps.v_idx[*vit++] = -1;
int idx = 0;
for (; vit != mesh.vertices().end(); ++vit) maps.v_idx[*vit] = idx++;
Replaced in three places:
README.md 'Minimal usage' code block
example_euclidean.cpp Step 3
example_layout.cpp pin_first() helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 01:49:05 +02:00
Tarik Moussa
02a3745b67
examples: add real conformal-flattening + CGAL-API examples (U1+U2)
...
Finding-U1 and Finding-U2 from doc/reviewer/usability-audit-2026-05-31.md.
The existing examples (example_euclidean, example_layout, example_hyper_ideal)
all used the "natural theta" pattern which makes x*=0 trivially the
equilibrium — u_v ≈ 0 everywhere, no deformation. A new user following
these examples saw solver output but not conformal geometry.
New: example_flatten.cpp
- PRIMARY USE CASE: conformally flatten a mesh to the plane
- Sets Θ_v = 2π for all interior vertices (flat target)
- Pins boundary vertices (no Gauss-Bonnet check for open meshes)
- Demonstrates non-trivial u_v (cathead.obj: range ≈ 2.96, 5 Newton iters)
- Documents the difference from "natural theta" explicitly
New: example_cgal_api.cpp
- Demonstrates CGAL::discrete_conformal_map_euclidean (Discrete_conformal_map.h)
- First runnable CGAL public API example; contrast with internal API
- Documents the "natural theta" default behaviour and explains why u_v=0
- Explains when to use CGAL API vs internal API
Both examples registered in code/examples/CMakeLists.txt and compile
cleanly with -DWITH_CGAL=ON.
Updated:
- example_euclidean.cpp: prominent "TESTING CONVENTION" warning
- example_layout.cpp: same warning on set_natural_theta helper
- doc/getting-started.md: example_flatten is now the recommended
"start here" example; note on natural-theta behaviour added
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 01:35:37 +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