From 70c13419c46c005841a1576c09794ef802f7ee7d Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Thu, 26 Oct 2023 17:50:22 -0400 Subject: [PATCH] Switch to CPM --- CMakeLists.txt | 55 ++++++++----- cmake/recipes/CPM.cmake | 33 ++++++++ cmake/recipes/catch2.cmake | 27 ++----- cmake/recipes/eigen.cmake | 60 ++++++-------- cmake/simple_bvh/simple_bvh_cpm_cache.cmake | 24 ++++++ cmake/simple_bvh/simple_bvh_warnings.cmake | 6 +- src/{ => SimpleBVH}/BVH.cpp | 8 +- src/{ => SimpleBVH}/BVH.hpp | 86 +++++++++++---------- src/{ => SimpleBVH}/Morton.cpp | 4 +- src/{ => SimpleBVH}/Morton.hpp | 0 tests/CMakeLists.txt | 16 ++-- tests/main.cpp | 6 -- tests/tests.cpp | 9 +-- 13 files changed, 192 insertions(+), 142 deletions(-) create mode 100644 cmake/recipes/CPM.cmake create mode 100644 cmake/simple_bvh/simple_bvh_cpm_cache.cmake rename src/{ => SimpleBVH}/BVH.cpp (98%) rename src/{ => SimpleBVH}/BVH.hpp (90%) rename src/{ => SimpleBVH}/Morton.cpp (98%) rename src/{ => SimpleBVH}/Morton.hpp (100%) delete mode 100644 tests/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e78a6e..08fa87e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ else() endif() # Check required CMake version -set(REQUIRED_CMAKE_VERSION "3.14.0") +set(REQUIRED_CMAKE_VERSION "3.18.0") if(SIMPLE_BVH_TOPLEVEL_PROJECT) cmake_minimum_required(VERSION ${REQUIRED_CMAKE_VERSION}) else() @@ -24,13 +24,33 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/SimpleBVHOptions.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/SimpleBVHOptions.cmake) endif() +# Enable ccache if available +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + option(SIMPLE_BVH_WITH_CCACHE "Enable ccache when building IPC Toolkit" ${SIMPLE_BVH_TOPLEVEL_PROJECT}) +else() + option(SIMPLE_BVH_WITH_CCACHE "Enable ccache when building IPC Toolkit" OFF) +endif() +if(SIMPLE_BVH_WITH_CCACHE AND CCACHE_PROGRAM) + message(STATUS "Enabling Ccache support (${CCACHE_PROGRAM})") + set(ccacheEnv + CCACHE_BASEDIR=${CMAKE_BINARY_DIR} + CCACHE_SLOPPINESS=clang_index_store,include_file_ctime,include_file_mtime,locale,pch_defines,time_macros + ) + foreach(lang IN ITEMS C CXX) + set(CMAKE_${lang}_COMPILER_LAUNCHER + ${CMAKE_COMMAND} -E env ${ccacheEnv} ${CCACHE_PROGRAM} + ) + endforeach() +endif() + ################################################################################ project(SimpleBVH DESCRIPTION "A simple BVH data structure." LANGUAGES CXX) -option(SIMPLE_BVH_WITH_UNIT_TESTS "Build unit-tests" ${SIMPLE_BVH_TOPLEVEL_PROJECT}) +option(SIMPLE_BVH_BUILD_TESTS "Build unit-tests" ${SIMPLE_BVH_TOPLEVEL_PROJECT}) # Set default minimum C++ standard if(SIMPLE_BVH_TOPLEVEL_PROJECT) @@ -42,13 +62,16 @@ endif() list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/simple_bvh/") list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/recipes/") +# General CMake utils +include(simple_bvh_cpm_cache) + ################################################################################ # Main library ################################################################################ add_library(simple_bvh - src/BVH.cpp - src/Morton.cpp + src/SimpleBVH/BVH.cpp + src/SimpleBVH/Morton.cpp ) target_include_directories(simple_bvh PUBLIC src) add_library(simple_bvh::simple_bvh ALIAS simple_bvh) @@ -61,13 +84,13 @@ add_library(simple_bvh::simple_bvh ALIAS simple_bvh) # Required Libraries ################################################################################ -# Extra warnings -include(simple_bvh_warnings) -target_link_libraries(simple_bvh PRIVATE simple_bvh::warnings) - include(eigen) target_link_libraries(simple_bvh PUBLIC Eigen3::Eigen) +# Extra warnings (link last for highest priority) +include(simple_bvh_warnings) +target_link_libraries(simple_bvh PRIVATE simple_bvh::warnings) + ################################################################################ # Compiler options ################################################################################ @@ -80,14 +103,8 @@ target_compile_features(simple_bvh PUBLIC cxx_std_14) ################################################################################ # Enable unit testing at the root level -if(SIMPLE_BVH_WITH_UNIT_TESTS) - include(CTest) - enable_testing() - - # Include Catch2 and provide function `catch_discover_tests` to register tests. - include(catch2) - FetchContent_GetProperties(catch2) - include("${catch2_SOURCE_DIR}/contrib/Catch.cmake") - - add_subdirectory(tests) -endif() +if(SIMPLE_BVH_TOPLEVEL_PROJECT AND SIMPLE_BVH_BUILD_TESTS) + include(CTest) + enable_testing() + add_subdirectory(tests) +endif() \ No newline at end of file diff --git a/cmake/recipes/CPM.cmake b/cmake/recipes/CPM.cmake new file mode 100644 index 0000000..a3086b7 --- /dev/null +++ b/cmake/recipes/CPM.cmake @@ -0,0 +1,33 @@ +set(CPM_DOWNLOAD_VERSION 0.38.1) + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +function(download_cpm) + message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") + file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} + ) +endfunction() + +if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) + download_cpm() +else() + # resume download if it previously failed + file(READ ${CPM_DOWNLOAD_LOCATION} check) + if("${check}" STREQUAL "") + download_cpm() + endif() + unset(check) +endif() + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/cmake/recipes/catch2.cmake b/cmake/recipes/catch2.cmake index e74e07c..4efb1ce 100644 --- a/cmake/recipes/catch2.cmake +++ b/cmake/recipes/catch2.cmake @@ -1,25 +1,14 @@ -# -# Copyright 2020 Adobe. All rights reserved. -# This file is licensed to you under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. You may obtain a copy -# of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -# OF ANY KIND, either express or implied. See the License for the specific language -# governing permissions and limitations under the License. -# +# Catch2 (https://github.com/catchorg/Catch2) +# License: BSL-1.0 if(TARGET Catch2::Catch2) return() endif() message(STATUS "Third-party: creating target 'Catch2::Catch2'") -include(FetchContent) -FetchContent_Declare( - catch2 - GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v2.13.6 - GIT_SHALLOW TRUE -) -FetchContent_MakeAvailable(catch2) +option(CATCH_CONFIG_CPP17_STRING_VIEW "Enable support for std::string_view" ON) +option(CATCH_INSTALL_DOCS "Install documentation alongside library" OFF) +option(CATCH_INSTALL_EXTRAS "Install extras alongside library" OFF) + +include(CPM) +CPMAddPackage("gh:catchorg/Catch2@3.3.2") \ No newline at end of file diff --git a/cmake/recipes/eigen.cmake b/cmake/recipes/eigen.cmake index 8e33f24..30992de 100644 --- a/cmake/recipes/eigen.cmake +++ b/cmake/recipes/eigen.cmake @@ -1,53 +1,39 @@ -# -# Copyright 2020 Adobe. All rights reserved. -# This file is licensed to you under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. You may obtain a copy -# of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed under -# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -# OF ANY KIND, either express or implied. See the License for the specific language -# governing permissions and limitations under the License. -# +# Eigen (https://gitlab.com/libeigen/eigen) +# License: MPL 2.0 if(TARGET Eigen3::Eigen) return() endif() option(EIGEN_WITH_MKL "Use Eigen with MKL" OFF) +option(EIGEN_DONT_VECTORIZE "Disable Eigen vectorization" OFF) +option(EIGEN_MPL2_ONLY "Enable Eigen MPL2 license only" OFF) -if(EIGEN_ROOT) - message(STATUS "Third-party: creating target 'Eigen3::Eigen' for external path: ${EIGEN_ROOT}") - set(EIGEN_INCLUDE_DIRS ${EIGEN_ROOT}) -else() - message(STATUS "Third-party: creating target 'Eigen3::Eigen'") +message(STATUS "Third-party: creating target 'Eigen3::Eigen'") - include(FetchContent) - FetchContent_Declare( - eigen - GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git - GIT_TAG tags/3.3.7 - GIT_SHALLOW TRUE - ) - FetchContent_GetProperties(eigen) - if(NOT eigen_POPULATED) - FetchContent_Populate(eigen) - endif() - set(EIGEN_INCLUDE_DIRS ${eigen_SOURCE_DIR}) - - install(DIRECTORY ${EIGEN_INCLUDE_DIRS}/Eigen - DESTINATION include - ) -endif() +include(CPM) +CPMAddPackage( + NAME eigen + GITLAB_REPOSITORY libeigen/eigen + GIT_TAG 3.4.0 + DOWNLOAD_ONLY ON +) add_library(Eigen3_Eigen INTERFACE) add_library(Eigen3::Eigen ALIAS Eigen3_Eigen) include(GNUInstallDirs) target_include_directories(Eigen3_Eigen SYSTEM INTERFACE - $ + $ $ ) -# target_compile_definitions(Eigen3_Eigen INTERFACE EIGEN_MPL2_ONLY) + +if(EIGEN_MPL2_ONLY) + target_compile_definitions(Eigen3_Eigen INTERFACE EIGEN_MPL2_ONLY) +endif() + +if(EIGEN_DONT_VECTORIZE) + target_compile_definitions(Eigen3_Eigen INTERFACE EIGEN_DONT_VECTORIZE) +endif() if(EIGEN_WITH_MKL) # TODO: Checks that, on 64bits systems, `mkl::mkl` is using the LP64 interface @@ -68,6 +54,6 @@ endif() # Install rules set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME eigen) set_target_properties(Eigen3_Eigen PROPERTIES EXPORT_NAME Eigen) -install(DIRECTORY ${EIGEN_INCLUDE_DIRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${eigen_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(TARGETS Eigen3_Eigen EXPORT Eigen_Targets) -install(EXPORT Eigen_Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/eigen NAMESPACE Eigen3::) +install(EXPORT Eigen_Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/eigen NAMESPACE Eigen3::) \ No newline at end of file diff --git a/cmake/simple_bvh/simple_bvh_cpm_cache.cmake b/cmake/simple_bvh/simple_bvh_cpm_cache.cmake new file mode 100644 index 0000000..bd57d22 --- /dev/null +++ b/cmake/simple_bvh/simple_bvh_cpm_cache.cmake @@ -0,0 +1,24 @@ +# +# Copyright 2021 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +if(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_SOURCE_CACHE_DEFAULT $ENV{CPM_SOURCE_CACHE}) +else() + # Set CPM cache folder if unset + file(REAL_PATH "~/.cache/CPM" CPM_SOURCE_CACHE_DEFAULT EXPAND_TILDE) +endif() + +set(CPM_SOURCE_CACHE + ${CPM_SOURCE_CACHE_DEFAULT} + CACHE PATH "Directory to download CPM dependencies" +) +message(STATUS "Using CPM cache folder: ${CPM_SOURCE_CACHE}") \ No newline at end of file diff --git a/cmake/simple_bvh/simple_bvh_warnings.cmake b/cmake/simple_bvh/simple_bvh_warnings.cmake index fc923cb..291fceb 100644 --- a/cmake/simple_bvh/simple_bvh_warnings.cmake +++ b/cmake/simple_bvh/simple_bvh_warnings.cmake @@ -7,7 +7,7 @@ if(TARGET simple_bvh::warnings) return() endif() -set(SIMPLE_BVH_FLAGS +set(SIMPLE_BVH_WARNING_FLAGS -Wall -Wextra -pedantic @@ -147,7 +147,7 @@ set(SIMPLE_BVH_FLAGS # Flags above don't make sense for MSVC if(MSVC) - set(SIMPLE_BVH_FLAGS) + set(SIMPLE_BVH_WARNING_FLAGS) endif() include(CheckCXXCompilerFlag) @@ -155,7 +155,7 @@ include(CheckCXXCompilerFlag) add_library(simple_bvh_warnings INTERFACE) add_library(simple_bvh::warnings ALIAS simple_bvh_warnings) -foreach(FLAG IN ITEMS ${SIMPLE_BVH_FLAGS}) +foreach(FLAG IN ITEMS ${SIMPLE_BVH_WARNING_FLAGS}) string(REPLACE "=" "-" FLAG_VAR "${FLAG}") if(NOT DEFINED IS_SUPPORTED_${FLAG_VAR}) check_cxx_compiler_flag("${FLAG}" IS_SUPPORTED_${FLAG_VAR}) diff --git a/src/BVH.cpp b/src/SimpleBVH/BVH.cpp similarity index 98% rename from src/BVH.cpp rename to src/SimpleBVH/BVH.cpp index 0b530e2..7fe6ea1 100644 --- a/src/BVH.cpp +++ b/src/SimpleBVH/BVH.cpp @@ -1,9 +1,9 @@ -#include -#include +#include "BVH.hpp" +#include #include -namespace BVH { +namespace SimpleBVH { namespace { bool box_box_intersection( const Eigen::Vector3d& min1, @@ -201,4 +201,4 @@ bool BVH::box_intersects_box( return box_box_intersection(bbd0, bbd1, bmin, bmax); } -} // namespace BVH +} // namespace SimpleBVH diff --git a/src/BVH.hpp b/src/SimpleBVH/BVH.hpp similarity index 90% rename from src/BVH.hpp rename to src/SimpleBVH/BVH.hpp index 83858b1..8000a74 100644 --- a/src/BVH.hpp +++ b/src/SimpleBVH/BVH.hpp @@ -6,44 +6,26 @@ #include #include -namespace BVH { +namespace SimpleBVH { using VectorMax3d = Eigen::Matrix; class BVH { -private: - std::vector> boxlist; - std::vector new2old; - size_t n_corners = -1; - - void init_boxes_recursive( - const std::vector>& cornerlist, - int node_index, - int b, - int e); - - void box_search_recursive( - const Eigen::Vector3d& bbd0, - const Eigen::Vector3d& bbd1, - std::vector& list, - int n, - int b, - int e) const; - - static int max_node_index(int node_index, int b, int e); - - bool box_intersects_box( - const Eigen::Vector3d& bbd0, - const Eigen::Vector3d& bbd1, - int index) const; - public: void init(const std::vector>& cornerlist); + void init(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const double tol); - inline void intersect_3D_box( + void clear() + { + boxlist.clear(); + new2old.clear(); + n_corners = -1; + } + + void intersect_3D_box( const Eigen::Vector3d& bbd0, const Eigen::Vector3d& bbd1, std::vector& list) const @@ -57,32 +39,58 @@ class BVH { list[i] = new2old[tmp[i]]; } - inline void intersect_box( - const VectorMax3d& bbd0, - const VectorMax3d& bbd1, + void intersect_2D_box( + const Eigen::Vector2d& bbd0, + const Eigen::Vector2d& bbd1, std::vector& list) const { Eigen::Vector3d bbd0_3D = Eigen::Vector3d::Zero(); - bbd0_3D.head(bbd0.size()) = bbd0.head(bbd0.size()); + bbd0_3D.head<2>() = bbd0; Eigen::Vector3d bbd1_3D = Eigen::Vector3d::Zero(); - bbd1_3D.head(bbd1.size()) = bbd1.head(bbd1.size()); + bbd1_3D.head<2>() = bbd1; intersect_3D_box(bbd0_3D, bbd1_3D, list); } - inline void intersect_2D_box( - const Eigen::Vector2d& bbd0, - const Eigen::Vector2d& bbd1, + void intersect_box( + const VectorMax3d& bbd0, + const VectorMax3d& bbd1, std::vector& list) const { Eigen::Vector3d bbd0_3D = Eigen::Vector3d::Zero(); - bbd0_3D.head<2>() = bbd0; + bbd0_3D.head(bbd0.size()) = bbd0.head(bbd0.size()); Eigen::Vector3d bbd1_3D = Eigen::Vector3d::Zero(); - bbd1_3D.head<2>() = bbd1; + bbd1_3D.head(bbd1.size()) = bbd1.head(bbd1.size()); intersect_3D_box(bbd0_3D, bbd1_3D, list); } + +private: + void init_boxes_recursive( + const std::vector>& cornerlist, + int node_index, + int b, + int e); + + void box_search_recursive( + const Eigen::Vector3d& bbd0, + const Eigen::Vector3d& bbd1, + std::vector& list, + int n, + int b, + int e) const; + + bool box_intersects_box( + const Eigen::Vector3d& bbd0, + const Eigen::Vector3d& bbd1, + int index) const; + + static int max_node_index(int node_index, int b, int e); + + std::vector> boxlist; + std::vector new2old; + size_t n_corners = -1; }; -} // namespace BVH +} // namespace SimpleBVH diff --git a/src/Morton.cpp b/src/SimpleBVH/Morton.cpp similarity index 98% rename from src/Morton.cpp rename to src/SimpleBVH/Morton.cpp index 6ef990e..306e4e5 100644 --- a/src/Morton.cpp +++ b/src/SimpleBVH/Morton.cpp @@ -5,7 +5,7 @@ // // @author Nico Schertler -#include +#include "Morton.hpp" #include using namespace Resorting; @@ -44,7 +44,7 @@ int32_t CompactBy3Bits21(uint64_t x) return (int32_t)d; } -MortonCode64::MortonCode64() {} +MortonCode64::MortonCode64() { } MortonCode64::MortonCode64(int32_t x, int32_t y, int32_t z) { diff --git a/src/Morton.hpp b/src/SimpleBVH/Morton.hpp similarity index 100% rename from src/Morton.hpp rename to src/SimpleBVH/Morton.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0721a75..a4a5ce8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,10 +2,7 @@ # Tests ################################################################################ -add_executable(simple_bvh_tests - main.cpp - tests.cpp -) +add_executable(simple_bvh_tests tests.cpp) ################################################################################ # Required Libraries @@ -13,12 +10,13 @@ add_executable(simple_bvh_tests target_link_libraries(simple_bvh_tests PUBLIC simple_bvh::simple_bvh) +include(catch2) +target_link_libraries(simple_bvh_tests PUBLIC Catch2::Catch2WithMain) + +# Extra warnings (link last for highest priority) include(simple_bvh_warnings) target_link_libraries(simple_bvh_tests PRIVATE simple_bvh::warnings) -include(catch2) -target_link_libraries(simple_bvh_tests PUBLIC Catch2::Catch2) - ################################################################################ # Compiler options ################################################################################ @@ -27,6 +25,10 @@ target_link_libraries(simple_bvh_tests PUBLIC Catch2::Catch2) # Register tests ################################################################################ +FetchContent_GetProperties(catch2) +list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) +include(Catch) + # Register tests set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON) catch_discover_tests(simple_bvh_tests) diff --git a/tests/main.cpp b/tests/main.cpp deleted file mode 100644 index d1ec1ae..0000000 --- a/tests/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Keep this file empty, and implement unit tests in separate compilation units! -//////////////////////////////////////////////////////////////////////////////// - -#define CATCH_CONFIG_MAIN -#include diff --git a/tests/tests.cpp b/tests/tests.cpp index fd52b98..dd307f7 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -1,8 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -//////////////////////////////////////////////////////////////////////////////// +#include +#include TEST_CASE("test_tree", "[tests]") { @@ -22,7 +19,7 @@ TEST_CASE("test_tree", "[tests]") 1, 2, 3; // clang-format on - BVH::BVH bvh; + SimpleBVH::BVH bvh; bvh.init(pts, tri, 1e-10); std::vector pairs;