10#include <tclap/CmdLine.h> 
   12#include <QCoreApplication> 
   50                                         std::size_t 
const n_intervals)
 
   52    std::vector<GeoLib::Point*> points;
 
   55    double const interval = length / n_intervals;
 
   57    GeoLib::Point const vec((end[0] - start[0]), (end[1] - start[1]),
 
   59    for (std::size_t i = 1; i < n_intervals; ++i)
 
   62            start[0] + ((i * interval) / length * vec[0]),
 
   63            start[1] + ((i * interval) / length * vec[1]), 0, i));
 
 
   73    std::size_t 
const length = points.size();
 
   74    for (std::size_t i = 0; i < length; ++i)
 
 
   84    std::vector<std::string> 
const& layer_names,
 
   87    double const resolution)
 
   89    std::vector<std::string> geo_name_list;
 
   90    std::size_t 
const n_layers = layer_names.size();
 
   91    for (std::size_t i = 0; i < n_layers; ++i)
 
   93        std::unique_ptr<MeshLib::Mesh> 
const layer(
 
   97            ERR(
"Could not read file {:s}. Skipping layer...", layer_names[i]);
 
  100        if (layer->getDimension() != 2)
 
  102            ERR(
"Layer {:d} is not a 2D mesh. Skipping layer...", i);
 
  106        std::string geo_name(std::to_string(i));
 
  107        auto points(
createPoints(pnt_start, pnt_end, resolution));
 
  111        std::vector<GeoLib::Polyline*> lines;
 
  118        geo_name_list.push_back(geo_name);
 
  120    return geo_name_list;
 
 
  125    return ((*a)[2] < (*b)[2]) ? a : b;
 
 
  132                     std::vector<std::string> 
const& geo_names,
 
  133                     std::string& merged_geo_name)
 
  135    std::vector<GeoLib::Point*> points;
 
  136    std::vector<GeoLib::Polyline*> lines;
 
  139    std::size_t 
const pnts_per_line = DEM_pnts.size();
 
  140    std::size_t 
const n_layers = geo_names.size();
 
  141    std::vector<std::size_t> last_line_idx(pnts_per_line, 0);
 
  143    auto layer_pnts = *geo.
getPointVec(geo_names.back());
 
  144    for (std::size_t i = 0; i < pnts_per_line; ++i)
 
  148        last_line_idx[i] = i;
 
  150    for (
int j = n_layers - 2; j >= 0; --j)
 
  153        for (std::size_t i = 0; i < pnts_per_line; ++i)
 
  155            line->
addPoint(last_line_idx[pnts_per_line - i - 1]);
 
  158        for (std::size_t i = 0; i < pnts_per_line; ++i)
 
  162            std::size_t idx = last_line_idx[i];
 
  163            if ((*points[idx])[2] < (*layer_pnts[i])[2])
 
  169                last_line_idx[i] = idx;
 
  175        lines.push_back(line);
 
  178    geo.
addPointVec(std::move(points), merged_geo_name,
 
 
  186    std::vector<GeoLib::Point*>& points)
 
  189    auto const [plane_normal, d] =
 
  192    Eigen::Matrix3d 
const rotation_matrix =
 
  197    double const z_shift =
 
  199    std::for_each(points.begin(), points.end(),
 
  201    return {rotation_matrix, z_shift};
 
 
  209                         std::string 
const& output_name,
 
  210                         std::string& merged_geo_name,
 
  211                         bool const keep_gml_file)
 
  213    std::string 
const filename(output_name + 
".gml");
 
 
  232                            std::string 
const& geo_name,
 
  233                            std::string 
const& output_name, 
double res)
 
  235    std::string 
const gmsh_geo_name(output_name + 
".geo");
 
  236    std::vector<std::string> gmsh_geo;
 
  237    gmsh_geo.push_back(geo_name);
 
  240        0, gmsh_geo, 
false, 
false);
 
  244        ERR(
"Writing gmsh geo file '{:s}' failed.", gmsh_geo_name);
 
  247    std::string 
const gmsh_mesh_name = output_name + 
".msh";
 
  248    std::string gmsh_command = 
"gmsh -2 -algo meshadapt " + gmsh_geo_name;
 
  249    gmsh_command += 
" -o " + gmsh_mesh_name + 
" -format msh22";
 
  250    int const return_value = std::system(gmsh_command.c_str());
 
  251    if (return_value != 0)
 
  253        ERR(
"Execution of gmsh command returned non-zero status, %d",
 
 
  262                double const z_shift)
 
  264    std::vector<MeshLib::Node*> 
const& nodes = mesh.
getNodes();
 
  265    std::for_each(nodes.begin(), nodes.end(),
 
 
  273    std::vector<std::size_t> line_idx;
 
  274    std::vector<MeshLib::Element*> 
const& elems = mesh.
getElements();
 
  275    std::for_each(elems.begin(), elems.end(),
 
  278                      if (e->getGeomType() == MeshLib::MeshElemType::LINE)
 
  280                          line_idx.push_back(e->getID());
 
  283    if (line_idx.size() == mesh.getNumberOfElements())
 
 
  291                   std::vector<std::size_t> 
const& idx_array,
 
  292                   std::string 
const& file_name)
 
  294    std::unique_ptr<MeshLib::Mesh> 
const boundary(
 
  296    if (boundary == 
nullptr)
 
  298        ERR(
"Error extracting boundary '{:s}'", file_name);
 
 
  306                       std::string 
const& output_name,
 
  309    auto const edge_length = minMaxEdgeLength(mesh.
getElements());
 
  310    double const eps = edge_length.first / 100.0;
 
  311    std::unique_ptr<MeshLib::Mesh> boundary_mesh(
 
  318    auto const& elems = boundary_mesh->getElements();
 
  319    std::vector<std::size_t> left_bound_idx, right_bound_idx, top_bound_idx,
 
  321    Eigen::Vector2d 
const anchor(pnt_start[0], pnt_start[1]);
 
  324        Eigen::Vector2d 
const n1((*e->getNode(0))[0], (*e->getNode(0))[1]);
 
  325        Eigen::Vector2d 
const n2((*e->getNode(1))[0], (*e->getNode(1))[1]);
 
  326        Eigen::Vector2d 
const dist1(n1 - anchor);
 
  327        Eigen::Vector2d 
const dist2(n2 - anchor);
 
  328        std::size_t 
const id = e->getID();
 
  330        if ((dist1 - dist2).squaredNorm() < eps)
 
  332            top_bound_idx.push_back(
id);
 
  333            bottom_bound_idx.push_back(
id);
 
  335            if (dist1.squaredNorm() < eps)
 
  337                right_bound_idx.push_back(
id);
 
  341                left_bound_idx.push_back(
id);
 
  346        if (dist2.squaredNorm() < dist1.squaredNorm())
 
  348            top_bound_idx.push_back(
id);
 
  349            left_bound_idx.push_back(
id);
 
  350            right_bound_idx.push_back(
id);
 
  354            bottom_bound_idx.push_back(
id);
 
  355            left_bound_idx.push_back(
id);
 
  356            right_bound_idx.push_back(
id);
 
  360    writeBoundary(*boundary_mesh, left_bound_idx, output_name + 
"_left");
 
  361    writeBoundary(*boundary_mesh, right_bound_idx, output_name + 
"_right");
 
  362    writeBoundary(*boundary_mesh, top_bound_idx, output_name + 
"_top");
 
  363    writeBoundary(*boundary_mesh, bottom_bound_idx, output_name + 
"_bottom");
 
 
  366int main(
int argc, 
char* argv[])
 
  368    QCoreApplication a(argc, argv);
 
  370        "Creates a triangle-mesh of a vertical slice out of a list of input " 
  371        "layer meshes. The slice is defined by a start- and end-point. In " 
  372        "addition, the resolution for meshing the extracted slice (i.e. the " 
  373        "maximum edge length of the domain discretisation) needs to be " 
  374        "specified. The utility requires access to the meshing utility GMSH to " 
  375        "work correctly.\n\n" 
  376        "OpenGeoSys-6 software, version " +
 
  379            "Copyright (c) 2012-2025, OpenGeoSys Community " 
  380            "(http://www.opengeosys.org)",
 
  382    TCLAP::SwitchArg test_arg(
"t", 
"testdata", 
"keep test data", 
false);
 
  384    TCLAP::SwitchArg bound_arg(
"b", 
"bounds", 
"save mesh boundaries", 
false);
 
  386    TCLAP::ValueArg<double> res_arg(
 
  388        "desired edge length of triangles in the resulting slice, (min = 0)",
 
  389        true, 0, 
"RESOLUTION");
 
  391    TCLAP::ValueArg<double> end_y_arg(
 
  392        "", 
"end-y", 
"y-coordinates of the end point defining the slice", 
true,
 
  395    TCLAP::ValueArg<double> end_x_arg(
 
  396        "", 
"end-x", 
"x-coordinates of the end point defining the slice", 
true,
 
  399    TCLAP::ValueArg<double> start_y_arg(
 
  400        "", 
"start-y", 
"y-coordinates of the start point defining the slice",
 
  402    cmd.add(start_y_arg);
 
  403    TCLAP::ValueArg<double> start_x_arg(
 
  404        "", 
"start-x", 
"x-coordinates of the start point defining the slice",
 
  406    cmd.add(start_x_arg);
 
  407    TCLAP::ValueArg<std::string> output_arg(
 
  408        "o", 
"output", 
"Output (.vtu). Name of output mesh file", 
true, 
"",
 
  411    TCLAP::ValueArg<std::string> input_arg(
 
  413        "Input (.vtu | .msh). Name of the input file list containing the paths " 
  414        "the all input layers " 
  415        "in correct order from top to bottom",
 
  416        true, 
"", 
"INPUT_FILE_LIST");
 
  419    cmd.add(log_level_arg);
 
  420    cmd.parse(argc, argv);
 
  425    std::string 
const input_name = input_arg.getValue();
 
  426    std::string 
const output_name = output_arg.getValue();
 
  429        {start_x_arg.getValue(), start_y_arg.getValue(), 0.0}};
 
  431        {end_x_arg.getValue(), end_y_arg.getValue(), 0.0}};
 
  434    std::size_t 
const res = std::ceil(length / res_arg.getValue());
 
  435    double const interval_length = length / res;
 
  437    std::vector<std::string> 
const layer_names =
 
  439    if (layer_names.size() < 2)
 
  441        ERR(
"At least two layers are required to extract a slice.");
 
  446    std::vector<std::string> 
const geo_name_list =
 
  449    if (geo_name_list.size() < 2)
 
  451        ERR(
"Less than two geometries could be created from layers. Aborting " 
  456    std::string merged_geo_name = 
"merged_geometries";
 
  458    std::vector<GeoLib::Point*> points = *geo.
getPointVec(merged_geo_name);
 
  462    std::unique_ptr<MeshLib::Mesh> mesh(
 
  463        generateMesh(geo, merged_geo_name, output_name, interval_length));
 
  464    if (!test_arg.getValue())
 
  471        ERR(
"Error generating mesh... (GMSH was unable to output mesh)");
 
  476    if (new_mesh == 
nullptr)
 
  478        ERR(
"Error generating mesh... (GMSH created line mesh)");
 
  485    auto const edge_length = minMaxEdgeLength(new_mesh->getElements());
 
  486    double const minimum_node_distance = edge_length.first / 100.0;
 
  488    std::unique_ptr<MeshLib::Mesh> revised_mesh(
 
  489        rev.
simplifyMesh(
"RevisedMesh", minimum_node_distance));
 
  491    if (bound_arg.getValue())
 
 
Definition of the AABB class.
 
Definition of analytical geometry functions.
 
Definition of the Element class.
 
Definition of the GEOObjects class.
 
Definition of the Point class.
 
Definition of the GeoMapper class.
 
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
 
Definition of the MeshRevision class.
 
Definition of the Mesh class.
 
Definition of the Node class.
 
Definition of the Point3d class.
 
Definition of the Polygon class.
 
Definition of the PolyLine class.
 
int main(int argc, char *argv[])
 
void rotateMesh(MeshLib::Mesh &mesh, Eigen::Matrix3d const &rot_mat, double const z_shift)
inverse rotation of the mesh, back into original position
 
void extractBoundaries(MeshLib::Mesh const &mesh, std::string const &output_name, MathLib::Point3d const &pnt_start)
 
std::vector< std::string > createGeometries(GeoLib::GEOObjects &geo, std::vector< std::string > const &layer_names, MathLib::Point3d const &pnt_start, MathLib::Point3d const &pnt_end, double const resolution)
creates a mapped line for each of the mesh layers
 
void writeBoundary(MeshLib::Mesh const &mesh, std::vector< std::size_t > const &idx_array, std::string const &file_name)
 
void mergeGeometries(GeoLib::GEOObjects &geo, std::vector< std::string > const &geo_names, std::string &merged_geo_name)
 
MeshLib::Mesh * removeLineElements(MeshLib::Mesh const &mesh)
removes line elements from mesh such that only triangles remain
 
GeoLib::Polyline * createPolyline(std::vector< GeoLib::Point * > const &points)
creates a polyline to be mapped on a mesh layer
 
std::pair< Eigen::Matrix3d, double > rotateGeometryToXY(std::vector< GeoLib::Point * > &points)
rotates the merged geometry into the XY-plane
 
std::vector< GeoLib::Point * > createPoints(MathLib::Point3d const &start, MathLib::Point3d const &end, std::size_t const n_intervals)
creates a vector of sampling points based on the specified resolution
 
static GeoLib::Point * getMinElevationPoint(GeoLib::Point *a, GeoLib::Point *b)
 
void consolidateGeometry(GeoLib::GEOObjects &geo, std::string const &output_name, std::string &merged_geo_name, bool const keep_gml_file)
 
MeshLib::Mesh * generateMesh(GeoLib::GEOObjects &geo, std::string const &geo_name, std::string const &output_name, double res)
converts geometry into GMSH format and creates mesh
 
Implementation of the VtuInterface class.
 
Definition of the XmlGmlInterface class.
 
std::string writeToString()
Writes the object to a string.
 
Reads and writes GMSH-files to and from OGS data structures.
 
void writePhysicalGroups(bool flag)
 
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
 
Eigen::Vector3d const & getMaxPoint() const
 
Eigen::Vector3d const & getMinPoint() const
 
Container class for geometric objects.
 
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()))
 
bool removePointVec(const std::string &name)
 
bool removePolylineVec(const std::string &name)
 
Reads and writes GeoObjects to and from XML files.
 
int readFile(const QString &fileName) override
Reads an xml-file containing geometric object definitions into the GEOObjects used in the constructor...
 
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
 
std::size_t getPointID(std::size_t const i) const
 
virtual bool addPoint(std::size_t pnt_id)
 
std::map< std::string, std::size_t > NameIdMap
 
Reads and writes VtkXMLUnstructuredGrid-files (vtu) to and from OGS data structures....
 
bool writeToFile(std::filesystem::path const &file_path)
 
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
 
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
 
std::vector< std::string > readStringListFromFile(std::string const &filename)
Reads non-empty lines from a list of strings from a file into a vector.
 
int writeStringToFile(std::string_view content, std::filesystem::path const &file_path)
 
TCLAP::ValueArg< std::string > makeLogLevelArg()
 
void removeFile(std::string const &filename)
 
void initOGSLogger(std::string const &log_level)
 
@ FixedMeshDensity
set the parameter with a fixed value
 
MeshLib::Mesh * readGMSHMesh(std::string const &fname, bool const is_created_with_gmsh2)
 
void rotatePoints(Eigen::Matrix3d const &rot_mat, InputIterator pnts_begin, InputIterator pnts_end)
 
Eigen::Matrix3d computeRotationMatrixToXY(Eigen::Vector3d const &n)
 
std::pair< Eigen::Vector3d, double > getNewellPlane(InputIterator pnts_begin, InputIterator pnts_end)
 
GITINFOLIB_EXPORT const std::string ogs_version
 
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
 
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
 
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
 
Definition of readMeshFromFile function.