From 4b55254c416a329cd84cb019027e8f55333c2f80 Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:13:36 +0200 Subject: [PATCH 1/7] initial refactoring of CMake setup --- CMakeLists.txt | 67 ++++- src/CMakeLists.txt | 364 ++++++++------------------- src/browser/CMakeLists.txt | 17 ++ src/browser/res/CMakeLists.txt | 3 + src/dag_builder/CMakeLists.txt | 18 ++ src/dag_convert_debug/CMakeLists.txt | 5 + src/index_browser/CMakeLists.txt | 5 + src/mesh_builder/CMakeLists.txt | 9 + src/mesh_convert/CMakeLists.txt | 5 + src/mesh_merger/CMakeLists.txt | 5 + src/mesh_simplify/CMakeLists.txt | 10 + src/sf_merger/CMakeLists.txt | 9 + src/terrainlib/CMakeLists.txt | 81 ++++++ src/tile_builder/CMakeLists.txt | 15 ++ src/tile_downloader/CMakeLists.txt | 5 + unittests/CMakeLists.txt | 113 ++++----- 16 files changed, 394 insertions(+), 337 deletions(-) create mode 100644 src/browser/CMakeLists.txt create mode 100644 src/dag_builder/CMakeLists.txt create mode 100644 src/dag_convert_debug/CMakeLists.txt create mode 100644 src/index_browser/CMakeLists.txt create mode 100644 src/mesh_builder/CMakeLists.txt create mode 100644 src/mesh_convert/CMakeLists.txt create mode 100644 src/mesh_merger/CMakeLists.txt create mode 100644 src/mesh_simplify/CMakeLists.txt create mode 100644 src/sf_merger/CMakeLists.txt create mode 100644 src/terrainlib/CMakeLists.txt create mode 100644 src/tile_builder/CMakeLists.txt create mode 100644 src/tile_downloader/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f8cef9fe..e9f4b1fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,39 @@ cmake_minimum_required(VERSION 3.21) -project(alpine-terrain-builder) -option(ALP_UNITTESTS "include unit test targets in the buildsystem" ON) +project(alpine-terrain-builder LANGUAGES C CXX) -# ASAN & TSAN -option(ALP_ENABLE_THREAD_SANITIZER "compiles with thread sanitizer enabled" OFF) -option(ALP_ENABLE_ADDRESS_SANITIZER "compiles with address sanitizer enabled" OFF) +# Executable targets +option(ALP_BUILD_TILE_BUILDER "Build tile-builder" ON) +option(ALP_BUILD_SF_MERGER "Build sf-merger" ON) +option(ALP_BUILD_MESH_BUILDER "Build mesh-builder" ON) +option(ALP_BUILD_MESH_SIMPLIFY "Build mesh-simplify" ON) +option(ALP_BUILD_TILE_DOWNLOADER "Build tile-downloader" ON) +option(ALP_BUILD_MESH_CONVERT "Build mesh-convert" ON) +option(ALP_BUILD_MESH_MERGER "Build mesh_merger" ON) +option(ALP_BUILD_INDEX_BROWSER "Build index-browser" ON) +option(ALP_BUILD_DAG_BUILDER "Build dag-builder" ON) +option(ALP_BUILD_DAG_CONVERT_DEBUG "Build dag-convert-debug" ON) +option(ALP_BUILD_BROWSER "Build browser" ON) +option(ALP_BUILD_UNITTESTS "Build unit tests for enabled components" ON) -if(ALP_ENABLE_ADDRESS_SANITIZER) - if(ALP_ENABLE_THREAD_SANITIZER) - message(FATAL_ERROR "Cannot enable both AddressSanitizer and ThreadSanitizer") - endif() +# Project configuration +option(ALP_ENABLE_THREAD_SANITIZER "Compile with ThreadSanitizer enabled" OFF) +option(ALP_ENABLE_ADDRESS_SANITIZER "Compile with AddressSanitizer enabled" OFF) +option(ALP_ENABLE_OVERVIEW_READING "Enable GDAL overview reading (broken with newer GDAL versions)" OFF) +option(ALP_ENABLE_UNITY_BUILD "Enable unity (jumbo) builds to speed compilation" OFF) +set(ALP_UNITY_BUILD_BATCH_SIZE 4 CACHE STRING "Number of source files per unity translation unit") +set(ALP_RELEASE_OPT_LEVEL "3" CACHE STRING "Optimization level (0=O0,1=O1,2=O2,3=O3)") + +# Unit-test configuration +option(ATB_UNITTESTS_EXTENDED "Perform extended unit tests (they take long)" OFF) +option(ATB_UNITTESTS_DEBUG_IMAGES "Output debug height images for visual comparison" OFF) +set(ATB_UNITTESTS_AUSTRIA_HIGHRES "" CACHE FILEPATH "Path to the high resolution Austrian terrain dataset") + +if(ALP_ENABLE_ADDRESS_SANITIZER AND ALP_ENABLE_THREAD_SANITIZER) + message(FATAL_ERROR "Cannot enable both AddressSanitizer and ThreadSanitizer") endif() +set(ALP_SANITIZER_FLAGS) if(ALP_ENABLE_ADDRESS_SANITIZER) message(STATUS "AddressSanitizer enabled") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") @@ -26,8 +47,7 @@ endif() if(ALP_ENABLE_THREAD_SANITIZER) if(CMAKE_BUILD_TYPE STREQUAL "Release") - message(WARNING "ThreadSanitizer is not recommended with Release builds. " - "Use Debug or RelWithDebInfo for accurate race detection.") + message(WARNING "ThreadSanitizer is not recommended with Release builds. Use Debug or RelWithDebInfo for accurate race detection.") endif() message(STATUS "ThreadSanitizer enabled") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") @@ -39,11 +59,32 @@ if(ALP_ENABLE_THREAD_SANITIZER) endif() endif() +if(CMAKE_BUILD_TYPE MATCHES Release) + set(ALP_ENABLE_ASSERTS ON CACHE BOOL "Do not define NDEBUG even in Release mode, i.e., enable asserts" FORCE) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Using optimization level ${ALP_RELEASE_OPT_LEVEL}") + add_compile_options($<$:-O${ALP_RELEASE_OPT_LEVEL}>) +endif() + +# Compiler launchers must be configured before targets are created. +find_program(SCCACHE_PROGRAM sccache) +find_program(CCACHE_PROGRAM ccache) +if(SCCACHE_PROGRAM) + message(STATUS "Using sccache as compiler launcher: ${SCCACHE_PROGRAM}") + set(CMAKE_C_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}") +elseif(CCACHE_PROGRAM) + message(STATUS "Using ccache as compiler launcher: ${CCACHE_PROGRAM}") + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") +endif() + include(cmake/AddRepo.cmake) include(cmake/SetupCMakeProject.cmake) - add_subdirectory(src) -if (ALP_UNITTESTS) +if(ALP_BUILD_UNITTESTS) add_subdirectory(unittests) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05452981..2249a197 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,28 +1,7 @@ -cmake_minimum_required(VERSION 3.19) -project(terrain_builder_src LANGUAGES C CXX) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}") -# TODO: This is needed to avoid NDEBUG being undefined on Release -if (CMAKE_BUILD_TYPE MATCHES Release) - set(ALP_ENABLE_ASSERTS ON CACHE BOOL "" FORCE) -endif() - -option(ALP_ENABLE_OVERVIEW_READING "enable GDAL overview reading (broken with newer GDAL versions)" OFF) - -set(ALP_RELEASE_OPT_LEVEL "3" CACHE STRING "Optimization level (0=O0,1=O1,2=O2,3=O3)") - -if (CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Using optimization level ${ALP_RELEASE_OPT_LEVEL}") - set(CMAKE_CXX_FLAGS_RELEASE "-O${ALP_RELEASE_OPT_LEVEL}") -endif() - +# Dependencies used by the unconditional terrainlib umbrella target. find_package(ZLIB REQUIRED) -find_package(CURL REQUIRED) alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 12.2.0) -alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH v2.6.1) alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH 3.4.0 DO_NOT_ADD_SUBPROJECT) add_library(Eigen3 INTERFACE) @@ -62,274 +41,131 @@ target_include_directories(tl_expected INTERFACE SYSTEM ${tl_expected_SOURCE_DIR set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "SPDLOG_FMT_EXTERNAL" FORCE) alp_add_git_repository(spdlog URL https://github.com/gabime/spdlog.git COMMITISH v1.17.0) -add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COMMITISH v4.7.2 DO_NOT_ADD_SUBPROJECT) add_library(zpp_bits INTERFACE) target_include_directories(zpp_bits INTERFACE SYSTEM ${zpp_bits_SOURCE_DIR}) alp_add_git_repository(libassert URL https://github.com/jeremy-rifkin/libassert.git COMMITISH v2.1.0) - alp_add_git_repository(magic_enum URL https://github.com/Neargye/magic_enum.git COMMITISH v0.9.7) - -alp_add_git_repository(ftxui URL https://github.com/ArthurSonzogni/FTXUI COMMITISH v6.1.9) - alp_add_git_repository(meshoptimizer URL https://github.com/zeux/meshoptimizer.git COMMITISH v1.0.1) -alp_add_git_repository(xatlas URL https://github.com/jpcy/xatlas COMMITISH f700c7790aaa030e794b52ba7791a05c085faf0c DO_NOT_ADD_SUBPROJECT) -add_library(xatlas STATIC ${xatlas_SOURCE_DIR}/source/xatlas/xatlas.cpp) -target_include_directories(xatlas PUBLIC ${xatlas_SOURCE_DIR}/source) - set(LIBIGL_COPYLEFT_CORE ON) set(LIBIGL_RESTRICTED_TRIANGLE ON) alp_add_git_repository(libigl URL https://github.com/libigl/libigl.git COMMITISH v2.6.0) -alp_add_git_repository(rectpack2D URL https://github.com/TeamHypersomnia/rectpack2D.git COMMITISH bbc9d0ec05b9b508f6c781667fec718bf9e78d21) +alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH 2ce3484513b826bb11e5433f868b048eaffe3e5d NOT_SYSTEM DEEP_CLONE) -set(METIS_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) -set(METIS_INSTALL OFF CACHE BOOL "" FORCE) -alp_add_git_repository(metis URL https://github.com/scivision/metis COMMITISH v5.2.1.2) -target_compile_definitions(metis INTERFACE IDXTYPEWIDTH=32 REALTYPEWIDTH=32) +set(ALP_CLI_COMPONENT_OPTIONS + ALP_BUILD_SF_MERGER + ALP_BUILD_MESH_BUILDER + ALP_BUILD_MESH_SIMPLIFY + ALP_BUILD_TILE_DOWNLOADER + ALP_BUILD_MESH_CONVERT + ALP_BUILD_MESH_MERGER + ALP_BUILD_INDEX_BROWSER + ALP_BUILD_DAG_BUILDER + ALP_BUILD_DAG_CONVERT_DEBUG +) +set(ALP_NEEDS_CLI11 OFF) +foreach(option_name IN LISTS ALP_CLI_COMPONENT_OPTIONS) + if(${option_name}) + set(ALP_NEEDS_CLI11 ON) + endif() +endforeach() +if(ALP_NEEDS_CLI11) + alp_add_git_repository(cli11 URL https://github.com/CLIUtils/CLI11.git COMMITISH v2.6.1) +endif() -alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMMITISH 2ce3484513b826bb11e5433f868b048eaffe3e5d NOT_SYSTEM DEEP_CLONE) +if(ALP_BUILD_TILE_DOWNLOADER) + find_package(CURL REQUIRED) +endif() -# Don't build glfw docs, tests and examples -set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) -set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) -if (UNIX) - # Enable Wayland and X11 on Unix builds - set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) - set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) -endif (UNIX) -alp_add_git_repository(glfw URL https://github.com/glfw/glfw.git COMMITISH e7ea71be039836da3a98cea55ae5569cb5eb885c NOT_SYSTEM) +if(ALP_BUILD_INDEX_BROWSER) + alp_add_git_repository(ftxui URL https://github.com/ArthurSonzogni/FTXUI COMMITISH v6.1.9) +endif() -alp_add_git_repository(glad URL https://github.com/Dav1dde/glad.git COMMITISH 431786d8126e4f383a81e36f47b61a5d52a1c20d DO_NOT_ADD_SUBPROJECT) -add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) -glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) +if(ALP_BUILD_DAG_BUILDER OR ALP_BUILD_DAG_CONVERT_DEBUG) + alp_add_git_repository(xatlas URL https://github.com/jpcy/xatlas COMMITISH f700c7790aaa030e794b52ba7791a05c085faf0c DO_NOT_ADD_SUBPROJECT) + add_library(xatlas STATIC ${xatlas_SOURCE_DIR}/source/xatlas/xatlas.cpp) + target_include_directories(xatlas PUBLIC ${xatlas_SOURCE_DIR}/source) -alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237 NOT_SYSTEM) -add_subdirectory(browser/res resources-lib) + alp_add_git_repository(rectpack2D URL https://github.com/TeamHypersomnia/rectpack2D.git COMMITISH bbc9d0ec05b9b508f6c781667fec718bf9e78d21) -alp_add_git_repository(imgui URL https://github.com/ocornut/imgui.git COMMITISH 5f0acadf7db1b6d469f0771284e2e3f7818443ce DO_NOT_ADD_SUBPROJECT) -add_library(imgui STATIC - ${imgui_SOURCE_DIR}/imgui.cpp - ${imgui_SOURCE_DIR}/imgui_draw.cpp - ${imgui_SOURCE_DIR}/imgui_tables.cpp - ${imgui_SOURCE_DIR}/imgui_widgets.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp -) -target_include_directories(imgui PUBLIC - ${imgui_SOURCE_DIR} - ${imgui_SOURCE_DIR}/backends -) -target_link_libraries(imgui PUBLIC glfw) + set(METIS_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + set(METIS_INSTALL OFF CACHE BOOL "" FORCE) + alp_add_git_repository(metis URL https://github.com/scivision/metis COMMITISH v5.2.1.2) + target_compile_definitions(metis INTERFACE IDXTYPEWIDTH=32 REALTYPEWIDTH=32) +endif() +if(ALP_BUILD_BROWSER) + set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) + set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + if(UNIX) + set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) + set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) + endif() + alp_add_git_repository(glfw URL https://github.com/glfw/glfw.git COMMITISH e7ea71be039836da3a98cea55ae5569cb5eb885c NOT_SYSTEM) + + alp_add_git_repository(glad URL https://github.com/Dav1dde/glad.git COMMITISH 431786d8126e4f383a81e36f47b61a5d52a1c20d DO_NOT_ADD_SUBPROJECT) + add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) + glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) + + alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237 NOT_SYSTEM) + + alp_add_git_repository(imgui URL https://github.com/ocornut/imgui.git COMMITISH 5f0acadf7db1b6d469f0771284e2e3f7818443ce DO_NOT_ADD_SUBPROJECT) + add_library(imgui STATIC + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp + ) + target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends) + target_link_libraries(imgui PUBLIC glfw) +endif() -# Unity Builds -option(ALP_ENABLE_UNITY_BUILD "Enable unity (jumbo) builds to speed compilation" OFF) -set(ALP_UNITY_BUILD_BATCH_SIZE 4 CACHE STRING "Number of source files per unity translation unit") +# First-party components. if(ALP_ENABLE_UNITY_BUILD) - message(STATUS "ALP_ENABLE_UNITY_BUILD: enabling CMake unity builds (CMAKE_UNITY_BUILD=ON)") + message(STATUS "ALP_ENABLE_UNITY_BUILD: enabling unity builds for first-party targets") set(CMAKE_UNITY_BUILD ON) set(CMAKE_UNITY_BUILD_BATCH_SIZE ${ALP_UNITY_BUILD_BATCH_SIZE}) endif() +add_subdirectory(terrainlib) -# Own targets -add_library(terrainlib - terrainlib/ctb/CTBException.hpp - terrainlib/ctb/GlobalGeodetic.hpp terrainlib/ctb/GlobalGeodetic.cpp - terrainlib/ctb/GlobalMercator.hpp terrainlib/ctb/GlobalMercator.cpp - terrainlib/ctb/Grid.hpp - terrainlib/ctb/TileCoordinate.hpp - terrainlib/ctb/types.hpp - - terrainlib/io/bytes.cpp - terrainlib/io/utils.cpp - - terrainlib/mesh/igl/igl.cpp - - terrainlib/mesh/io/gltf.cpp - terrainlib/mesh/io/terrain.cpp - terrainlib/mesh/io/texture.cpp - terrainlib/mesh/io/utils.cpp - - terrainlib/mesh/merging/mapping.cpp - - terrainlib/mesh/bfs.cpp - terrainlib/mesh/boolean.cpp - terrainlib/mesh/boundary.cpp - terrainlib/mesh/cleanup.cpp - terrainlib/mesh/clip.cpp - terrainlib/mesh/compute_topology.cpp - terrainlib/mesh/convert.cpp - terrainlib/mesh/geometry.cpp - terrainlib/mesh/holes.cpp - terrainlib/mesh/io.cpp - terrainlib/mesh/manifold.cpp - terrainlib/mesh/texture_trim.cpp - terrainlib/mesh/topology.cpp - terrainlib/mesh/validate.cpp - terrainlib/mesh/vertex_index_range.cpp - - terrainlib/octree/storage/helpers.cpp - terrainlib/octree/IndexMap.cpp - terrainlib/octree/Space.cpp - terrainlib/octree/OddLevelShifted.cpp - - terrainlib/polygon/triangulate.cpp - terrainlib/polygon/utils.cpp - - terrainlib/uv/unwrap.cpp - - terrainlib/Dataset.cpp - terrainlib/init.cpp - terrainlib/log.cpp - terrainlib/ProgressIndicator.cpp -) -target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib) -target_precompile_headers(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/terrainlib/pch.h) -target_link_libraries(terrainlib PUBLIC - radix ZLIB::ZLIB CGAL::CGAL Eigen3 GDAL::GDAL spdlog fmt zpp_bits cgltf TBB::tbb tl_expected opencv_core opencv_imgproc opencv_imgcodecs libassert::assert magic_enum::magic_enum meshoptimizer igl::core igl_restricted::triangle) - -if(ALP_ENABLE_OVERVIEW_READING) - target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) +if(ALP_BUILD_TILE_BUILDER) + add_subdirectory(tile_builder) endif() - - -add_library(tilebuilderlib - tile_builder/alpine_raster.cpp - tile_builder/DatasetReader.cpp - tile_builder/Image.cpp - tile_builder/ParallelTileGenerator.cpp - tile_builder/ParallelTiler.cpp - tile_builder/TileHeightsGenerator.cpp - tile_builder/Tiler.cpp - tile_builder/TopDownTiler.cpp -) -target_include_directories(tilebuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tile_builder) -target_link_libraries(tilebuilderlib PUBLIC terrainlib radix ZLIB::ZLIB GDAL::GDAL fmt) -add_executable(tile-builder - tile_builder/main.cpp -) -target_link_libraries(tile-builder PUBLIC tilebuilderlib) - - -add_library(sfmergerlib sf_merger/merge.h) -target_include_directories(sfmergerlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/sf_merger) -target_link_libraries(sfmergerlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) -add_executable(sf-merger - sf_merger/main.cpp - sf_merger/cli.cpp -) -target_link_libraries(sf-merger PUBLIC sfmergerlib) - - -add_library(meshbuilderlib - mesh_builder/terrainbuilder.cpp - mesh_builder/mesh_builder.cpp -) -target_include_directories(meshbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/mesh_builder) -target_link_libraries(meshbuilderlib PUBLIC terrainlib spdlog CLI11::CLI11 tl_expected) -add_executable(mesh-builder - mesh_builder/main.cpp -) -target_link_libraries(mesh-builder PUBLIC meshbuilderlib) - - -add_library(meshsimplifylib - mesh_simplify/cli.cpp - mesh_simplify/simplify.cpp - mesh_simplify/uv_map.cpp -) -target_include_directories(meshsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/mesh_simplify) -target_link_libraries(meshsimplifylib PUBLIC terrainlib radix CLI11::CLI11 Eigen3 CGAL::CGAL) -add_executable(mesh-simplify - mesh_simplify/main.cpp -) -target_link_libraries(mesh-simplify PUBLIC meshsimplifylib) - -add_executable(tile-downloader - tile_downloader/main.cpp - tile_downloader/cli.cpp -) -target_link_libraries(tile-downloader PUBLIC terrainlib CLI11::CLI11 ${CURL_LIBRARIES}) - -add_executable(mesh-convert - mesh_convert/cli.cpp - mesh_convert/main.cpp -) -target_link_libraries(mesh-convert PUBLIC terrainlib CLI11::CLI11) - -add_executable(mesh_merger - mesh_merger/cli.cpp - mesh_merger/main.cpp -) -target_link_libraries(mesh_merger PUBLIC terrainlib CLI11::CLI11) - -add_executable(index-browser - index_browser/cli.cpp - index_browser/main.cpp -) -target_link_libraries(index-browser PUBLIC terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) - -add_library(dagbuilderlib - dag_builder/atlas/Packer.cpp - dag_builder/atlas/rect/atlas.cpp - dag_builder/atlas/rect/HorizontalStripPlanner.cpp - dag_builder/atlas/rect/PackingPlanner.cpp - dag_builder/build.cpp - dag_builder/merge/clusterings.cpp -) -target_include_directories(dagbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/dag_builder) -target_link_libraries(dagbuilderlib PUBLIC terrainlib libassert::assert metis rectpack2D meshoptimizer xatlas) -add_executable(dag-builder - dag_builder/cli.cpp - dag_builder/main.cpp -) -target_link_libraries(dag-builder PUBLIC dagbuilderlib CLI11::CLI11) - -add_executable(dag-convert-debug - dag_convert_debug/cli.cpp - dag_convert_debug/main.cpp -) -target_link_libraries(dag-convert-debug PUBLIC dagbuilderlib CLI11::CLI11) - -add_executable(browser - # browser/main2.cpp - - browser/main.cpp - - browser/core/Application.cpp - browser/core/window/Window.cpp - browser/core/shader/Shader.cpp - browser/core/shader/ShaderProgram.cpp - browser/core/shader/Uniform.h - browser/core/shader/GLUniformAbstractions.h - browser/core/Buffer.cpp - browser/core/Camera.cpp - - browser/core/geometry/UnitCube.h - - browser/core/rendering/OctreeRenderManager.cpp -) - -#target_compile_features(browser PRIVATE cxx_std_20) -#target_compile_options(browser PRIVATE /utf-8) -target_include_directories(browser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/browser) -target_link_libraries(browser PUBLIC terrainlib glfw glad_gl_core_46 resources-lib imgui) - -# Setup compiler caching with sccache or ccache if available -find_program(SCCACHE_PROGRAM sccache) -find_program(CCACHE_PROGRAM ccache) -if (SCCACHE_PROGRAM) - message(STATUS "Using sccache as compiler launcher: ${SCCACHE_PROGRAM}") - set(CMAKE_C_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}") - set(CMAKE_CXX_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}") -elseif (CCACHE_PROGRAM) - message(STATUS "Using ccache as compiler launcher: ${CCACHE_PROGRAM}") - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") +if(ALP_BUILD_SF_MERGER) + add_subdirectory(sf_merger) +endif() +if(ALP_BUILD_MESH_BUILDER) + add_subdirectory(mesh_builder) +endif() +if(ALP_BUILD_MESH_SIMPLIFY) + add_subdirectory(mesh_simplify) +endif() +if(ALP_BUILD_TILE_DOWNLOADER) + add_subdirectory(tile_downloader) +endif() +if(ALP_BUILD_MESH_CONVERT) + add_subdirectory(mesh_convert) +endif() +if(ALP_BUILD_MESH_MERGER) + add_subdirectory(mesh_merger) +endif() +if(ALP_BUILD_INDEX_BROWSER) + add_subdirectory(index_browser) +endif() +if(ALP_BUILD_DAG_BUILDER OR ALP_BUILD_DAG_CONVERT_DEBUG) + add_subdirectory(dag_builder) +endif() +if(ALP_BUILD_DAG_CONVERT_DEBUG) + add_subdirectory(dag_convert_debug) +endif() +if(ALP_BUILD_BROWSER) + add_subdirectory(browser) endif() diff --git a/src/browser/CMakeLists.txt b/src/browser/CMakeLists.txt new file mode 100644 index 00000000..70773897 --- /dev/null +++ b/src/browser/CMakeLists.txt @@ -0,0 +1,17 @@ +add_subdirectory(res) + +add_executable(browser + main.cpp + core/Application.cpp + core/window/Window.cpp + core/shader/Shader.cpp + core/shader/ShaderProgram.cpp + core/shader/Uniform.h + core/shader/GLUniformAbstractions.h + core/Buffer.cpp + core/Camera.cpp + core/geometry/UnitCube.h + core/rendering/OctreeRenderManager.cpp +) +target_include_directories(browser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(browser PRIVATE terrainlib glfw glad_gl_core_46 resources-lib imgui) diff --git a/src/browser/res/CMakeLists.txt b/src/browser/res/CMakeLists.txt index 47c7430d..2629bed9 100644 --- a/src/browser/res/CMakeLists.txt +++ b/src/browser/res/CMakeLists.txt @@ -16,3 +16,6 @@ cmrc_add_resource_library( shaders/octree_lines.frag # shaders/select.csh ) + +# Generated CMRC sources reuse internal symbol names and cannot share a unity translation unit. +set_target_properties(resources-lib PROPERTIES UNITY_BUILD OFF) diff --git a/src/dag_builder/CMakeLists.txt b/src/dag_builder/CMakeLists.txt new file mode 100644 index 00000000..9a739fb0 --- /dev/null +++ b/src/dag_builder/CMakeLists.txt @@ -0,0 +1,18 @@ +add_library(dagbuilderlib + atlas/Packer.cpp + atlas/rect/atlas.cpp + atlas/rect/HorizontalStripPlanner.cpp + atlas/rect/PackingPlanner.cpp + build.cpp + merge/clusterings.cpp +) +target_include_directories(dagbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(dagbuilderlib PUBLIC terrainlib libassert::assert metis rectpack2D meshoptimizer xatlas) + +if(ALP_BUILD_DAG_BUILDER) + add_executable(dag-builder + cli.cpp + main.cpp + ) + target_link_libraries(dag-builder PRIVATE dagbuilderlib CLI11::CLI11) +endif() diff --git a/src/dag_convert_debug/CMakeLists.txt b/src/dag_convert_debug/CMakeLists.txt new file mode 100644 index 00000000..ade99815 --- /dev/null +++ b/src/dag_convert_debug/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(dag-convert-debug + cli.cpp + main.cpp +) +target_link_libraries(dag-convert-debug PRIVATE dagbuilderlib CLI11::CLI11) diff --git a/src/index_browser/CMakeLists.txt b/src/index_browser/CMakeLists.txt new file mode 100644 index 00000000..3be0182e --- /dev/null +++ b/src/index_browser/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(index-browser + cli.cpp + main.cpp +) +target_link_libraries(index-browser PRIVATE terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) diff --git a/src/mesh_builder/CMakeLists.txt b/src/mesh_builder/CMakeLists.txt new file mode 100644 index 00000000..0447eecc --- /dev/null +++ b/src/mesh_builder/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(meshbuilderlib + terrainbuilder.cpp + mesh_builder.cpp +) +target_include_directories(meshbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(meshbuilderlib PUBLIC terrainlib spdlog tl_expected) + +add_executable(mesh-builder main.cpp) +target_link_libraries(mesh-builder PRIVATE meshbuilderlib CLI11::CLI11) diff --git a/src/mesh_convert/CMakeLists.txt b/src/mesh_convert/CMakeLists.txt new file mode 100644 index 00000000..8779e0f7 --- /dev/null +++ b/src/mesh_convert/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(mesh-convert + cli.cpp + main.cpp +) +target_link_libraries(mesh-convert PRIVATE terrainlib CLI11::CLI11) diff --git a/src/mesh_merger/CMakeLists.txt b/src/mesh_merger/CMakeLists.txt new file mode 100644 index 00000000..ba648d39 --- /dev/null +++ b/src/mesh_merger/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(mesh_merger + cli.cpp + main.cpp +) +target_link_libraries(mesh_merger PRIVATE terrainlib CLI11::CLI11) diff --git a/src/mesh_simplify/CMakeLists.txt b/src/mesh_simplify/CMakeLists.txt new file mode 100644 index 00000000..5b03ba55 --- /dev/null +++ b/src/mesh_simplify/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(meshsimplifylib + cli.cpp + simplify.cpp + uv_map.cpp +) +target_include_directories(meshsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(meshsimplifylib PUBLIC terrainlib CLI11::CLI11 Eigen3 CGAL::CGAL) + +add_executable(mesh-simplify main.cpp) +target_link_libraries(mesh-simplify PRIVATE meshsimplifylib) diff --git a/src/sf_merger/CMakeLists.txt b/src/sf_merger/CMakeLists.txt new file mode 100644 index 00000000..c17cfc9a --- /dev/null +++ b/src/sf_merger/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(sfmergerlib INTERFACE) +target_include_directories(sfmergerlib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(sfmergerlib INTERFACE terrainlib) + +add_executable(sf-merger + main.cpp + cli.cpp +) +target_link_libraries(sf-merger PRIVATE sfmergerlib CLI11::CLI11) diff --git a/src/terrainlib/CMakeLists.txt b/src/terrainlib/CMakeLists.txt new file mode 100644 index 00000000..49428599 --- /dev/null +++ b/src/terrainlib/CMakeLists.txt @@ -0,0 +1,81 @@ +add_library(terrainlib + ctb/CTBException.hpp + ctb/GlobalGeodetic.hpp ctb/GlobalGeodetic.cpp + ctb/GlobalMercator.hpp ctb/GlobalMercator.cpp + ctb/Grid.hpp + ctb/TileCoordinate.hpp + ctb/types.hpp + + io/bytes.cpp + io/utils.cpp + + mesh/igl/igl.cpp + + mesh/io/gltf.cpp + mesh/io/terrain.cpp + mesh/io/texture.cpp + mesh/io/utils.cpp + + mesh/merging/mapping.cpp + + mesh/bfs.cpp + mesh/boolean.cpp + mesh/boundary.cpp + mesh/cleanup.cpp + mesh/clip.cpp + mesh/compute_topology.cpp + mesh/convert.cpp + mesh/geometry.cpp + mesh/holes.cpp + mesh/io.cpp + mesh/manifold.cpp + mesh/texture_trim.cpp + mesh/topology.cpp + mesh/validate.cpp + mesh/vertex_index_range.cpp + + octree/storage/helpers.cpp + octree/IndexMap.cpp + octree/Space.cpp + octree/OddLevelShifted.cpp + + polygon/triangulate.cpp + polygon/utils.cpp + + uv/unwrap.cpp + + Dataset.cpp + init.cpp + log.cpp + ProgressIndicator.cpp +) + +target_compile_features(terrainlib PUBLIC cxx_std_20) +target_compile_definitions(terrainlib PUBLIC SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) +target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_precompile_headers(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/pch.h) +target_link_libraries(terrainlib PUBLIC + radix + ZLIB::ZLIB + CGAL::CGAL + Eigen3 + GDAL::GDAL + spdlog + fmt + zpp_bits + cgltf + TBB::tbb + tl_expected + opencv_core + opencv_imgproc + opencv_imgcodecs + libassert::assert + magic_enum::magic_enum + meshoptimizer + igl::core + igl_restricted::triangle +) + +if(ALP_ENABLE_OVERVIEW_READING) + target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) +endif() diff --git a/src/tile_builder/CMakeLists.txt b/src/tile_builder/CMakeLists.txt new file mode 100644 index 00000000..d4464342 --- /dev/null +++ b/src/tile_builder/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library(tilebuilderlib + alpine_raster.cpp + DatasetReader.cpp + Image.cpp + ParallelTileGenerator.cpp + ParallelTiler.cpp + TileHeightsGenerator.cpp + Tiler.cpp + TopDownTiler.cpp +) +target_include_directories(tilebuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(tilebuilderlib PUBLIC terrainlib ZLIB::ZLIB GDAL::GDAL fmt) + +add_executable(tile-builder main.cpp) +target_link_libraries(tile-builder PRIVATE tilebuilderlib) diff --git a/src/tile_downloader/CMakeLists.txt b/src/tile_downloader/CMakeLists.txt new file mode 100644 index 00000000..c1aebead --- /dev/null +++ b/src/tile_downloader/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(tile-downloader + main.cpp + cli.cpp +) +target_link_libraries(tile-downloader PRIVATE terrainlib CLI11::CLI11 CURL::libcurl) diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 7bbdd015..e8b51cb4 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -1,38 +1,21 @@ -cmake_minimum_required(VERSION 3.21) - -project(alpine-terrain-builder-unittests) - -option(ATB_UNITTESTS_EXTENDED "perform extended unit tests (they take long)" OFF) -option(ATB_UNITTESTS_DEBUG_IMAGES "output debug height images for visual comparison" OFF) -set(ATB_UNITTESTS_AUSTRIA_HIGHRES CACHE FILEPATH "path to the high res austrian dataset (terrain model, i.e., OeRect_01m_gt_31287.img)") - -add_compile_definitions(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) -if (NOT TARGET Catch2) +if(NOT TARGET Catch2::Catch2) alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.8.1) endif() - -add_compile_definitions( - ATB_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/unittests/data/" - ATB_UNITTESTS_AUSTRIA_HIGHRES="${ATB_UNITTESTS_AUSTRIA_HIGHRES}" -) - -if (ATB_UNITTESTS_EXTENDED) - add_compile_definitions(ATB_UNITTESTS_EXTENDED=true) -else() - add_compile_definitions(ATB_UNITTESTS_EXTENDED=false) -endif() - -if (ATB_UNITTESTS_DEBUG_IMAGES) - add_compile_definitions(ATB_UNITTESTS_DEBUG_IMAGES=true) -else() - add_compile_definitions(ATB_UNITTESTS_DEBUG_IMAGES=false) -endif() +function(atb_configure_test target) + target_compile_definitions(${target} PRIVATE + CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS + ATB_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/unittests/data/" + ATB_UNITTESTS_AUSTRIA_HIGHRES="${ATB_UNITTESTS_AUSTRIA_HIGHRES}" + ATB_UNITTESTS_EXTENDED=$ + ATB_UNITTESTS_DEBUG_IMAGES=$ + ) +endfunction() add_executable(unittests_terrainlib catch2_helpers.h opencv_helpers.h - + terrainlib/convert.cpp terrainlib/cow.cpp terrainlib/dataset.cpp @@ -74,39 +57,49 @@ add_executable(unittests_terrainlib terrainlib/tiny_vector.cpp terrainlib/union_find.cpp ) -target_link_libraries(unittests_terrainlib PUBLIC terrainlib Catch2::Catch2WithMain) - +target_link_libraries(unittests_terrainlib PRIVATE terrainlib Catch2::Catch2WithMain) +atb_configure_test(unittests_terrainlib) -add_executable(unittests_tilebuilder - catch2_helpers.h - tilebuilder/alpine_raster_format.cpp - tilebuilder/dataset_reading.cpp - tilebuilder/depth_first_tile_traverser.cpp - tilebuilder/image.cpp - tilebuilder/parallel_tile_generator.cpp - tilebuilder/parallel_tiler.cpp - tilebuilder/tile_heights_generator.cpp - tilebuilder/top_down_tiler.cpp -) -target_link_libraries(unittests_tilebuilder PUBLIC tilebuilderlib Catch2::Catch2WithMain) - -add_executable(unittests_meshbuilder - catch2_helpers.h - mesh_builder/mesh.cpp - mesh_builder/texture.cpp -) -target_link_libraries(unittests_meshbuilder PUBLIC meshbuilderlib terrainlib Catch2WithMain) -target_compile_definitions(unittests_meshbuilder PUBLIC "ATB_TEST_DATA_DIR=\"${CMAKE_SOURCE_DIR}/unittests/data/\"") +if(TARGET tilebuilderlib) + add_executable(unittests_tilebuilder + catch2_helpers.h + tilebuilder/alpine_raster_format.cpp + tilebuilder/dataset_reading.cpp + tilebuilder/depth_first_tile_traverser.cpp + tilebuilder/image.cpp + tilebuilder/parallel_tile_generator.cpp + tilebuilder/parallel_tiler.cpp + tilebuilder/tile_heights_generator.cpp + tilebuilder/top_down_tiler.cpp + ) + target_link_libraries(unittests_tilebuilder PRIVATE tilebuilderlib Catch2::Catch2WithMain) + atb_configure_test(unittests_tilebuilder) +endif() +if(TARGET meshbuilderlib) + add_executable(unittests_meshbuilder + catch2_helpers.h + mesh_builder/mesh.cpp + mesh_builder/texture.cpp + ) + target_link_libraries(unittests_meshbuilder PRIVATE meshbuilderlib Catch2::Catch2WithMain) + atb_configure_test(unittests_meshbuilder) +endif() -add_executable(unittests_dagbuilder - catch2_helpers.h - dag_builder/slice.cpp -) -target_link_libraries(unittests_dagbuilder PUBLIC dagbuilderlib Catch2::Catch2WithMain) +if(TARGET dagbuilderlib) + add_executable(unittests_dagbuilder + catch2_helpers.h + dag_builder/slice.cpp + ) + target_link_libraries(unittests_dagbuilder PRIVATE dagbuilderlib Catch2::Catch2WithMain) + atb_configure_test(unittests_dagbuilder) +endif() -add_executable(unittests_sfmerger - catch2_helpers.h - sf_merger/sphere_projector.cpp -) -target_link_libraries(unittests_sfmerger PUBLIC sfmergerlib terrainlib Catch2WithMain) +if(TARGET sfmergerlib) + add_executable(unittests_sfmerger + catch2_helpers.h + sf_merger/sphere_projector.cpp + ) + target_link_libraries(unittests_sfmerger PRIVATE sfmergerlib Catch2::Catch2WithMain) + atb_configure_test(unittests_sfmerger) +endif() From 96a0f97998acabc2a676d511b8af5bdb0fb856ce Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:14:36 +0200 Subject: [PATCH 2/7] Make assertion setting configurable --- CMakeLists.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9f4b1fe..44ee0b4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,13 @@ option(ALP_ENABLE_THREAD_SANITIZER "Compile with ThreadSanitizer enabled" OFF) option(ALP_ENABLE_ADDRESS_SANITIZER "Compile with AddressSanitizer enabled" OFF) option(ALP_ENABLE_OVERVIEW_READING "Enable GDAL overview reading (broken with newer GDAL versions)" OFF) option(ALP_ENABLE_UNITY_BUILD "Enable unity (jumbo) builds to speed compilation" OFF) + +set(ALP_ENABLE_ASSERTS_DEFAULT OFF) +if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$") + set(ALP_ENABLE_ASSERTS_DEFAULT ON) +endif() +option(ALP_ENABLE_ASSERTS "Do not define NDEBUG, i.e., enable asserts" ${ALP_ENABLE_ASSERTS_DEFAULT}) + set(ALP_UNITY_BUILD_BATCH_SIZE 4 CACHE STRING "Number of source files per unity translation unit") set(ALP_RELEASE_OPT_LEVEL "3" CACHE STRING "Optimization level (0=O0,1=O1,2=O2,3=O3)") @@ -59,10 +66,6 @@ if(ALP_ENABLE_THREAD_SANITIZER) endif() endif() -if(CMAKE_BUILD_TYPE MATCHES Release) - set(ALP_ENABLE_ASSERTS ON CACHE BOOL "Do not define NDEBUG even in Release mode, i.e., enable asserts" FORCE) -endif() - if(CMAKE_BUILD_TYPE STREQUAL "Release") message(STATUS "Using optimization level ${ALP_RELEASE_OPT_LEVEL}") add_compile_options($<$:-O${ALP_RELEASE_OPT_LEVEL}>) From 5974b59483b0106eb4ec200c4904f950af8844af Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:33:10 +0200 Subject: [PATCH 3/7] Rename remaining CMake options to ALP --- CMakeLists.txt | 6 +-- src/terrainlib/CMakeLists.txt | 2 +- src/tile_builder/DatasetReader.cpp | 4 +- unittests/CMakeLists.txt | 8 ++-- unittests/mesh_builder/mesh.cpp | 4 +- unittests/terrainlib/dataset.cpp | 8 ++-- unittests/terrainlib/mesh_clip.cpp | 2 +- .../tilebuilder/alpine_raster_format.cpp | 8 ++-- unittests/tilebuilder/dataset_reading.cpp | 44 +++++++++---------- .../depth_first_tile_traverser.cpp | 4 +- .../tilebuilder/parallel_tile_generator.cpp | 2 +- unittests/tilebuilder/parallel_tiler.cpp | 10 ++--- .../tilebuilder/tile_heights_generator.cpp | 4 +- unittests/tilebuilder/top_down_tiler.cpp | 4 +- 14 files changed, 55 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ee0b4d..722871a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,9 @@ set(ALP_UNITY_BUILD_BATCH_SIZE 4 CACHE STRING "Number of source files per unity set(ALP_RELEASE_OPT_LEVEL "3" CACHE STRING "Optimization level (0=O0,1=O1,2=O2,3=O3)") # Unit-test configuration -option(ATB_UNITTESTS_EXTENDED "Perform extended unit tests (they take long)" OFF) -option(ATB_UNITTESTS_DEBUG_IMAGES "Output debug height images for visual comparison" OFF) -set(ATB_UNITTESTS_AUSTRIA_HIGHRES "" CACHE FILEPATH "Path to the high resolution Austrian terrain dataset") +option(ALP_UNITTESTS_EXTENDED "Perform extended unit tests (they take long)" OFF) +option(ALP_UNITTESTS_DEBUG_IMAGES "Output debug height images for visual comparison" OFF) +set(ALP_UNITTESTS_AUSTRIA_HIGHRES "" CACHE FILEPATH "Path to the high resolution Austrian terrain dataset") if(ALP_ENABLE_ADDRESS_SANITIZER AND ALP_ENABLE_THREAD_SANITIZER) message(FATAL_ERROR "Cannot enable both AddressSanitizer and ThreadSanitizer") diff --git a/src/terrainlib/CMakeLists.txt b/src/terrainlib/CMakeLists.txt index 49428599..69c984fc 100644 --- a/src/terrainlib/CMakeLists.txt +++ b/src/terrainlib/CMakeLists.txt @@ -77,5 +77,5 @@ target_link_libraries(terrainlib PUBLIC ) if(ALP_ENABLE_OVERVIEW_READING) - target_compile_definitions(terrainlib PUBLIC DATB_ENABLE_OVERVIEW_READING) + target_compile_definitions(terrainlib PUBLIC ALP_ENABLE_OVERVIEW_READING) endif() diff --git a/src/tile_builder/DatasetReader.cpp b/src/tile_builder/DatasetReader.cpp index b7bfccf1..bad96340 100644 --- a/src/tile_builder/DatasetReader.cpp +++ b/src/tile_builder/DatasetReader.cpp @@ -114,7 +114,7 @@ WarpOptionData makeWarpOptions(const DatasetReader& reader, Dataset* dataset, co return { std::move(options), GdalImageTransformArgsPtr(nullptr, &GDALDestroyGenImgProjTransformer) }; } -#ifdef ATB_ENABLE_OVERVIEW_READING +#ifdef ALP_ENABLE_OVERVIEW_READING std::shared_ptr getOverviewDataset(const std::shared_ptr& dataset, void* hTransformerArg, bool warn_on_missing_overviews) { GDALDataset* poSrcDS = dataset->gdalDataset(); @@ -192,7 +192,7 @@ HeightData DatasetReader::read(const radix::tile::SrsBounds& bounds, unsigned wi HeightData DatasetReader::readWithOverviews(const radix::tile::SrsBounds& bounds, unsigned width, unsigned height) const { -#ifdef ATB_ENABLE_OVERVIEW_READING +#ifdef ALP_ENABLE_OVERVIEW_READING auto transformer_args = make_image_transform_args(*this, m_dataset.get(), bounds, width, height); auto source_dataset = getOverviewDataset(m_dataset, transformer_args.get(), m_warn_on_missing_overviews); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index e8b51cb4..440f0664 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -5,10 +5,10 @@ endif() function(atb_configure_test target) target_compile_definitions(${target} PRIVATE CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS - ATB_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/unittests/data/" - ATB_UNITTESTS_AUSTRIA_HIGHRES="${ATB_UNITTESTS_AUSTRIA_HIGHRES}" - ATB_UNITTESTS_EXTENDED=$ - ATB_UNITTESTS_DEBUG_IMAGES=$ + ALP_TEST_DATA_DIR="${CMAKE_SOURCE_DIR}/unittests/data/" + ALP_UNITTESTS_AUSTRIA_HIGHRES="${ALP_UNITTESTS_AUSTRIA_HIGHRES}" + ALP_UNITTESTS_EXTENDED=$ + ALP_UNITTESTS_DEBUG_IMAGES=$ ) endfunction() diff --git a/unittests/mesh_builder/mesh.cpp b/unittests/mesh_builder/mesh.cpp index 0b6053bc..2025c28a 100644 --- a/unittests/mesh_builder/mesh.cpp +++ b/unittests/mesh_builder/mesh.cpp @@ -157,7 +157,7 @@ TEST_CASE("can build reference mesh patches for various datasets", "[terrainbuil for (const auto &data : test_data) { DYNAMIC_SECTION(data.path_suffix) { - Dataset dataset(std::filesystem::path(ATB_TEST_DATA_DIR).concat(data.path_suffix)); + Dataset dataset(std::filesystem::path(ALP_TEST_DATA_DIR).concat(data.path_suffix)); const auto source_srs = dataset.srs(); const auto &mesh_srs = data.mesh_srs; const auto &target_srs = data.target_srs; @@ -253,7 +253,7 @@ TEST_CASE("neighbouring patches fit together", "[terrainbuilder]") { nodes.push_back(summit_node); const std::string dataset_suffix = "/austria/pizbuin_1m_mgi.tif"; - const std::filesystem::path dataset_path = std::filesystem::path(ATB_TEST_DATA_DIR).concat(dataset_suffix); + const std::filesystem::path dataset_path = std::filesystem::path(ALP_TEST_DATA_DIR).concat(dataset_suffix); Dataset dataset(dataset_path); std::vector node_meshes; diff --git a/unittests/terrainlib/dataset.cpp b/unittests/terrainlib/dataset.cpp index 9709e192..0e67eb54 100644 --- a/unittests/terrainlib/dataset.cpp +++ b/unittests/terrainlib/dataset.cpp @@ -44,8 +44,8 @@ void checkBounds(const radix::tile::SrsBounds &a, const radix::tile::SrsBounds & } TEST_CASE("datasets are as expected") { - auto d_mgi = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); - auto d_wgs84 = Dataset(ATB_TEST_DATA_DIR "/austria/at_wgs84.tif"); + auto d_mgi = Dataset(ALP_TEST_DATA_DIR "/austria/at_mgi.tif"); + auto d_wgs84 = Dataset(ALP_TEST_DATA_DIR "/austria/at_wgs84.tif"); OGRSpatialReference webmercator; webmercator.importFromEPSG(3857); @@ -107,8 +107,8 @@ TEST_CASE("datasets are as expected") { } TEST_CASE("bbox width pixels") { - auto d_mgi = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); - auto d_wgs84 = Dataset(ATB_TEST_DATA_DIR "/austria/at_wgs84.tif"); + auto d_mgi = Dataset(ALP_TEST_DATA_DIR "/austria/at_mgi.tif"); + auto d_wgs84 = Dataset(ALP_TEST_DATA_DIR "/austria/at_wgs84.tif"); OGRSpatialReference webmercator; webmercator.importFromEPSG(3857); diff --git a/unittests/terrainlib/mesh_clip.cpp b/unittests/terrainlib/mesh_clip.cpp index 5d57842b..04b47104 100644 --- a/unittests/terrainlib/mesh_clip.cpp +++ b/unittests/terrainlib/mesh_clip.cpp @@ -323,7 +323,7 @@ TEST_CASE("clip_on_bounds produces manifold mesh") { #ifdef NDEBUG TEST_CASE("mesh::clip_on_bounds benchmark") { BENCHMARK_ADVANCED("clip based on octree")(Catch::Benchmark::Chronometer meter) { - const std::filesystem::path mesh_path = ATB_TEST_DATA_DIR "/meshes/6857.terrain"; + const std::filesystem::path mesh_path = ALP_TEST_DATA_DIR "/meshes/6857.terrain"; auto mesh_result = mesh::io::load_from_path(mesh_path); REQUIRE(mesh_result.has_value()); SimpleMesh &mesh = mesh_result.value(); diff --git a/unittests/tilebuilder/alpine_raster_format.cpp b/unittests/tilebuilder/alpine_raster_format.cpp index df7f2194..00ec9bf4 100644 --- a/unittests/tilebuilder/alpine_raster_format.cpp +++ b/unittests/tilebuilder/alpine_raster_format.cpp @@ -41,7 +41,7 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal SECTION("raste write") { - const auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes); + const auto generator = alpine_raster::make_generator(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes); generator.write(radix::tile::Descriptor { {0, glm::uvec2(0, 0)}, {}, int(ctb::Grid::Srs::SphericalMercator), 256, 257 }, HeightData(257, 257)); CHECK(std::filesystem::exists("./unittest_tiles/0/0/0.png")); @@ -58,7 +58,7 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal SECTION("process all tiles") { - auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); + auto generator = alpine_raster::make_generator(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); generator.setWarnOnMissingOverviews(false); generator.process({ 0, 7 }); const auto tiles = generator.tiler().generateTiles({ 0, 7 }); @@ -68,10 +68,10 @@ TEMPLATE_TEST_CASE("alpine raster format, border ", "", std::true_type, std::fal }; CHECK(std::transform_reduce(tiles.begin(), tiles.end(), true, std::logical_and<>(), check) == true); } -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED +#if defined(ALP_UNITTESTS_EXTENDED) && ALP_UNITTESTS_EXTENDED SECTION("process all tiles with max zoom") { - auto generator = alpine_raster::make_generator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); + auto generator = alpine_raster::make_generator(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", "./unittest_tiles/", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, testTypeValue2Border(TestType::value)); generator.setWarnOnMissingOverviews(false); generator.process({ 4, 8 }); const auto tiles = generator.tiler().generateTiles({ 4, 8 }); diff --git a/unittests/tilebuilder/dataset_reading.cpp b/unittests/tilebuilder/dataset_reading.cpp index b14f0e5e..17c714e9 100644 --- a/unittests/tilebuilder/dataset_reading.cpp +++ b/unittests/tilebuilder/dataset_reading.cpp @@ -83,7 +83,7 @@ TEST_CASE("reading") const std::array test_srses = { 4326, 3857 }; const std::array test_locations = { // CRS bounds, [lower limit, at least one value smaller, at least one value larger, upper limit] -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED +#if defined(ALP_UNITTESTS_EXTENDED) && ALP_UNITTESTS_EXTENDED std::make_tuple( "at100m", at100m, @@ -106,7 +106,7 @@ TEST_CASE("reading") const auto [test_name, test_datasets, geodetic_bounds, limits] = test; for (std::string dataset_name : test_datasets) { - const auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR + std::string(dataset_name)).value(); + const auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR + std::string(dataset_name)).value(); for (const auto& test_srs : test_srses) { OGRSpatialReference srs; srs.importFromEPSG(test_srs); @@ -116,7 +116,7 @@ TEST_CASE("reading") require_projection_available(*dataset, srs); const DatasetReader reader(dataset, srs, 1); - if (ATB_UNITTESTS_DEBUG_IMAGES) { + if (ALP_UNITTESTS_DEBUG_IMAGES) { const auto heights = reader.read(srs_bounds, 1000, 1000); const auto s = std::string("/austria/").length(); const auto l = dataset_name.length() - std::string(".tif").length() - s; @@ -141,7 +141,7 @@ TEST_CASE("reading") SECTION("compare with ref render") { const std::array test_data = { -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED +#if defined(ALP_UNITTESTS_EXTENDED) && ALP_UNITTESTS_EXTENDED std::make_tuple( "at100m", at100m, @@ -153,7 +153,7 @@ TEST_CASE("reading") pizbuin1m, radix::tile::SrsBounds{{10.105646780, 46.839864531}, {10.129815588, 46.847626067}}, 740U, 315U, 3.01, 0.006), -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED +#if defined(ALP_UNITTESTS_EXTENDED) && ALP_UNITTESTS_EXTENDED std::make_tuple( "pizbuin1m_highres", pizbuin1m, @@ -165,15 +165,15 @@ TEST_CASE("reading") for (const auto& test : test_data) { auto [test_name, datasets, ref_bounds, render_width, render_height, max_abs_diff, max_mse] = test; - const auto ref_dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR + std::string(datasets.front())).value(); + const auto ref_dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR + std::string(datasets.front())).value(); require_projection_available(*ref_dataset, geodetic_srs); const auto ref_reader = DatasetReader(ref_dataset, geodetic_srs, 1); const auto ref_heights = ref_reader.read(ref_bounds, render_width, render_height); - if (ATB_UNITTESTS_DEBUG_IMAGES) + if (ALP_UNITTESTS_DEBUG_IMAGES) image::debugOut(ref_heights, fmt::format("./heights_ref.png")); for (std::string dataset_name : datasets) { - const auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR + std::string(dataset_name)).value(); + const auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR + std::string(dataset_name)).value(); require_projection_available(*dataset, geodetic_srs); const auto reader = DatasetReader(dataset, geodetic_srs, 1); const auto heights = reader.read(ref_bounds, render_width, render_height); @@ -181,7 +181,7 @@ TEST_CASE("reading") const auto s = std::string("/austria/").length(); const auto l = dataset_name.length() - std::string(".tif").length() - s; - if (ATB_UNITTESTS_DEBUG_IMAGES) { + if (ALP_UNITTESTS_DEBUG_IMAGES) { image::debugOut(ref_heights, fmt::format("./heights_{}_{}.png", test_name, dataset_name.substr(s, l))); auto height_diffs = HeightData(render_width, render_height); @@ -202,13 +202,13 @@ TEST_CASE("reading") } } -#if defined(ATB_UNITTESTS_EXTENDED) && ATB_UNITTESTS_EXTENDED +#if defined(ALP_UNITTESTS_EXTENDED) && ALP_UNITTESTS_EXTENDED SECTION("overview without warping") { - REQUIRE(std::string(ATB_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); + REQUIRE(std::string(ALP_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); const auto border = 5; - const auto low_res_ds = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_100m_mgi.tif").value(); - const auto high_res_ds = Dataset::open_shared_raster(ATB_UNITTESTS_AUSTRIA_HIGHRES).value(); + const auto low_res_ds = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_100m_mgi.tif").value(); + const auto high_res_ds = Dataset::open_shared_raster(ALP_UNITTESTS_AUSTRIA_HIGHRES).value(); const auto srs = low_res_ds->srs(); const auto low_res_reader = DatasetReader(low_res_ds, srs, 1); @@ -244,7 +244,7 @@ TEST_CASE("reading") const auto high_res_time = std::chrono::duration_cast(t2 - t1).count(); fmt::print("low res time: {}; high res time: {}\n", double(low_res_time) / 1000.0, double(high_res_time) / 1000.0); - if (ATB_UNITTESTS_DEBUG_IMAGES) { + if (ALP_UNITTESTS_DEBUG_IMAGES) { image::debugOut(low_res_heights, fmt::format("./low_res_heights.png")); image::debugOut(high_res_heights, fmt::format("./high_res_heights.png")); @@ -265,9 +265,9 @@ TEST_CASE("reading") SECTION("overview with warping") { - REQUIRE(std::string(ATB_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); - const auto low_res_ds = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_100m_epsg4326.tif").value(); - const auto high_res_ds = Dataset::open_shared_raster(ATB_UNITTESTS_AUSTRIA_HIGHRES).value(); + REQUIRE(std::string(ALP_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); + const auto low_res_ds = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_100m_epsg4326.tif").value(); + const auto high_res_ds = Dataset::open_shared_raster(ALP_UNITTESTS_AUSTRIA_HIGHRES).value(); const auto srs = low_res_ds->srs(); const auto low_res_reader = DatasetReader(low_res_ds, srs, 1); const auto high_res_reader = DatasetReader(high_res_ds, srs, 1); @@ -286,7 +286,7 @@ TEST_CASE("reading") REQUIRE(high_res_heights.width() == render_width); REQUIRE(high_res_heights.height() == render_height); - if (ATB_UNITTESTS_DEBUG_IMAGES) { + if (ALP_UNITTESTS_DEBUG_IMAGES) { image::debugOut(low_res_heights, fmt::format("./ov_with_warping_low_res_heights.png")); image::debugOut(high_res_heights, fmt::format("./ov_with_warping_high_res_heights.png")); @@ -307,9 +307,9 @@ TEST_CASE("reading") SECTION("lowres overview with warping") { - REQUIRE(std::string(ATB_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); - const auto low_res_ds = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_100m_epsg4326.tif").value(); - const auto high_res_ds = Dataset::open_shared_raster(ATB_UNITTESTS_AUSTRIA_HIGHRES).value(); + REQUIRE(std::string(ALP_UNITTESTS_AUSTRIA_HIGHRES).length() > 5); + const auto low_res_ds = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_100m_epsg4326.tif").value(); + const auto high_res_ds = Dataset::open_shared_raster(ALP_UNITTESTS_AUSTRIA_HIGHRES).value(); const auto srs = low_res_ds->srs(); const auto low_res_reader = DatasetReader(low_res_ds, srs, 1); const auto high_res_reader = DatasetReader(high_res_ds, srs, 1); @@ -328,7 +328,7 @@ TEST_CASE("reading") REQUIRE(high_res_heights.width() == render_width); REQUIRE(high_res_heights.height() == render_height); - if (ATB_UNITTESTS_DEBUG_IMAGES) { + if (ALP_UNITTESTS_DEBUG_IMAGES) { image::debugOut(low_res_heights, fmt::format("./lowres_ov_with_warping_low_res_heights.png")); image::debugOut(high_res_heights, fmt::format("./lowres_ov_with_warping_high_res_heights.png")); diff --git a/unittests/tilebuilder/depth_first_tile_traverser.cpp b/unittests/tilebuilder/depth_first_tile_traverser.cpp index 51442cdf..3f49e05a 100644 --- a/unittests/tilebuilder/depth_first_tile_traverser.cpp +++ b/unittests/tilebuilder/depth_first_tile_traverser.cpp @@ -116,8 +116,8 @@ TEST_CASE("depth_first_tile_traverser basics") TEST_CASE("depth_first_tile_traverser austrian heights") { const auto grid = ctb::GlobalMercator(); - const auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_100m_mgi.tif").value(); - // const auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); + const auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_100m_mgi.tif").value(); + // const auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto bounds = dataset->bounds(grid.getSRS()); const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, radix::tile::Scheme::Tms); const auto tile_reader = DatasetReader(dataset, grid.getSRS(), 1, false); diff --git a/unittests/tilebuilder/parallel_tile_generator.cpp b/unittests/tilebuilder/parallel_tile_generator.cpp index 350c046c..ee57262d 100644 --- a/unittests/tilebuilder/parallel_tile_generator.cpp +++ b/unittests/tilebuilder/parallel_tile_generator.cpp @@ -55,7 +55,7 @@ TEST_CASE("parallel tile generator") }; std::filesystem::path base_path = "./unittest_tiles/"; - auto generator = ParallelTileGenerator::make(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, std::make_unique(&tile_counter, &validation_error_counter), base_path); + auto generator = ParallelTileGenerator::make(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, std::make_unique(&tile_counter, &validation_error_counter), base_path); generator.setWarnOnMissingOverviews(false); SECTION("dataset tiles only") { diff --git a/unittests/tilebuilder/parallel_tiler.cpp b/unittests/tilebuilder/parallel_tiler.cpp index 0d624b95..815b48ba 100644 --- a/unittests/tilebuilder/parallel_tiler.cpp +++ b/unittests/tilebuilder/parallel_tiler.cpp @@ -62,7 +62,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f SECTION("mercator tms / level 1 and 2") { const auto grid = ctb::GlobalMercator(); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_mgi.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_mgi.tif").value(); const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::No, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(1, TestType::value ? 1 : 0)); @@ -143,7 +143,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f SECTION("geodetic tms / level 1 and 2") { const auto grid = ctb::GlobalGeodetic(64); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_mgi.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_mgi.tif").value(); const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::Yes, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(2, TestType::value ? 1 : 0)); @@ -189,7 +189,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f SECTION("mercator tms / level 1 and 2 (test with cape horn, on southern and western hemisphere)") { const auto grid = ctb::GlobalMercator(); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/capehorn/small.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/capehorn/small.tif").value(); const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::No, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(0, TestType::value ? 0 : 1)); @@ -233,7 +233,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f SECTION("geodetic tms / level 1 and 2 (test with cape horn, on southern and western hemisphere)") { const auto grid = ctb::GlobalGeodetic(64); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/capehorn/small.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/capehorn/small.tif").value(); const auto tiler = ParallelTiler(grid, dataset->bounds(grid.getSRS()), radix::tile::Border::Yes, TestType::value ? radix::tile::Scheme::Tms : radix::tile::Scheme::SlippyMap); CHECK(tiler.northEastTile(1).coords == glm::uvec2(1, TestType::value ? 0 : 1)); @@ -279,7 +279,7 @@ TEMPLATE_TEST_CASE("ParallelTiler, using tms scheme", "", std::true_type, std::f TEST_CASE("ParallelTiler returns tiles for several zoom levels") { - const auto dataset = Dataset(ATB_TEST_DATA_DIR "/austria/at_mgi.tif"); + const auto dataset = Dataset(ALP_TEST_DATA_DIR "/austria/at_mgi.tif"); const auto grid = ctb::GlobalMercator(256); const auto tiler = ParallelTiler(grid, dataset.bounds(grid.getSRS()), radix::tile::Border::Yes, radix::tile::Scheme::Tms); diff --git a/unittests/tilebuilder/tile_heights_generator.cpp b/unittests/tilebuilder/tile_heights_generator.cpp index 40d23b20..43f74237 100644 --- a/unittests/tilebuilder/tile_heights_generator.cpp +++ b/unittests/tilebuilder/tile_heights_generator.cpp @@ -30,7 +30,7 @@ TEST_CASE("TileHeightsGenerator") constexpr auto file_name = "height_data.atb"; SECTION("mercator") { - const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); + const auto generator = TileHeightsGenerator(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::SphericalMercator, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); generator.run(8); const auto heights = TileHeights::read_from(base_path / file_name); @@ -50,7 +50,7 @@ TEST_CASE("TileHeightsGenerator") } SECTION("geodetic") { - const auto generator = TileHeightsGenerator(ATB_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::WGS84, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); + const auto generator = TileHeightsGenerator(ALP_TEST_DATA_DIR "/austria/at_mgi.tif", ctb::Grid::Srs::WGS84, radix::tile::Scheme::Tms, radix::tile::Border::Yes, base_path / file_name); generator.run(8); const auto heights = TileHeights::read_from(base_path / file_name); diff --git a/unittests/tilebuilder/top_down_tiler.cpp b/unittests/tilebuilder/top_down_tiler.cpp index 6a550ced..cd1e33b5 100644 --- a/unittests/tilebuilder/top_down_tiler.cpp +++ b/unittests/tilebuilder/top_down_tiler.cpp @@ -67,7 +67,7 @@ TEMPLATE_TEST_CASE("BottomUpTiler, using tms scheme", "", std::true_type, std::f SECTION("mercator / level 0 austria") { const auto grid = ctb::GlobalMercator(); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_mgi.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_mgi.tif").value(); const auto bounds = dataset->bounds(grid.getSRS()); const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, scheme); @@ -91,7 +91,7 @@ TEMPLATE_TEST_CASE("BottomUpTiler, using tms scheme", "", std::true_type, std::f SECTION("geodetic / level 0 austria") { const auto grid = ctb::GlobalGeodetic(); - auto dataset = Dataset::open_shared_raster(ATB_TEST_DATA_DIR "/austria/at_mgi.tif").value(); + auto dataset = Dataset::open_shared_raster(ALP_TEST_DATA_DIR "/austria/at_mgi.tif").value(); const auto bounds = dataset->bounds(grid.getSRS()); const auto tiler = TopDownTiler(grid, bounds, radix::tile::Border::No, scheme); From 33521eaeedb6f0872a17c5a2a9b9cf617446c60d Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:17:42 +0200 Subject: [PATCH 4/7] Mark third-party dependencies as system libraries --- src/CMakeLists.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2249a197..3f7c8a60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,7 @@ alp_add_git_repository(fmt URL https://github.com/fmtlib/fmt COMMITISH 12.2.0) alp_add_git_repository(eigen URL https://gitlab.com/libeigen/eigen.git COMMITISH 3.4.0 DO_NOT_ADD_SUBPROJECT) add_library(Eigen3 INTERFACE) -target_include_directories(Eigen3 INTERFACE SYSTEM ${eigen_SOURCE_DIR}) +target_include_directories(Eigen3 SYSTEM INTERFACE ${eigen_SOURCE_DIR}) alp_setup_cmake_project(boost URL https://github.com/boostorg/boost.git COMMITISH "boost-1.88.0" CMAKE_ARGUMENTS -DBOOST_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF "-DBOOST_INCLUDE_LIBRARIES='graph\;multiprecision\;heap\;format\;logic'") find_package(Boost CONFIG REQUIRED) @@ -24,7 +24,7 @@ alp_setup_opencv(4.11.0) alp_add_git_repository(cgltf URL https://github.com/jkuhlmann/cgltf COMMITISH 7331a5adf4b0fde15f0e682a5803e4f17137e0ad DO_NOT_ADD_SUBPROJECT) add_library(cgltf INTERFACE) -target_include_directories(cgltf INTERFACE SYSTEM ${cgltf_SOURCE_DIR}) +target_include_directories(cgltf SYSTEM INTERFACE ${cgltf_SOURCE_DIR}) set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) @@ -33,18 +33,18 @@ alp_add_git_repository(tinygltf URL https://github.com/syoyo/tinygltf COMMITISH alp_add_git_repository(stb URL https://github.com/nothings/stb COMMITISH f4a71b13373436a2866c5d68f8f80ac6f0bc1ffe DO_NOT_ADD_SUBPROJECT) add_library(stb INTERFACE) -target_include_directories(stb INTERFACE SYSTEM ${stb_SOURCE_DIR}) +target_include_directories(stb SYSTEM INTERFACE ${stb_SOURCE_DIR}) alp_add_git_repository(tl_expected URL https://github.com/TartanLlama/expected.git COMMITISH v1.1.0 DO_NOT_ADD_SUBPROJECT) add_library(tl_expected INTERFACE) -target_include_directories(tl_expected INTERFACE SYSTEM ${tl_expected_SOURCE_DIR}/include) +target_include_directories(tl_expected SYSTEM INTERFACE ${tl_expected_SOURCE_DIR}/include) set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "SPDLOG_FMT_EXTERNAL" FORCE) alp_add_git_repository(spdlog URL https://github.com/gabime/spdlog.git COMMITISH v1.17.0) alp_add_git_repository(zpp_bits URL https://github.com/eyalz800/zpp_bits.git COMMITISH v4.7.2 DO_NOT_ADD_SUBPROJECT) add_library(zpp_bits INTERFACE) -target_include_directories(zpp_bits INTERFACE SYSTEM ${zpp_bits_SOURCE_DIR}) +target_include_directories(zpp_bits SYSTEM INTERFACE ${zpp_bits_SOURCE_DIR}) alp_add_git_repository(libassert URL https://github.com/jeremy-rifkin/libassert.git COMMITISH v2.1.0) alp_add_git_repository(magic_enum URL https://github.com/Neargye/magic_enum.git COMMITISH v0.9.7) @@ -88,7 +88,7 @@ endif() if(ALP_BUILD_DAG_BUILDER OR ALP_BUILD_DAG_CONVERT_DEBUG) alp_add_git_repository(xatlas URL https://github.com/jpcy/xatlas COMMITISH f700c7790aaa030e794b52ba7791a05c085faf0c DO_NOT_ADD_SUBPROJECT) add_library(xatlas STATIC ${xatlas_SOURCE_DIR}/source/xatlas/xatlas.cpp) - target_include_directories(xatlas PUBLIC ${xatlas_SOURCE_DIR}/source) + target_include_directories(xatlas SYSTEM PUBLIC ${xatlas_SOURCE_DIR}/source) alp_add_git_repository(rectpack2D URL https://github.com/TeamHypersomnia/rectpack2D.git COMMITISH bbc9d0ec05b9b508f6c781667fec718bf9e78d21) @@ -106,13 +106,14 @@ if(ALP_BUILD_BROWSER) set(GLFW_BUILD_WAYLAND ON CACHE BOOL "" FORCE) set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE) endif() - alp_add_git_repository(glfw URL https://github.com/glfw/glfw.git COMMITISH e7ea71be039836da3a98cea55ae5569cb5eb885c NOT_SYSTEM) + alp_add_git_repository(glfw URL https://github.com/glfw/glfw.git COMMITISH e7ea71be039836da3a98cea55ae5569cb5eb885c) alp_add_git_repository(glad URL https://github.com/Dav1dde/glad.git COMMITISH 431786d8126e4f383a81e36f47b61a5d52a1c20d DO_NOT_ADD_SUBPROJECT) add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) glad_add_library(glad_gl_core_46 REPRODUCIBLE API gl:core=4.6) + set_property(TARGET glad_gl_core_46 PROPERTY SYSTEM TRUE) - alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237 NOT_SYSTEM) + alp_add_git_repository(resources-lib URL https://github.com/vector-of-bool/cmrc.git COMMITISH 952ffddba731fc110bd50409e8d2b8a06abbd237) alp_add_git_repository(imgui URL https://github.com/ocornut/imgui.git COMMITISH 5f0acadf7db1b6d469f0771284e2e3f7818443ce DO_NOT_ADD_SUBPROJECT) add_library(imgui STATIC @@ -123,7 +124,7 @@ if(ALP_BUILD_BROWSER) ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp ) - target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends) + target_include_directories(imgui SYSTEM PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends) target_link_libraries(imgui PUBLIC glfw) endif() From fcdebe665ed4cacbeeb134aa417bc538e09a2af8 Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:14:27 +0200 Subject: [PATCH 5/7] Remove obsolete mesh tools --- CMakeLists.txt | 2 - src/CMakeLists.txt | 8 - src/mesh_merger/CMakeLists.txt | 5 - src/mesh_merger/cli.cpp | 47 --- src/mesh_merger/cli.h | 20 -- src/mesh_merger/main.cpp | 71 ----- src/mesh_simplify/CMakeLists.txt | 10 - src/mesh_simplify/cli.cpp | 110 ------- src/mesh_simplify/cli.h | 54 ---- src/mesh_simplify/main.cpp | 141 --------- src/mesh_simplify/simplify.cpp | 521 ------------------------------- src/mesh_simplify/simplify.h | 66 ---- src/mesh_simplify/uv_map.cpp | 199 ------------ src/mesh_simplify/uv_map.h | 73 ----- 14 files changed, 1327 deletions(-) delete mode 100644 src/mesh_merger/CMakeLists.txt delete mode 100644 src/mesh_merger/cli.cpp delete mode 100644 src/mesh_merger/cli.h delete mode 100644 src/mesh_merger/main.cpp delete mode 100644 src/mesh_simplify/CMakeLists.txt delete mode 100644 src/mesh_simplify/cli.cpp delete mode 100644 src/mesh_simplify/cli.h delete mode 100644 src/mesh_simplify/main.cpp delete mode 100644 src/mesh_simplify/simplify.cpp delete mode 100644 src/mesh_simplify/simplify.h delete mode 100644 src/mesh_simplify/uv_map.cpp delete mode 100644 src/mesh_simplify/uv_map.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 722871a9..cb33f30d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,8 @@ project(alpine-terrain-builder LANGUAGES C CXX) option(ALP_BUILD_TILE_BUILDER "Build tile-builder" ON) option(ALP_BUILD_SF_MERGER "Build sf-merger" ON) option(ALP_BUILD_MESH_BUILDER "Build mesh-builder" ON) -option(ALP_BUILD_MESH_SIMPLIFY "Build mesh-simplify" ON) option(ALP_BUILD_TILE_DOWNLOADER "Build tile-downloader" ON) option(ALP_BUILD_MESH_CONVERT "Build mesh-convert" ON) -option(ALP_BUILD_MESH_MERGER "Build mesh_merger" ON) option(ALP_BUILD_INDEX_BROWSER "Build index-browser" ON) option(ALP_BUILD_DAG_BUILDER "Build dag-builder" ON) option(ALP_BUILD_DAG_CONVERT_DEBUG "Build dag-convert-debug" ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f7c8a60..e6dbaa82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,10 +59,8 @@ alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMM set(ALP_CLI_COMPONENT_OPTIONS ALP_BUILD_SF_MERGER ALP_BUILD_MESH_BUILDER - ALP_BUILD_MESH_SIMPLIFY ALP_BUILD_TILE_DOWNLOADER ALP_BUILD_MESH_CONVERT - ALP_BUILD_MESH_MERGER ALP_BUILD_INDEX_BROWSER ALP_BUILD_DAG_BUILDER ALP_BUILD_DAG_CONVERT_DEBUG @@ -146,18 +144,12 @@ endif() if(ALP_BUILD_MESH_BUILDER) add_subdirectory(mesh_builder) endif() -if(ALP_BUILD_MESH_SIMPLIFY) - add_subdirectory(mesh_simplify) -endif() if(ALP_BUILD_TILE_DOWNLOADER) add_subdirectory(tile_downloader) endif() if(ALP_BUILD_MESH_CONVERT) add_subdirectory(mesh_convert) endif() -if(ALP_BUILD_MESH_MERGER) - add_subdirectory(mesh_merger) -endif() if(ALP_BUILD_INDEX_BROWSER) add_subdirectory(index_browser) endif() diff --git a/src/mesh_merger/CMakeLists.txt b/src/mesh_merger/CMakeLists.txt deleted file mode 100644 index ba648d39..00000000 --- a/src/mesh_merger/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_executable(mesh_merger - cli.cpp - main.cpp -) -target_link_libraries(mesh_merger PRIVATE terrainlib CLI11::CLI11) diff --git a/src/mesh_merger/cli.cpp b/src/mesh_merger/cli.cpp deleted file mode 100644 index b0804c48..00000000 --- a/src/mesh_merger/cli.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "cli.h" - -#include -#include -#include - -using namespace cli; - -Args cli::parse(int argc, const char * const * argv) { - DEBUG_ASSERT(argc >= 0); - - Args args; - CLI::App app{"mesh merger"}; - app.positionals_at_end(false); - app.allow_windows_style_options(false); - - app.add_option("--input", args.mesh_paths, "Meshes to to merge together") - ->check(CLI::ExistingFile) - ->required(); - - app.add_option("--output", args.output_path, "Path to write the merged mesh to") - ->required(); - - app.add_option("--epsilon", args.epsilon, "Epsilon for vertex deduplication") - ->check(CLI::Range(std::numeric_limits::min(), std::numeric_limits::max())); - - const std::map - log_level_names{ - {"off", spdlog::level::level_enum::off}, - {"critical", spdlog::level::level_enum::critical}, - {"error", spdlog::level::level_enum::err}, - {"warn", spdlog::level::level_enum::warn}, - {"info", spdlog::level::level_enum::info}, - {"debug", spdlog::level::level_enum::debug}, - {"trace", spdlog::level::level_enum::trace}}; - app.add_option("--verbosity", args.log_level, "Verbosity level of logging") - ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)) - ->default_val(spdlog::level::level_enum::info); - - try { - app.parse(argc, argv); - } catch (const CLI::ParseError &e) { - exit(app.exit(e)); - } - - return args; -} diff --git a/src/mesh_merger/cli.h b/src/mesh_merger/cli.h deleted file mode 100644 index 0ae05d85..00000000 --- a/src/mesh_merger/cli.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace cli { - -struct Args { - std::vector mesh_paths; - std::filesystem::path output_path; - std::optional epsilon; - spdlog::level::level_enum log_level; -}; - -Args parse(int argc, const char *const *argv); - -} diff --git a/src/mesh_merger/main.cpp b/src/mesh_merger/main.cpp deleted file mode 100644 index 2cce21b2..00000000 --- a/src/mesh_merger/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "cli.h" -#include "log.h" -#include "mesh/SimpleMesh.h" -#include "mesh/io.h" -#include "mesh/merging/mapping.h" -#include "mesh/holes.h" - -SimpleMesh merge(const std::span meshes, const std::optional epsilon) { - std::vector> mesh_refs; - mesh_refs.reserve(meshes.size()); - for (const SimpleMesh &mesh : meshes) { - mesh_refs.push_back(std::cref(mesh)); - } - - mesh::merging::VertexMapping mapping; - if (epsilon.has_value()) { - mapping = mesh::merging::create_mapping(mesh_refs, - mesh::merging::create_options().epsilon(epsilon.value())); - } else { - mapping = mesh::merging::create_mapping(mesh_refs); - } - - SimpleMesh merged = mesh::merging::apply_mapping(mesh_refs, mapping); - mesh::fill_holes_on_merge_border(merged, mapping); - return merged; -} - -void run(const cli::Args &args) { - std::vector meshes; - meshes.reserve(args.mesh_paths.size()); - for (const std::filesystem::path& mesh_path : args.mesh_paths) { - LOG_INFO("Loading mesh from {}", mesh_path); - auto result = mesh::io::load_from_path(mesh_path); - if (!result.has_value()) { - LOG_ERROR_AND_EXIT("Failed to load mesh to {} due to {}", mesh_path, result.error().description()); - } - const SimpleMesh mesh = result.value(); - meshes.push_back(mesh); - } - - LOG_INFO("Merging meshes"); - const SimpleMesh merged = merge(meshes, args.epsilon); - - LOG_INFO("Saving mesh to {}", args.output_path); - auto result = mesh::io::save_to_path(merged, args.output_path); - if (!result.has_value()) { - LOG_ERROR_AND_EXIT("Failed to save mesh to {} due to {}", args.output_path, result.error().description()); - } -} - -int main(int argc, char **argv) { - const cli::Args args = cli::parse(argc, argv); - Log::init(args.log_level); - - const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), - [](const std::string &acc, const char *arg) { - return acc + (acc.empty() ? "" : " ") + arg; - }); - LOG_DEBUG("Running with: {}", arg_str); - - run(args); - return 0; -} diff --git a/src/mesh_simplify/CMakeLists.txt b/src/mesh_simplify/CMakeLists.txt deleted file mode 100644 index 5b03ba55..00000000 --- a/src/mesh_simplify/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_library(meshsimplifylib - cli.cpp - simplify.cpp - uv_map.cpp -) -target_include_directories(meshsimplifylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(meshsimplifylib PUBLIC terrainlib CLI11::CLI11 Eigen3 CGAL::CGAL) - -add_executable(mesh-simplify main.cpp) -target_link_libraries(mesh-simplify PRIVATE meshsimplifylib) diff --git a/src/mesh_simplify/cli.cpp b/src/mesh_simplify/cli.cpp deleted file mode 100644 index a5c4c201..00000000 --- a/src/mesh_simplify/cli.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "cli.h" - -#include -#include - -using namespace cli; - -Args cli::parse(int argc, const char * const * argv) { - DEBUG_ASSERT(argc >= 0); - - CLI::App app{"mesh_simplify"}; - app.allow_windows_style_options(); - // argv = app.ensure_utf8(argv); - - std::vector input_paths; - app.add_option("--input", input_paths, "Paths to tiles that should be merged") - ->required() - ->expected(-1) - ->check(CLI::ExistingFile); - - std::filesystem::path output_path; - app.add_option("--output", output_path, "Path to output the merged tile to") - ->required(); - - bool no_mesh_simplification = false; - app.add_flag("--no-simplify", no_mesh_simplification, "Disable mesh simplification"); - - std::optional simplification_vertex_ratio; - app.add_option("--simplify-vertex-ratio", simplification_vertex_ratio, "Target mesh vertex simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_edge_ratio; - app.add_option("--simplify-edge-ratio", simplification_edge_ratio, "Target mesh edge simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_face_ratio; - app.add_option("--simplify-face-ratio", simplification_face_ratio, "Target mesh face simplification factor") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_target_error_relative; - app.add_option("--simplify-error-relative", simplification_target_error_relative, "Relative mesh simplification error bound") - ->check(CLI::Range(0.0, 1.0)) - ->excludes("--no-simplify"); - - std::optional simplification_target_error_absolute; - app.add_option("--simplify-error-absolute", simplification_target_error_absolute, "Absolute mesh simplification error bound") - ->check(CLI::PositiveNumber) - ->excludes("--no-simplify"); - - std::vector target_texture_resolution; - app.add_option("--texture-resolution", target_texture_resolution, "Resolution of merged mesh texture") - ->check(CLI::PositiveNumber) - ->expected(2); - - bool save_intermediate_meshes = false; - app.add_flag("--save-debug-meshes", save_intermediate_meshes, "Output intermediate meshes"); - - spdlog::level::level_enum log_level = spdlog::level::level_enum::info; - const std::map log_level_names{ - {"off", spdlog::level::level_enum::off}, - {"critical", spdlog::level::level_enum::critical}, - {"error", spdlog::level::level_enum::err}, - {"warn", spdlog::level::level_enum::warn}, - {"info", spdlog::level::level_enum::info}, - {"debug", spdlog::level::level_enum::debug}, - {"trace", spdlog::level::level_enum::trace}}; - app.add_option("--verbosity", log_level, "Verbosity level of logging") - ->transform(CLI::CheckedTransformer(log_level_names, CLI::ignore_case)); - - try { - app.parse(argc, argv); - } catch (const CLI::ParseError &e) { - exit(app.exit(e)); - } - Args args; - args.input_paths = input_paths; - args.output_path = output_path; - args.log_level = log_level; - args.save_intermediate_meshes = save_intermediate_meshes; - if (target_texture_resolution.size() == 2) { - args.target_texture_resolution = {target_texture_resolution[0], target_texture_resolution[1]}; - } - if (!no_mesh_simplification) { - SimplificationArgs simplification_args = {}; - if (simplification_vertex_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::VertexRatio { .ratio=simplification_vertex_ratio.value() }); - } - if (simplification_edge_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=simplification_edge_ratio.value() }); - } - if (simplification_face_ratio.has_value()) { - simplification_args.stop_condition.push_back(simplify::FaceRatio { .ratio=simplification_face_ratio.value() }); - } - if (simplification_target_error_relative.has_value()) { - simplification_args.stop_condition.push_back(simplify::RelativeError { .error_bound = simplification_target_error_relative.value() }); - } - if (simplification_target_error_absolute.has_value()) { - simplification_args.stop_condition.push_back(simplify::AbsoluteError { .error_bound=simplification_target_error_absolute.value() }); - } - if (simplification_args.stop_condition.empty()) { - simplification_args.stop_condition.push_back(simplify::EdgeRatio { .ratio=1.0/args.input_paths.size() }); - } - args.simplification = simplification_args; - } - - return args; -} diff --git a/src/mesh_simplify/cli.h b/src/mesh_simplify/cli.h deleted file mode 100644 index ea102601..00000000 --- a/src/mesh_simplify/cli.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef CLI_H -#define CLI_H - -#include "pch.h" - -#include - -#include "simplify.h" - -namespace cli { - struct SimplificationArgs { - std::vector stop_condition; - }; - - struct Args { - std::filesystem::path output_path; - std::vector input_paths; - std::optional simplification; - spdlog::level::level_enum log_level; - bool save_intermediate_meshes; - std::optional target_texture_resolution; - }; - - Args parse(int argc, const char *const *argv); - - namespace { - template - Args _parse(const std::span args) { - std::array raw_args; - std::transform(args.begin(), args.end(), raw_args.begin(), - [](const T &str) { return str.data(); }); - return cli::parse(raw_args.size(), raw_args.data()); - } - template - Args _parse(const std::span args) { - std::vector raw_args; - raw_args.resize(args.size()); - std::transform(args.begin(), args.end(), raw_args.begin(), - [](const T &str) { return str.data(); }); - return cli::parse(raw_args.size(), raw_args.data()); - } - } - - template - Args parse(const std::span args) { - return _parse(args); - } - template - Args parse(const std::span args) { - return _parse(args); - } -} - -#endif diff --git a/src/mesh_simplify/main.cpp b/src/mesh_simplify/main.cpp deleted file mode 100644 index f380df0d..00000000 --- a/src/mesh_simplify/main.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include - -#include "cli.h" -#include "mesh/convert.h" -#include "log.h" -#include "mesh/merge.h" -#include "mesh/io.h" -#include "simplify.h" -#include "uv_map.h" -#include "mesh/validate.h" - -std::vector load_meshes_from_path(std::span paths, const bool print_errors = true) { - std::vector meshes; - meshes.reserve(paths.size()); - for (const std::filesystem::path &path : paths) { - auto result = mesh::io::load_from_path(path); - if (!result.has_value()) { - const mesh::io::LoadMeshError error = result.error(); - if (print_errors) { - LOG_ERROR("Failed to load mesh from {}: {}", path, error.description()); - } - exit(EXIT_FAILURE); - } - - const SimpleMesh mesh = std::move(result.value()); - mesh::validate(mesh); - meshes.push_back(mesh); - } - - return meshes; -} - -uv_map::UvMap parameterize_mesh(SimpleMesh &mesh) { - const tl::expected result = - uv_map::parameterize_mesh(mesh, uv_map::Algorithm::DiscreteConformalMap, uv_map::Border::Circle); - if (result) { - return result.value(); - } else { - const uv_map::UvParameterizationError error = result.error(); - LOG_ERROR("Failed to parameterize merged mesh due to '{}'", error.description()); - exit(EXIT_FAILURE); - } -} - -SimpleMesh simplify_mesh(const SimpleMesh &mesh, const cli::SimplificationArgs &args) { - const simplify::Result result = simplify::simplify_mesh(mesh, args.stop_condition); - const SimpleMesh &simplified_mesh = result.mesh; - - const size_t initial_vertex_count = mesh.positions.size(); - const size_t initial_face_count = mesh.triangles.size(); - const size_t simplified_vertex_count = simplified_mesh.positions.size(); - const size_t simplified_face_count = simplified_mesh.triangles.size(); - - LOG_DEBUG("Simplified mesh to {}/{} vertices and {}/{} faces", - simplified_vertex_count, initial_vertex_count, - simplified_face_count, initial_face_count); - - return result.mesh; -} - -glm::uvec2 cv2glm(cv::Point2i point) { - return glm::uvec2(point.x, point.y); -} - -void run(const cli::Args &args) { - LOG_INFO("Loading meshes..."); - std::vector meshes = load_meshes_from_path(args.input_paths); - - const bool meshes_have_uvs = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_uvs(); }); - const bool meshes_have_textures = std::all_of(meshes.begin(), meshes.end(), [](const SimpleMesh &mesh) { return mesh.has_texture(); }); - - const std::optional texture_size = (!meshes.empty() && meshes[0].texture.has_value()) - ? std::optional{cv2glm(meshes[0].texture.value().size())} - : std::nullopt; - const glm::uvec2 target_texture_size = args.target_texture_resolution.has_value() ? - args.target_texture_resolution.value() : (texture_size.has_value() ? texture_size.value() : glm::uvec2(256)); - - LOG_INFO("Merging meshes..."); - const mesh::merging::VertexMapping vertex_mapping = mesh::merging::create_mapping(meshes); - SimpleMesh merged_mesh = mesh::merging::apply_mapping(meshes, vertex_mapping); - if (args.save_intermediate_meshes) { - const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".merged.glb"); - LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - mesh::io::save_to_path(merged_mesh, merged_mesh_path, mesh::io::SaveOptions{.name = "merged"}); - } - - if (meshes_have_uvs) { - LOG_INFO("Calculating uv mapping..."); - const uv_map::UvMap uv_map = parameterize_mesh(merged_mesh); - merged_mesh.uvs = uv_map::decode_uv_map(uv_map, merged_mesh.vertex_count()); - - if (meshes_have_textures) { - LOG_INFO("Merging textures..."); - merged_mesh.texture = uv_map::merge_textures(meshes, merged_mesh, vertex_mapping, uv_map, target_texture_size * glm::uvec2(2)); - - if (args.save_intermediate_meshes) { - const std::filesystem::path merged_mesh_path = std::filesystem::path(args.output_path).replace_extension(".textured.glb"); - LOG_DEBUG("Saving merged mesh to {}", merged_mesh_path); - mesh::io::save_to_path(merged_mesh, merged_mesh_path, mesh::io::SaveOptions{.name = "textured"}); - } - } - } - - SimpleMesh simplified_mesh; - if (args.simplification) { - LOG_INFO("Simplifying merged mesh..."); - simplified_mesh = simplify_mesh(merged_mesh, args.simplification.value()); - - if (merged_mesh.texture.has_value()) { - LOG_INFO("Simplifying merged texture..."); - simplified_mesh.texture = simplify::simplify_texture(merged_mesh.texture.value(), target_texture_size); - } - - if (args.save_intermediate_meshes) { - const std::filesystem::path simplified_mesh_path = std::filesystem::path(args.output_path).replace_extension(".simplified.glb"); - LOG_DEBUG("Saving simplified mesh to {}", simplified_mesh_path.string()); - mesh::io::save_to_path(simplified_mesh, simplified_mesh_path, mesh::io::SaveOptions{.name = "simplified"}); - } - } else { - simplified_mesh = merged_mesh; - } - - LOG_INFO("Saving final mesh..."); - mesh::io::save_to_path(simplified_mesh, args.output_path); - - LOG_INFO("Done"); -} - -int main(int argc, char **argv) { - const cli::Args args = cli::parse(argc, argv); - Log::init(args.log_level); - - const std::string arg_str = std::accumulate(argv, argv + argc, std::string(), - [](const std::string &acc, const char *arg) { - return acc + (acc.empty() ? "" : " ") + arg; - }); - LOG_DEBUG("Running with: {}", arg_str); - - run(args); -} diff --git a/src/mesh_simplify/simplify.cpp b/src/mesh_simplify/simplify.cpp deleted file mode 100644 index db3acedb..00000000 --- a/src/mesh_simplify/simplify.cpp +++ /dev/null @@ -1,521 +0,0 @@ -// required before distance.h due to a bug in cgal -// https://github.com/CGAL/cgal/issues/8009 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "mesh/convert.h" -#include "mesh/bounds.h" -#include "opencv_utils.h" -#include "log.h" -#include "simplify.h" -#include "uv_map.h" -#include "mesh/cleanup.h" -#include "mesh/validate.h" -#include "mesh/cgal.h" - - -auto fmt::formatter::format(const simplify::Algorithm &algorithm, format_context &ctx) const { - string_view name = "unknown"; - - switch (algorithm) { - case simplify::Algorithm::GarlandHeckbert: - name = "GarlandHeckbert"; - break; - case simplify::Algorithm::LindstromTurk: - name = "LindstromTurk"; - break; - } - - return formatter::format(name, ctx); -} - -std::ostream &operator<<(std::ostream &os, const simplify::Algorithm &algorithm) { - os << fmt::format("{}", algorithm); - return os; -} - -namespace simplify { - -namespace { -template -struct overloaded : Ts... { - using Ts::operator()...; -}; - -// We use a different uv map type here, because we need this one to be attached to the mesh -// as otherwise the entries for removed vertices are not removed during garbage collection. -// We could use the same type as in uv_map but this would require a custom visitor or similar. -using AttachedUvPropertyMap = cgal::Mesh::Property_map; - -inline std::vector decode_uv_map(const AttachedUvPropertyMap &uv_map, size_t number_of_vertices) { - std::vector uvs; - uvs.reserve(number_of_vertices); - for (size_t i = 0; i < number_of_vertices; i++) { - const cgal::Point2 &uv = uv_map[CGAL::SM_Vertex_index(i)]; - uvs.push_back(convert::to_glm_point(uv)); - } - return uvs; -} - -template -T clone(const T &orig) { - return T{orig}; -} - -class ExpensiveStopPredicate { -public: - ExpensiveStopPredicate(cgal::Mesh& mesh) : mesh(mesh), original_mesh(clone(mesh)) { - if (this->has_expensive_checks()) { - this->make_snapshot(std::move(clone(mesh)), mesh); - } - } - - template - bool operator()(const F & /*current_cost*/, - const Profile &/*profile*/, - size_t /*initial_edge_count*/, - size_t /*current_edge_count*/) const { - if (this->has_stopped) { - return true; - } - - if (this->has_expensive_checks() && this->should_check_expensive(this->original_mesh, this->mesh)) { - // At this point we know that we will perform expensive checks - // and thus want to clean up the removed geometry. - cgal::Mesh mesh_clone = clone(this->mesh); - mesh_clone.collect_garbage(); - - if (this->should_stop(this->original_mesh, mesh_clone, true)) { - this->restore_snapshot(this->mesh); - this->has_stopped = true; - return true; - } else { - this->make_snapshot(std::move(mesh_clone), this->mesh); - return false; - } - } - - if (this->should_stop(this->original_mesh, this->mesh, false)) { - this->has_stopped = true; - return true; - } else { - return false; - } - } - -protected: - virtual bool has_expensive_checks() const { - return true; - }; - - virtual bool should_check_expensive(const cgal::Mesh &original, const cgal::Mesh &simplified) const = 0; - virtual bool should_stop(const cgal::Mesh &original, const cgal::Mesh &simplified, const bool check_expensive) const = 0; - - virtual void make_snapshot(cgal::Mesh &&/*mesh_copy*/, cgal::Mesh& mesh) const { - this->mesh_snapshot = mesh; - } - virtual void restore_snapshot(cgal::Mesh& mesh) const { - mesh = this->mesh_snapshot; - } - -private: - mutable bool has_stopped = false; - cgal::Mesh &mesh; - mutable cgal::Mesh mesh_snapshot; - mutable cgal::Mesh original_mesh; -}; - -inline double measure_max_absolute_error(const cgal::Mesh &original, const cgal::Mesh &simplified, const double bound_on_error = 0.0001) { - const double error = CGAL::Polygon_mesh_processing::bounded_error_Hausdorff_distance( - original, simplified, bound_on_error); - return error + bound_on_error; -} - -inline radix::geometry::Aabb3d calculate_bounds(const cgal::Mesh &mesh) { - radix::geometry::Aabb3d bounds; - bounds.min = glm::dvec3(std::numeric_limits::infinity()); - bounds.max = glm::dvec3(-std::numeric_limits::infinity()); - - for (const CGAL::SM_Vertex_index vertex_index : mesh.vertices()) { - const cgal::Point3 &position = mesh.point(vertex_index); - bounds.expand_by(convert::to_glm_point(position)); - } - return bounds; -} - -inline std::pair check_condition(const VertexRatio &vertex_ratio, const cgal::Mesh &modified, const cgal::Mesh &original) { - const double modified_vertex_count = modified.number_of_vertices(); - const double current_ratio = static_cast(modified_vertex_count) / original.num_vertices(); - // LOG_TRACE("Current vertex ratio is {:g}% with target {:g}%", current_ratio * 100, vertex_ratio.ratio * 100); - DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); - const bool fulfilled = current_ratio <= vertex_ratio.ratio; - return {fulfilled, current_ratio}; -} -inline std::pair check_condition(const EdgeRatio &edge_ratio, const cgal::Mesh &modified, const cgal::Mesh &original) { - const double modified_edge_count = modified.number_of_edges(); - const double current_ratio = static_cast(modified_edge_count) / original.num_edges(); - // LOG_TRACE("Current edge ratio is {:g}% with target {:g}%", current_ratio * 100, edge_ratio.ratio * 100); - DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); - const bool fulfilled = current_ratio <= edge_ratio.ratio; - return {fulfilled, current_ratio}; -} -inline std::pair check_condition(const FaceRatio &face_ratio, const cgal::Mesh &modified, const cgal::Mesh &original) { - const double modified_face_count = modified.number_of_faces(); - const double current_ratio = static_cast(modified_face_count) / original.num_faces(); - // LOG_TRACE("Current face ratio is {:g}% with target {:g}%", current_ratio * 100, face_ratio.ratio * 100); - DEBUG_ASSERT(current_ratio >= 0 && current_ratio <= 1); - const bool fulfilled = current_ratio <= face_ratio.ratio; - return {fulfilled, current_ratio}; -} -inline std::pair check_condition(const RelativeError &relative_error, const cgal::Mesh &modified, const cgal::Mesh &original) { - // TODO: use CGAL::Polygon_mesh_processing::is_Hausdorff_distance_larger() instead - const glm::dvec3 original_mesh_size = calculate_bounds(original).size(); - const double original_mesh_max_size = std::max({original_mesh_size[0], original_mesh_size[1], original_mesh_size[2]}); - const double absolute_error_bound = relative_error.error_bound * original_mesh_max_size; - const double current_absolute_error = measure_max_absolute_error(original, modified, absolute_error_bound * 0.1 /* TODO: */); - const double current_relative_error = current_absolute_error / original_mesh_max_size; - LOG_TRACE("Current relative error is {:g}% with target {:g}%", current_relative_error * 100, relative_error.error_bound * 100); - const bool fulfilled = current_relative_error >= relative_error.error_bound; - return {fulfilled, current_relative_error}; -} -inline std::pair check_condition(const AbsoluteError absolute_error, const cgal::Mesh &modified, const cgal::Mesh &original) { - const double current_absolute_error = measure_max_absolute_error(convert::to_cgal_mesh(convert::to_simple_mesh(original)), convert::to_cgal_mesh(convert::to_simple_mesh(modified)), absolute_error.error_bound * 0.1 /* TODO: */); - LOG_TRACE("Current absolute error is {:g} with target {:g}", current_absolute_error, absolute_error.error_bound); - const bool fulfilled = current_absolute_error >= absolute_error.error_bound; - return {fulfilled, current_absolute_error}; -} -inline std::pair check_condition(const StopCondition &stop_condition, const cgal::Mesh &modified, const cgal::Mesh &original) { - return std::visit(overloaded{ - [&](const VertexRatio &vertex_ratio) { - return check_condition(vertex_ratio, modified, original); - }, - [&](const EdgeRatio &edge_ratio) { - return check_condition(edge_ratio, modified, original); - }, - [&](const FaceRatio &face_ratio) { - return check_condition(face_ratio, modified, original); - }, - [&](const RelativeError &relative_error) { - return check_condition(relative_error, modified, original); - }, - [&](const AbsoluteError &absolute_error) { - return check_condition(absolute_error, modified, original); - }}, - stop_condition); -} - -inline bool is_evaluation_expensive(const StopCondition &stop_condition) { - return std::visit(overloaded{ - [&](const VertexRatio &) { - return false; - }, - [&](const EdgeRatio &) { - return false; - }, - [&](const FaceRatio &) { - return false; - }, - [&](const RelativeError &) { - return true; - }, - [&](const AbsoluteError &) { - return true; - }}, - stop_condition); -} - -struct MeshSnapshot { - // mesh is already saved by ExpensiveStopPredicate - std::vector uv_map; -}; - -class StopConditionStopPredicate : public ExpensiveStopPredicate { -public: - StopConditionStopPredicate(cgal::Mesh &mesh, AttachedUvPropertyMap &uv_map, const std::span stop_conditions) - : ExpensiveStopPredicate(mesh), stop_conditions(stop_conditions), uv_map_ref(uv_map) { - this->has_expensive_condition = std::any_of(this->stop_conditions.begin(), this->stop_conditions.end(), is_evaluation_expensive); - this->next_check_edge_count = CGAL::num_edges(mesh) * 0.9; - this->last_snapshot = {}; - } - -protected: - bool has_expensive_checks() const override { - return this->has_expensive_condition; - } - bool should_check_expensive(const cgal::Mesh &, const cgal::Mesh &simplified) const override { - if (!this->has_expensive_condition) { - return false; - } - - const double current_edge_count = simplified.number_of_edges(); - if (this->next_check_edge_count >= current_edge_count) { - LOG_TRACE("Current edge count threshold of {} reached", this->next_check_edge_count); - this->next_check_edge_count *= 0.9; - LOG_TRACE("Next expensive stop condition check is at edge count of {}", this->next_check_edge_count); - return true; - } - return false; - } - - bool should_stop(const cgal::Mesh &original, const cgal::Mesh &simplified, const bool check_expensive) const override { - return std::any_of(this->stop_conditions.begin(), this->stop_conditions.end(), [&](const StopCondition &stop_condition) { - if (is_evaluation_expensive(stop_condition) && !check_expensive) { - return false; - } - return check_condition(stop_condition, simplified, original).first; - }); - } - - void make_snapshot(cgal::Mesh &&mesh, cgal::Mesh& mesh2) const override { - LOG_TRACE("Making new snapshot of current geometry"); - this->last_snapshot.uv_map.clear(); - this->last_snapshot.uv_map.resize(mesh2.num_vertices()); - - for (const CGAL::SM_Vertex_index vertex_index : mesh2.vertices()) { - const cgal::Point2 &uv = uv_map_ref[vertex_index]; - this->last_snapshot.uv_map[vertex_index] = convert::to_glm_point(uv); - } - - ExpensiveStopPredicate::make_snapshot(std::move(mesh), mesh2); - } - - void restore_snapshot(cgal::Mesh& mesh) const override { - LOG_TRACE("Restoring last valid snapshot"); - ExpensiveStopPredicate::restore_snapshot(mesh); - - mesh.remove_property_map(this->uv_map_ref); - this->uv_map_ref = mesh.add_property_map("h:uv").first; - for (size_t i = 0; i < this->last_snapshot.uv_map.size(); i++) { - this->uv_map_ref[CGAL::SM_Vertex_index(i)] = convert::to_cgal_point(this->last_snapshot.uv_map[i]); - } - } - -private: - const std::span stop_conditions; - AttachedUvPropertyMap &uv_map_ref; - mutable size_t next_check_edge_count; - bool has_expensive_condition; - mutable MeshSnapshot last_snapshot; -}; - -struct UvMapUpdateEdgeCollapseVisitor : CGAL::Surface_mesh_simplification::Edge_collapse_visitor_base { - UvMapUpdateEdgeCollapseVisitor(AttachedUvPropertyMap &uv_map) - : uv_map(uv_map) {} - - // Called during the processing phase for each edge being collapsed. - // If placement is absent the edge is left uncollapsed. - void OnCollapsing(const Profile &profile, std::optional placement) { - if (!placement) { - return; - } - - const cgal::VertexDescriptor v0 = profile.v0(); - const cgal::VertexDescriptor v1 = profile.v1(); - - const glm::dvec3 pt = convert::to_glm_point(*placement); - const glm::dvec3 p0 = convert::to_glm_point(profile.p0()); - const glm::dvec3 p1 = convert::to_glm_point(profile.p1()); - - const auto w1 = std::clamp(glm::length(pt - p0) / glm::length(p1 - p0), 0.0, 1.0); - const auto w0 = 1 - w1; - - const glm::dvec2 uv0 = convert::to_glm_point(get(uv_map, v0)); - const glm::dvec2 uv1 = convert::to_glm_point(get(uv_map, v1)); - this->new_uv = convert::to_cgal_point(uv0 * w0 + uv1 * w1); - } - - // Called after each edge has been collapsed - void OnCollapsed(const Profile &, cgal::VertexDescriptor vd) { - uv_map[vd] = new_uv; - } - - AttachedUvPropertyMap &uv_map; - cgal::Point2 new_uv; -}; - -// Property map that indicates whether an edge is marked as non-removable. -struct BorderIsConstrainedEdgeMap { - typedef cgal::EdgeDescriptor key_type; - typedef bool value_type; - typedef value_type reference; - typedef boost::readable_property_map_tag category; - - const cgal::Mesh *mesh; - const bool active = true; - const bool restrict_border_triangles = true; - - BorderIsConstrainedEdgeMap(const cgal::Mesh &mesh, const bool active = true) - : mesh(&mesh), active(active) {} - - friend value_type get(const BorderIsConstrainedEdgeMap &map, const key_type &edge) { - if (!map.active) { - return false; - } - - const cgal::Mesh &mesh = *map.mesh; - - // return CGAL::is_border(edge, mesh); // old version - if (CGAL::is_border(edge, mesh)) { - return true; - } - - if (!map.restrict_border_triangles) { - return false; - } - - const cgal::VertexDescriptor v0 = mesh.vertex(edge, 0); - const cgal::VertexDescriptor v1 = mesh.vertex(edge, 1); - if (CGAL::is_border(v0, mesh).has_value() || CGAL::is_border(v1, mesh).has_value()) { - return true; - } - - return false; - } -}; - -struct SimplificationArgs { - bool lock_borders; - std::span stop_conditions; -}; - -template -inline size_t _simplify_mesh_with_cost_and_placement( - cgal::Mesh &mesh, - AttachedUvPropertyMap &uv_map, - const Cost &cost, - const Placement &placement, - const SimplificationArgs args) { - typedef typename CGAL::Surface_mesh_simplification::Constrained_placement ConstrainedPlacement; - BorderIsConstrainedEdgeMap bem(mesh, args.lock_borders); - const ConstrainedPlacement constrained_placement(bem, placement); - - // const CGAL::Surface_mesh_simplification::Count_ratio_stop_predicate stop_predicate(args.stop_edge_ratio); - const StopConditionStopPredicate stop_predicate(mesh, uv_map, args.stop_conditions); - UvMapUpdateEdgeCollapseVisitor visitor(uv_map); - const CGAL::Surface_mesh_simplification::Bounded_normal_change_filter<> filter; - - const size_t removed_edge_count = CGAL::Surface_mesh_simplification::edge_collapse(mesh, stop_predicate, - CGAL::parameters::edge_is_constrained_map(bem) - .get_placement(constrained_placement) - .get_cost(cost) - .filter(filter) - .visitor(visitor)); - - LOG_TRACE("Removed {} edges from simplified mesh", removed_edge_count); - - // Actually remove the vertices, edges and faces - mesh.collect_garbage(); - - return removed_edge_count; -} - -template -inline size_t _simplify_mesh_with_policies( - cgal::Mesh &mesh, - AttachedUvPropertyMap &uv_map, - const Policies &policies, - const SimplificationArgs args) { - typedef typename Policies::Get_cost Cost; - typedef typename Policies::Get_placement Placement; - - const Cost &cost = policies.get_cost(); - const Placement &placement = policies.get_placement(); - - return _simplify_mesh_with_cost_and_placement(mesh, uv_map, cost, placement, args); -} - -inline size_t _simplify_mesh( - cgal::Mesh &mesh, - AttachedUvPropertyMap &uv_map, - const Algorithm algorithm, - const SimplificationArgs args) { - // LOG_TRACE("Simplifying mesh (stop ratio={:g}, borders={}, algorithm={})", args.stop_edge_ratio, args.lock_borders ? "Locked" : "Unlocked", algorithm); - - switch (algorithm) { - case Algorithm::GarlandHeckbert: - typedef CGAL::Surface_mesh_simplification::GarlandHeckbert_policies GH_policies; - return _simplify_mesh_with_policies(mesh, uv_map, GH_policies(mesh), args); - case Algorithm::LindstromTurk: - typedef CGAL::Surface_mesh_simplification::LindstromTurk_cost LT_cost; - typedef CGAL::Surface_mesh_simplification::LindstromTurk_placement LT_placement; - return _simplify_mesh_with_cost_and_placement(mesh, uv_map, LT_cost(), LT_placement(), args); - } - - throw std::invalid_argument("invalid algorithm specified"); - } -} - - -Result simplify_mesh(const mesh::Simple&mesh, std::span stop_conditions, Options options) { - // simplification fails with large numerical values so we normalize the values here. - // EPECK is way too slow - const size_t vertex_count = mesh.positions.size(); - glm::dvec3 average_position(0, 0, 0); - for (size_t i = 0; i < vertex_count; i++) { - average_position += mesh.positions[i] / static_cast(vertex_count); - } - - mesh::Simple normalized_mesh = mesh; - for (size_t i = 0; i < vertex_count; i++) { - const glm::dvec3 normalized_position = mesh.positions[i] - average_position; - normalized_mesh.positions[i] = normalized_position; - } - - cgal::Mesh cgal_mesh = convert::to_cgal_mesh(normalized_mesh); - const cgal::Mesh original_mesh(cgal_mesh); - - AttachedUvPropertyMap uv_map = cgal_mesh.add_property_map("h:uv").first; - for (size_t i = 0; i < mesh.uvs.size(); i++) { - uv_map[CGAL::SM_Vertex_index(i)] = convert::to_cgal_point(mesh.uvs[i]); - } - - const SimplificationArgs args{ - .lock_borders = options.lock_borders, - .stop_conditions = stop_conditions}; - - /*const size_t removed_edge_count = */_simplify_mesh(cgal_mesh, uv_map, options.algorithm, args); - const double simplification_error = measure_max_absolute_error(original_mesh, cgal_mesh, 0.01); - - if (!CGAL::Polygon_mesh_processing::experimental::remove_self_intersections(cgal_mesh)) { - LOG_WARN("Failed to remove self intersections after simplification"); - } - - mesh::Simple simplified_mesh = convert::to_simple_mesh(cgal_mesh); - for (size_t i = 0; i < CGAL::num_vertices(cgal_mesh); i++) { - simplified_mesh.positions[i] += average_position; - } - - mesh::remove_isolated_vertices(simplified_mesh); - - mesh::validate(simplified_mesh); - - return Result{ - .mesh = simplified_mesh, - .max_absolute_error = simplification_error}; -} - -cv::Mat simplify_texture(const cv::Mat &texture, glm::uvec2 target_resolution) { - return rescale_texture(texture, target_resolution); -} - -void simplify_mesh_texture(mesh::Simple &mesh, glm::uvec2 target_resolution) { - if (mesh.texture.has_value()) { - mesh.texture = simplify_texture(mesh.texture.value(), target_resolution); - } -} - -} \ No newline at end of file diff --git a/src/mesh_simplify/simplify.h b/src/mesh_simplify/simplify.h deleted file mode 100644 index a5472042..00000000 --- a/src/mesh_simplify/simplify.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "mesh/SimpleMesh.h" -#include "mesh/cgal.h" - -#include -#include -#include - -#include -#include -#include - -namespace simplify { -// We use a different uv map type here, because we need this one to be attached to the mesh -// as otherwise the entries for removed vertices are not removed during garbage collection. -// We could use the same type as in uv_map but this would require a custom visitor or similar. -using AttachedUvPropertyMap = cgal::Mesh::Property_map; - -cv::Mat simplify_texture(const cv::Mat& texture, glm::uvec2 target_resolution); - -void simplify_mesh_texture(mesh::Simple& mesh, glm::uvec2 target_resolution); - -enum class Algorithm { - GarlandHeckbert, - LindstromTurk -}; - -struct VertexRatio { - double ratio; -}; -struct EdgeRatio { - double ratio; -}; -struct FaceRatio { - double ratio; -}; -struct AbsoluteError { - double error_bound; -}; -struct RelativeError { - double error_bound; -}; - -using StopCondition = std::variant; - -struct Options { - Algorithm algorithm = Algorithm::LindstromTurk; - bool lock_borders = true; -}; - -struct Result { - mesh::Simple mesh; - double max_absolute_error; -}; - -Result simplify_mesh(const mesh::Simple &mesh, std::span stop_conditions, Options options = Options()); -inline Result simplify_mesh(const mesh::Simple &mesh, const StopCondition& stop_condition, Options options = Options()) { - return simplify_mesh(mesh, std::span{&stop_condition, 1}, options); -} -} - -// fmt support -template <> struct fmt::formatter: formatter { - auto format(const simplify::Algorithm& algorithm, format_context& ctx) const; -}; diff --git a/src/mesh_simplify/uv_map.cpp b/src/mesh_simplify/uv_map.cpp deleted file mode 100644 index aedad705..00000000 --- a/src/mesh_simplify/uv_map.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mesh/convert.h" -#include "mesh/merge.h" -#include "uv_map.h" - -using namespace uv_map; - -std::vector uv_map::decode_uv_map(const UvMap &uv_map, size_t number_of_vertices) { - std::vector uvs; - uvs.reserve(number_of_vertices); - for (size_t i = 0; i < number_of_vertices; i++) { - const cgal::Point2 &uv = uv_map[CGAL::SM_Vertex_index(i)]; - uvs.push_back(convert::to_glm_point(uv)); - } - return uvs; -} - -std::vector uv_map::decode_uv_map(const UvPropertyMap &uv_map, size_t number_of_vertices) { - std::vector uvs; - uvs.reserve(number_of_vertices); - for (size_t i = 0; i < number_of_vertices; i++) { - const cgal::Point2 &uv = uv_map[CGAL::SM_Vertex_index(i)]; - uvs.push_back(convert::to_glm_point(uv)); - } - return uvs; -} - -tl::expected uv_map::parameterize_mesh(cgal::Mesh &mesh, Algorithm algorithm, Border border) { - typedef CGAL::Surface_mesh_parameterization::Circular_border_uniform_parameterizer_3 CircleBorderParameterizer; - typedef CGAL::Surface_mesh_parameterization::Square_border_uniform_parameterizer_3 SquareBorderParameterizer; - - typedef CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3 TutteBarycentricMappingParameterizerCircularBorder; - typedef CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3 TutteBarycentricMappingParameterizerSquareBorder; - typedef CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3 DiscreteAuthalicParameterizerCircularBorder; - typedef CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3 DiscreteAuthalicParameterizerSquareBorder; - typedef CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3 DiscreteConformalMapParameterizerCircularBorder; - typedef CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3 DiscreteConformalMapParameterizerSquareBorder; - typedef CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3 FloaterMeanValueCoordinatesParameterizerCircularBorder; - typedef CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3 FloaterMeanValueCoordinatesParameterizerSquareBorder; - - const cgal::HalfedgeDescriptor bhd = CGAL::Polygon_mesh_processing::longest_border(mesh).first; - - UvMap uv_uhm; - UvPropertyMap uv_map(uv_uhm); - - CGAL::Surface_mesh_parameterization::Error_code result; - if (border != Border::Circle && border != Border::Square) { - throw std::invalid_argument("illegal border specifier"); - } - - if (algorithm == Algorithm::TutteBarycentricMapping) { - if (border == Border::Circle) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, TutteBarycentricMappingParameterizerCircularBorder(), bhd, uv_map); - } else if (border == Border::Square) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, TutteBarycentricMappingParameterizerSquareBorder(), bhd, uv_map); - } - } else if (algorithm == Algorithm::DiscreteAuthalic) { - if (border == Border::Circle) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteAuthalicParameterizerCircularBorder(), bhd, uv_map); - } else if (border == Border::Square) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteAuthalicParameterizerSquareBorder(), bhd, uv_map); - } - } else if (algorithm == Algorithm::DiscreteConformalMap) { - if (border == Border::Circle) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteConformalMapParameterizerCircularBorder(), bhd, uv_map); - } else if (border == Border::Square) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, DiscreteConformalMapParameterizerSquareBorder(), bhd, uv_map); - } - } else if (algorithm == Algorithm::FloaterMeanValueCoordinates) { - if (border == Border::Circle) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, FloaterMeanValueCoordinatesParameterizerCircularBorder(), bhd, uv_map); - } else if (border == Border::Square) { - result = CGAL::Surface_mesh_parameterization::parameterize(mesh, FloaterMeanValueCoordinatesParameterizerSquareBorder(), bhd, uv_map); - } - } else { - throw std::invalid_argument("illegal algorithm specifier"); - } - - if (result != CGAL::Surface_mesh_parameterization::OK) { - return tl::unexpected(UvParameterizationError(result)); - } - - for (size_t i = 0; i < CGAL::num_vertices(mesh); i++) { - cgal::Point2 &uv = uv_map[CGAL::SM_Vertex_index(i)]; - uv = convert::to_cgal_point(glm::clamp(convert::to_glm_point(uv), glm::dvec2(0), glm::dvec2(1))); - } - - return uv_uhm; -} - -tl::expected uv_map::parameterize_mesh(const SimpleMesh &mesh, Algorithm algorithm, Border border) { - cgal::Mesh cgal_mesh = convert::to_cgal_mesh(mesh); - return parameterize_mesh(cgal_mesh, algorithm, border); -} - -template -static cv::Rect_ clamp_rect_to_mat_bounds(const cv::Rect_ &rect, const cv::Mat &mat) { - const T x = std::max(rect.x, 0); - const T y = std::max(rect.y, 0); - const T width = std::max(std::min(rect.width, mat.cols - x), 0); - const T height = std::max(std::min(rect.height, mat.rows - y), 0); - - return cv::Rect(x, y, width, height); -} - -static void warp_triangle(const cv::Mat &source_image, cv::Mat &target_image, std::array source_triangle, std::array target_triangle) { - // Find bounding rectangle for each triangle - const cv::Rect source_rect = clamp_rect_to_mat_bounds(cv::boundingRect(source_triangle), source_image); - const cv::Rect target_rect = clamp_rect_to_mat_bounds(cv::boundingRect(target_triangle), target_image); - if (source_rect.width == 0 || source_rect.height == 0 - || target_rect.width == 0 || target_rect.height == 0) { - return; - } - - // Relativize triangles to bounds - std::array source_triangle_cropped; - std::array target_triangle_cropped; - for (size_t i = 0; i < 3; i++) { - source_triangle_cropped[i] = cv::Point2f(source_triangle[i].x - source_rect.x, source_triangle[i].y - source_rect.y); - target_triangle_cropped[i] = cv::Point2f(target_triangle[i].x - target_rect.x, target_triangle[i].y - target_rect.y); - } - - // Convert points to int triangles as fillConvexPoly needs a vector of Point and not Point2f - std::array target_triangle_cropped_int; - for (size_t i = 0; i < 3; i++) { - target_triangle_cropped_int[i]= cv::Point2i((int)(target_triangle[i].x - target_rect.x), (int)(target_triangle[i].y - target_rect.y)); - } - - // Read source region from source image - cv::Mat source_image_cropped; - source_image(source_rect).copyTo(source_image_cropped); - source_image_cropped.convertTo(source_image_cropped, CV_32FC3); - - // Given a pair of triangles, find the affine transform. - const cv::Mat warp_tranform = cv::getAffineTransform(source_triangle_cropped, target_triangle_cropped); - - // Apply the affine transform just found to the source image - cv::Mat target_image_cropped = cv::Mat::zeros(target_rect.height, target_rect.width, CV_32FC3); - cv::warpAffine(source_image_cropped, target_image_cropped, warp_tranform, target_image_cropped.size(), cv::INTER_LINEAR, cv::BORDER_REFLECT_101); - - // Get mask by filling triangle - cv::Mat mask = cv::Mat::zeros(target_rect.height, target_rect.width, CV_32FC3); - cv::fillConvexPoly(mask, target_triangle_cropped_int, cv::Scalar(1.0, 1.0, 1.0), 16, 0); - - // Copy triangular region of the rectangular patch to the output image - cv::multiply(target_image_cropped, mask, target_image_cropped, 1, CV_32FC3); - cv::multiply(target_image(target_rect), cv::Scalar(1.0, 1.0, 1.0) - mask, target_image(target_rect), 1, CV_32FC3); - target_image(target_rect) = target_image(target_rect) + target_image_cropped; -} - -// TODO: use dag_builder/reproject_texture.h here -Texture uv_map::merge_textures( - const std::span original_meshes, - const SimpleMesh &merged_mesh, - const mesh::merging::VertexMapping &mapping, - const UvMap &uv_map, - const glm::uvec2 merged_texture_size) { - for (const SimpleMesh& mesh : original_meshes) { - DEBUG_ASSERT(mesh.has_texture()); - } - - cv::Mat merged_atlas = cv::Mat::zeros(merged_texture_size.y, merged_texture_size.x, CV_32FC3); - - for (const glm::uvec3 &mapped_triangle : merged_mesh.triangles) { - std::array mapped_uv_triangle; - for (size_t i = 0; i < static_cast(mapped_triangle.length()); i++) { - glm::dvec2 uv = convert::to_glm_point(uv_map[CGAL::SM_Vertex_index(mapped_triangle[i])]); - // Fix for black borders - uv = (uv - 0.5) * 1.01 + 0.5; - mapped_uv_triangle[i] = cv::Point2f(uv.x * merged_texture_size.x, uv.y * merged_texture_size.y); - } - - const mesh::merging::TriangleInMesh source_mesh_and_triangle = mapping.find_source_triangle(mapped_triangle); - const size_t source_mesh_index = source_mesh_and_triangle.mesh_index; - const SimpleMesh &source_mesh = original_meshes[source_mesh_index]; - const glm::uvec3 source_triangle = source_mesh_and_triangle.triangle; - - std::array source_uv_triangle; - for (size_t i = 0; i < static_cast(source_triangle.length()); i++) { - const glm::dvec2 uv = source_mesh.uvs[source_triangle[i]]; - const cv::Size source_texture_size = source_mesh.texture->size(); - source_uv_triangle[i] = cv::Point2f(uv.x * source_texture_size.width, uv.y * source_texture_size.height); - } - - warp_triangle(source_mesh.texture.value(), merged_atlas, source_uv_triangle, mapped_uv_triangle); - } - - return merged_atlas; -} diff --git a/src/mesh_simplify/uv_map.h b/src/mesh_simplify/uv_map.h deleted file mode 100644 index 2e364627..00000000 --- a/src/mesh_simplify/uv_map.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mesh/merge.h" - -typedef cv::Mat Texture; - -namespace uv_map { - -enum class Algorithm { - TutteBarycentricMapping, - DiscreteAuthalic, - DiscreteConformalMap, - FloaterMeanValueCoordinates -}; - -enum class Border { - Circle, - Square -}; - -class UvParameterizationError { -public: - UvParameterizationError() = default; - constexpr UvParameterizationError(int code) - : code(code) {} - - operator int() const { - return this->code; - } - - std::string description() const { - return CGAL::Surface_mesh_parameterization::get_error_message(this->code); - } - -private: - int code; -}; - -typedef CGAL::Unique_hash_map UvMap; -typedef boost::associative_property_map UvPropertyMap; - -std::vector decode_uv_map(const UvMap& uv_map, size_t number_of_vertices); -std::vector decode_uv_map(const UvPropertyMap& uv_map, size_t number_of_vertices); - -tl::expected parameterize_mesh( - cgal::Mesh &mesh, - Algorithm algorithm, - Border border); - -tl::expected parameterize_mesh( - const mesh::Simple &mesh, - Algorithm algorithm, - Border border); - -Texture merge_textures( - const std::span original_meshes, - const mesh::Simple& merged_mesh, - const mesh::merging::VertexMapping &mapping, - const UvMap& uv_map, - const glm::uvec2 merged_texture_size); - -} From d0b21edab29056a1c106318b1d849825e07d6ff3 Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:00:21 +0200 Subject: [PATCH 6/7] Use C++23 --- src/terrainlib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terrainlib/CMakeLists.txt b/src/terrainlib/CMakeLists.txt index 69c984fc..c9a0c1ca 100644 --- a/src/terrainlib/CMakeLists.txt +++ b/src/terrainlib/CMakeLists.txt @@ -50,7 +50,7 @@ add_library(terrainlib ProgressIndicator.cpp ) -target_compile_features(terrainlib PUBLIC cxx_std_20) +target_compile_features(terrainlib PUBLIC cxx_std_23) target_compile_definitions(terrainlib PUBLIC SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) target_include_directories(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_precompile_headers(terrainlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/pch.h) From 0101cc973af91ed54aa9540c4c4bc95d6718947e Mon Sep 17 00:00:00 2001 From: adam-ce <5292991+adam-ce@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:35:43 +0200 Subject: [PATCH 7/7] Rename SF components --- .github/workflows/ci.yml | 2 +- CMakeLists.txt | 6 +++--- src/CMakeLists.txt | 20 +++++++++---------- src/index_browser/CMakeLists.txt | 5 ----- src/mesh_builder/CMakeLists.txt | 9 --------- src/{browser => sf_browser}/CMakeLists.txt | 6 +++--- .../core/Application.cpp | 0 .../core/Application.h | 0 src/{browser => sf_browser}/core/Buffer.cpp | 0 src/{browser => sf_browser}/core/Buffer.h | 0 src/{browser => sf_browser}/core/Camera.cpp | 0 src/{browser => sf_browser}/core/Camera.h | 0 .../core/geometry/UnitCube.h | 0 .../core/rendering/OctreeRenderManager.cpp | 0 .../core/rendering/OctreeRenderManager.h | 0 .../core/shader/GLUniformAbstractions.h | 0 .../core/shader/Shader.cpp | 0 .../core/shader/Shader.h | 0 .../core/shader/ShaderProgram.cpp | 0 .../core/shader/ShaderProgram.h | 0 .../core/shader/Uniform.h | 0 .../core/window/Window.cpp | 0 .../core/window/Window.h | 0 src/{browser => sf_browser}/main.cpp | 0 .../res/CMakeLists.txt | 4 ++-- .../res/shaders/octree_lines.frag | 0 .../res/shaders/octree_lines.vert | 0 src/sf_builder/CMakeLists.txt | 9 +++++++++ src/{mesh_builder => sf_builder}/border.h | 0 src/{mesh_builder => sf_builder}/main.cpp | 2 +- .../mesh_builder.cpp | 0 .../mesh_builder.h | 0 src/{mesh_builder => sf_builder}/raster.h | 0 .../raw_dataset_reader.h | 0 .../terrainbuilder.cpp | 0 .../terrainbuilder.h | 0 .../texture_assembler.h | 0 .../tile_provider.h | 0 src/sf_index_browser/CMakeLists.txt | 5 +++++ .../cli.cpp | 2 +- src/{index_browser => sf_index_browser}/cli.h | 0 .../main.cpp | 0 unittests/CMakeLists.txt | 12 +++++------ .../{mesh_builder => sf_builder}/mesh.cpp | 0 .../{mesh_builder => sf_builder}/texture.cpp | 0 45 files changed, 41 insertions(+), 41 deletions(-) delete mode 100644 src/index_browser/CMakeLists.txt delete mode 100644 src/mesh_builder/CMakeLists.txt rename src/{browser => sf_browser}/CMakeLists.txt (61%) rename src/{browser => sf_browser}/core/Application.cpp (100%) rename src/{browser => sf_browser}/core/Application.h (100%) rename src/{browser => sf_browser}/core/Buffer.cpp (100%) rename src/{browser => sf_browser}/core/Buffer.h (100%) rename src/{browser => sf_browser}/core/Camera.cpp (100%) rename src/{browser => sf_browser}/core/Camera.h (100%) rename src/{browser => sf_browser}/core/geometry/UnitCube.h (100%) rename src/{browser => sf_browser}/core/rendering/OctreeRenderManager.cpp (100%) rename src/{browser => sf_browser}/core/rendering/OctreeRenderManager.h (100%) rename src/{browser => sf_browser}/core/shader/GLUniformAbstractions.h (100%) rename src/{browser => sf_browser}/core/shader/Shader.cpp (100%) rename src/{browser => sf_browser}/core/shader/Shader.h (100%) rename src/{browser => sf_browser}/core/shader/ShaderProgram.cpp (100%) rename src/{browser => sf_browser}/core/shader/ShaderProgram.h (100%) rename src/{browser => sf_browser}/core/shader/Uniform.h (100%) rename src/{browser => sf_browser}/core/window/Window.cpp (100%) rename src/{browser => sf_browser}/core/window/Window.h (100%) rename src/{browser => sf_browser}/main.cpp (100%) rename src/{browser => sf_browser}/res/CMakeLists.txt (89%) rename src/{browser => sf_browser}/res/shaders/octree_lines.frag (100%) rename src/{browser => sf_browser}/res/shaders/octree_lines.vert (100%) create mode 100644 src/sf_builder/CMakeLists.txt rename src/{mesh_builder => sf_builder}/border.h (100%) rename src/{mesh_builder => sf_builder}/main.cpp (99%) rename src/{mesh_builder => sf_builder}/mesh_builder.cpp (100%) rename src/{mesh_builder => sf_builder}/mesh_builder.h (100%) rename src/{mesh_builder => sf_builder}/raster.h (100%) rename src/{mesh_builder => sf_builder}/raw_dataset_reader.h (100%) rename src/{mesh_builder => sf_builder}/terrainbuilder.cpp (100%) rename src/{mesh_builder => sf_builder}/terrainbuilder.h (100%) rename src/{mesh_builder => sf_builder}/texture_assembler.h (100%) rename src/{mesh_builder => sf_builder}/tile_provider.h (100%) create mode 100644 src/sf_index_browser/CMakeLists.txt rename src/{index_browser => sf_index_browser}/cli.cpp (97%) rename src/{index_browser => sf_index_browser}/cli.h (100%) rename src/{index_browser => sf_index_browser}/main.cpp (100%) rename unittests/{mesh_builder => sf_builder}/mesh.cpp (100%) rename unittests/{mesh_builder => sf_builder}/texture.cpp (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d4f94da..9f5e9269 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,7 +173,7 @@ jobs: status=0 ./unittests/unittests_terrainlib "~mesh::clip_on_bounds benchmark" || status=$? ./unittests/unittests_tilebuilder || status=$? - ./unittests/unittests_meshbuilder || status=$? + ./unittests/unittests_sfbuilder || status=$? ./unittests/unittests_dagbuilder || status=$? ./unittests/unittests_sfmerger || status=$? exit $status diff --git a/CMakeLists.txt b/CMakeLists.txt index cb33f30d..3c2a9664 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,13 +5,13 @@ project(alpine-terrain-builder LANGUAGES C CXX) # Executable targets option(ALP_BUILD_TILE_BUILDER "Build tile-builder" ON) option(ALP_BUILD_SF_MERGER "Build sf-merger" ON) -option(ALP_BUILD_MESH_BUILDER "Build mesh-builder" ON) +option(ALP_BUILD_SF_BUILDER "Build sf-builder" ON) option(ALP_BUILD_TILE_DOWNLOADER "Build tile-downloader" ON) option(ALP_BUILD_MESH_CONVERT "Build mesh-convert" ON) -option(ALP_BUILD_INDEX_BROWSER "Build index-browser" ON) +option(ALP_BUILD_SF_INDEX_BROWSER "Build sf-index-browser" ON) option(ALP_BUILD_DAG_BUILDER "Build dag-builder" ON) option(ALP_BUILD_DAG_CONVERT_DEBUG "Build dag-convert-debug" ON) -option(ALP_BUILD_BROWSER "Build browser" ON) +option(ALP_BUILD_SF_BROWSER "Build sf-browser" ON) option(ALP_BUILD_UNITTESTS "Build unit tests for enabled components" ON) # Project configuration diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6dbaa82..5ece70b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,10 +58,10 @@ alp_add_git_repository(radix URL https://github.com/AlpineMapsOrg/radix.git COMM set(ALP_CLI_COMPONENT_OPTIONS ALP_BUILD_SF_MERGER - ALP_BUILD_MESH_BUILDER + ALP_BUILD_SF_BUILDER ALP_BUILD_TILE_DOWNLOADER ALP_BUILD_MESH_CONVERT - ALP_BUILD_INDEX_BROWSER + ALP_BUILD_SF_INDEX_BROWSER ALP_BUILD_DAG_BUILDER ALP_BUILD_DAG_CONVERT_DEBUG ) @@ -79,7 +79,7 @@ if(ALP_BUILD_TILE_DOWNLOADER) find_package(CURL REQUIRED) endif() -if(ALP_BUILD_INDEX_BROWSER) +if(ALP_BUILD_SF_INDEX_BROWSER) alp_add_git_repository(ftxui URL https://github.com/ArthurSonzogni/FTXUI COMMITISH v6.1.9) endif() @@ -96,7 +96,7 @@ if(ALP_BUILD_DAG_BUILDER OR ALP_BUILD_DAG_CONVERT_DEBUG) target_compile_definitions(metis INTERFACE IDXTYPEWIDTH=32 REALTYPEWIDTH=32) endif() -if(ALP_BUILD_BROWSER) +if(ALP_BUILD_SF_BROWSER) set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) @@ -141,8 +141,8 @@ endif() if(ALP_BUILD_SF_MERGER) add_subdirectory(sf_merger) endif() -if(ALP_BUILD_MESH_BUILDER) - add_subdirectory(mesh_builder) +if(ALP_BUILD_SF_BUILDER) + add_subdirectory(sf_builder) endif() if(ALP_BUILD_TILE_DOWNLOADER) add_subdirectory(tile_downloader) @@ -150,8 +150,8 @@ endif() if(ALP_BUILD_MESH_CONVERT) add_subdirectory(mesh_convert) endif() -if(ALP_BUILD_INDEX_BROWSER) - add_subdirectory(index_browser) +if(ALP_BUILD_SF_INDEX_BROWSER) + add_subdirectory(sf_index_browser) endif() if(ALP_BUILD_DAG_BUILDER OR ALP_BUILD_DAG_CONVERT_DEBUG) add_subdirectory(dag_builder) @@ -159,6 +159,6 @@ endif() if(ALP_BUILD_DAG_CONVERT_DEBUG) add_subdirectory(dag_convert_debug) endif() -if(ALP_BUILD_BROWSER) - add_subdirectory(browser) +if(ALP_BUILD_SF_BROWSER) + add_subdirectory(sf_browser) endif() diff --git a/src/index_browser/CMakeLists.txt b/src/index_browser/CMakeLists.txt deleted file mode 100644 index 3be0182e..00000000 --- a/src/index_browser/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_executable(index-browser - cli.cpp - main.cpp -) -target_link_libraries(index-browser PRIVATE terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) diff --git a/src/mesh_builder/CMakeLists.txt b/src/mesh_builder/CMakeLists.txt deleted file mode 100644 index 0447eecc..00000000 --- a/src/mesh_builder/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_library(meshbuilderlib - terrainbuilder.cpp - mesh_builder.cpp -) -target_include_directories(meshbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(meshbuilderlib PUBLIC terrainlib spdlog tl_expected) - -add_executable(mesh-builder main.cpp) -target_link_libraries(mesh-builder PRIVATE meshbuilderlib CLI11::CLI11) diff --git a/src/browser/CMakeLists.txt b/src/sf_browser/CMakeLists.txt similarity index 61% rename from src/browser/CMakeLists.txt rename to src/sf_browser/CMakeLists.txt index 70773897..8ed300c6 100644 --- a/src/browser/CMakeLists.txt +++ b/src/sf_browser/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(res) -add_executable(browser +add_executable(sf-browser main.cpp core/Application.cpp core/window/Window.cpp @@ -13,5 +13,5 @@ add_executable(browser core/geometry/UnitCube.h core/rendering/OctreeRenderManager.cpp ) -target_include_directories(browser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(browser PRIVATE terrainlib glfw glad_gl_core_46 resources-lib imgui) +target_include_directories(sf-browser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(sf-browser PRIVATE terrainlib glfw glad_gl_core_46 sf-browser-resources imgui) diff --git a/src/browser/core/Application.cpp b/src/sf_browser/core/Application.cpp similarity index 100% rename from src/browser/core/Application.cpp rename to src/sf_browser/core/Application.cpp diff --git a/src/browser/core/Application.h b/src/sf_browser/core/Application.h similarity index 100% rename from src/browser/core/Application.h rename to src/sf_browser/core/Application.h diff --git a/src/browser/core/Buffer.cpp b/src/sf_browser/core/Buffer.cpp similarity index 100% rename from src/browser/core/Buffer.cpp rename to src/sf_browser/core/Buffer.cpp diff --git a/src/browser/core/Buffer.h b/src/sf_browser/core/Buffer.h similarity index 100% rename from src/browser/core/Buffer.h rename to src/sf_browser/core/Buffer.h diff --git a/src/browser/core/Camera.cpp b/src/sf_browser/core/Camera.cpp similarity index 100% rename from src/browser/core/Camera.cpp rename to src/sf_browser/core/Camera.cpp diff --git a/src/browser/core/Camera.h b/src/sf_browser/core/Camera.h similarity index 100% rename from src/browser/core/Camera.h rename to src/sf_browser/core/Camera.h diff --git a/src/browser/core/geometry/UnitCube.h b/src/sf_browser/core/geometry/UnitCube.h similarity index 100% rename from src/browser/core/geometry/UnitCube.h rename to src/sf_browser/core/geometry/UnitCube.h diff --git a/src/browser/core/rendering/OctreeRenderManager.cpp b/src/sf_browser/core/rendering/OctreeRenderManager.cpp similarity index 100% rename from src/browser/core/rendering/OctreeRenderManager.cpp rename to src/sf_browser/core/rendering/OctreeRenderManager.cpp diff --git a/src/browser/core/rendering/OctreeRenderManager.h b/src/sf_browser/core/rendering/OctreeRenderManager.h similarity index 100% rename from src/browser/core/rendering/OctreeRenderManager.h rename to src/sf_browser/core/rendering/OctreeRenderManager.h diff --git a/src/browser/core/shader/GLUniformAbstractions.h b/src/sf_browser/core/shader/GLUniformAbstractions.h similarity index 100% rename from src/browser/core/shader/GLUniformAbstractions.h rename to src/sf_browser/core/shader/GLUniformAbstractions.h diff --git a/src/browser/core/shader/Shader.cpp b/src/sf_browser/core/shader/Shader.cpp similarity index 100% rename from src/browser/core/shader/Shader.cpp rename to src/sf_browser/core/shader/Shader.cpp diff --git a/src/browser/core/shader/Shader.h b/src/sf_browser/core/shader/Shader.h similarity index 100% rename from src/browser/core/shader/Shader.h rename to src/sf_browser/core/shader/Shader.h diff --git a/src/browser/core/shader/ShaderProgram.cpp b/src/sf_browser/core/shader/ShaderProgram.cpp similarity index 100% rename from src/browser/core/shader/ShaderProgram.cpp rename to src/sf_browser/core/shader/ShaderProgram.cpp diff --git a/src/browser/core/shader/ShaderProgram.h b/src/sf_browser/core/shader/ShaderProgram.h similarity index 100% rename from src/browser/core/shader/ShaderProgram.h rename to src/sf_browser/core/shader/ShaderProgram.h diff --git a/src/browser/core/shader/Uniform.h b/src/sf_browser/core/shader/Uniform.h similarity index 100% rename from src/browser/core/shader/Uniform.h rename to src/sf_browser/core/shader/Uniform.h diff --git a/src/browser/core/window/Window.cpp b/src/sf_browser/core/window/Window.cpp similarity index 100% rename from src/browser/core/window/Window.cpp rename to src/sf_browser/core/window/Window.cpp diff --git a/src/browser/core/window/Window.h b/src/sf_browser/core/window/Window.h similarity index 100% rename from src/browser/core/window/Window.h rename to src/sf_browser/core/window/Window.h diff --git a/src/browser/main.cpp b/src/sf_browser/main.cpp similarity index 100% rename from src/browser/main.cpp rename to src/sf_browser/main.cpp diff --git a/src/browser/res/CMakeLists.txt b/src/sf_browser/res/CMakeLists.txt similarity index 89% rename from src/browser/res/CMakeLists.txt rename to src/sf_browser/res/CMakeLists.txt index 2629bed9..49087e2d 100644 --- a/src/browser/res/CMakeLists.txt +++ b/src/sf_browser/res/CMakeLists.txt @@ -8,7 +8,7 @@ # For usage see: https://github.com/vector-of-bool/cmrc/tree/master#usage cmrc_add_resource_library( - resources-lib + sf-browser-resources NAMESPACE res # ADD NEW RESOURCES AFTER HERE @@ -18,4 +18,4 @@ cmrc_add_resource_library( ) # Generated CMRC sources reuse internal symbol names and cannot share a unity translation unit. -set_target_properties(resources-lib PROPERTIES UNITY_BUILD OFF) +set_target_properties(sf-browser-resources PROPERTIES UNITY_BUILD OFF) diff --git a/src/browser/res/shaders/octree_lines.frag b/src/sf_browser/res/shaders/octree_lines.frag similarity index 100% rename from src/browser/res/shaders/octree_lines.frag rename to src/sf_browser/res/shaders/octree_lines.frag diff --git a/src/browser/res/shaders/octree_lines.vert b/src/sf_browser/res/shaders/octree_lines.vert similarity index 100% rename from src/browser/res/shaders/octree_lines.vert rename to src/sf_browser/res/shaders/octree_lines.vert diff --git a/src/sf_builder/CMakeLists.txt b/src/sf_builder/CMakeLists.txt new file mode 100644 index 00000000..c50cae1c --- /dev/null +++ b/src/sf_builder/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(sfbuilderlib + terrainbuilder.cpp + mesh_builder.cpp +) +target_include_directories(sfbuilderlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(sfbuilderlib PUBLIC terrainlib spdlog tl_expected) + +add_executable(sf-builder main.cpp) +target_link_libraries(sf-builder PRIVATE sfbuilderlib CLI11::CLI11) diff --git a/src/mesh_builder/border.h b/src/sf_builder/border.h similarity index 100% rename from src/mesh_builder/border.h rename to src/sf_builder/border.h diff --git a/src/mesh_builder/main.cpp b/src/sf_builder/main.cpp similarity index 99% rename from src/mesh_builder/main.cpp rename to src/sf_builder/main.cpp index 91186ae4..9edfde4a 100644 --- a/src/mesh_builder/main.cpp +++ b/src/sf_builder/main.cpp @@ -177,7 +177,7 @@ int run(std::span args) { int argc = args.size(); char **argv = args.data(); - CLI::App app{"mesh_builder"}; + CLI::App app{"sf_builder"}; app.allow_windows_style_options(); argv = app.ensure_utf8(argv); diff --git a/src/mesh_builder/mesh_builder.cpp b/src/sf_builder/mesh_builder.cpp similarity index 100% rename from src/mesh_builder/mesh_builder.cpp rename to src/sf_builder/mesh_builder.cpp diff --git a/src/mesh_builder/mesh_builder.h b/src/sf_builder/mesh_builder.h similarity index 100% rename from src/mesh_builder/mesh_builder.h rename to src/sf_builder/mesh_builder.h diff --git a/src/mesh_builder/raster.h b/src/sf_builder/raster.h similarity index 100% rename from src/mesh_builder/raster.h rename to src/sf_builder/raster.h diff --git a/src/mesh_builder/raw_dataset_reader.h b/src/sf_builder/raw_dataset_reader.h similarity index 100% rename from src/mesh_builder/raw_dataset_reader.h rename to src/sf_builder/raw_dataset_reader.h diff --git a/src/mesh_builder/terrainbuilder.cpp b/src/sf_builder/terrainbuilder.cpp similarity index 100% rename from src/mesh_builder/terrainbuilder.cpp rename to src/sf_builder/terrainbuilder.cpp diff --git a/src/mesh_builder/terrainbuilder.h b/src/sf_builder/terrainbuilder.h similarity index 100% rename from src/mesh_builder/terrainbuilder.h rename to src/sf_builder/terrainbuilder.h diff --git a/src/mesh_builder/texture_assembler.h b/src/sf_builder/texture_assembler.h similarity index 100% rename from src/mesh_builder/texture_assembler.h rename to src/sf_builder/texture_assembler.h diff --git a/src/mesh_builder/tile_provider.h b/src/sf_builder/tile_provider.h similarity index 100% rename from src/mesh_builder/tile_provider.h rename to src/sf_builder/tile_provider.h diff --git a/src/sf_index_browser/CMakeLists.txt b/src/sf_index_browser/CMakeLists.txt new file mode 100644 index 00000000..22dbfda5 --- /dev/null +++ b/src/sf_index_browser/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(sf-index-browser + cli.cpp + main.cpp +) +target_link_libraries(sf-index-browser PRIVATE terrainlib CLI11::CLI11 ftxui::dom ftxui::component ftxui::screen) diff --git a/src/index_browser/cli.cpp b/src/sf_index_browser/cli.cpp similarity index 97% rename from src/index_browser/cli.cpp rename to src/sf_index_browser/cli.cpp index b97f5f58..60b680e6 100644 --- a/src/index_browser/cli.cpp +++ b/src/sf_index_browser/cli.cpp @@ -10,7 +10,7 @@ Args cli::parse(int argc, const char * const * argv) { DEBUG_ASSERT(argc >= 0); Args args; - CLI::App app{"index_browser"}; + CLI::App app{"sf_index_browser"}; app.positionals_at_end(false); app.allow_windows_style_options(false); diff --git a/src/index_browser/cli.h b/src/sf_index_browser/cli.h similarity index 100% rename from src/index_browser/cli.h rename to src/sf_index_browser/cli.h diff --git a/src/index_browser/main.cpp b/src/sf_index_browser/main.cpp similarity index 100% rename from src/index_browser/main.cpp rename to src/sf_index_browser/main.cpp diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 440f0664..cbf59ea8 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -76,14 +76,14 @@ if(TARGET tilebuilderlib) atb_configure_test(unittests_tilebuilder) endif() -if(TARGET meshbuilderlib) - add_executable(unittests_meshbuilder +if(TARGET sfbuilderlib) + add_executable(unittests_sfbuilder catch2_helpers.h - mesh_builder/mesh.cpp - mesh_builder/texture.cpp + sf_builder/mesh.cpp + sf_builder/texture.cpp ) - target_link_libraries(unittests_meshbuilder PRIVATE meshbuilderlib Catch2::Catch2WithMain) - atb_configure_test(unittests_meshbuilder) + target_link_libraries(unittests_sfbuilder PRIVATE sfbuilderlib Catch2::Catch2WithMain) + atb_configure_test(unittests_sfbuilder) endif() if(TARGET dagbuilderlib) diff --git a/unittests/mesh_builder/mesh.cpp b/unittests/sf_builder/mesh.cpp similarity index 100% rename from unittests/mesh_builder/mesh.cpp rename to unittests/sf_builder/mesh.cpp diff --git a/unittests/mesh_builder/texture.cpp b/unittests/sf_builder/texture.cpp similarity index 100% rename from unittests/mesh_builder/texture.cpp rename to unittests/sf_builder/texture.cpp