FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
cgal.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5#pragma once
6
7#include <iterator>
9#include <kernel/geometry/mesh_part.hpp>
10#include <kernel/shape.hpp>
11#include <kernel/util/string.hpp>
12#include <kernel/util/tiny_algebra.hpp>
13#include <fstream>
14
15#if defined(FEAT_HAVE_CGAL) || defined(DOXYGEN)
16
17#include <cstddef>
18#include <optional>
19#include <functional>
20
21namespace FEAT
22{
23 namespace Geometry
24 {
25
26 enum class CGALFileMode
27 {
28 fm_off = 0,
29 fm_obj
30 };
31
40 using CGALFeature = std::vector<std::uint32_t>;
41
47 using CGALFeatureNetwork = std::vector<CGALFeature>;
48
61 template<typename T_>
63 {
64 using iterator_category = std::input_iterator_tag;
65 using difference_type = Index;
66 using value_type = T_;
67 using pointer = T_*;
68 using reference = T_&;
69
70 using GeneratorType = std::function<std::optional<T_>()>;
71
72 private:
73 GeneratorType _generator;
74 std::optional<T_> _current;
75
76 public:
77 explicit CGALValueIteratorWrapper(GeneratorType&& g) : _generator(std::move(g)), _current(_generator())
78 {
79 }
80
81 T_ operator*()
82 {
83 return _current.value();
84 }
85
86 T_ operator->()
87 {
88 return _current.value();
89 }
90
91 CGALValueIteratorWrapper& operator++()
92 {
93 ASSERT(_current.has_value());
94 _current = _generator();
95 return *this;
96 }
97
98 CGALValueIteratorWrapper operator++(int)
99 {
100 ASSERT(_current.has_value());
101 CGALValueIteratorWrapper tmp = *this;
102 ++(*this);
103 return tmp;
104 }
105
106 explicit operator bool() const
107 {
108 return static_cast<bool>(_current);
109 }
110
111 friend bool operator==(const CGALValueIteratorWrapper& a, const CGALValueIteratorWrapper& b)
112 {
113 if(!a && !b)
114 {
115 // Both empty
116 return true;
117 }
118 if(!a || !b)
119 {
120 // One empty
121 return false;
122 }
123 // None empty
124 return true;
125 }
126
127 friend bool operator!=(const CGALValueIteratorWrapper& a, const CGALValueIteratorWrapper& b)
128 {
129 return !(a == b);
130 }
131 };
132
133 template<typename DT_>
134 class CGALWrapper;
135
137 template<typename DT_>
139 {
140 const CGALWrapper<DT_>* _wrapper;
141 public:
142
144 explicit CGALVerticesAroundFaceAdjactor(const CGALWrapper<DT_>* w) : _wrapper(w)
145 {
146 }
147
150
153
156
159 };
160
171 template<typename DT_>
173 {
174 public:
175 typedef DT_ DataType;
178
179 private:
180 void * _cgal_data;
181 bool _expensive_intersection = false;
182
184 void _parse_mesh(std::istream & file, CGALFileMode file_mode);
185
187
188 public:
190 CGALWrapper(const CGALWrapper&) = delete;
191 CGALWrapper& operator=(const CGALWrapper&) = delete;
192 CGALWrapper(CGALWrapper&&) noexcept;
193 CGALWrapper& operator=(CGALWrapper&& other) noexcept;
194 virtual ~CGALWrapper();
195
197 explicit CGALWrapper(const String & filename, CGALFileMode file_mode);
198
200 explicit CGALWrapper(std::istream & file, CGALFileMode file_mode);
201
213 explicit CGALWrapper(const std::vector<PointType>& vertices, const std::vector<std::array<Index, 3>>& faces);
214
216 bool point_inside(DataType x, DataType y, DataType z) const;
217
219 bool point_not_outside(DataType x, DataType y, DataType z) const;
220
222 DataType squared_distance(DataType x, DataType y, DataType z) const;
223
225 DataType squared_distance_to_feature(const CGALFeature& f, const PointType& p) const;
226
228 PointType point(std::uint32_t idx) const;
229
231 std::vector<PointType> points() const;
232
235
237 PointType closest_point(DataType x, DataType y, DataType z) const;
238
239 PointType closest_point(const PointType& point, PointType& primitive_grad) const;
240
243
245 CGALFeatureNetwork detect_features(DataType critical_angle);
246
248 bool intersects_line(const PointType& a, const PointType& b) const;
249
250 bool intersects_hexaedron(const std::array<FEAT::Geometry::CGALWrapper<DT_>::PointType, 8>& points) const;
251
252 template<std::size_t num_verts_>
253 bool intersects_polygon(const std::array<FEAT::Geometry::CGALWrapper<DT_>::PointType, num_verts_>& points) const
254 {
255 if constexpr(num_verts_ == 2)
256 {
257 return intersects_line(points[0], points[1]);
258 }
259 else if constexpr(num_verts_ == 8)
260 {
261 return intersects_hexaedron(points);
262 }
263
264 XABORTM("Not implemented");
265
266 return false;
267 }
268
272 void transform(const TransformMatrix& trafo_mat, const PointType& translation, DataType scale = DataType(1));
273
275 std::size_t bytes() const;
276
278 void write_off(std::ostream& stream) const;
279
282 void write_off(const String& filename) const
283 {
284 // try to open our output file
285 const String name(filename + ".off");
286 std::ofstream ofs(name.c_str());
287 if(!(ofs.is_open() && ofs.good()))
288 {
289 throw FileError("Failed to create '" + name + "'");
290 }
291
292 write_off(ofs);
293 ofs.close();
294 }
295
305 void displace_vertices(const std::vector<PointType>& offsets);
306
309
311 Index get_num_entities(int dim) const;
312
315
317 std::vector<PointType> outer_normals_at_faces() const;
318
320 void set_expensive_intersection(bool expensive_test);
321
322 private:
327
328 }; // class CGALWrapper<typename DT_>
329
330 template<typename MeshType_>
331 static CGALWrapper<typename MeshType_::CoordType> cgal_wrapper_from_mesh(const MeshType_& mesh, const MeshPart<MeshType_>& part)
332 {
333 using MeshType = MeshType_;
334 using DT = typename MeshType::CoordType;
335 using ShapeType = typename MeshType::ShapeType;
336 using FaceType = typename Shape::FaceTraits<ShapeType, 2>::ShapeType;
337 using PointType = typename CGALWrapper<DT>::PointType;
338
339 constexpr int vertices_per_face = Shape::FaceTraits<FaceType, 0>::count;
340
341 static_assert(ShapeType::dimension == 3);
342
343 std::vector<PointType> vertices;
344 vertices.reserve(part.get_num_entities(0));
345
346 // Prepare vertices
347 const auto& vertex_set = mesh.get_vertex_set();
348 const TargetSet& vts = part.template get_target_set<0>();
349 for(Index i(0); i < part.get_num_entities(0); i++)
350 {
351 vertices.push_back(vertex_set[vts[i]]);
352 }
353
354 // Prepare faces
355 std::vector<std::array<Index, 3>> faces;
356
357 const auto& v_at_f = mesh.template get_index_set<2, 0>();
358 const TargetSet& fts = part.template get_target_set<2>();
359 const Index num_mesh_faces = part.get_num_entities(2);
360
361 if constexpr(std::is_same_v<ShapeType, Shape::Hexahedron>)
362 {
363 // Quad faces get split into triangles
364 faces.reserve(2 * num_mesh_faces);
365 }
366 if constexpr(std::is_same_v<ShapeType, Shape::Tetrahedron>)
367 {
368 // Triangle faces do not need to be split
369 faces.reserve(num_mesh_faces);
370 }
371
372 std::array<Index, vertices_per_face> vs;
373 for(Index i(0); i < num_mesh_faces; i++)
374 {
375 for(int j(0); j < vertices_per_face; j++)
376 {
377 // Get mesh index
378 Index v = v_at_f(fts[i], j);
379
380 // Find corresponding index in vertex target set
381 for(Index k(0); k < vts.get_num_entities(); k++)
382 {
383 if(vts[k] == v)
384 {
385 vs[std::size_t(j)] = k;
386 break;
387 }
388 }
389 }
390
391 if constexpr(std::is_same_v<ShapeType, Shape::Hexahedron>)
392 {
393 faces.push_back({vs[0], vs[1], vs[2]});
394 faces.push_back({vs[3], vs[2], vs[1]});
395 }
396 if constexpr(std::is_same_v<ShapeType, Shape::Tetrahedron>)
397 {
398 faces.push_back({vs[0], vs[1], vs[2]});
399 }
400 }
401
402 return CGALWrapper<DT>(vertices, faces);
403 }
404 } // namespace Geometry
405} // namespace FEAT
406#endif //defined(FEAT_HAVE_CGAL) || defined(DOXYGEN)
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
FEAT Kernel base header.
Base class for file related errors.
Definition: exception.hpp:173
Wrapper for arbitrary iterators that produce values.
Definition: cgal.hpp:63
Adjactor for vertices around a face.
Definition: cgal.hpp:139
CGALValueIteratorWrapper< Index > image_begin(Index face) const
Adjactor begin.
CGALValueIteratorWrapper< Index > image_end(Index face) const
Adjactor end.
Index get_num_nodes_image() const
Number of vertices.
Index get_num_nodes_domain() const
Number of faces.
CGALVerticesAroundFaceAdjactor(const CGALWrapper< DT_ > *w)
Constructor.
Definition: cgal.hpp:144
Wrapper for the CGAL Library.
Definition: cgal.hpp:173
void displace_vertices(const std::vector< PointType > &offsets)
Displace each vertex of the mesh by its given offset.
void _init_wrapper()
initializes tree and inside tester with already initialized polyhedron
std::vector< PointType > points() const
Returns a vector of all points of the surface mesh.
void transform(const TransformMatrix &trafo_mat, const PointType &translation, DataType scale=DataType(1))
Index get_num_entities(int dim) const
Returns the number of entities of dimension dim of the underlying polyhedron.
void write_off(std::ostream &stream) const
Write the surface file to an ostream object.
bool point_inside(DataType x, DataType y, DataType z) const
Check whether a point is inside the Polyhedron defined at objects' construction.
std::vector< PointType > outer_normals_at_faces() const
Returns the outer normals at each surface element.
bool intersects_line(const PointType &a, const PointType &b) const
tests whether the cgal mesh intersects with the line segment a->b
void write_off(const String &filename) const
Definition: cgal.hpp:282
void _delete_tree()
Delete tree, which also requires to delete the inside tester.
DataType squared_distance(DataType x, DataType y, DataType z) const
Returns the minimun squared distance between the query point and all input primitives defined at obje...
void set_expensive_intersection(bool expensive_test)
Sets whether we do an expensive test for the intersection test or only use boundingboxes.
CGALVerticesAroundFaceAdjactor< DT_ > vertices_around_face() const
Returns an adjactor for vertices around faces of the mesh.
std::size_t bytes() const
Returns the size in bytes.
CGALFeatureNetwork detect_features(DataType critical_angle)
Returns a vector of all feature vertices defined at objects' construction.
Index get_num_vertices() const
Returns the number of vertices of the underlying polyhedron.
CGALWrapper(const CGALWrapper &)=delete
rule of five
PointType closest_point(const PointType &point) const
Returns the nearest point regarding on all input primitives defined at objects' construction.
DataType squared_distance_to_feature(const CGALFeature &f, const PointType &p) const
Returns the minimum squared distance between the query point and the given feature.
bool point_not_outside(DataType x, DataType y, DataType z) const
Check whether a point is inside or on the boundary of the Polyhedron defined at objects' construction...
PointType point(std::uint32_t idx) const
Returns the point of the surface mesh with the given index.
void _parse_mesh(std::istream &file, CGALFileMode file_mode)
read in stream in prescibed file format and preprocess search tree for in/out test
PointType closest_point_on_feature(const CGALFeature &f, const PointType &p) const
Returns the closest point closest to p on the given feature.
Class template for partial meshes.
Definition: mesh_part.hpp:90
Index get_num_entities(int dim) const
Returns the number of entities.
Definition: mesh_part.hpp:311
Target set class.
Definition: target_set.hpp:27
Index get_num_entities() const
Returns the number of entities.
Definition: target_set.hpp:92
String class implementation.
Definition: string.hpp:47
Tiny Matrix class template.
Tiny Vector class template.
std::vector< CGALFeature > CGALFeatureNetwork
A FeatureNetwork is a list of features.
Definition: cgal.hpp:47
std::vector< std::uint32_t > CGALFeature
A feature is an edge-path on a surface mesh, stored as a list of vertex indices.
Definition: cgal.hpp:40
@ other
generic/other permutation strategy
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
Face traits tag struct template.
Definition: shape.hpp:106