diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 290579417e3e5b2cc956cb91d6522ec7f7e66803..5d16bda517930ed9887cb9b3a3c2f89bacd6ad71 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -54,7 +54,8 @@ struct Polyhedron { private: std::vector> m_points; std::vector> m_faces; - cgal_helper::Polyhedron m_cgal_polyhedron; + std::shared_ptr m_cgal_polyhedron; + std::shared_ptr m_cgal_aabb_tree; public: std::optional name; @@ -65,11 +66,16 @@ public: m_faces.push_back(std::vector(f.begin(), f.end())); } m_cgal_polyhedron = cgal_helper::create_polyhedron(m_points, m_faces); + m_cgal_aabb_tree = cgal_helper::create_aabb_tree(m_cgal_polyhedron); } - const cgal_helper::Polyhedron &cgal_polyhedron() const { + const std::shared_ptr &cgal_polyhedron() const { return m_cgal_polyhedron; } + + const std::shared_ptr &cgal_aabb_tree() const { + return m_cgal_aabb_tree; + } }; struct Polygon { diff --git a/src/csg/cgal_helper_polyhedron.cpp b/src/csg/cgal_helper_polyhedron.cpp index 2cc5bf99c6fd2df8140020d50ef39b49b517d7f5..f4c79a13fa6afd761fd8e1becee499ef7ea994c2 100644 --- a/src/csg/cgal_helper_polyhedron.cpp +++ b/src/csg/cgal_helper_polyhedron.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -15,10 +14,6 @@ namespace { typedef cgal_helper::Polyhedron::HalfedgeDS HalfedgeDS; typedef typename HalfedgeDS::Vertex Vertex; typedef typename Vertex::Point Point; -typedef CGAL::AABB_face_graph_triangle_primitive - Primitive; -typedef CGAL::AABB_traits Traits; -typedef CGAL::AABB_tree Tree; typedef CGAL::Side_of_triangle_mesh Point_inside; @@ -66,30 +61,36 @@ public: namespace cgal_helper { -Polyhedron +std::shared_ptr create_polyhedron(const std::vector> &points, const std::vector> &faces) { - Polyhedron p; + auto p = std::make_shared(); // Build incrementally PolyhedronBuilder bp(points, faces); - p.delegate(bp); - CGAL_assertion(p.is_valid()); + p->delegate(bp); + CGAL_assertion(p->is_valid()); // Triangulate faces - needed for levelset - CGAL::Polygon_mesh_processing::triangulate_faces(p); - CGAL_assertion(p.is_valid()); + CGAL::Polygon_mesh_processing::triangulate_faces(*p); + CGAL_assertion(p->is_valid()); return p; } -bool inside(const Polyhedron &polyhedron, double xx, double yy, double zz) { - cgal_helper::CK::Point_3 pt(xx, yy, zz); +std::shared_ptr +create_aabb_tree(const std::shared_ptr &polyhedron) { // Construct AABB tree with a KdTree - Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron); - tree.accelerate_distance_queries(); - // Initialize the point-in-polyhedron tester - Point_inside inside_tester(tree); + auto tree = std::make_shared( + faces(*polyhedron).first, faces(*polyhedron).second, *polyhedron); + tree->accelerate_distance_queries(); + return tree; +} + +bool inside(const std::shared_ptr &tree, double xx, double yy, + double zz) { + cgal_helper::CK::Point_3 pt(xx, yy, zz); + Point_inside inside_tester(*tree); // Determine the side and return true if inside! return inside_tester(pt) == CGAL::ON_BOUNDED_SIDE; diff --git a/src/csg/levelset_3d.cpp b/src/csg/levelset_3d.cpp index 61701ce6e7e88401e97d4a171fbb74e61f8ede11..c2b5eeebf26793e9dfb61b55f82ba9c337e2dad9 100644 --- a/src/csg/levelset_3d.cpp +++ b/src/csg/levelset_3d.cpp @@ -149,7 +149,7 @@ double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, double tt = std::atan2(yy, xx) * DEGREES_PER_RADIAN; tt = tt >= 0 ? tt : 360 + tt; - assert(tt >= 0 && tt <= 360); //tt must be between 0 and 360 + assert(tt >= 0 && tt <= 360); // tt must be between 0 and 360 double sign_t = (tt <= rot_ext.angle) ? -1.0 : 1.0; double dist_t = std::min(std::fabs(rot_ext.angle - tt), (360 - tt)); @@ -166,8 +166,8 @@ double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, 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_polyhedron(), xx, yy, zz) ? 1.0 - : -1.0; + return cgal_helper::inside(polyhedron.cgal_aabb_tree(), xx, yy, zz) ? 1.0 + : -1.0; } double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { diff --git a/src/csg/tests/parser/primitives.t.cpp b/src/csg/tests/parser/primitives.t.cpp index 7847718ffdf6c44f23d6e30189b174a23e2a39a8..818b82d8ebcdc2614ddcb03f86d586fe02029b42 100644 --- a/src/csg/tests/parser/primitives.t.cpp +++ b/src/csg/tests/parser/primitives.t.cpp @@ -63,8 +63,8 @@ $name="my_polyhedron"); )"); auto polyh = std::get(st.top.objs.at(0)); CHECK(polyh.name == "my_polyhedron"); - CHECK(polyh.cgal_polyhedron().size_of_vertices() == 5); - CHECK(polyh.cgal_polyhedron().size_of_facets() == 6); + CHECK(polyh.cgal_polyhedron()->size_of_vertices() == 5); + CHECK(polyh.cgal_polyhedron()->size_of_facets() == 6); } TEST_CASE("bad vs good polyhedron openscad example", "[csg]") { @@ -101,5 +101,5 @@ faces = [[0, 3, 2], [0, 2, 1], [4, 0, 5], [5, 0, 1], convexity = 1); )"); auto polyh = std::get(st.top.objs.at(0)); - CHECK(polyh.cgal_polyhedron().size_of_vertices() == 12); + CHECK(polyh.cgal_polyhedron()->size_of_vertices() == 12); } diff --git a/src/csg_cgal_helper.hpp b/src/csg_cgal_helper.hpp index 2a23e176a0daa6fa1e5569b7f0ba48eeed37b4c0..d437d5104b68641984a259c54fcfad46a2998acf 100644 --- a/src/csg_cgal_helper.hpp +++ b/src/csg_cgal_helper.hpp @@ -2,12 +2,14 @@ #define CGAL_HELPER_H_ #pragma GCC diagnostic ignored "-Wpedantic" -#pragma warning (disable : 4083 ) -#pragma warning (disable : 4244 ) +#pragma warning(disable : 4083) +#pragma warning(disable : 4244) #include #include #include +#include #include +#include #pragma GCC diagnostic pop #pragma warning default @@ -16,15 +18,23 @@ namespace cgal_helper { typedef CGAL::Simple_cartesian CK; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Polygon_2 Polygon; +typedef CGAL::AABB_face_graph_triangle_primitive + Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree AABBTree; -Polyhedron +std::shared_ptr create_polyhedron(const std::vector> &points, const std::vector> &faces); +std::shared_ptr +create_aabb_tree(const std::shared_ptr &polyhedron); + Polygon create_polygon(const std::vector> &points, const std::vector &path); -bool inside(const Polyhedron &polyhedron, double xx, double yy, double zz); +bool inside(const std::shared_ptr &tree, double xx, double yy, + double zz); bool inside(const Polygon &polygon, double xx, double yy);