OGS
generateGeometry.cpp
Go to the documentation of this file.
1
11// ThirdParty
12#include <tclap/CmdLine.h>
13
14#ifdef USE_PETSC
15#include <mpi.h>
16#endif
17
18#include <numeric>
19
20#include "GeoLib/GEOObjects.h"
22#include "GeoLib/Point.h"
23#include "GeoLib/Polyline.h"
24#include "GeoLib/Utils.h"
25#include "InfoLib/GitInfo.h"
26
27std::tuple<std::vector<GeoLib::Polyline*>, GeoLib::PolylineVec::NameIdMap>
28appendNamedPolyline(std::unique_ptr<GeoLib::Polyline> polyline,
29 std::string&& polyline_name)
30{
31 std::vector<GeoLib::Polyline*> lines;
33
34 lines.push_back(polyline.release());
35 name_map[std::move(polyline_name)] = lines.size() - 1;
36
37 return {lines, name_map};
38}
39
41 std::string&& point_name,
42 std::string& geometry_name,
43 GeoLib::GEOObjects& geometry)
44{
45 std::vector<GeoLib::Point*> points;
46 points.push_back(new GeoLib::Point{point});
47
48 GeoLib::PointVec::NameIdMap name_map{{std::move(point_name), 0}};
49
50 geometry.addPointVec(std::move(points), geometry_name, std::move(name_map));
51}
52
54 GeoLib::Point const& point1,
55 int const number_of_subdivisions,
56 std::string&& polyline_name,
57 std::string& geometry_name,
58 GeoLib::GEOObjects& geometry)
59{
60 auto intermediate_points = GeoLib::generateEquidistantPoints(
61 point0, point1, number_of_subdivisions);
62 std::vector<GeoLib::Point*> points(intermediate_points.begin(),
63 intermediate_points.end());
64 geometry.addPointVec(std::move(points), geometry_name,
66 auto const& point_vec = *geometry.getPointVecObj(geometry_name);
67
68 std::vector<std::size_t> polyline_point_ids(point_vec.getVector().size());
69 std::iota(begin(polyline_point_ids), end(polyline_point_ids), 0);
70
71 auto [lines, name_map] = appendNamedPolyline(
72 GeoLib::createPolyline(point_vec, std::move(polyline_point_ids)),
73 std::move(polyline_name));
74
75 geometry.addPolylineVec(std::move(lines), geometry_name,
76 std::move(name_map));
77}
78
79std::vector<GeoLib::Point*> generateQuadPoints(
80 std::array<GeoLib::Point, 4> const& points,
81 std::array<int, 4> const& number_of_subdivisions_per_edge)
82{
83 std::vector<GeoLib::Point*> quad_points;
84
85 auto addPointsOnLine = [&quad_points](auto const& begin, auto const& end,
86 auto const number_of_subdivisions)
87 {
88 auto intermediate_points = GeoLib::generateEquidistantPoints(
89 begin, end, number_of_subdivisions);
90 quad_points.insert(quad_points.end(), intermediate_points.begin(),
91 --intermediate_points.end());
92 delete intermediate_points.back(); // Release last point, other points
93 // are managed by GEOObjects.
94 };
95
96 addPointsOnLine(points[0], points[1], number_of_subdivisions_per_edge[0]);
97 addPointsOnLine(points[1], points[2], number_of_subdivisions_per_edge[1]);
98 addPointsOnLine(points[2], points[3], number_of_subdivisions_per_edge[2]);
99 addPointsOnLine(points[3], points[0], number_of_subdivisions_per_edge[3]);
100
101 return quad_points;
102}
103
105 GeoLib::Point const& point1,
106 int const number_of_subdivisions_first_x,
107 int const number_of_subdivisions_second_x,
108 int const number_of_subdivisions_first_y,
109 int const number_of_subdivisions_second_y,
110 int const number_of_subdivisions_first_z,
111 int const number_of_subdivisions_second_z,
112 std::string&& quad_name, std::string& geometry_name,
113 GeoLib::GEOObjects& geometry)
114{
115 std::array<GeoLib::Point, 4> edge_points;
116 edge_points[0] = point0;
117 edge_points[2] = point1;
118 std::array<int, 4> number_of_subdivisions;
119 if (point0[0] != point1[0] && point0[1] != point1[1] &&
120 point0[2] == point1[2])
121 {
122 // quad in xy plane
123 edge_points[1] =
124 GeoLib::Point{point1[0], point0[1], point0[2]}; // right front
125 edge_points[3] =
126 GeoLib::Point{point0[0], point1[1], point0[2]}; // left back
127 number_of_subdivisions = {
128 number_of_subdivisions_first_x, number_of_subdivisions_first_y,
129 number_of_subdivisions_second_x, number_of_subdivisions_second_y};
130 }
131 else if (point0[0] != point1[0] && point0[1] == point1[1] &&
132 point0[2] != point1[2])
133 {
134 // quad in xz plane
135 edge_points[1] =
136 GeoLib::Point{point1[0], point1[1], point0[2]}; // lower right
137 edge_points[3] =
138 GeoLib::Point{point0[0], point0[1], point1[2]}; // upper left
139 number_of_subdivisions = {
140 number_of_subdivisions_first_x, number_of_subdivisions_first_z,
141 number_of_subdivisions_second_x, number_of_subdivisions_second_z};
142 }
143 else if (point0[0] == point1[0] && point0[1] != point1[1] &&
144 point0[2] != point1[2])
145 {
146 // quad in yz plane
147 edge_points[1] =
148 GeoLib::Point{point1[0], point1[1], point0[2]}; // lower back
149 edge_points[3] =
150 GeoLib::Point{point0[0], point0[1], point1[2]}; // upper front
151 number_of_subdivisions = {
152 number_of_subdivisions_first_y, number_of_subdivisions_first_z,
153 number_of_subdivisions_second_y, number_of_subdivisions_second_z};
154 }
155 else
156 {
157 ERR("Input coordinates don't describe an axis aligned polyline or "
158 "quad.");
159 return EXIT_FAILURE;
160 }
161
162 geometry.addPointVec(
163 generateQuadPoints(edge_points, number_of_subdivisions), geometry_name,
165 auto const& point_vec = *geometry.getPointVecObj(geometry_name);
166
167 std::vector<std::size_t> polyline_point_ids(point_vec.getVector().size() +
168 1);
169 std::iota(begin(polyline_point_ids), end(polyline_point_ids), 0);
170 polyline_point_ids.back() = polyline_point_ids.front();
171
172 auto [lines, name_map] = appendNamedPolyline(
173 GeoLib::createPolyline(point_vec, std::move(polyline_point_ids)),
174 std::move(quad_name));
175
176 geometry.addPolylineVec(std::move(lines), geometry_name,
177 std::move(name_map));
178 return EXIT_SUCCESS;
179}
180
181int main(int argc, char* argv[])
182{
183 TCLAP::CmdLine cmd(
184 "Generate point, axis parallel polyline or axis parallel quad "
185 "geometry. \n\n"
186 "OpenGeoSys-6 software, version " +
188 ".\n"
189 "Copyright (c) 2012-2024, OpenGeoSys Community "
190 "(http://www.opengeosys.org)",
192 TCLAP::ValueArg<double> z0("", "z0", "z coordinate of the first point",
193 true, 0.0, "z0");
194 cmd.add(z0);
195 TCLAP::ValueArg<double> y0("", "y0", "y coordinate of the first point",
196 true, 0.0, "y0");
197 cmd.add(y0);
198 TCLAP::ValueArg<double> x0("", "x0", "x coordinate of the first point",
199 true, 0.0, "x0");
200 cmd.add(x0);
201 TCLAP::ValueArg<double> z1("", "z1", "z coordinate of the first point",
202 true, 1.0, "z1");
203 cmd.add(z1);
204 TCLAP::ValueArg<double> y1("", "y1", "y coordinate of the first point",
205 true, 1.0, "y1");
206 cmd.add(y1);
207 TCLAP::ValueArg<double> x1("", "x1", "x coordinate of the first point",
208 true, 1.0, "x1");
209 cmd.add(x1);
210 TCLAP::ValueArg<int> nx("", "nx", "number of subdivisions in x direction",
211 false, 0, "number of subdivisions in x direction");
212 cmd.add(nx);
213 TCLAP::ValueArg<int> nx1("", "nx1", "number of subdivisions in x direction",
214 false, -1,
215 "number of subdivisions in x direction");
216 cmd.add(nx1);
217 TCLAP::ValueArg<int> ny("", "ny", "number of subdivisions in y direction",
218 false, 0, "number of subdivisions in y direction");
219 cmd.add(ny);
220 TCLAP::ValueArg<int> ny1("", "ny1", "number of subdivisions in y direction",
221 false, -1,
222 "number of subdivisions in y direction");
223 cmd.add(ny1);
224 TCLAP::ValueArg<int> nz("", "nz", "number of subdivisions in z direction",
225 false, 0, "number of subdivisions in z direction");
226 cmd.add(nz);
227 TCLAP::ValueArg<int> nz1("", "nz1", "number of subdivisions in z direction",
228 false, -1,
229 "number of subdivisions in z direction");
230 cmd.add(nz1);
231 TCLAP::ValueArg<std::string> geometry_name(
232 "", "geometry_name", "name of the generated geometry", false,
233 "conceptual model", "name of the geometry");
234 cmd.add(geometry_name);
235 TCLAP::ValueArg<std::string> polyline_name(
236 "", "polyline_name", "name of the generated polyline", false,
237 "polyline", "name of the generated polyline");
238 cmd.add(polyline_name);
239 TCLAP::ValueArg<std::string> geo_output_arg(
240 "o", "output", "output geometry file (*.gml)", true, "", "output file");
241 cmd.add(geo_output_arg);
242 cmd.parse(argc, argv);
243
244#ifdef USE_PETSC
245 MPI_Init(&argc, &argv);
246#endif
247
248 auto const p0 = GeoLib::Point{x0.getValue(), y0.getValue(), z0.getValue()};
249 auto const p1 = GeoLib::Point{x1.getValue(), y1.getValue(), z1.getValue()};
250
251 GeoLib::GEOObjects geometry;
252 auto constexpr eps = std::numeric_limits<double>::epsilon();
253 if (p1[0] - p0[0] < eps && p1[1] - p0[1] < eps && p1[2] - p0[2] < eps)
254 {
255 generateSinglePointGeometry(p0, std::move(polyline_name.getValue()),
256 geometry_name.getValue(), geometry);
257 }
258 else if ((p1[0] - p0[0] >= eps && p1[1] - p0[1] < eps &&
259 p1[2] - p0[2] < eps) ||
260 (p1[0] - p0[0] < eps && p1[1] - p0[1] >= eps &&
261 p1[2] - p0[2] < eps) ||
262 (p1[0] - p0[0] < eps && p1[1] - p0[1] < eps &&
263 p1[2] - p0[2] >= eps))
264 {
265 generatePolylineGeometry(p0, p1, nx.getValue(),
266 std::move(polyline_name.getValue()),
267 geometry_name.getValue(), geometry);
268 }
269 else
270 {
271 auto eval = [](int v, int v1)
272 {
273 if (v1 == -1)
274 {
275 return v;
276 }
277 else
278 {
279 return v1;
280 }
281 };
283 p0, p1, nx.getValue(), eval(nx.getValue(), nx1.getValue()),
284 ny.getValue(), eval(ny.getValue(), ny1.getValue()),
285 nz.getValue(), eval(nz.getValue(), nz1.getValue()),
286 std::move(polyline_name.getValue()), geometry_name.getValue(),
287 geometry) == EXIT_FAILURE)
288 {
289#ifdef USE_PETSC
290 MPI_Finalize();
291#endif
292 return EXIT_FAILURE;
293 }
294 }
295
297 xml.export_name = geometry.getGeometryNames()[0];
298 BaseLib::IO::writeStringToFile(xml.writeToString(),
299 geo_output_arg.getValue());
300
301#ifdef USE_PETSC
302 MPI_Finalize();
303#endif
304 return EXIT_SUCCESS;
305}
Definition of the BoostXmlGmlInterface class.
Definition of the GEOObjects class.
Definition of the Point class.
Git information.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
Definition of the PolyLine class.
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)
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
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:41
int main(int argc, char *argv[])
std::tuple< std::vector< GeoLib::Polyline * >, GeoLib::PolylineVec::NameIdMap > appendNamedPolyline(std::unique_ptr< GeoLib::Polyline > polyline, std::string &&polyline_name)
void generatePolylineGeometry(GeoLib::Point const &point0, GeoLib::Point const &point1, int const number_of_subdivisions, std::string &&polyline_name, std::string &geometry_name, GeoLib::GEOObjects &geometry)
std::vector< GeoLib::Point * > generateQuadPoints(std::array< GeoLib::Point, 4 > const &points, std::array< int, 4 > const &number_of_subdivisions_per_edge)
int generateQuadGeometry(GeoLib::Point const &point0, GeoLib::Point const &point1, int const number_of_subdivisions_first_x, int const number_of_subdivisions_second_x, int const number_of_subdivisions_first_y, int const number_of_subdivisions_second_y, int const number_of_subdivisions_first_z, int const number_of_subdivisions_second_z, std::string &&quad_name, std::string &geometry_name, GeoLib::GEOObjects &geometry)
void generateSinglePointGeometry(GeoLib::Point const &point, std::string &&point_name, std::string &geometry_name, GeoLib::GEOObjects &geometry)
int writeStringToFile(std::string_view content, std::filesystem::path const &file_path)
Definition Writer.cpp:45
std::unique_ptr< Polyline > createPolyline(GeoLib::PointVec const &points_vec, std::vector< std::size_t > &&point_ids)
Create a polyline from given point ids.
Definition Polyline.cpp:564
std::vector< GeoLib::Point * > generateEquidistantPoints(MathLib::Point3d const &begin, MathLib::Point3d const &end, int const number_of_subdivisions)
Definition Utils.cpp:18
GITINFOLIB_EXPORT const std::string ogs_version