Loading src/csg/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ add_library(csg levelset_3d.cpp matrix_functions.cpp parser.cpp cgal_helper.cpp ) target_link_libraries(csg PRIVATE Loading src/csg/cgal_helper.cpp 0 → 100644 +90 −0 Original line number Diff line number Diff line #include "csg_cgal_helper.hpp" #include <CGAL/AABB_face_graph_triangle_primitive.h> #include <CGAL/AABB_traits.h> #include <CGAL/AABB_tree.h> #include <CGAL/Polygon_mesh_processing/triangulate_faces.h> #include <CGAL/Polyhedron_incremental_builder_3.h> #include <CGAL/Side_of_triangle_mesh.h> #include <CGAL/algorithm.h> #include <CGAL/boost/graph/graph_traits_Polyhedron_3.h> namespace cgal_helper { namespace { typedef Polyhedron::HalfedgeDS HalfedgeDS; typedef typename HalfedgeDS::Vertex Vertex; typedef typename Vertex::Point Point; typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive; typedef CGAL::AABB_traits<Kernel, Primitive> Traits; typedef CGAL::AABB_tree<Traits> Tree; typedef CGAL::Side_of_triangle_mesh<Polyhedron, Kernel> Point_inside; // A modifier creating a polyhedron with the incremental builder. template <class HDS> class PolyhedronBuilder : public CGAL::Modifier_base<HDS> { private: const std::vector<std::tuple<double, double, double>> &m_points; const std::vector<std::vector<unsigned int>> &m_faces; public: PolyhedronBuilder( const std::vector<std::tuple<double, double, double>> &points, const std::vector<std::vector<unsigned int>> &faces) : m_points(points), m_faces(faces) {} void operator()(HDS &hds) { CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true); B.begin_surface(m_points.size(), m_faces.size()); // Add all the vertices first for (const auto &p : m_points) { auto [px, py, pz] = p; B.add_vertex(Point(px, py, pz)); } // Add facets next for (const auto &face : m_faces) { B.begin_facet(); for (const auto &p_index : face) { B.add_vertex_to_facet(p_index); } B.end_facet(); } B.end_surface(); } }; } // namespace Polyhedron create_polyhedron(const std::vector<std::tuple<double, double, double>> &points, const std::vector<std::vector<unsigned int>> &faces) { Polyhedron p; // Build incrementally PolyhedronBuilder<HalfedgeDS> bp(points, faces); 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()); return p; } bool inside(const Polyhedron &polyhedron, double xx, double yy, double zz) { Kernel::Point_3 pt(xx, yy, zz); // 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); // Determine the side and return true if inside! return inside_tester(pt) == CGAL::ON_BOUNDED_SIDE; } } // namespace cgal_helper src/csg/levelset_3d.cpp +9 −0 Original line number Diff line number Diff line #include "csg_cgal_helper.hpp" #include "csg_types.hpp" #include <algorithm> Loading Loading @@ -27,6 +28,7 @@ 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); double signed_distance_3d(const Polyhedron &, double, double, double); double signed_distance_2d(const Union2D &, double, double); Loading Loading @@ -149,6 +151,13 @@ double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, return signed_distance_2d(rot_ext.group, XX, 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; } double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { return std::visit( Loading src/csg/meson.build +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ lib_csg_parser = static_library( 'levelset_2d.cpp', 'parser.cpp', 'matrix_functions.cpp', 'cgal_helper.cpp', include_directories: parser_inc, dependencies: [pegtl, cgal], install : true) Loading src/csg/parser.cpp +43 −8 Original line number Diff line number Diff line Loading @@ -13,7 +13,8 @@ using namespace tao::pegtl; namespace { using Attr = std::variant<double, bool, std::vector<double>, std::string>; using Attr = std::variant<double, bool, std::vector<double>, std::string, std::vector<std::vector<double>>>; using AttrMap = std::map<std::string, Attr>; struct parser_state { Loading Loading @@ -83,16 +84,18 @@ struct vector : seq<L_ARR, list<vector_cell, one<','>>, R_ARR> {}; struct vector_attr : vector {}; struct value : sor<padded_double, boolean_literal, string_literal, vector_attr> {}; struct row : vector {}; struct keyval : seq<pad<name, space>, string<'='>, pad<value, space>> {}; struct matrix : seq<L_ARR, list<row, one<','>>, R_ARR> {}; struct attr_list : list<keyval, one<','>> {}; struct matrix_attr : matrix {}; struct row : vector {}; struct value : sor<padded_double, boolean_literal, string_literal, vector_attr, matrix_attr> {}; struct matrix : seq<L_ARR, list<row, one<','>>, R_ARR> {}; struct keyval : seq<pad<name, space>, string<'='>, pad<value, space>> {}; struct attr_list : list<keyval, one<','>> {}; struct sphere : seq<string<'s', 'p', 'h', 'e', 'r', 'e'>, L_FUN, attr_list, R_FUN> {}; Loading @@ -102,6 +105,10 @@ struct cube : seq<string<'c', 'u', 'b', 'e'>, L_FUN, attr_list, R_FUN> {}; struct cylinder : seq<string<'c', 'y', 'l', 'i', 'n', 'd', 'e', 'r'>, L_FUN, attr_list, R_FUN> {}; struct polyhedron : seq<string<'p', 'o', 'l', 'y', 'h', 'e', 'd', 'r', 'o', 'n'>, L_FUN, attr_list, R_FUN> {}; struct circle : seq<string<'c', 'i', 'r', 'c', 'l', 'e'>, L_FUN, attr_list, R_FUN> {}; Loading @@ -111,7 +118,8 @@ struct square template <Dimension dim> struct shape; template <> struct shape<Dimension::D3> : seq<sor<cube, cylinder, sphere>, opt<S_CLN>> {}; struct shape<Dimension::D3> : seq<sor<cube, cylinder, sphere, polyhedron>, opt<S_CLN>> {}; template <> struct shape<Dimension::D2> : seq<sor<circle, square>, opt<S_CLN>> {}; Loading Loading @@ -562,6 +570,24 @@ template <> struct action<square> { } }; template <> struct action<polyhedron> { template <typename Input> static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); auto &curr_attr = st.curr_attrs.back(); auto points = std::get<std::vector<std::vector<double>>>(curr_attr["points"]); auto faces = std::get<std::vector<std::vector<double>>>(curr_attr["faces"]); csg::Polyhedron polyh(points, faces); polyh.name = get_name(curr_attr); st.current_3d_objs.back().push_back(polyh); st.curr_attrs.pop_back(); } }; template <> struct action<name> { template <typename Input> static void apply(const Input &in, parser_state &st) { Loading Loading @@ -615,6 +641,15 @@ template <> struct action<vector_attr> { } }; template <> struct action<matrix_attr> { template <typename Input> static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); st.curr_attr[st.current_name] = st.current_matrix; st.current_matrix.clear(); } }; std::optional<parser_state> do_parse(std::string str) { parser_state st; std::vector<csg::Type3D> new_3d_group; Loading Loading
src/csg/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ add_library(csg levelset_3d.cpp matrix_functions.cpp parser.cpp cgal_helper.cpp ) target_link_libraries(csg PRIVATE Loading
src/csg/cgal_helper.cpp 0 → 100644 +90 −0 Original line number Diff line number Diff line #include "csg_cgal_helper.hpp" #include <CGAL/AABB_face_graph_triangle_primitive.h> #include <CGAL/AABB_traits.h> #include <CGAL/AABB_tree.h> #include <CGAL/Polygon_mesh_processing/triangulate_faces.h> #include <CGAL/Polyhedron_incremental_builder_3.h> #include <CGAL/Side_of_triangle_mesh.h> #include <CGAL/algorithm.h> #include <CGAL/boost/graph/graph_traits_Polyhedron_3.h> namespace cgal_helper { namespace { typedef Polyhedron::HalfedgeDS HalfedgeDS; typedef typename HalfedgeDS::Vertex Vertex; typedef typename Vertex::Point Point; typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive; typedef CGAL::AABB_traits<Kernel, Primitive> Traits; typedef CGAL::AABB_tree<Traits> Tree; typedef CGAL::Side_of_triangle_mesh<Polyhedron, Kernel> Point_inside; // A modifier creating a polyhedron with the incremental builder. template <class HDS> class PolyhedronBuilder : public CGAL::Modifier_base<HDS> { private: const std::vector<std::tuple<double, double, double>> &m_points; const std::vector<std::vector<unsigned int>> &m_faces; public: PolyhedronBuilder( const std::vector<std::tuple<double, double, double>> &points, const std::vector<std::vector<unsigned int>> &faces) : m_points(points), m_faces(faces) {} void operator()(HDS &hds) { CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true); B.begin_surface(m_points.size(), m_faces.size()); // Add all the vertices first for (const auto &p : m_points) { auto [px, py, pz] = p; B.add_vertex(Point(px, py, pz)); } // Add facets next for (const auto &face : m_faces) { B.begin_facet(); for (const auto &p_index : face) { B.add_vertex_to_facet(p_index); } B.end_facet(); } B.end_surface(); } }; } // namespace Polyhedron create_polyhedron(const std::vector<std::tuple<double, double, double>> &points, const std::vector<std::vector<unsigned int>> &faces) { Polyhedron p; // Build incrementally PolyhedronBuilder<HalfedgeDS> bp(points, faces); 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()); return p; } bool inside(const Polyhedron &polyhedron, double xx, double yy, double zz) { Kernel::Point_3 pt(xx, yy, zz); // 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); // Determine the side and return true if inside! return inside_tester(pt) == CGAL::ON_BOUNDED_SIDE; } } // namespace cgal_helper
src/csg/levelset_3d.cpp +9 −0 Original line number Diff line number Diff line #include "csg_cgal_helper.hpp" #include "csg_types.hpp" #include <algorithm> Loading Loading @@ -27,6 +28,7 @@ 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); double signed_distance_3d(const Polyhedron &, double, double, double); double signed_distance_2d(const Union2D &, double, double); Loading Loading @@ -149,6 +151,13 @@ double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, return signed_distance_2d(rot_ext.group, XX, 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; } double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { return std::visit( Loading
src/csg/meson.build +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ lib_csg_parser = static_library( 'levelset_2d.cpp', 'parser.cpp', 'matrix_functions.cpp', 'cgal_helper.cpp', include_directories: parser_inc, dependencies: [pegtl, cgal], install : true) Loading
src/csg/parser.cpp +43 −8 Original line number Diff line number Diff line Loading @@ -13,7 +13,8 @@ using namespace tao::pegtl; namespace { using Attr = std::variant<double, bool, std::vector<double>, std::string>; using Attr = std::variant<double, bool, std::vector<double>, std::string, std::vector<std::vector<double>>>; using AttrMap = std::map<std::string, Attr>; struct parser_state { Loading Loading @@ -83,16 +84,18 @@ struct vector : seq<L_ARR, list<vector_cell, one<','>>, R_ARR> {}; struct vector_attr : vector {}; struct value : sor<padded_double, boolean_literal, string_literal, vector_attr> {}; struct row : vector {}; struct keyval : seq<pad<name, space>, string<'='>, pad<value, space>> {}; struct matrix : seq<L_ARR, list<row, one<','>>, R_ARR> {}; struct attr_list : list<keyval, one<','>> {}; struct matrix_attr : matrix {}; struct row : vector {}; struct value : sor<padded_double, boolean_literal, string_literal, vector_attr, matrix_attr> {}; struct matrix : seq<L_ARR, list<row, one<','>>, R_ARR> {}; struct keyval : seq<pad<name, space>, string<'='>, pad<value, space>> {}; struct attr_list : list<keyval, one<','>> {}; struct sphere : seq<string<'s', 'p', 'h', 'e', 'r', 'e'>, L_FUN, attr_list, R_FUN> {}; Loading @@ -102,6 +105,10 @@ struct cube : seq<string<'c', 'u', 'b', 'e'>, L_FUN, attr_list, R_FUN> {}; struct cylinder : seq<string<'c', 'y', 'l', 'i', 'n', 'd', 'e', 'r'>, L_FUN, attr_list, R_FUN> {}; struct polyhedron : seq<string<'p', 'o', 'l', 'y', 'h', 'e', 'd', 'r', 'o', 'n'>, L_FUN, attr_list, R_FUN> {}; struct circle : seq<string<'c', 'i', 'r', 'c', 'l', 'e'>, L_FUN, attr_list, R_FUN> {}; Loading @@ -111,7 +118,8 @@ struct square template <Dimension dim> struct shape; template <> struct shape<Dimension::D3> : seq<sor<cube, cylinder, sphere>, opt<S_CLN>> {}; struct shape<Dimension::D3> : seq<sor<cube, cylinder, sphere, polyhedron>, opt<S_CLN>> {}; template <> struct shape<Dimension::D2> : seq<sor<circle, square>, opt<S_CLN>> {}; Loading Loading @@ -562,6 +570,24 @@ template <> struct action<square> { } }; template <> struct action<polyhedron> { template <typename Input> static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); auto &curr_attr = st.curr_attrs.back(); auto points = std::get<std::vector<std::vector<double>>>(curr_attr["points"]); auto faces = std::get<std::vector<std::vector<double>>>(curr_attr["faces"]); csg::Polyhedron polyh(points, faces); polyh.name = get_name(curr_attr); st.current_3d_objs.back().push_back(polyh); st.curr_attrs.pop_back(); } }; template <> struct action<name> { template <typename Input> static void apply(const Input &in, parser_state &st) { Loading Loading @@ -615,6 +641,15 @@ template <> struct action<vector_attr> { } }; template <> struct action<matrix_attr> { template <typename Input> static void apply(const Input &in, parser_state &st) { std::stringstream ss(in.string()); st.curr_attr[st.current_name] = st.current_matrix; st.current_matrix.clear(); } }; std::optional<parser_state> do_parse(std::string str) { parser_state st; std::vector<csg::Type3D> new_3d_group; Loading