Medusa  1.1
Coordinate Free Mehless Method implementation
PolyhedronShape_fwd.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_DOMAINS_POLYHEDRONSHAPE_FWD_HPP_
2 #define MEDUSA_BITS_DOMAINS_POLYHEDRONSHAPE_FWD_HPP_
3 
11 #include <medusa/Config.hpp>
16 #include <medusa/bits/domains/PolytopeShape.hpp>
18 
19 #include <CGAL/AABB_face_graph_triangle_primitive.h>
20 #include <CGAL/AABB_traits.h>
21 #include <CGAL/AABB_tree.h>
22 #include <CGAL/Side_of_triangle_mesh.h>
23 #include <CGAL/Simple_cartesian.h>
24 #include <CGAL/Surface_mesh.h>
25 #include <CGAL/Polygon_mesh_processing/compute_normal.h>
26 
27 #include <fstream>
28 
29 namespace mm {
30 
45 template <typename vec_t>
46 class PolyhedronShape : public DomainShape<vec_t> {
47  static_assert(vec_t::dim == 3, "Only available in 3 dimensions.");
49 
50  /* CGAL types */
51  typedef CGAL::Simple_cartesian<double> K;
52  typedef K::Point_3 Point;
53  typedef K::Vector_3 Vector;
54  typedef CGAL::Surface_mesh<Point> Mesh;
55  typedef Mesh::Vertex_index VI;
56  typedef Mesh::Face_index FI;
57  typedef CGAL::AABB_face_graph_triangle_primitive<Mesh> Primitive;
60  typedef CGAL::AABB_tree<CGAL::AABB_traits<K, Primitive>> Tree;
62  typedef CGAL::Side_of_triangle_mesh<Mesh, K> PointInside;
63 
67 
69  void init() {
70  tree.insert(surface.faces_begin(), surface.faces_end(), surface);
71  tree.accelerate_distance_queries();
72 
73  auto vnormals = surface.add_property_map<VI, Vector>("v:normals", CGAL::NULL_VECTOR).first;
74  auto fnormals = surface.add_property_map<FI, Vector>("f:normals", CGAL::NULL_VECTOR).first;
75  CGAL::Polygon_mesh_processing::compute_normals(surface, vnormals, fnormals);
76  }
77 
78  public:
79  using typename base_t::scalar_t;
80  using typename base_t::vector_t;
81  using base_t::dim;
84 
85 
87  explicit PolyhedronShape(const Mesh& surface)
88  : surface(surface), tree(), inside_tester(tree) { init(); }
89 
92  : surface(other.surface), tree(), inside_tester(tree) { init(); }
93 
96  surface = other.surface;
97  tree.clear();
98  init();
99  return *this;
100  }
101 
110  static PolyhedronShape fromOFF(const std::string& filename) {
111  std::ifstream input(filename);
112  assert_msg(input, "Failed opening file %s: %s", filename, strerror(errno));
113  Mesh surface;
114  input >> surface;
115  assert_msg(!input.fail(), "Invalid OFF file - either parsing failed or the data "
116  "does not represent a two-manifold.");
117  assert_msg(input, "Failed reading file %s: %s", filename, strerror(errno));
118  assert_msg(!surface.is_empty(), "Surface is empty.");
119  assert_msg(CGAL::is_triangle_mesh(surface), "Surface must be a triangle mesh.");
120  assert_msg(CGAL::is_closed(surface), "Surface must be closed (without holes).");
121  return PolyhedronShape(surface);
122  }
123 
124  bool contains(const vec_t& point) const override {
125  return inside_tester(Point(point[0], point[1], point[2])) != CGAL::ON_UNBOUNDED_SIDE;
126  }
127 
128  std::pair<vec_t, vec_t> bbox() const override {
129  auto b = tree.bbox();
130  return {{b.xmin(), b.ymin(), b.zmin()}, {b.xmax(), b.ymax(), b.zmax()}};
131  }
132 
134  const std::function<scalar_t(vec_t)>& dr, int type) const override;
135 
136  std::ostream& print(std::ostream& os) const override {
137  return os << "PolyhedronShape with " << surface.num_vertices() << " vertices"
138  << " and " << surface.num_faces() << " faces.";
139  }
140 
141  PolyhedronShape* clone() const override { return new PolyhedronShape(*this); }
142 
144  static int rgb2type(uint8_t r, uint8_t g, uint8_t b) {
145  return -((static_cast<int>(r) << 16) + (static_cast<int>(g) << 8) + b) - 1;
146  }
147 
148  private:
150  vec_t getPoint(VI idx) const {
151  auto p = surface.point(idx);
152  return {p.x(), p.y(), p.z()};
153  }
154 };
155 
156 // This must be hidden during a doxygen run due to a bug in processing const declarations with
157 // differently named template parameters.
158 // See https://github.com/doxygen/doxygen/issues/8178
159 #ifndef DOXYGEN_RUN
160 
165 template <typename Scalar>
166 class PolytopeShape<Vec<Scalar, 3>> : public PolyhedronShape<Vec<Scalar, 3>> {
167  using base_t = PolyhedronShape<Vec<Scalar, 3>>;
168  using typename base_t::PolyhedronShape;
169  public:
170  PolytopeShape(const base_t& shape) : base_t(shape) {}
171 };
172 #endif
173 
174 
175 } // namespace mm
176 
177 #endif // MEDUSA_BITS_DOMAINS_POLYHEDRONSHAPE_FWD_HPP_
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
mm::PolyhedronShape::operator=
PolyhedronShape & operator=(const PolyhedronShape &other)
Copy assignment (necessary to rebuild the tree).
Definition: PolyhedronShape_fwd.hpp:95
mm::PolyhedronShape::fromOFF
static PolyhedronShape fromOFF(const std::string &filename)
Read a triangular closed surface mesh describing a polyhedron from a .off file.
Definition: PolyhedronShape_fwd.hpp:110
mm::DomainDiscretization
Class representing domain discretization along with an associated shape.
Definition: DomainDiscretization_fwd.hpp:46
mm::Vec
Eigen::Matrix< scalar_t, dim, 1, Eigen::ColMajor|Eigen::AutoAlign, dim, 1 > Vec
Fixed size vector type, representing a mathematical 1d/2d/3d vector.
Definition: Vec_fwd.hpp:31
mm::PolyhedronShape::clone
PolyhedronShape * clone() const override
Polymorphic clone pattern.
Definition: PolyhedronShape_fwd.hpp:141
dim
@ dim
Number of elements of this matrix.
Definition: MatrixBaseAddons.hpp:14
mm::PolyhedronShape::discretizeBoundaryWithDensity
DomainDiscretization< vec_t > discretizeBoundaryWithDensity(const std::function< scalar_t(vec_t)> &dr, int type) const override
Discretizes boundary with given density and fill engine.
Definition: PolyhedronShape.hpp:11
mm::DomainShape::dim
@ dim
Dimensionality of the domain.
Definition: DomainShape_fwd.hpp:57
mm::PolyhedronShape::Primitive
CGAL::AABB_face_graph_triangle_primitive< Mesh > Primitive
CGAL type for storing triangular faces of surface meshes in AABB tree.
Definition: PolyhedronShape_fwd.hpp:58
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
mm::PolyhedronShape::Tree
CGAL::AABB_tree< CGAL::AABB_traits< K, Primitive > > Tree
CGAL type for axis-aligned bounding-box trees, used for testing point inclusions.
Definition: PolyhedronShape_fwd.hpp:60
mm::PolyhedronShape::PointInside
CGAL::Side_of_triangle_mesh< Mesh, K > PointInside
CGAL type of the function for testing point inclusion.
Definition: PolyhedronShape_fwd.hpp:62
mm::DomainShape
Base class for geometric shapes of domains.
Definition: DomainShape_fwd.hpp:52
DomainShape.hpp
mm::PolyhedronShape::PolyhedronShape
PolyhedronShape(const PolyhedronShape &other)
Copy constructor (necessary to rebuild the tree).
Definition: PolyhedronShape_fwd.hpp:91
mm::PolyhedronShape::PolyhedronShape
PolyhedronShape(const Mesh &surface)
Construct a shape from a CGAL surface mesh.
Definition: PolyhedronShape_fwd.hpp:87
Config.hpp
mm::DomainShape::vector_t
vec_t vector_t
Vector data type used in computations.
Definition: DomainShape_fwd.hpp:54
mm::PolyhedronShape::init
void init()
Initialize the tree and compute surface normals.
Definition: PolyhedronShape_fwd.hpp:69
mm::PolyhedronShape::Mesh
CGAL::Surface_mesh< Point > Mesh
CGAL surface mesh type.
Definition: PolyhedronShape_fwd.hpp:54
mm::DomainShape::discretizeBoundaryWithDensity
virtual DomainDiscretization< vec_t > discretizeBoundaryWithDensity(const std::function< scalar_t(vec_t)> &dr, int type) const =0
Discretizes boundary with given density and fill engine.
mm::PolyhedronShape::Point
K::Point_3 Point
CGAL point type.
Definition: PolyhedronShape_fwd.hpp:52
mm::PolyhedronShape::rgb2type
static int rgb2type(uint8_t r, uint8_t g, uint8_t b)
Convert a RBG color to an integer value that can be used as a boundary type.
Definition: PolyhedronShape_fwd.hpp:144
discretization_helpers_advanced.hpp
mm::PolyhedronShape::inside_tester
PointInside inside_tester
Function used for testing point inclusions.
Definition: PolyhedronShape_fwd.hpp:66
mm::PolyhedronShape::K
CGAL::Simple_cartesian< double > K
CGAL geometry kernel.
Definition: PolyhedronShape_fwd.hpp:51
mm::PolyhedronShape::print
std::ostream & print(std::ostream &os) const override
Output information about this shape to given output stream os.
Definition: PolyhedronShape_fwd.hpp:136
mm::DomainShape::discretizeBoundaryWithStep
virtual DomainDiscretization< vec_t > discretizeBoundaryWithStep(scalar_t step, int type) const
Returns a discretization of the boundary of this shape with approximately uniform distance step betwe...
Definition: DomainShape_fwd.hpp:118
discretization_helpers.hpp
mm::PolyhedronShape::tree
Tree tree
AABB tree of the faces.
Definition: PolyhedronShape_fwd.hpp:65
mm::PolyhedronShape::bbox
std::pair< vec_t, vec_t > bbox() const override
Return the bounding box of the domain.
Definition: PolyhedronShape_fwd.hpp:128
Vec.hpp
mm::PolyhedronShape::Vector
K::Vector_3 Vector
CGAL vector type.
Definition: PolyhedronShape_fwd.hpp:53
mm::PolyhedronShape::FI
Mesh::Face_index FI
CGAL index type for a face on a surface mesh.
Definition: PolyhedronShape_fwd.hpp:56
mm::PolyhedronShape::surface
Mesh surface
Surface of the polyhedron represented as a triangular mesh.
Definition: PolyhedronShape_fwd.hpp:64
mm::PolyhedronShape::VI
Mesh::Vertex_index VI
CGAL index type for a point on a surface mesh.
Definition: PolyhedronShape_fwd.hpp:55
GeneralFill.hpp
mm::PolyhedronShape
A polyhedron represented by a closed triangular mesh.
Definition: PolyhedronShape_fwd.hpp:46
mm::DomainShape::scalar_t
vec_t::Scalar scalar_t
Scalar data type used in computation.
Definition: DomainShape_fwd.hpp:55
mm::PolyhedronShape::contains
bool contains(const vec_t &point) const override
Return true if point is not more than margin() outside the domain.
Definition: PolyhedronShape_fwd.hpp:124
mm::PolyhedronShape::getPoint
vec_t getPoint(VI idx) const
Convert a CGAL vertex index to a Medusa vector.
Definition: PolyhedronShape_fwd.hpp:150