FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
cgal_surface_mesh.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
8#include <kernel/geometry/atlas/chart.hpp>
9#include <kernel/util/math.hpp>
10#include <kernel/util/string.hpp>
11#include <kernel/geometry/cgal.hpp>
12#include <kernel/runtime.hpp>
13
14#include <memory>
15
16namespace FEAT
17{
18 namespace Geometry
19 {
20 namespace Atlas
21 {
24 {
26 static constexpr bool is_explicit = false;
28 static constexpr bool is_implicit = true;
30 static constexpr int world_dim = 3;
32 static constexpr int param_dim = 2;
33 };
34
45 template<typename Mesh_>
47#ifdef FEAT_HAVE_CGAL
48 public ChartCRTP<CGALSurfaceMesh<Mesh_>, Mesh_, CGALSurfaceMeshTraits>
49 {
50 public:
52 static constexpr int shape_dim = 2;
56 typedef typename BaseClass::CoordType CoordType;
58 typedef typename BaseClass::WorldPoint WorldPoint;
59
60
61 private:
64
65 public:
67 CGALSurfaceMesh() = delete;
71 CGALSurfaceMesh& operator=(CGALSurfaceMesh&&) = delete;
73 CGALSurfaceMesh(const CGALSurfaceMesh&) = delete;
75 CGALSurfaceMesh& operator=(const CGALSurfaceMesh&) = delete;
76
77
78 CGALSurfaceMesh(const String& filename, Geometry::CGALFileMode file_mode) :
79 cgal{filename, file_mode}
80 {}
81
82 CGALSurfaceMesh(std::istream & file, CGALFileMode file_mode) :
83 cgal{file, file_mode}
84 {}
85
86 static std::unique_ptr<CGALSurfaceMesh<Mesh_>> create_cgal_surface_mesh(std::istream& file, Geometry::CGALFileMode file_mode)
87 {
88 return std::make_unique<CGALSurfaceMesh<Mesh_>>(file, file_mode);
89 }
90
91
92 ~CGALSurfaceMesh() = default;
93
95 std::size_t bytes() const override
96 {
97 return cgal.bytes();
98 }
99
101 String get_type() const override
102 {
103 return "CGALSurfaceMesh";
104 }
105
107 void transform(const WorldPoint& origin, const WorldPoint& angles, const WorldPoint& offset) override
108 {
109 // create rotation matrix
111 rot.set_rotation_3d(angles[0], angles[1], angles[2]);
112 Tiny::Vector<CoordType, 3> trans = (-1) * rot * origin + offset;
113 cgal.transform(rot, trans);
114 }
115
117 void write(std::ostream& /*os*/, const String& /*sindent*/) const override
118 {
119 XABORTM("Not implemented yet");
120 }
121
128 void project_point(WorldPoint& point) const
129 {
130 point = cgal.closest_point(point);
131 }
132
143 void project_point(WorldPoint& point, WorldPoint& normal) const
144 {
145 WorldPoint tmp_norm;
146 point = cgal.closest_point(point, tmp_norm);
147 normal = tmp_norm;
148 }
149
150
165 void project_meshpart(Mesh_& mesh, const MeshPart<Mesh_>& meshpart) const
166 {
167 Index num_facets(meshpart.get_num_entities(shape_dim));
168
169 // There is nothing to do if the meshpart does not have any cells (which refer to facets of the original
170 // mesh)
171 if(num_facets == Index(0))
172 return;
173
174 // The number of vertices that need to be projected
175 const Index num_verts(meshpart.get_num_entities(0));
176 // Mapping of vertices from the meshpart to the real mesh
177 const auto& ts_verts(meshpart.template get_target_set<0>());
178
179 //get vertex set of mesh
180 auto& vtx(mesh.get_vertex_set());
181
182 //we could simply go through the vertices of the meshpart, project and hope for the best...
183 // but we should and can at least check, if the new facet is at about the same distance away
184 for(Index i = 0; i < num_verts; ++i)
185 {
186 project_point(vtx[ts_verts[i]]);
187 }
188 //already done
189 }
190
191
193 CoordType compute_dist(const WorldPoint& point) const
194 {
195 return Math::sqrt(cgal.squared_distance(point[0], point[1], point[2]));
196 }
197
200 CoordType compute_dist(const WorldPoint& point, WorldPoint& grad_distance) const
201 {
202 // WorldPoint normal;
203 WorldPoint projected_point(point);
204 project_point(projected_point);
205 // project_point(projected_point, normal);
206
207 grad_distance = (projected_point - point);
208 CoordType dist = grad_distance.norm_euclid();
209
210 // If the distance is too small, we set the gradient vector to zero
211 if(grad_distance.norm_euclid() < Math::eps<CoordType>())
212 {
213 grad_distance.format(CoordType(0));
214 }
215 else
216 {
217 grad_distance.normalize();
218 }
219
220 return dist;
221 }
222
224 CoordType compute_signed_dist(const WorldPoint& point) const
225 {
226 return cgal.point_inside(point[0], point[1], point[2]) ? -compute_dist(point) : compute_dist(point);
227 }
228
230 CoordType compute_signed_dist(const WorldPoint& point, WorldPoint& grad_distance) const
231 {
232 return cgal.point_inside(point[0], point[1], point[2]) ? -compute_dist(point, grad_distance) : compute_dist(point, grad_distance);
233 }
234#else
235 public ChartBase<Mesh_> //dummy implementation... you should not create a CGALSurfaceMesh chart, if you do not have cgal loaded...
236 {
237 public:
239 static constexpr int shape_dim = 2;
250
252 {
253 XABORTM("ERROR: Can not create a CGALSurfaceMesh without CGAL enabled");
254 }
255
256 bool can_explicit() const override
257 {
258 return false;
259 }
260
261 bool can_implicit() const override
262 {
263 return false;
264 }
265
266 void adapt(MeshType&, const PartType&) const override
267 {
268 XABORTM("Thou shalt not arrive here!");
269 }
270
271 void adapt(PartType&, const PartType&) const override
272 {
273 XABORTM("Thou shalt not arrive here!");
274 }
275
276 void transform(const WorldPoint&, const WorldPoint&, const WorldPoint&) override
277 {
278 XABORTM("Thou shalt not arrive here!");
279 }
280
281 WorldPoint map(const WorldPoint&) const override
282 {
283 XABORTM("Thou shalt not arrive here!");
284 return WorldPoint{};
285 }
286
287 WorldPoint project(const WorldPoint&) const override
288 {
289 XABORTM("Thou shalt not arrive here!");
290 return WorldPoint{};
291 }
292
293 CoordType dist(const WorldPoint&) const override
294 {
295 XABORTM("Thou shalt not arrive here!");
296 return CoordType{};
297 }
298
299 CoordType dist(const WorldPoint&, WorldPoint&) const override
300 {
301 XABORTM("Thou shalt not arrive here!");
302 return CoordType{};
303 }
304
305 CoordType signed_dist(const WorldPoint&) const override
306 {
307 XABORTM("Thou shalt not arrive here!");
308 return CoordType{};
309 }
310
312 {
313 XABORTM("Thou shalt not arrive here!");
314 return CoordType{};
315 }
316
317 String get_type() const override
318 {
319 return "CGALSurfaceMeshDummy";
320 }
321
322 void write(std::ostream&, const String&) const override
323 {
324 return;
325 }
326
327#endif
328 }; //class CGALSurfaceMesh
329
330
331/* For now, CGALSurfaceMeshParser should not be used... in any case, lets keep the implementation if it is required someday...
332 template<typename Mesh_, typename ChartReturn_ = ChartBase<Mesh_>, bool enable_ = (Mesh_::shape_dim > 2)>
333 class CGALSurfaceMeshChartParser :
334 public Xml::DummyParser
335 {
336 public:
337 explicit CGALSurfaceMeshChartParser(std::unique_ptr<ChartReturn_>&)
338 {
339 XABORTM("Thou shall not arrive here");
340 }
341 };
342
343 template<typename Mesh_, typename ChartReturn_>
344 class CGALSurfaceMeshChartParser<Mesh_, ChartReturn_, true> :
345 public Xml::MarkupParser
346 {
347 private:
348 typedef CGALSurfaceMesh<Mesh_> ChartType;
349 typedef typename ChartType::CoordType CoordType;
350 std::unique_ptr<ChartBase<Mesh_>>& _chart;
351
352 public:
353 explicit CGALSurfaceMeshChartParser(std::unique_ptr<ChartReturn_>& chart) :
354 _chart(chart)
355 {
356 }
357
358 bool attribs(std::map<String,bool>& attrs) const override
359 {
360 attrs.emplace("filename", true);
361 return true;
362 }
363
364 void create(
365 int iline,
366 const String& sline,
367 const String&,
368 const std::map<String, String>& attrs,
369 bool) override
370 {
371#ifdef FEAT_HAVE_CGAL
372 String filename;
373
374 // try to parse the filename
375 if(!attrs.find("filename")->second.parse(filename))
376 throw Xml::GrammarError(iline, sline, "Failed to parse filename");
377
378 // get filemode
379 CGALFileMode mode;
380 auto split = filename.split_by_charset(".");
381 if(split.back().compare_no_case("off") == 0)
382 {
383 mode = CGALFileMode::fm_off;
384 }
385 else if (split.back().compare_no_case("obj"))
386 {
387 mode = CGALFileMode::fm_obj;
388 }
389 else
390 {
391 XABORTM("ERROR: File extension ." + split.back() + " is not valid/implemented yet.");
392 }
393
395
396 // everything seems fine, let's create the chart then
397 _chart.reset(new ChartType(filename, mode));
398#else
399 std::cout << "ERROR: Trying to parse a CGALMeshpart chart without CGAL enabled\n";
400 FEAT::Runtime::abort();
401 //no unused warnings by casting to void:
402 (void)iline;
403 (void)sline;
404 (void)attrs;
405#endif
406 }
407
408 void close(int, const String&) override
409 {
410 }
411
412 bool content(int, const String&) override
413 {
414 return false;
415 }
416
417 std::shared_ptr<Xml::MarkupParser> markup(int, const String&, const String&) override
418 {
419 return nullptr;
420 }
421 }; // class CGALSurfaceMeshChartParser<...>
422*/
423 } //namespace Atlas
424 } //namespace Geometry
425} //namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
Boundary description by a cgal based surface in 3d.
ChartBase< Mesh_ > BaseClass
The CRTP base class.
BaseClass::PartType PartType
Parttype of Baseclass.
void transform(const WorldPoint &, const WorldPoint &, const WorldPoint &) override
Applies a "proper rigid" transformation onto the chart.
BaseClass::WorldPoint WorldPoint
Vector type for world points.
BaseClass::CoordType CoordType
Floating point type for coordinates.
CoordType signed_dist(const WorldPoint &) const override
Computes the signed distance of a point to this chart.
void adapt(PartType &, const PartType &) const override
Adapts a mesh part using this chart.
WorldPoint project(const WorldPoint &) const override
Projects a point onto the chart.
static constexpr int shape_dim
Dimension of the CGAL mesh.
String get_type() const override
Writes the type as String.
BaseClass::MeshType MeshType
Meshtype of Baseclass.
WorldPoint map(const WorldPoint &) const override
Maps a parameter to a world point.
void write(std::ostream &, const String &) const override
Writes the Chart into a stream in XML format.
void adapt(MeshType &, const PartType &) const override
Adapts a mesh using this chart.
bool can_implicit() const override
Specifies whether the chart can perform implicit projection.
bool can_explicit() const override
Specifies whether the chart can perform explicit projection.
CoordType dist(const WorldPoint &) const override
Computes the distance of a point to this chart.
CoordType dist(const WorldPoint &, WorldPoint &) const override
Computes the distance of a point to this chart.
CoordType signed_dist(const WorldPoint &, WorldPoint &) const override
Computes the signed distance of a point to this chart.
virtual std::size_t bytes() const
Definition: chart.hpp:52
VertexSetType::CoordType CoordType
out coordinate type
Definition: chart.hpp:43
Mesh_ MeshType
our mesh type
Definition: chart.hpp:35
VertexSetType::VertexType WorldPoint
Type of a single vertex.
Definition: chart.hpp:41
Chart CRTP base-class template.
Definition: chart.hpp:354
Wrapper for the CGAL Library.
Definition: cgal.hpp:57
void transform(const TransformMatrix &trafo_mat, const PointType &translation, DataType scale=DataType(1))
bool point_inside(DataType x, DataType y, DataType z) const
Check whether a point is inside the Polyhedron defined at objects' construction.
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...
std::size_t bytes() const
Returns the size in bytes.
PointType closest_point(const PointType &point) const
Returns the nearest point regarding on all input primitives defined at objects' construction.
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
String class implementation.
Definition: string.hpp:46
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_rotation_3d(T_ yaw, T_ pitch, T_ roll)
Sets this matrix to a 3D yaw-pitch-roll rotation matrix.
Tiny Vector class template.
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
static constexpr int world_dim
This is a world_dim dimensional object.
static constexpr bool is_implicit
We support implicit projection.
static constexpr int param_dim
If there was a parametrization, it would be the object's shape dim.
static constexpr bool is_explicit
No explicit map is available in general.