OGS
GeoMapper.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "GeoMapper.h"
5
6#include <algorithm>
7#include <numeric>
8#include <sstream>
9
10#include "BaseLib/Algorithm.h"
11#include "BaseLib/Logging.h"
12#include "GeoLib/AABB.h"
14#include "GeoLib/GEOObjects.h"
15#include "GeoLib/Raster.h"
19#include "MeshLib/Mesh.h"
21#include "MeshLib/Node.h"
23
24namespace MeshGeoToolsLib
25{
27 const std::string& geo_name)
28 : _geo_objects(geo_objects),
29 _geo_name(const_cast<std::string&>(geo_name)),
30 _surface_mesh(nullptr),
31 _grid(nullptr),
32 _raster(nullptr)
33{
34}
35
40
41void GeoMapper::mapOnDEM(std::unique_ptr<GeoLib::Raster const> raster)
42{
43 std::vector<GeoLib::Point*> const* pnts(
44 _geo_objects.getPointVec(_geo_name));
45 if (!pnts)
46 {
47 ERR("Geometry '{:s}' does not exist.", _geo_name);
48 return;
49 }
50 _raster = std::move(raster);
51
52 if (GeoLib::isStation((*pnts)[0]))
53 {
54 mapStationData(*pnts);
55 }
56 else
57 {
58 mapPointDataToDEM(*pnts);
59 }
60}
61
62void GeoMapper::mapOnMesh(MeshLib::Mesh const* const mesh)
63{
64 std::vector<GeoLib::Point*> const* pnts(
65 _geo_objects.getPointVec(_geo_name));
66 if (!pnts)
67 {
68 ERR("Geometry '{:s}' does not exist.", _geo_name);
69 return;
70 }
71
72 // the variable _surface_mesh is reused below, so first the existing
73 // _surface_mesh has to be cleaned up
74 delete _surface_mesh;
75
76 if (mesh->getDimension() < 3)
77 {
78 _surface_mesh = new MeshLib::Mesh(*mesh);
79 }
80 else
81 {
82 Eigen::Vector3d const dir(0, 0, -1);
85 }
86
87 // init grid
88 MathLib::Point3d origin(std::array<double, 3>{{0, 0, 0}});
89 std::vector<MeshLib::Node> flat_nodes;
90 flat_nodes.reserve(_surface_mesh->getNumberOfNodes());
91 // copy nodes and project the copied nodes to the x-y-plane, i.e. set
92 // z-coordinate to zero
93 for (auto n_ptr : _surface_mesh->getNodes())
94 {
95 flat_nodes.emplace_back(*n_ptr);
96 flat_nodes.back()[2] = 0.0;
97 }
98 _grid =
99 new GeoLib::Grid<MeshLib::Node>(flat_nodes.cbegin(), flat_nodes.cend());
100
101 if (GeoLib::isStation((*pnts)[0]))
102 {
103 mapStationData(*pnts);
104 }
105 else
106 {
108 }
109
110 delete _grid;
111}
112
114{
115 std::vector<GeoLib::Point*> const* points(
116 this->_geo_objects.getPointVec(this->_geo_name));
117 if (points == nullptr)
118 {
119 ERR("Geometry '{:s}' not found.", this->_geo_name);
120 return;
121 }
122 std::for_each(points->begin(), points->end(),
123 [value](GeoLib::Point* pnt) { (*pnt)[2] = value; });
124}
125
126void GeoMapper::mapStationData(std::vector<GeoLib::Point*> const& points)
127{
128 double min_val(0);
129 double max_val(0);
130 if (_surface_mesh)
131 {
132 GeoLib::AABB bounding_box(_surface_mesh->getNodes().begin(),
133 _surface_mesh->getNodes().end());
134 min_val = bounding_box.getMinPoint()[2];
135 max_val = bounding_box.getMaxPoint()[2];
136 }
137
138 for (auto* pnt : points)
139 {
140 double offset =
141 (_grid)
142 ? (getMeshElevation((*pnt)[0], (*pnt)[1], min_val, max_val) -
143 (*pnt)[2])
144 : getDemElevation(*pnt);
145
146 if (!GeoLib::isBorehole(pnt))
147 {
148 (*pnt)[2] = offset;
149 continue;
150 }
151 auto const& layers =
152 static_cast<GeoLib::StationBorehole*>(pnt)->getProfile();
153 for (auto* layer_pnt : layers)
154 {
155 (*layer_pnt)[2] = (*layer_pnt)[2] + offset;
156 }
157 }
158}
159
161 std::vector<GeoLib::Point*> const& points) const
162{
163 for (auto* pnt : points)
164 {
165 GeoLib::Point& p(*pnt);
166 p[2] = getDemElevation(p);
167 }
168}
169
171 std::vector<GeoLib::Point*> const& pnts)
172{
173 GeoLib::AABB const aabb(_surface_mesh->getNodes().cbegin(),
174 _surface_mesh->getNodes().cend());
175 auto const [min, max] = aabb.getMinMaxPoints();
176
177 for (auto* pnt : pnts)
178 {
179 // check if pnt is inside of the bounding box of the _surface_mesh
180 // projected onto the y-x plane
181 GeoLib::Point& p(*pnt);
182 if (p[0] < min[0] || max[0] < p[0])
183 {
184 continue;
185 }
186 if (p[1] < min[1] || max[1] < p[1])
187 {
188 continue;
189 }
190
191 p[2] = getMeshElevation(p[0], p[1], min[2], max[2]);
192 }
193}
194
196{
197 double const elevation(_raster->getValueAtPoint(pnt));
198 if (std::abs(elevation - _raster->getHeader().no_data) <
199 std::numeric_limits<double>::epsilon())
200 {
201 return 0.0;
202 }
203 return static_cast<float>(elevation);
204}
205
206double GeoMapper::getMeshElevation(double x, double y, double min_val,
207 double max_val) const
208{
209 const MeshLib::Node* pnt =
210 _grid->getNearestPoint(MathLib::Point3d{{{x, y, 0}}});
211 auto const elements(
212 _surface_mesh->getElementsConnectedToNode(pnt->getID()));
213 std::unique_ptr<GeoLib::Point> intersection;
214
215 for (auto const& element : elements)
216 {
217 if (intersection == nullptr &&
218 element->getGeomType() != MeshLib::MeshElemType::LINE)
219 {
221 *element->getNode(0), *element->getNode(1),
222 *element->getNode(2), GeoLib::Point(x, y, max_val),
223 GeoLib::Point(x, y, min_val));
224 }
225
226 if (intersection == nullptr &&
227 element->getGeomType() == MeshLib::MeshElemType::QUAD)
228 {
230 *element->getNode(0), *element->getNode(2),
231 *element->getNode(3), GeoLib::Point(x, y, max_val),
232 GeoLib::Point(x, y, min_val));
233 }
234 }
235 if (intersection)
236 {
237 return (*intersection)[2];
238 }
239 // if something goes wrong, simply take the elevation of the nearest mesh
240 // node
241 return (*(_surface_mesh->getNode(pnt->getID())))[2];
242}
243
251 std::vector<MeshLib::Element const*> const& elements,
252 MathLib::Point3d const& p)
253{
254 for (auto const elem : elements)
255 {
256 std::unique_ptr<MeshLib::Element> elem_2d(elem->clone());
257 // reset/copy the nodes
258 for (std::size_t k(0); k < elem_2d->getNumberOfNodes(); ++k)
259 {
260 elem_2d->setNode(k, new MeshLib::Node(*elem_2d->getNode(k)));
261 }
262 // project to xy
263 for (std::size_t k(0); k < elem_2d->getNumberOfNodes(); ++k)
264 {
265 (*const_cast<MeshLib::Node*>(elem_2d->getNode(k)))[2] = 0.0;
266 }
267 if (elem_2d->isPntInElement(MathLib::Point3d{{{p[0], p[1], 0.0}}}))
268 {
269 // clean up the copied nodes
270 for (std::size_t k(0); k < elem_2d->getNumberOfNodes(); ++k)
271 {
272 delete elem_2d->getNode(k);
273 }
274 return elem;
275 }
276 // clean up the copied nodes
277 for (std::size_t k(0); k < elem_2d->getNumberOfNodes(); ++k)
278 {
279 delete elem_2d->getNode(k);
280 }
281 }
282 return nullptr;
283}
284
285static std::vector<MathLib::Point3d> computeElementSegmentIntersections(
286 MeshLib::Element const& elem, GeoLib::LineSegment const& segment)
287{
288 std::vector<MathLib::Point3d> element_intersections;
289 for (std::size_t k(0); k < elem.getNumberOfEdges(); ++k)
290 {
291 auto const edge =
292 std::unique_ptr<MeshLib::Element const>(elem.getEdge(k));
293 GeoLib::LineSegment elem_segment{
294 new GeoLib::Point(*dynamic_cast<MathLib::Point3d*>(
295 const_cast<MeshLib::Node*>(edge->getNode(0))),
296 0),
297 new GeoLib::Point(*dynamic_cast<MathLib::Point3d*>(
298 const_cast<MeshLib::Node*>(edge->getNode(1))),
299 0),
300 true};
301 std::vector<MathLib::Point3d> const intersections(
302 GeoLib::lineSegmentIntersect2d(segment, elem_segment));
303 element_intersections.insert(end(element_intersections),
304 begin(intersections), end(intersections));
305 }
306 return element_intersections;
307}
308
309static std::vector<GeoLib::LineSegment> createSubSegmentsForElement(
310 std::vector<MathLib::Point3d> const& intersections,
311 MeshLib::Element const* const beg_elem,
312 MeshLib::Element const* const end_elem, MathLib::Point3d const& beg_pnt,
313 MathLib::Point3d const& end_pnt, MeshLib::Element const* const elem)
314{
315 std::vector<GeoLib::LineSegment> sub_segments;
316 if (intersections.size() > 2)
317 {
318 std::stringstream out;
319 out << "element with id " << elem->getID() << " and seg "
320 << " intersecting at more than two edges\n";
321 for (std::size_t k(0); k < intersections.size(); ++k)
322 {
323 out << k << " " << intersections[k] << "\n";
324 }
325 out << "Could not map segment on element. Aborting.\n";
326 OGS_FATAL("{:s}", out.str());
327 }
328
329 if (intersections.size() == 1 && elem == beg_elem)
330 {
331 // The line segment intersects the element that contains the begin
332 // point of the line segment. Here the first sub line segment is
333 // added.
334 if (MathLib::sqrDist(beg_pnt, intersections[0]) >
335 std::numeric_limits<double>::epsilon())
336 {
337 sub_segments.emplace_back(new GeoLib::Point{beg_pnt, 0},
338 new GeoLib::Point{intersections[0], 0},
339 true);
340 }
341 }
342
343 if (intersections.size() == 1 && elem == end_elem)
344 {
345 // The line segment intersects the element that contains the end
346 // point of the line segment. Here the last sub line segment is
347 // added.
348 if (MathLib::sqrDist(end_pnt, intersections[0]) >
349 std::numeric_limits<double>::epsilon())
350 {
351 sub_segments.emplace_back(new GeoLib::Point{intersections[0], 0},
352 new GeoLib::Point{end_pnt, 0}, true);
353 }
354 }
355
356 if (intersections.size() == 1 && (elem != beg_elem && elem != end_elem))
357 {
358 // Since the line segment enters and leaves the element in the same
359 // point there isn't any need to insert a new sub line segment.
360 return sub_segments;
361 }
362
363 // create sub segment for the current element
364 if (intersections.size() == 2)
365 {
366 sub_segments.emplace_back(new GeoLib::Point{intersections[0], 0},
367 new GeoLib::Point{intersections[1], 0}, true);
368 }
369 return sub_segments;
370}
371
372static std::vector<GeoLib::LineSegment> mapLineSegment(
373 GeoLib::LineSegment const& segment,
374 std::vector<MeshLib::Element const*> const& surface_elements,
375 MeshLib::Element const* const beg_elem,
376 MeshLib::Element const* const end_elem)
377{
378 std::vector<GeoLib::LineSegment> sub_segments;
379 MathLib::Point3d const& beg_pnt(segment.getBeginPoint());
380 MathLib::Point3d const& end_pnt(segment.getEndPoint());
381
382 for (auto const elem : surface_elements)
383 {
384 // compute element-segment-intersections (2d in x-y-plane)
385 std::vector<MathLib::Point3d> element_intersections(
386 computeElementSegmentIntersections(*elem, segment));
387 if (element_intersections.empty())
388 {
389 continue;
390 }
391
392 BaseLib::makeVectorUnique(element_intersections);
393
394 std::vector<GeoLib::LineSegment> sub_seg_elem(
395 createSubSegmentsForElement(element_intersections, beg_elem,
396 end_elem, beg_pnt, end_pnt, elem));
397 sub_segments.insert(sub_segments.end(), sub_seg_elem.begin(),
398 sub_seg_elem.end());
399 }
400
401 // beg_elem == nullptr means there isn't any element corresponding to the
402 // beg_pnt and as a consequence the above algorithm doesn't insert a sub
403 // segment
404 if (beg_elem == nullptr)
405 {
406 auto min_dist_segment = std::min_element(
407 sub_segments.begin(), sub_segments.end(),
408 [&beg_pnt](GeoLib::LineSegment const& seg0,
409 GeoLib::LineSegment const& seg1)
410 {
411 // min dist for segment 0
412 const double d0(
413 std::min(MathLib::sqrDist(beg_pnt, seg0.getBeginPoint()),
414 MathLib::sqrDist(beg_pnt, seg0.getEndPoint())));
415 // min dist for segment 1
416 const double d1(
417 std::min(MathLib::sqrDist(beg_pnt, seg1.getBeginPoint()),
418 MathLib::sqrDist(beg_pnt, seg1.getEndPoint())));
419 return d0 < d1;
420 });
421 GeoLib::Point* pnt{
422 MathLib::sqrDist(beg_pnt, min_dist_segment->getBeginPoint()) <
423 MathLib::sqrDist(beg_pnt, min_dist_segment->getEndPoint())
424 ? new GeoLib::Point{min_dist_segment->getBeginPoint()}
425 : new GeoLib::Point{min_dist_segment->getEndPoint()}};
426 sub_segments.emplace_back(new GeoLib::Point{beg_pnt, 0}, pnt, true);
427 }
428 // sort all sub segments for the given segment (beg_pnt, end_pnt)
429 GeoLib::sortSegments(beg_pnt, sub_segments);
430
431 sub_segments.erase(std::unique(sub_segments.begin(), sub_segments.end()),
432 sub_segments.end());
433
434 return sub_segments;
435}
436
439{
440 // create plane equation: n*p = d
441 auto const& p = elem.getNode(0)->asEigenVector3d();
442 Eigen::Vector3d const n(MeshLib::FaceRule::getSurfaceNormal(elem));
443 if (n[2] == 0.0)
444 { // vertical plane, z coordinate is arbitrary
445 q[2] = p[2];
446 }
447 else
448 {
449 double const d(n.dot(p));
450 q[2] = (d - n[0] * q[0] - n[1] * q[1]) / n[2];
451 }
452}
453
454static std::vector<MeshLib::Element const*>
456 MeshLib::MeshElementGrid const& mesh_element_grid,
457 GeoLib::LineSegment const& segment)
458{
459 GeoLib::LineSegment seg_deep_copy(
460 new GeoLib::Point(segment.getBeginPoint()),
461 new GeoLib::Point(segment.getEndPoint()), true);
462 // modify z coordinates such that all surface elements around the line
463 // segment are found
464 seg_deep_copy.getBeginPoint()[2] = mesh_element_grid.getMinPoint()[2];
465 seg_deep_copy.getEndPoint()[2] = mesh_element_grid.getMaxPoint()[2];
466 std::array<MathLib::Point3d, 2> const pnts{
467 {seg_deep_copy.getBeginPoint(), seg_deep_copy.getEndPoint()}};
468 GeoLib::AABB aabb(pnts.cbegin(), pnts.cend());
469
470 // TODO TF: remove after getElementsInVolume interface change
471 auto convert_to_Point3d = [](Eigen::Vector3d const& v) {
472 return MathLib::Point3d{std::array{v[0], v[1], v[2]}};
473 };
474
475 auto const min = convert_to_Point3d(aabb.getMinPoint());
476 auto const max = convert_to_Point3d(aabb.getMaxPoint());
477 auto candidate_elements = mesh_element_grid.getElementsInVolume(min, max);
478
479 // make candidate elements unique
480 BaseLib::makeVectorUnique(candidate_elements);
481
482 return candidate_elements;
483}
484
486 MeshLib::Element const& elem, double rel_eps)
487{
488 // values will be initialized within computeSqrNodeDistanceRange
489 auto const [sqr_min, sqr_max] = MeshLib::computeSqrNodeDistanceRange(elem);
490
491 double const sqr_eps(rel_eps * rel_eps * sqr_min);
492 for (std::size_t k(0); k < elem.getNumberOfNodes(); ++k)
493 {
494 auto const& node(*elem.getNode(k));
495 double const sqr_dist_2d(MathLib::sqrDist2d(p, node));
496 if (sqr_dist_2d < sqr_eps)
497 {
498#ifdef DEBUG_GEOMAPPER
499 std::stringstream out;
500 out.precision(std::numeric_limits<double>::max_digits10);
501 out << "Segment point snapped from " << p;
502#endif
503 p = node;
504#ifdef DEBUG_GEOMAPPER
505 out << "to " << p;
506 DBUG("{:s}", out.str());
507#endif
508 return true;
509 }
510 }
511 return false;
512}
513
517 std::vector<GeoLib::LineSegment> const& sub_segments)
518{
519 std::size_t const j(segment_it.getSegmentNumber());
520 std::size_t new_pnts_cnt(0);
521 for (auto const& segment : sub_segments)
522 {
523 auto const begin_id(points.push_back(
524 new GeoLib::Point(segment.getBeginPoint(), points.size())));
525 if (ply.insertPoint(j + new_pnts_cnt + 1, begin_id))
526 {
527 new_pnts_cnt++;
528 }
529 auto const end_id(points.push_back(
530 new GeoLib::Point(segment.getEndPoint(), points.size())));
531 if (ply.insertPoint(j + new_pnts_cnt + 1, end_id))
532 {
533 new_pnts_cnt++;
534 }
535 }
536 segment_it += new_pnts_cnt;
537}
538
540 GeoLib::Polyline& ply,
541 GeoLib::PointVec& orig_points,
542 MeshLib::MeshElementGrid const& mesh_element_grid)
543{
544 // for each segment ...
545 for (auto segment_it(ply.begin()); segment_it != ply.end(); ++segment_it)
546 {
548 mesh_element_grid, *segment_it));
549
550 auto mapPoint = [&candidate_elements](MathLib::Point3d& p)
551 {
552 auto const* elem(
553 findElementContainingPointXY(candidate_elements, p));
554 if (elem)
555 {
556 if (!snapPointToElementNode(p, *elem, 1e-3))
557 {
558 mapPointOnSurfaceElement(*elem, p);
559 }
560 }
561 return elem;
562 };
563
564 // map segment begin and end point
565 auto const* beg_elem(mapPoint((*segment_it).getBeginPoint()));
566 auto const* end_elem(mapPoint((*segment_it).getEndPoint()));
567
568 // Since the mapping of the segment begin and end points the coordinates
569 // changed. The internal data structures of PointVec are possibly
570 // invalid and hence it is necessary to re-create them.
571 orig_points.resetInternalDataStructures();
572
573 if (beg_elem == end_elem)
574 {
575 // TODO: handle cases: beg_elem == end_elem == nullptr
576 // There are further checks necessary to determine which case we are
577 // in:
578 // 1. beg_elem == end_elem and the segment intersects elements
579 // 2. beg_elem == end_elem and the segment does not intersect any
580 // element, i.e., the segment is located outside of the mesh area
581 //
582 // Case 1 needs additional work.
583 continue;
584 }
585
586 // map the line segment (and if necessary for the mapping partition it)
587 std::vector<GeoLib::LineSegment> sub_segments(mapLineSegment(
588 *segment_it, candidate_elements, beg_elem, end_elem));
589
590 if (sub_segments.empty())
591 {
592 continue;
593 }
594
595 // The case sub_segment.size() == 1 is already handled above.
596
597 if (sub_segments.size() > 1)
598 {
599 insertSubSegments(ply, orig_points, segment_it, sub_segments);
600 }
601 }
602}
603
605{
606 // 1. extract surface
607 delete _surface_mesh;
608
609 if (mesh.getDimension() < 3)
610 {
611 _surface_mesh = new MeshLib::Mesh(mesh);
612 }
613 else
614 {
615 Eigen::Vector3d const dir({0, 0, -1});
617 mesh, dir, 90 + 1e-6);
618 }
619
620 // 2. compute mesh grid for surface
621 MeshLib::MeshElementGrid const mesh_element_grid(*_surface_mesh);
622
623 // 3. map each polyline
624 auto org_lines(_geo_objects.getPolylineVec(_geo_name));
625 auto org_points(_geo_objects.getPointVecObj(_geo_name));
626 for (auto org_line : *org_lines)
627 {
628 mapPolylineOnSurfaceMesh(*org_line, *org_points, mesh_element_grid);
629 }
630}
631
632} // end namespace MeshGeoToolsLib
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:176
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:169
MinMaxPoints getMinMaxPoints() const
Definition AABB.h:163
Container class for geometric objects.
Definition GEOObjects.h:46
GeoLib::Point const & getBeginPoint() const
GeoLib::Point const & getEndPoint() const
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition PointVec.h:25
std::size_t push_back(Point *pnt)
Definition PointVec.cpp:124
void resetInternalDataStructures()
Definition PointVec.cpp:250
std::size_t getSegmentNumber() const
Definition Polyline.cpp:376
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
virtual bool insertPoint(std::size_t pos, std::size_t pnt_id)
Definition Polyline.cpp:44
SegmentIterator begin() const
Definition Polyline.h:177
SegmentIterator end() const
Definition Polyline.h:179
A borehole as a geometric object.
std::size_t size() const
Definition TemplateVec.h:88
std::size_t getID() const
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55
GeoMapper(GeoLib::GEOObjects &geo_objects, const std::string &geo_name)
Definition GeoMapper.cpp:26
void mapToConstantValue(double value)
Maps geometry to a constant elevation value.
void mapOnDEM(std::unique_ptr< GeoLib::Raster const > raster)
Maps geometry based on a raster file.
Definition GeoMapper.cpp:41
void mapPointDataToDEM(std::vector< GeoLib::Point * > const &points) const
Mapping points on a raster.
std::string & _geo_name
Definition GeoMapper.h:74
void mapStationData(std::vector< GeoLib::Point * > const &points)
Mapping stations, boreholes on a raster or mesh.
double getMeshElevation(double x, double y, double min_val, double max_val) const
GeoLib::GEOObjects & _geo_objects
Definition GeoMapper.h:73
float getDemElevation(GeoLib::Point const &pnt) const
Returns the elevation at Point (x,y) based on a raster.
std::unique_ptr< GeoLib::Raster const > _raster
only necessary for mapping on DEM
Definition GeoMapper.h:81
MeshLib::Mesh * _surface_mesh
only necessary for mapping on mesh
Definition GeoMapper.h:77
void mapOnMesh(MeshLib::Mesh const *const mesh)
Definition GeoMapper.cpp:62
void advancedMapOnMesh(MeshLib::Mesh const &mesh)
GeoLib::Grid< MeshLib::Node > * _grid
Definition GeoMapper.h:78
void mapPointDataToMeshSurface(std::vector< GeoLib::Point * > const &pnts)
Mapping points on mesh.
virtual const Element * getEdge(unsigned i) const =0
Returns the i-th edge of the element.
virtual unsigned getNumberOfNodes() const =0
virtual const Node * getNode(unsigned idx) const =0
virtual unsigned getNumberOfEdges() const =0
Get the number of edges for this element.
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
static Eigen::Vector3d getSurfaceNormal(Element const &e)
Returns the surface normal of a 2D element.
Definition FaceRule.cpp:33
Eigen::Vector3d const & getMinPoint() const
std::vector< MeshLib::Element const * > getElementsInVolume(POINT const &min, POINT const &max) const
Eigen::Vector3d const & getMaxPoint() const
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
static MeshLib::Mesh * getMeshSurface(const MeshLib::Mesh &subsfc_mesh, Eigen::Vector3d const &dir, double angle, std::string_view subsfc_node_id_prop_name="", std::string_view subsfc_element_id_prop_name="", std::string_view face_id_prop_name="")
void makeVectorUnique(std::vector< T > &v)
Definition Algorithm.h:173
bool isStation(GeoLib::Point const *pnt)
Definition Station.cpp:66
void sortSegments(MathLib::Point3d const &seg_beg_pnt, std::vector< GeoLib::LineSegment > &sub_segments)
bool isBorehole(GeoLib::Point const *pnt)
std::vector< MathLib::Point3d > lineSegmentIntersect2d(GeoLib::LineSegment const &ab, GeoLib::LineSegment const &cd)
std::unique_ptr< GeoLib::Point > triangleLineIntersection(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c, MathLib::Point3d const &p, MathLib::Point3d const &q)
double sqrDist2d(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.h:114
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19
static std::vector< GeoLib::LineSegment > createSubSegmentsForElement(std::vector< MathLib::Point3d > const &intersections, MeshLib::Element const *const beg_elem, MeshLib::Element const *const end_elem, MathLib::Point3d const &beg_pnt, MathLib::Point3d const &end_pnt, MeshLib::Element const *const elem)
static bool snapPointToElementNode(MathLib::Point3d &p, MeshLib::Element const &elem, double rel_eps)
static std::vector< MathLib::Point3d > computeElementSegmentIntersections(MeshLib::Element const &elem, GeoLib::LineSegment const &segment)
static void insertSubSegments(GeoLib::Polyline &ply, GeoLib::PointVec &points, GeoLib::Polyline::SegmentIterator &segment_it, std::vector< GeoLib::LineSegment > const &sub_segments)
static void mapPointOnSurfaceElement(MeshLib::Element const &elem, MathLib::Point3d &q)
static std::vector< MeshLib::Element const * > getCandidateElementsForLineSegmentIntersection(MeshLib::MeshElementGrid const &mesh_element_grid, GeoLib::LineSegment const &segment)
static void mapPolylineOnSurfaceMesh(GeoLib::Polyline &ply, GeoLib::PointVec &orig_points, MeshLib::MeshElementGrid const &mesh_element_grid)
static MeshLib::Element const * findElementContainingPointXY(std::vector< MeshLib::Element const * > const &elements, MathLib::Point3d const &p)
static std::vector< GeoLib::LineSegment > mapLineSegment(GeoLib::LineSegment const &segment, std::vector< MeshLib::Element const * > const &surface_elements, MeshLib::Element const *const beg_elem, MeshLib::Element const *const end_elem)
std::pair< double, double > computeSqrNodeDistanceRange(MeshLib::Element const &element, bool const check_allnodes)
Compute the minimum and maximum node distances for this element.
Definition Element.cpp:143