OGS
convertMeshToGeo.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 "convertMeshToGeo.h"
5
6#include "BaseLib/Logging.h"
7#include "GeoLib/GEOObjects.h"
8#include "GeoLib/Surface.h"
9#include "GeoLib/Triangle.h"
12#include "MeshLib/Mesh.h"
15
16namespace
17{
21 double const eps,
22 GeoLib::GEOObjects& geo_objects)
23{
24 std::vector<GeoLib::Point*> points;
25 points.reserve(mesh.getNumberOfNodes());
26
27 std::transform(begin(mesh.getNodes()), end(mesh.getNodes()),
28 std::back_inserter(points),
29 [](MeshLib::Node const* node_ptr)
30 { return new GeoLib::Point(*node_ptr, node_ptr->getID()); });
31
32 auto geoobject_name = mesh.getName(); // Possibly modified when adding
33 // points to the geo objects.
34 geo_objects.addPointVec(std::move(points), geoobject_name, {}, eps);
35 return geoobject_name;
36}
37
39 std::vector<std::size_t> const& id_map,
40 GeoLib::Surface& surface)
41{
43 {
44 surface.addTriangle(id_map[getNodeIndex(e, 0)],
45 id_map[getNodeIndex(e, 1)],
46 id_map[getNodeIndex(e, 2)]);
47 return;
48 }
50 {
51 surface.addTriangle(id_map[getNodeIndex(e, 0)],
52 id_map[getNodeIndex(e, 1)],
53 id_map[getNodeIndex(e, 2)]);
54 surface.addTriangle(id_map[getNodeIndex(e, 0)],
55 id_map[getNodeIndex(e, 2)],
56 id_map[getNodeIndex(e, 3)]);
57 return;
58 }
59 // all other element types are ignored (i.e. lines)
60};
61
62} // namespace
63
64namespace MeshToolsLib
65{
67 GeoLib::GEOObjects& geo_objects,
68 double const eps)
69{
70 if (mesh.getDimension() != 2)
71 {
72 ERR("Mesh to geometry conversion is only working for 2D meshes.");
73 return false;
74 }
75
76 // Special handling of the bounds in case there are no materialIDs present.
77 auto get_material_ids_and_bounds = [&]()
78 -> std::tuple<MeshLib::PropertyVector<int> const*, std::pair<int, int>>
79 {
80 auto const materialIds = materialIDs(mesh);
81 if (!materialIds)
82 {
83 return std::make_tuple(nullptr, std::make_pair(0, 0));
84 }
85
86 auto const bounds =
88 if (!bounds)
89 {
91 "Could not get minimum/maximum ranges values for the "
92 "MaterialIDs property in the mesh '{:s}'.",
93 mesh.getName());
94 }
95 return std::make_tuple(materialIds, *bounds);
96 };
97
98 auto const [materialIds, bounds] = get_material_ids_and_bounds();
99 // elements to surface triangles conversion
100 const unsigned nMatGroups(bounds.second - bounds.first + 1);
101 std::vector<GeoLib::Surface*> sfcs;
102 sfcs.reserve(nMatGroups);
103 std::string const geoobject_name =
104 convertMeshNodesToGeoPoints(mesh, eps, geo_objects);
105 auto const& points = *geo_objects.getPointVec(geoobject_name);
106 for (unsigned i = 0; i < nMatGroups; ++i)
107 {
108 sfcs.push_back(new GeoLib::Surface(points));
109 }
110
111 const std::vector<std::size_t>& id_map(
112 geo_objects.getPointVecObj(geoobject_name)->getIDMap());
113 const std::vector<MeshLib::Element*>& elements = mesh.getElements();
114 const std::size_t nElems(mesh.getNumberOfElements());
115
116 for (unsigned i = 0; i < nElems; ++i)
117 {
118 auto surfaceId = !materialIds ? 0 : ((*materialIds)[i] - bounds.first);
119 addElementToSurface(*elements[i], id_map, *sfcs[surfaceId]);
120 }
121
122 std::for_each(sfcs.begin(), sfcs.end(),
123 [](GeoLib::Surface*& sfc)
124 {
125 if (sfc->getNumberOfTriangles() == 0)
126 {
127 delete sfc;
128 sfc = nullptr;
129 }
130 });
131 auto sfcs_end = std::remove(sfcs.begin(), sfcs.end(), nullptr);
132 sfcs.erase(sfcs_end, sfcs.end());
133
134 geo_objects.addSurfaceVec(std::move(sfcs), geoobject_name,
136 return true;
137}
138
140 const std::string& mesh_name,
141 double eps)
142{
143 // convert to a mesh including duplicated nodes
144 std::vector<MeshLib::Node*> nodes;
145 std::vector<MeshLib::Element*> elements;
146 std::size_t nodeId = 0;
147 for (std::size_t i = 0; i < sfc.getNumberOfTriangles(); i++)
148 {
149 auto* tri = sfc[i];
150 auto** tri_nodes = new MeshLib::Node*[3];
151 for (unsigned j = 0; j < 3; j++)
152 {
153 tri_nodes[j] =
154 new MeshLib::Node(tri->getPoint(j)->data(), nodeId++);
155 }
156 elements.push_back(new MeshLib::Tri(tri_nodes, i));
157 for (unsigned j = 0; j < 3; j++)
158 {
159 nodes.push_back(tri_nodes[j]);
160 }
161 }
162 MeshLib::Mesh mesh_with_duplicated_nodes(
163 mesh_name, nodes, elements, true /* compute_element_neighbors */);
164
165 // remove duplicated nodes
166 MeshToolsLib::MeshRevision rev(mesh_with_duplicated_nodes);
167 return rev.simplifyMesh(mesh_with_duplicated_nodes.getName(), eps);
168}
169
170} // namespace MeshToolsLib
#define OGS_FATAL(...)
Definition Error.h:19
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Container class for geometric objects.
Definition GEOObjects.h:46
const std::vector< Point * > * getPointVec(const std::string &name) const
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
const PointVec * getPointVecObj(const std::string &name) const
const std::vector< std::size_t > & getIDMap() const
Definition PointVec.h:86
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
std::size_t getNumberOfTriangles() const
Definition Surface.cpp:76
void addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c)
Definition Surface.cpp:43
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:30
virtual MeshElemType getGeomType() const =0
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:97
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:94
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:88
static std::optional< std::pair< T, T > > const getValueBounds(MeshLib::PropertyVector< T > const &property)
MeshLib::Mesh * simplifyMesh(const std::string &new_mesh_name, double eps, unsigned min_elem_dim=1) const
TemplateElement< MeshLib::TriRule3 > Tri
Definition Tri.h:15
bool convertMeshToGeo(const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects, double const eps)
MeshLib::Mesh * convertSurfaceToMesh(const GeoLib::Surface &sfc, const std::string &mesh_name, double eps)
void addElementToSurface(MeshLib::Element const &e, std::vector< std::size_t > const &id_map, GeoLib::Surface &surface)
std::string convertMeshNodesToGeoPoints(MeshLib::Mesh const &mesh, double const eps, GeoLib::GEOObjects &geo_objects)