From 845e3566a576279fe7fa27698fe1eb516c9ac013 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Thu, 4 Nov 2021 10:26:20 -0400 Subject: [PATCH 1/4] support cmake option to be able to build without CGAL and its dependencies. it will have limited SCAD support as a result. --- CMakeLists.txt | 8 +++++++- include/csg_types.hpp | 26 +++++++++++++++++++++++++ src/csg/CMakeLists.txt | 15 +++++++++++--- src/csg/levelset_2d.cpp | 6 ++++++ src/csg/levelset_3d.cpp | 10 ++++++++++ src/csg/parser.cpp | 16 +++++++++++++++ src/csg/tests/CMakeLists.txt | 16 ++++++++++++--- src/csg/tests/levelset/extrude.t.cpp | 2 ++ src/csg/tests/levelset/primitives.t.cpp | 2 ++ src/csg/tests/parser/extrude.t.cpp | 4 ++++ src/csg/tests/parser/primitives.t.cpp | 18 +++++++++++++++++ 11 files changed, 116 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38703b8..042cbeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,13 +12,19 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +option(CSG_CGAL_ENABLED "Enable CGAL" ON) + find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) set( CMAKE_CXX_COMPILER_LAUNCHER ccache ) endif() find_package(pegtl REQUIRED) -find_package(CGAL REQUIRED) + +if (CSG_CGAL_ENABLED) + find_package(CGAL REQUIRED) + add_definitions(-DUSE_CGAL) +endif() add_subdirectory(src/csg) diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 536c1f4..d26b81b 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -1,7 +1,9 @@ #ifndef CSG_TYPES_H_ #define CSG_TYPES_H_ +#if USE_CGAL #include "csg_cgal_helper.hpp" +#endif #include "csg_matrix_functions.hpp" #include @@ -50,6 +52,7 @@ struct Cone { bool center; }; +#if USE_CGAL struct Polyhedron { private: std::vector> m_points; @@ -77,7 +80,9 @@ public: return m_cgal_aabb_tree; } }; +#endif +#if USE_CGAL struct Polygon { private: std::vector> m_points; @@ -97,6 +102,7 @@ public: const cgal_helper::Polygon &cgal_polygon() const { return m_cgal_polygon; } }; +#endif enum Dimension { D2, D3 }; @@ -110,19 +116,37 @@ struct Hull; template struct TypeHelper; +#if USE_CGAL template <> struct TypeHelper { using Type = std::variant, Intersection, Difference, Mulmatrix, Polygon>; }; +#else +template <> struct TypeHelper { + using Type = + std::variant, + Intersection, Difference, + Mulmatrix>; +}; +#endif +#if USE_CGAL template <> struct TypeHelper { using Type = std::variant, Intersection, Difference, Mulmatrix, LinearExtrude, RotateExtrude, Polyhedron, Hull>; }; +#else +template <> struct TypeHelper { + using Type = + std::variant, + Intersection, Difference, + Mulmatrix, LinearExtrude, RotateExtrude>; +}; +#endif template struct Union { std::vector::Type> objs; @@ -195,6 +219,7 @@ struct RotateExtrude { Union group; }; +#if USE_CGAL struct Hull { private: std::shared_ptr m_cgal_polyhedron; @@ -222,6 +247,7 @@ public: return m_cgal_aabb_tree; } }; +#endif struct Tree { Union top; diff --git a/src/csg/CMakeLists.txt b/src/csg/CMakeLists.txt index bcf3a9b..eedaa15 100644 --- a/src/csg/CMakeLists.txt +++ b/src/csg/CMakeLists.txt @@ -1,9 +1,9 @@ ################################################################################ # CSG Parser ################################################################################ -add_library(csg-eb - cgal_helper_polygon.cpp - cgal_helper_polyhedron.cpp + +set(csg-eb_SOURCES) +list(APPEND csg-eb_SOURCES csg.cpp levelset_2d.cpp levelset_3d.cpp @@ -12,6 +12,15 @@ add_library(csg-eb exception.cpp ) +if (CSG_CGAL_ENABLED) + list(APPEND csg-eb_SOURCES + cgal_helper_polygon.cpp + cgal_helper_polyhedron.cpp + ) +endif() + +add_library(csg-eb ${csg-eb_SOURCES}) + target_link_libraries(csg-eb PRIVATE CGAL::CGAL stdc++fs diff --git a/src/csg/levelset_2d.cpp b/src/csg/levelset_2d.cpp index 66a5284..50c9fe0 100644 --- a/src/csg/levelset_2d.cpp +++ b/src/csg/levelset_2d.cpp @@ -1,4 +1,6 @@ +#if USE_CGAL #include "csg_cgal_helper.hpp" +#endif #include "csg_types.hpp" #include @@ -25,7 +27,9 @@ double signed_distance_2d(const Difference2D &, double, double); double signed_distance_2d(const Intersection2D &, double, double); double signed_distance_2d(const Mulmatrix2D &, double, double); double signed_distance_2d(const Union2D &, double, double); +#if USE_CGAL double signed_distance_2d(const Polygon &, double, double); +#endif double signed_distance_2d(const Union2D &group, double xx, double yy) { auto sdist = -std::numeric_limits::max(); @@ -90,6 +94,7 @@ double signed_distance_2d(const Circle &cir, double xx, double yy) { return EXTERNAL_FLOW * sign * dist; } +#if USE_CGAL double signed_distance_2d(const Polygon &polygon, double xx, double yy) { bool inside = cgal_helper::inside(polygon.cgal_polygon(), xx, yy); @@ -99,6 +104,7 @@ double signed_distance_2d(const Polygon &polygon, double xx, double yy) { return EXTERNAL_FLOW * sign * dist; } +#endif double signed_distance_2d(const Type2D &obj, double xx, double yy) { diff --git a/src/csg/levelset_3d.cpp b/src/csg/levelset_3d.cpp index 589b092..cdc0811 100644 --- a/src/csg/levelset_3d.cpp +++ b/src/csg/levelset_3d.cpp @@ -1,7 +1,11 @@ +#if USE_CGAL #include "csg_cgal_helper.hpp" +#endif #include "csg_types.hpp" #include +#include +#include #include #include @@ -29,8 +33,10 @@ double signed_distance_3d(const Sphere &, double, double, double); double signed_distance_3d(const Type3D &, double, double, double); double signed_distance_3d(const LinearExtrude &, double, double, double); double signed_distance_3d(const RotateExtrude &, double, double, double); +#if USE_CGAL double signed_distance_3d(const Polyhedron &, double, double, double); double signed_distance_3d(const Hull &, double, double, double); +#endif double signed_distance_2d(const Union2D &, double, double); @@ -176,17 +182,21 @@ double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, return EXTERNAL_FLOW * std::max(sign_t * dist_t, sign_2d * dist_2d); } +#if USE_CGAL double signed_distance_3d(const Polyhedron &polyhedron, double xx, double yy, double zz) { // TODO: support signed distance instead of -1.0/1.0 return cgal_helper::inside(polyhedron.cgal_aabb_tree(), xx, yy, zz) ? 1.0 : -1.0; } +#endif +#if USE_CGAL double signed_distance_3d(const Hull &hull, double xx, double yy, double zz) { // TODO: support signed distance instead of -1.0/1.0 return cgal_helper::inside(hull.cgal_aabb_tree(), xx, yy, zz) ? 1.0 : -1.0; } +#endif double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 20f0f0d..86fcf7c 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -1,5 +1,6 @@ // standard includes #include +#include #include #include @@ -515,6 +516,7 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); +#if USE_CGAL csg::Hull hull; // Only a very limited hull is currently supported @@ -546,6 +548,10 @@ template <> struct action { "hull() support is limited to a multmatrix of a centered cube followed " "by a sphere; added for the CLR support"; throw csg::Exception(except_src, except_msg); +#else + throw csg::Exception("action", + "Needs to be built with CGAL enabled!"); +#endif } }; @@ -656,6 +662,7 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); +#if USE_CGAL auto &curr_attr = st.curr_attrs.back(); auto points_raw = @@ -690,6 +697,10 @@ template <> struct action { st.current_2d_objs.back().push_back(diff); st.curr_attrs.pop_back(); +#else + throw csg::Exception("action", + "Needs to be built with CGAL enabled"); +#endif } }; @@ -697,6 +708,7 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); +#if USE_CGAL auto &curr_attr = st.curr_attrs.back(); auto points_raw = @@ -715,6 +727,10 @@ template <> struct action { st.current_3d_objs.back().push_back(polyh); st.curr_attrs.pop_back(); +#else + throw csg::Exception("action", + "Needs to be build with CGAL enabled!"); +#endif } }; diff --git a/src/csg/tests/CMakeLists.txt b/src/csg/tests/CMakeLists.txt index 7041326..bc2854f 100644 --- a/src/csg/tests/CMakeLists.txt +++ b/src/csg/tests/CMakeLists.txt @@ -2,18 +2,17 @@ # CSG Parsing Tests ################################################################################ -add_executable(unit_tests_csg EXCLUDE_FROM_ALL +set(unit_tests_csg_SOURCES) +list(APPEND unit_tests_csg_SOURCES levelset/boolean.t.cpp levelset/empty.t.cpp levelset/extrude.t.cpp - levelset/hull.t.cpp levelset/internal_flow.t.cpp levelset/primitives.t.cpp levelset/transform.t.cpp parser/boolean.t.cpp parser/empty.t.cpp parser/extrude.t.cpp - parser/hull.t.cpp parser/nest.cpp parser/other.t.cpp parser/primitives.t.cpp @@ -21,6 +20,17 @@ add_executable(unit_tests_csg EXCLUDE_FROM_ALL unit_tests_csg.main.cpp ) +if (CSG_CGAL_ENABLED) + list(APPEND unit_tests_csg_SOURCES + levelset/hull.t.cpp + parser/hull.t.cpp + ) +endif() + +add_executable(unit_tests_csg EXCLUDE_FROM_ALL + ${unit_tests_csg_SOURCES} + ) + target_include_directories(unit_tests_csg PRIVATE ${CMAKE_SOURCE_DIR}/src ) diff --git a/src/csg/tests/levelset/extrude.t.cpp b/src/csg/tests/levelset/extrude.t.cpp index cc402c2..8706dd0 100644 --- a/src/csg/tests/levelset/extrude.t.cpp +++ b/src/csg/tests/levelset/extrude.t.cpp @@ -161,6 +161,7 @@ TEST_CASE("simple torus", "[Levelset Extrude]") { } } +#if USE_CGAL TEST_CASE("Linear extrude of a triangle with hole", "[Levelset Primitives]") { double ht = 100.0, outer = 100.0, inner = 80.0; double thick = outer - inner; @@ -244,6 +245,7 @@ TEST_CASE("Linear extrude of a triangle with hole", "[Levelset Primitives]") { CHECK(Approx(ht / 2) == my_levelset(0.5 * thick, 0.7 * outer, 0.0)); } } +#endif TEST_CASE("sliced torus", "[Levelset Extrude]") { auto my_rot_ext = csg::RotateExtrude{.angle = 45, .group = csg::Union2D()}; diff --git a/src/csg/tests/levelset/primitives.t.cpp b/src/csg/tests/levelset/primitives.t.cpp index b950f82..57690ec 100644 --- a/src/csg/tests/levelset/primitives.t.cpp +++ b/src/csg/tests/levelset/primitives.t.cpp @@ -545,6 +545,7 @@ TEST_CASE("Cone", "[Levelset Primitives]") { } } +#if USE_CGAL TEST_CASE("Polyhedron", "[Levelset Primitives]") { double Lx = 10.0, Ly = 7.0, Lz = 5.0; // A 10 x 7 x 5 cuboid in positive quandrant formed using polyhedron @@ -584,5 +585,6 @@ TEST_CASE("Polyhedron", "[Levelset Primitives]") { CHECK(0 < my_levelset(0.7 * Lx, 0.1 * Ly, 0.01 * Lz)); } } +#endif } // namespace diff --git a/src/csg/tests/parser/extrude.t.cpp b/src/csg/tests/parser/extrude.t.cpp index a13b474..c37fd72 100644 --- a/src/csg/tests/parser/extrude.t.cpp +++ b/src/csg/tests/parser/extrude.t.cpp @@ -162,6 +162,7 @@ linear_extrude(height = 10, center = false, scale = [5, 5]) { CHECK(st == nullptr); } +#if USE_CGAL TEST_CASE("linear extrude polygon without paths", "[csg]") { auto st = *csg::parse_csg(R"( linear_extrude( @@ -189,7 +190,9 @@ paths = undef); CHECK(diff.next_objs.objs.size() == 0); CHECK(outer.cgal_polygon().size() == 4); } +#endif +#if USE_CGAL TEST_CASE("linear extrude polygon with hole", "[csg]") { auto st = *csg::parse_csg(R"( linear_extrude( @@ -218,5 +221,6 @@ paths = [[0, 1, 2], [3, 4, 5]]); CHECK(outer.cgal_polygon().size() == 3); CHECK(inner.cgal_polygon().size() == 3); } +#endif } // namespace diff --git a/src/csg/tests/parser/primitives.t.cpp b/src/csg/tests/parser/primitives.t.cpp index 818b82d..bc57dd4 100644 --- a/src/csg/tests/parser/primitives.t.cpp +++ b/src/csg/tests/parser/primitives.t.cpp @@ -5,6 +5,7 @@ // Tests for the primitives on their own +namespace { TEST_CASE("cylinder", "[csg]") { auto st = *csg::parse_csg(R"( cylinder($name="my_cyl", h = 2, r = 10, center=true); @@ -54,6 +55,7 @@ sphere(r = 10) CHECK(sph.radius == 10); } +#if USE_CGAL TEST_CASE("square pyramid polyhedron", "[csg]") { auto st = *csg::parse_csg(R"( polyhedron( @@ -66,7 +68,9 @@ $name="my_polyhedron"); CHECK(polyh.cgal_polyhedron()->size_of_vertices() == 5); CHECK(polyh.cgal_polyhedron()->size_of_facets() == 6); } +#endif +#if USE_CGAL TEST_CASE("bad vs good polyhedron openscad example", "[csg]") { // https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#polyhedron CHECK_THROWS(csg::parse_csg(R"( @@ -103,3 +107,17 @@ convexity = 1); auto polyh = std::get(st.top.objs.at(0)); CHECK(polyh.cgal_polyhedron()->size_of_vertices() == 12); } +#endif + +#if !(USE_CGAL) +TEST_CASE("without cgal test", "[csg]") { + CHECK_THROWS(*csg::parse_csg(R"( +polyhedron( +points = [[10, 10, 0], [10, -10, 0], [-10, -10, 0], [-10, 10, 0], [0, 0, 10]], +faces = [[0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4], [1, 0, 3], [2, 1, 3]], +$name="my_polyhedron"); +)")); +} +#endif + +} // namespace -- GitLab From 23ed5ba1b5e67ae2aa500741eee74b61ae74e14d Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Thu, 4 Nov 2021 14:02:15 -0400 Subject: [PATCH 2/4] fix after rebase --- src/csg/CMakeLists.txt | 4 +++- src/csg/tests/CMakeLists.txt | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/csg/CMakeLists.txt b/src/csg/CMakeLists.txt index eedaa15..867d42d 100644 --- a/src/csg/CMakeLists.txt +++ b/src/csg/CMakeLists.txt @@ -22,9 +22,11 @@ endif() add_library(csg-eb ${csg-eb_SOURCES}) target_link_libraries(csg-eb PRIVATE - CGAL::CGAL stdc++fs taocpp::pegtl ) +if (CSG_CGAL_ENABLED) + target_link_libraries(csg-eb PRIVATE CGAL::CGAL) +endif() add_subdirectory(tests) diff --git a/src/csg/tests/CMakeLists.txt b/src/csg/tests/CMakeLists.txt index bc2854f..3f4d075 100644 --- a/src/csg/tests/CMakeLists.txt +++ b/src/csg/tests/CMakeLists.txt @@ -38,9 +38,12 @@ target_include_directories(unit_tests_csg find_package(Catch2 REQUIRED) include(Catch) target_link_libraries(unit_tests_csg - CGAL::CGAL Catch2::Catch2 csg-eb ) +if (CSG_CGAL_ENABLED) + target_link_libraries(unit_tests_csg CGAL::CGAL) +endif() + catch_discover_tests(unit_tests_csg) -- GitLab From 99ca27241f02e56a565c7b5dad711b9c817a90aa Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Fri, 5 Nov 2021 11:08:31 -0400 Subject: [PATCH 3/4] make it compile on gcc 10; add CI job with cgal off --- .gitlab-ci.yml | 17 ++++++++++------- include/csg_types.hpp | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4442a89..4066fb2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,6 @@ build-img: tags: - docker - ###### Test jobs ##### .test:cmake: &cmake_def @@ -28,20 +27,24 @@ build-img: - conan install -if build -g cmake_find_package cgal/5.2.1@ - conan install -if build -g cmake_find_package taocpp-pegtl/3.2.1@ - - cmake -S. -Bbuild -GNinja -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_MODULE_PATH=$PWD/build + - cmake -S. + -Bbuild + -GNinja + -DCMAKE_MODULE_PATH=$PWD/build + -DCMAKE_BUILD_TYPE=Debug + -DCSG_CGAL_ENABLED=${ENABLE_CSG} - cmake --build build --target unit_tests_csg - cd build - ctest tags: - docker -test:cmake:debug: +test:cgal: variables: - BUILD_TYPE: "Debug" + ENABLE_CSG: "ON" <<: *cmake_def -test:cmake:release: +test:no_cgal: variables: - BUILD_TYPE: "Release" - allow_failure: true + ENABLE_CSG: "OFF" <<: *cmake_def diff --git a/include/csg_types.hpp b/include/csg_types.hpp index d26b81b..7f85146 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include -- GitLab From 4e88c6efa48654abf67cce1be4466c21d11ae703 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Fri, 5 Nov 2021 11:42:53 -0400 Subject: [PATCH 4/4] CI does not install cgal when its off --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4066fb2..3c96047 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ build-img: needs: ['build-img'] script: - conan install -if build -g cmake_find_package catch2/2.13.7@ - - conan install -if build -g cmake_find_package cgal/5.2.1@ + - if [ "$ENABLE_CSG" == "ON" ]; then conan install -if build -g cmake_find_package cgal/5.2.1@; fi - conan install -if build -g cmake_find_package taocpp-pegtl/3.2.1@ - cmake -S. -- GitLab