Files
ConformalLabpp/doc/getting-started.md
Tarik Moussa d1399ca82f docs: fix stale version, CGAL header, add LOW_MEMORY_BUILD docs (U4+U5+U7+U8)
U4 (README.md:17) — status line: v0.9.0 → v0.10.0, test count 0 → 277

U5 (Discrete_conformal_map.h:6-16) — \file Doxygen block rewritten:
  was: 'provides a single function … Spherical/hyperbolic scheduled for Phase 8b.2'
  now: lists all three discrete_conformal_map_* functions already present,
       plus pointers to the circle-packing companion headers

U7 (getting-started.md) — new 'Mode 4 — Low-memory build' section added
  after Mode 3; shows CONFORMALLAB_LOW_MEMORY_BUILD=ON with -j1 and explains
  the -O0 / no PCH / batch-1 tradeoffs for Raspberry Pi / ≤ 4 GB runners

U8 (README.md compile-time modes) — LOW_MEMORY_BUILD entry added to the
  compile-time workflow code block with a one-line explanation and the
  mandatory -j1 note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:46:08 +02:00

6.8 KiB
Raw Blame History

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:

# Ubuntu / Debian
apt install libboost-dev

# macOS
brew install boost

Clone

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.

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).

Full CGAL test suite. Requires Boost headers only — no display, no Wayland, no GLFW.

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).

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).

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):

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

# 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):

# 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

# 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 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):

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:

docker buildx build \
  --platform linux/arm64 \
  -f .gitea/docker/Dockerfile.ci-cpp \
  -t git.eulernest.eu/conformallab/ci-cpp:latest \
  --push \
  .gitea/docker/