# tests/cgal/CMakeLists.txt # # CGAL-dependent test target. Only built when -DWITH_CGAL=ON. # Requires Boost (find_package(Boost REQUIRED) is called in the root CMakeLists). # # Run with: # cmake -S code -B build -DWITH_CGAL=ON # cmake --build build --target conformallab_cgal_tests # ctest --test-dir build -R cgal add_executable(conformallab_cgal_tests # ── Phase 3a: mesh infrastructure ────────────────────────────────────── test_conformal_mesh.cpp # ── Phase 3b: HyperIdealFunctional ───────────────────────────────────── test_hyper_ideal_functional.cpp # ── Phase 3c + 3e: SphericalFunctional + gauge-fix ──────────────────── test_spherical_functional.cpp # ── Phase 3d: EuclideanCyclicFunctional ─────────────────────────────── test_euclidean_functional.cpp # ── Phase 3f: Hessians (cotangent Laplacian, spherical + Euclidean) ─── test_euclidean_hessian.cpp test_spherical_hessian.cpp # ── Phase 9b: Hyper-ideal Hessian — block-FD vs full-FD validation ─── # Verifies the O(F·36) block-local Hessian agrees with the # O(F·n) full-FD baseline. Java upstream has no Hessian at all # (HyperIdealFunctional.hasHessian() returns false) — both # variants are conformallab++ extensions beyond the port. test_hyper_ideal_hessian.cpp # ── Phase 4a: Newton solver ──────────────────────────────────────────── test_newton_solver.cpp # ── Phase 4b: Mesh I/O (CGAL::IO) ───────────────────────────────────── test_mesh_io.cpp # ── Phase 4c: End-to-end pipeline + user examples ───────────────────── test_pipeline.cpp # ── Phase 5: Layout / embedding + serialization ──────────────────────── test_layout.cpp # ── Phase 6: Gauss–Bonnet, cut graph, exact trilateration, normalisation test_phase6.cpp # ── Phase 7: Java-parity layout — MobiusMap, priority BFS, halfedge_uv, # period matrix, fundamental domain, tiling test_phase7.cpp # ── Java parity: geometry utility tests ────────────────────────────────── # Ported from CuttinUtilityTest, UnwrapUtilityTest, # ConvergenceUtilityTests, HomologyTest. All tests active — # the v0.7.0 genus-2 homology stub was implemented in Phase 7 # (HomologyGenerators.Genus2_FourCutEdges, brezel2.obj). test_geometry_utils.cpp # ── Scalability smoke tests ──────────────────────────────────────────────── # Newton convergence on large real-world meshes (cathead, brezel, brezel2). # Assert correctness only (< 30 iterations, ||G|| < 1e-8). # Wall-clock time is printed for documentation but NOT asserted, # so the tests remain stable on slow CI hardware (Raspberry Pi ARM64). test_scalability_smoke.cpp # ── Phase 8 MVP: new CGAL-style public API ──────────────────────────────── # First client of Conformal_map_traits.h + Discrete_conformal_map.h. # Acceptance probe before Phase 9a (Inversive-Distance) lands. test_cgal_traits_mvp.cpp # ── Phase 9a.1: CPEuclideanFunctional (BPS 2010 circle packing) ────────── # Face-based circle-packing functional ported from # CPEuclideanFunctional.java. Reference: Bobenko-Pinkall-Springborn 2010. test_cp_euclidean_functional.cpp # ── Phase 9a.2: InversiveDistance (Luo 2004 + Glickenstein 2011) ───────── # Vertex-based inversive-distance circle-packing functional. No Java # reference; implemented from the literature. Cross-validated against # EuclideanCyclicFunctional at the natural initial geometry (u = 0). test_inversive_distance_functional.cpp # ── Phase 9a: Newton solvers for the two new circle-packing functionals ── # Convergence tests for newton_cp_euclidean (analytic Hessian) and # newton_inversive_distance (FD Hessian). test_newton_phase9a.cpp # ── Tier-3 Java cross-validation: Lawson square-tiled HyperIdeal ───────── # Low-level half-edge genus-2 generator + golden-vector convergence. test_lawson_hyperideal.cpp # ── Pn projective-metric substrate (de.jreality.math.Pn port) ─────────── # Inner product / norm / distance / geodesic interpolation in # Euclidean, Elliptic, Hyperbolic signatures. test_pn_geometry.cpp # ── Phase 8b-Lite: CGAL entry wrappers for the 4 non-Euclidean modes ───── # Spherical, HyperIdeal, CircleP-Euclidean, Inversive-Distance via # public API + Conformal_layout.h wrapper. test_cgal_phase8b_lite.cpp # ── Phase 9g.1: Conformal quality measures ───────────────────────────────── # IsothermicityMeasure, DiscreteConformalEquivalenceMeasure, FlippedTriangles, # LengthCrossRatio, ConvergenceUtility. Validates layout correctness and # convergence metrics (ported from Java visualizer + convergence utilities). test_conformal_quality.cpp # ── Phase 9d.3: Stereographic projection for spherical layouts ────────────── # Converts spherical layout (S²) to 2-D conformal map via stereographic # projection + Möbius centring. Tests round-trip consistency. test_stereographic_layout.cpp ) target_include_directories(conformallab_cgal_tests SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/deps/eigen-3.4.0 ${CMAKE_SOURCE_DIR}/deps/CGAL-6.1.1/include ${CMAKE_SOURCE_DIR}/deps/single_includes ${Boost_INCLUDE_DIRS} ) target_include_directories(conformallab_cgal_tests PRIVATE ${CMAKE_SOURCE_DIR}/include ) target_compile_definitions(conformallab_cgal_tests PRIVATE CGAL_DISABLE_GMP CGAL_DISABLE_MPFR # Data directory — absolute path to code/data/ at build time. # Used by tests that load real mesh files (cathead.obj, brezel2.obj, …). CONFORMALLAB_DATA_DIR="${CMAKE_SOURCE_DIR}/data" ) # Suppress warnings from CGAL/Boost headers target_compile_options(conformallab_cgal_tests PRIVATE $<$:-Wno-unused-parameter> ) # Fast test-build mode (lever #10): -O0 -g overrides the inherited # Release-mode -O3 + -DNDEBUG. Applies only to this test target. if(CONFORMALLAB_FAST_TEST_BUILD) target_compile_options(conformallab_cgal_tests PRIVATE $<$:-O0 -g -UNDEBUG> ) endif() # ── Low-memory build mode (for RAM-constrained CI runners, e.g. Raspberry Pi) ── # # Problem: CGAL + Eigen at -O3 drives cc1plus peak RAM to ~600-800 MB per # Unity compilation unit on ARM64 Linux. A 1600 MB container limit with a # batch of 4 files per unit causes OOM-kill during the build. # # This flag enables three orthogonal memory-saving measures: # # 1. -O0 (no debug info): drops cc1plus backend RAM by ~60-70 %. # Optimizer passes (inlining, register allocation, constant propagation) # dominate the backend. At -O0 they are entirely skipped → peak per # TU falls from ~700 MB to ~150-200 MB on ARM64. # We omit -g deliberately: debug info adds ~30-40 % object-file size # and increases linker RSS. CI needs "does it compile + do tests pass", # not debuggability. # # 2. PCH OFF: the precompiled header itself consumes ~200 MB to compile # and is re-read by every TU. Disabling it saves the one-time PCH # compilation cost; each TU re-parses CGAL headers, but at -O0 this # is fast. # # 3. UNITY_BUILD_BATCH_SIZE=1: one source file per unity unit. Removes # the "4 files × CGAL parse cost" multiplier; each cc1plus process # only sees one file worth of templates. # # 4. Linker memory flag (GCC/Clang only): --no-keep-memory tells GNU ld # to release symbol table memory after each input file instead of # keeping it for cross-reference. Reduces linker RSS by 15-25 % at # the cost of slightly longer link time. # # Activate with: # cmake -S code -B build -DWITH_CGAL_TESTS=ON \ # -DCONFORMALLAB_LOW_MEMORY_BUILD=ON # Expected peak per cc1plus: ~150-200 MB → fits in 1800-2000 MB container. # Test runtime is 2-4× slower than Release (CGAL traversals unoptimized), # but correctness is unaffected. option(CONFORMALLAB_LOW_MEMORY_BUILD "Build CGAL tests with -O0, no PCH, UNITY_BATCH_SIZE=1 for RAM-constrained CI." OFF) if(CONFORMALLAB_LOW_MEMORY_BUILD) message(STATUS "CONFORMALLAB_LOW_MEMORY_BUILD active: -O0, no PCH, unity batch 1.") # 1. -O0, no debug info target_compile_options(conformallab_cgal_tests PRIVATE $<$:-O0 -UNDEBUG> ) # 2. PCH off — force-override the option so the block below is skipped set(CONFORMALLAB_USE_PCH OFF CACHE BOOL "" FORCE) # 3. Unity batch size = 1 (one source file per compilation unit) set_target_properties(conformallab_cgal_tests PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE BATCH UNITY_BUILD_BATCH_SIZE 1) # 4. Linker memory hint (GNU ld / lld) target_link_options(conformallab_cgal_tests PRIVATE $<$:-Wl,--no-keep-memory>) endif() target_link_libraries(conformallab_cgal_tests PRIVATE GTest::gtest_main) # ── Compile-time speed-up: precompiled headers ─────────────────────────────── # # The CGAL+Eigen template soup dominates every TU in this target: # measured at 5.9 s per minimal "include " # TU on Apple M1. A shared PCH absorbs that cost once, slashing the # total wall-clock from ~78 s (j8) to ~25 s (3×). # # Opt-out with -DCONFORMALLAB_USE_PCH=OFF if the PCH itself misbehaves # (e.g. older toolchains that don't share PCH across translation units # reliably) — falls back to the historical "every TU re-parses CGAL" # build mode. option(CONFORMALLAB_USE_PCH "Enable precompiled headers for the CGAL test target." ON) if(CONFORMALLAB_USE_PCH) # Per-target Unity Build property takes precedence over the global # CMAKE_UNITY_BUILD; honour CONFORMALLAB_DEV_BUILD's preference here # so `-DCONFORMALLAB_DEV_BUILD=ON` truly turns Unity Build off for # incremental-rebuild workflows. if(NOT CONFORMALLAB_DEV_BUILD) set_target_properties(conformallab_cgal_tests PROPERTIES # Unity-builds amortise the per-TU CGAL+Eigen header cost # across several tests in the same compile. Batch size 4 # keeps gtest's TEST(...) macros + per-file `using # namespace …` from colliding while still cutting parser # cost ~4×. UNITY_BUILD ON UNITY_BUILD_MODE BATCH UNITY_BUILD_BATCH_SIZE 4) endif() target_precompile_headers(conformallab_cgal_tests PRIVATE # CGAL headers that every test transitively includes. # Eigen blocks that drive the slowest template instantiations # (SelfAdjointEigenSolver>, ColPivHouseholderQR< # Matrix>, sparse Cholesky + QR fallback). # GoogleTest itself; every test includes it. # std headers that appear in every test. ) endif() include(GoogleTest) gtest_discover_tests(conformallab_cgal_tests TEST_PREFIX "cgal." DISCOVERY_TIMEOUT 60 )