From 9c3c012a898c21ac334db18796fdf96268222f8e Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 23 Dec 2020 13:22:51 +0000 Subject: [PATCH] Improve polyhedron perf --- include/csg_types.hpp | 10 ++++++-- src/csg/cgal_helper_polyhedron.cpp | 35 ++++++++++++++------------- src/csg/levelset_3d.cpp | 6 ++--- src/csg/tests/parser/primitives.t.cpp | 6 ++--- src/csg_cgal_helper.hpp | 18 +++++++++++--- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 2905794..5d16bda 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 2cc5bf9..f4c79a1 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 61701ce..c2b5eee 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 7847718..818b82d 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 2a23e17..d437d51 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); -- GitLab