OGS
createSurface.cpp
Go to the documentation of this file.
1
12#include "createSurface.h"
13
14#include <cstdio>
15#include <list>
16
18#include "BaseLib/Logging.h"
19#include "BaseLib/StringTools.h"
21#include "GeoLib/GEOObjects.h"
22#include "GeoLib/Point.h"
23#include "GeoLib/Polygon.h"
24#include "GeoLib/Polyline.h"
25#include "GeoLib/Surface.h"
26#include "GeoLib/Triangle.h"
28#include "MeshLib/Mesh.h"
30
31namespace FileIO
32{
34 GeoLib::GEOObjects& geometries,
35 std::string const& geometry_name,
36 std::string const& gmsh_binary)
37{
38 if (!ply.isClosed())
39 {
40 WARN("Error in createSurface() - Polyline is not closed.");
41 return false;
42 }
43
44 if (ply.getNumberOfPoints() <= 2)
45 {
46 WARN(
47 "Error in createSurface() - Polyline consists of less "
48 "than three points and therefore cannot be triangulated.");
49 return false;
50 }
51
52 // create new GEOObjects and insert a copy of the polyline
53 std::vector<GeoLib::Point*> polyline_points;
55 auto ply_points = ply.getPointsVec();
56 std::transform(ply_points.begin(), ply_points.end(),
57 std::back_inserter(polyline_points),
58 [](auto const* p) { return new GeoLib::Point(*p); });
59 std::string ply_name = "temporary_polyline_name";
60 geo.addPointVec(std::move(polyline_points), ply_name,
61 std::map<std::string, std::size_t>{});
62 auto polyline =
63 std::make_unique<GeoLib::Polyline>(*geo.getPointVec(ply_name));
64 for (std::size_t k(0); k < ply.getNumberOfPoints(); ++k)
65 {
66 polyline->addPoint(ply.getPointID(k));
67 }
68 std::vector<GeoLib::Polyline*> polylines;
69 polylines.push_back(polyline.release());
70 geo.addPolylineVec(std::move(polylines), ply_name,
72
73 // use GMSHInterface to create a mesh from the closed polyline
74 auto const geo_names = geo.getGeometryNames();
77 0.0, 0, geo_names, false, false);
78
79 // write to random file in temp directory
80 auto geo_file = std::filesystem::temp_directory_path() /=
82 auto msh_file = std::filesystem::temp_directory_path() /=
84
86 // Using GMSH's vtk output here so we don't have to deal with GMSH and it's
87 // various file format versions here
88 std::string gmsh_command = "\"" + gmsh_binary +
89 "\" -2 -algo meshadapt -format vtk -o " +
90 msh_file.string() + " " + geo_file.string();
91
92 int const gmsh_return_value = std::system(gmsh_command.c_str());
93 if (gmsh_return_value != 0)
94 {
95 WARN("Call to '{:s}' returned non-zero value {:d}.", gmsh_command,
96 gmsh_return_value);
97 }
98 auto const* surface_mesh = MeshLib::IO::readMeshFromFile(
99 msh_file.string(), true /* compute_element_neighbors */);
100 if (!surface_mesh)
101 {
102 WARN("The surface mesh could not be created.");
103 return false;
104 }
105 if (!(std::filesystem::remove(geo_file) &&
106 std::filesystem::remove(msh_file)))
107 {
108 WARN("Could not remove temporary files in createSurface.");
109 }
110
111 // convert the surface mesh into a geometric surface
112 if (!MeshToolsLib::convertMeshToGeo(*surface_mesh, geometries,
113 std::numeric_limits<double>::epsilon()))
114 {
115 WARN("The surface mesh could not be converted to a geometry.");
116 return false;
117 }
118 std::string merged_geometry_name("geometry_with_surfaces");
119 geometries.mergeGeometries({geometry_name, surface_mesh->getName()},
120 merged_geometry_name);
121 geometries.removeSurfaceVec(geometry_name);
122 geometries.removePolylineVec(geometry_name);
123 geometries.removePointVec(geometry_name);
124 geometries.removeSurfaceVec(surface_mesh->getName());
125 geometries.removePolylineVec(surface_mesh->getName());
126 geometries.removePointVec(surface_mesh->getName());
127 geometries.renameGeometry(merged_geometry_name, geometry_name);
128
129 return true;
130}
131
132std::unique_ptr<GeoLib::Surface> createSurfaceWithEarClipping(
133 GeoLib::Polyline const& line)
134{
135 if (!line.isClosed())
136 {
137 WARN("Error in Surface::createSurface() - Polyline is not closed.");
138 return nullptr;
139 }
140
141 if (line.getNumberOfPoints() <= 2)
142 {
143 WARN(
144 "Error in Surface::createSurface() - Polyline consists of less "
145 "than three points and therefore cannot be triangulated.");
146 return nullptr;
147 }
148
149 // create empty surface
150 auto sfc = std::make_unique<GeoLib::Surface>(line.getPointsVec());
151 auto polygon = std::make_unique<GeoLib::Polygon>(GeoLib::Polygon(line));
152 std::list<GeoLib::Polygon*> const& list_of_simple_polygons =
153 polygon->computeListOfSimplePolygons();
154
155 for (auto const& simple_polygon : list_of_simple_polygons)
156 {
157 std::list<GeoLib::Triangle> triangles;
158 GeoLib::EarClippingTriangulation(*simple_polygon, triangles);
159
160 // add Triangles to Surface
161 for (auto const& t : triangles)
162 {
163 sfc->addTriangle(t[0], t[1], t[2]);
164 }
165 }
166 if (sfc->getNumberOfTriangles() == 0)
167 {
168 WARN(
169 "Surface::createSurface(): Triangulation does not contain any "
170 "triangles.");
171 return nullptr;
172 }
173 return sfc;
174}
175
176} // namespace FileIO
Definition of the EarClippingTriangulation class.
Definition of the GEOObjects class.
Definition of the Point class.
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Definition of the Mesh class.
Definition of the Polygon class.
Definition of the PolyLine class.
Definition of string helper functions.
std::string writeToString()
Writes the object to a string.
Definition Writer.cpp:31
Reads and writes GMSH-files to and from OGS data structures.
Container class for geometric objects.
Definition GEOObjects.h:57
std::vector< std::string > getGeometryNames() const
Returns the names of all geometry vectors.
void addPolylineVec(std::vector< Polyline * > &&lines, std::string const &name, PolylineVec::NameIdMap &&ply_names)
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()))
void renameGeometry(std::string const &old_name, std::string const &new_name)
bool removePointVec(const std::string &name)
bool removeSurfaceVec(const std::string &name)
int mergeGeometries(std::vector< std::string > const &geo_names, std::string &merged_geo_name)
bool removePolylineVec(const std::string &name)
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:40
std::size_t getPointID(std::size_t const i) const
Definition Polyline.cpp:160
std::size_t getNumberOfPoints() const
Definition Polyline.cpp:109
bool isClosed() const
Definition Polyline.cpp:119
std::vector< Point * > const & getPointsVec() const
Definition Polyline.cpp:185
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:41
Definition of mesh to geometry conversion.
int writeStringToFile(std::string_view content, std::filesystem::path const &file_path)
Definition Writer.cpp:45
std::string randomString(std::size_t const length)
Returns a random string of the given length containing just a-z,A-Z,0-9.
@ FixedMeshDensity
set the parameter with a fixed value
bool createSurface(GeoLib::Polyline const &ply, GeoLib::GEOObjects &geometries, std::string const &geometry_name, std::string const &gmsh_binary)
std::unique_ptr< GeoLib::Surface > createSurfaceWithEarClipping(GeoLib::Polyline const &line)
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
bool convertMeshToGeo(const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects, double const eps)
Definition of readMeshFromFile function.