Commit ea1f4b0c authored by Deepak Rangarajan's avatar Deepak Rangarajan Committed by Mark Meredith
Browse files

Resolve "support polyhedron"

parent f0e2fab6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ add_library(csg
  levelset_3d.cpp
  matrix_functions.cpp
  parser.cpp
  cgal_helper.cpp
  )

target_link_libraries(csg PRIVATE
+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
+9 −0
Original line number Diff line number Diff line
#include "csg_cgal_helper.hpp"
#include "csg_types.hpp"

#include <algorithm>
@@ -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);

@@ -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(
+1 −0
Original line number Diff line number Diff line
@@ -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)
+43 −8
Original line number Diff line number Diff line
@@ -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 {
@@ -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> {};
@@ -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> {};

@@ -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>> {};
@@ -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) {
@@ -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