OGS
TINInterface.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 "TINInterface.h"
5
6#include <fstream>
7#include <limits>
8
9#include "BaseLib/FileTools.h"
10#include "BaseLib/Logging.h"
11#include "BaseLib/StringTools.h"
13#include "GeoLib/Surface.h"
14#include "GeoLib/Triangle.h"
16
17namespace GeoLib
18{
19namespace IO
20{
21GeoLib::Surface* TINInterface::readTIN(std::string const& fname,
22 GeoLib::PointVec& pnt_vec,
23 std::vector<std::string>* errors)
24{
25 // open file
26 std::ifstream in(fname.c_str());
27 if (!in)
28 {
29 WARN("readTIN(): could not open stream from {:s}.", fname);
30 if (errors)
31 {
32 errors->push_back("readTINFile error opening stream from " + fname);
33 }
34 return nullptr;
35 }
36
37 auto* sfc = new GeoLib::Surface(pnt_vec.getVector());
38 std::size_t id;
42 std::string line;
43 while (std::getline(in, line).good())
44 {
45 // allow empty lines
46 if (line.empty())
47 {
48 continue;
49 }
50
51 // parse line
52 std::stringstream input(line);
53 // read id
54 if (!(input >> id))
55 {
56 in.close();
57 delete sfc;
58 return nullptr;
59 }
60 // read first point
61 if (!(input >> p0[0] >> p0[1] >> p0[2]))
62 {
63 ERR("Could not read coords of 1st point of triangle {:d}.", id);
64 if (errors)
65 {
66 errors->push_back(
67 std::string("readTIN error: ") +
68 std::string(
69 "Could not read coords of 1st point in triangle ") +
70 std::to_string(id));
71 }
72 in.close();
73 delete sfc;
74 return nullptr;
75 }
76 // read second point
77 if (!(input >> p1[0] >> p1[1] >> p1[2]))
78 {
79 ERR("Could not read coords of 2nd point of triangle {:d}.", id);
80 if (errors)
81 {
82 errors->push_back(
83 std::string("readTIN error: ") +
84 std::string(
85 "Could not read coords of 2nd point in triangle ") +
86 std::to_string(id));
87 }
88 in.close();
89 delete sfc;
90 return nullptr;
91 }
92 // read third point
93 if (!(input >> p2[0] >> p2[1] >> p2[2]))
94 {
95 ERR("Could not read coords of 3rd point of triangle {:d}.", id);
96 if (errors)
97 {
98 errors->push_back(
99 std::string("readTIN error: ") +
100 std::string(
101 "Could not read coords of 3rd point in triangle ") +
102 std::to_string(id));
103 }
104 in.close();
105 delete sfc;
106 return nullptr;
107 }
108
109 // check area of triangle
110 double const d_eps(std::numeric_limits<double>::epsilon());
111 if (MathLib::calcTriangleArea(p0, p1, p2) < d_eps)
112 {
113 ERR("readTIN: Triangle {:d} has zero area.", id);
114 if (errors)
115 {
116 errors->push_back(std::string("readTIN: Triangle ") +
117 std::to_string(id) +
118 std::string(" has zero area."));
119 }
120 delete sfc;
121 return nullptr;
122 }
123
124 // determine size pnt_vec to insert the correct ids
125 std::size_t const s(pnt_vec.getVector().size());
126
127 std::size_t const pnt_pos_0(
128 pnt_vec.push_back(new GeoLib::Point(p0, s)));
129 std::size_t const pnt_pos_1(
130 pnt_vec.push_back(new GeoLib::Point(p1, s + 1)));
131 std::size_t const pnt_pos_2(
132 pnt_vec.push_back(new GeoLib::Point(p2, s + 2)));
133 // create new Triangle
134 if (pnt_pos_0 != std::numeric_limits<std::size_t>::max() &&
135 pnt_pos_1 != std::numeric_limits<std::size_t>::max() &&
136 pnt_pos_2 != std::numeric_limits<std::size_t>::max())
137 {
138 sfc->addTriangle(pnt_pos_0, pnt_pos_1, pnt_pos_2);
139 }
140 }
141
142 if (sfc->getNumberOfTriangles() == 0)
143 {
144 WARN("readTIN(): No triangle found.", fname);
145 if (errors)
146 {
147 errors->push_back("readTIN error because of no triangle found");
148 }
149 delete sfc;
150 return nullptr;
151 }
152
153 return sfc;
154}
155
157 std::string const& file_name)
158{
159 std::ofstream os(file_name.c_str());
160 if (!os)
161 {
162 WARN("writeSurfaceAsTIN(): could not open stream to {:s}.", file_name);
163 return;
164 }
165 os.precision(std::numeric_limits<double>::max_digits10);
166 const std::size_t n_tris(surface.getNumberOfTriangles());
167 for (std::size_t l(0); l < n_tris; l++)
168 {
169 GeoLib::Triangle const& tri(*(surface[l]));
170 os << l << " " << *(tri.getPoint(0)) << " " << *(tri.getPoint(1)) << " "
171 << *(tri.getPoint(2)) << "\n";
172 }
173 os.close();
174}
175} // end namespace IO
176} // end namespace GeoLib
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
static GeoLib::Surface * readTIN(std::string const &fname, GeoLib::PointVec &pnt_vec, std::vector< std::string > *errors=nullptr)
static void writeSurfaceAsTIN(GeoLib::Surface const &surface, std::string const &file_name)
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition PointVec.h:25
std::size_t push_back(Point *pnt)
Definition PointVec.cpp:124
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
std::vector< T * > const & getVector() const
Definition TemplateVec.h:94
Class Triangle consists of a reference to a point vector and a vector that stores the indices in the ...
Definition Triangle.h:21
const Point * getPoint(std::size_t i) const
const access operator to access the i-th triangle Point
Definition Triangle.h:44
double calcTriangleArea(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)