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