Files
ConformalLabpp/doc/getting-started.md
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

211 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Getting Started
## Prerequisites
| Tool | Minimum | Notes |
|---|---|---|
| C++ compiler (GCC or Clang) | C++17 | GCC 11+ or Clang 14+ recommended |
| CMake | 3.20 | |
| Boost headers | 1.70 | Only for `-DWITH_CGAL_TESTS=ON` or `-DWITH_CGAL=ON` |
| Wayland/X11 dev headers | — | Only for `-DWITH_CGAL=ON` (viewer) |
All other dependencies (Eigen 3.4, CGAL 6.1.1, libigl 2.6, GLFW 3.4, GTest 1.14)
are bundled as tarballs in `code/deps/tarballs/` and extracted automatically at CMake
configure time. No internet access is required at build time (except GTest, fetched via
`FetchContent` from GitHub).
Install Boost on your system:
```bash
# Ubuntu / Debian
apt install libboost-dev
# macOS
brew install boost
```
---
## Clone
```bash
git clone https://codeberg.org/TMoussa/ConformalLabpp
cd ConformalLabpp
```
---
## Build modes
Three modes with increasing dependencies:
### Mode 1 — Fast tests (default, no system dependencies)
Pure-math tests: Clausen functions, hyper-ideal geometry, matrix utilities.
```bash
cmake -S code -B build
cmake --build build --target conformallab_tests -j$(nproc)
ctest --test-dir build --output-on-failure
```
Expected: all pure-math tests pass (count: [`doc/api/tests.md`](api/tests.md)).
### Mode 2 — CGAL tests, headless (recommended for CI and development)
Full CGAL test suite. Requires Boost headers only — no display, no Wayland, no GLFW.
```bash
cmake -S code -B build -DWITH_CGAL_TESTS=ON
cmake --build build --target conformallab_cgal_tests -j$(nproc)
ctest --test-dir build -R "^cgal\." --output-on-failure
```
Expected: all CGAL tests pass, 0 skipped (count: [`doc/api/tests.md`](api/tests.md)).
### Mode 3 — Full local build (CLI app + interactive viewer)
Requires Wayland or X11 development packages (`wayland-scanner`, `libx11-dev`, etc.).
Automatically enables the viewer library (GLFW + libigl).
```bash
cmake -S code -B build -DWITH_CGAL=ON
cmake --build build -j$(nproc)
```
> **Note:** `-DWITH_CGAL=ON` implies `-DWITH_VIEWER=ON`. Do not use this in headless
> environments — it will fail with `Failed to find wayland-scanner`.
---
## Running a single test
```bash
# By GTest filter (fastest, full output)
./build/conformallab_cgal_tests --gtest_filter="NewtonSolver*"
./build/conformallab_tests --gtest_filter="Clausen*"
# By CTest regex
ctest --test-dir build -R "cgal.NewtonSolver" --output-on-failure
```
All CGAL tests have the prefix `cgal.` in CTest (set in `tests/cgal/CMakeLists.txt`
via `TEST_PREFIX "cgal."`).
---
## First run — CLI app
After a full build (`-DWITH_CGAL=ON`):
```bash
# Euclidean conformal layout
./bin/conformallab_core -i input.off -g euclidean -o layout.off -j result.json
# Spherical layout
./bin/conformallab_core -i input.off -g spherical -o sphere.off
# Hyperbolic layout (HyperIdeal)
./bin/conformallab_core -i input.off -g hyper_ideal -o hyperbolic.off
# Show input mesh in interactive viewer
./bin/conformallab_core -i input.off -s
# All options
./bin/conformallab_core --help
```
## Example programs
```bash
# PRIMARY USE CASE: conformally flatten a mesh to the plane
./build/examples/example_flatten code/data/obj/cathead.obj flat.off
# → non-trivial u_v (e.g. range ≈ 2.96), real conformal deformation
# CGAL public API: one-call interface (natural theta by default)
./build/examples/example_cgal_api [input.off]
# Full pipeline with JSON/XML serialisation and round-trip test
./build/examples/example_layout [input.off] [layout.off] [result.json]
# Solver test (natural theta — u_v ≈ 0, used for pipeline validation)
./build/examples/example_euclidean [input.off] [output.off]
# Hyper-ideal (hyperbolic) functional
./build/examples/example_hyper_ideal [input.off] [output.off]
# Interactive viewer (requires WITH_VIEWER)
./build/examples/example_viewer [input.off]
```
**Start here:** `example_flatten.cpp` shows the primary use case — real conformal
flattening with `Θ_v = 2π`. `example_layout.cpp` adds JSON/XML serialisation.
> **Note on "natural theta":** `example_euclidean` and `example_layout` use the
> "natural theta" testing trick (`Θ_v = actual angle sum at x=0`), which makes
> `x* = 0` trivially the equilibrium. The output `u_v ≈ 0` is expected and
> correct for a pipeline test, but means **no conformal deformation was applied**.
> For real UV parameterisation, use `example_flatten.cpp`.
**Expected output of `example_euclidean` on the built-in quad-strip mesh:**
```
[example_euclidean] No input file given — using make_quad_strip().
[example_euclidean] Mesh: 6 vertices, 4 faces.
[example_euclidean] DOFs: 5 (1 vertex pinned).
[example_euclidean] Solving Newton system…
[example_euclidean] Converged in 1 iterations. ||G||_inf = 0
[example_euclidean] Per-vertex conformal factors u_i:
v0 u = 0 (pinned)
v1 u = -1.38778e-17 ← ≈ 0 (machine epsilon)
...
[example_euclidean] Mesh saved to: /tmp/conformallab_euclidean_out.off
```
Convergence in 1 iteration is expected: the "natural equilibrium" construction
sets x* = 0, so a small perturbation (-0.05) needs only one Newton step.
**Quick automated start (no interactive build needed):**
```bash
bash scripts/try_it.sh
```
This clones nothing (run from inside the repo), builds the CGAL test suite, runs
the full test suite, and prints a summary. See `scripts/try_it.sh` for details.
---
## Known issues
### macOS Finder duplicates
macOS Finder sometimes creates duplicate files named `foo 2.hpp` when copying
the repository. These cause confusing compile errors ("redefinition of …").
**Fix (run once from the repo root):**
```bash
find code/include -name "* 2.*" -delete
find code/include -name "*\ 2.*" -delete
```
Files without a ` 2` suffix are always canonical — the duplicates are safe to delete.
### First build is slow
The first CMake configure extracts four tarballs (Eigen 3.4, CGAL 6.1.1,
libigl 2.6, GLFW 3.4) and downloads GTest via `FetchContent`.
Allow **3090 seconds** for the first configure. Subsequent builds are fast
(< 10 s incremental).
---
## Rebuilding the CI Docker image
The CI runner is a self-hosted Raspberry Pi (ARM64). After changes to
`.gitea/docker/Dockerfile.ci-cpp`:
```bash
docker buildx build \
--platform linux/arm64 \
-f .gitea/docker/Dockerfile.ci-cpp \
-t git.eulernest.eu/conformallab/ci-cpp:latest \
--push \
.gitea/docker/
```