# 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`. ### Mode 4 — Low-memory build (RAM-constrained CI / Raspberry Pi ≤ 4 GB) For machines where the CGAL build OOMs (peak ~700 MB per compilation unit at `-O3`): ```bash cmake -S code -B build -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_LOW_MEMORY_BUILD=ON cmake --build build --target conformallab_cgal_tests -j1 ``` `LOW_MEMORY_BUILD` applies four measures: `-O0` (no debug info), PCH off, unity batch size 1, `--no-keep-memory` linker flag. Drops cc1plus peak from ~700 MB to ~150-200 MB per TU. Tests run ~15× slower at `-O0` but all pass. **Always use `-j1`** — parallel compilation would defeat the memory savings. --- ## 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 **30–90 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/ ```