diff --git a/FileIO/TINInterface.cpp b/FileIO/TINInterface.cpp index ec77d897047f06ba71d546431403579d6999d35b..09ffbd3c07455b70a08377edfc80aa8055e3df0a 100644 --- a/FileIO/TINInterface.cpp +++ b/FileIO/TINInterface.cpp @@ -17,7 +17,7 @@ #include "BaseLib/StringTools.h" #include "GeoLib/Surface.h" - +#include "GeoLib/AnalyticalGeometry.h" namespace FileIO { @@ -34,29 +34,70 @@ GeoLib::Surface* TINInterface::readTIN(std::string const& fname, std::vector<Geo GeoLib::Surface* sfc = new GeoLib::Surface(pnt_vec); std::size_t id; - double x, y, z; - while (in) + double p0[3], p1[3], p2[3]; + while (in.good()) { // read id - in >> id; - // determine size - std::size_t pnt_pos(pnt_vec.size()); + if (!(in >> id)) + continue; // read first point - in >> x >> y >> z; - pnt_vec.push_back(new GeoLib::Point(x, y, z)); + if (!(in >> p0[0] >> p0[1] >> p0[2])) { + ERR("Could not read coords of 1st point of triangle %d.", id); + if (errors) + errors->push_back (std::string("readTIN error: ") + + std::string("Could not read coords of 1st point in triangle ") + + std::to_string(id)); + in.close(); + delete sfc; + return nullptr; + } // read second point - in >> x >> y >> z; - pnt_vec.push_back(new GeoLib::Point(x, y, z)); + if (!(in >> p1[0] >> p1[1] >> p1[2])) { + ERR("Could not read coords of 2nd point of triangle %d.", id); + if (errors) + errors->push_back (std::string("readTIN error: ") + + std::string("Could not read coords of 2nd point in triangle ") + + std::to_string(id)); + in.close(); + delete sfc; + return nullptr; + } // read third point - in >> x >> y >> z; - pnt_vec.push_back(new GeoLib::Point(x, y, z)); + if (!(in >> p2[0] >> p2[1] >> p2[2])) { + ERR("Could not read coords of 3rd point of triangle %d.", id); + if (errors) + errors->push_back (std::string("readTIN error: ") + + std::string("Could not read coords of 3rd point in triangle ") + + std::to_string(id)); + in.close(); + delete sfc; + return nullptr; + } + + // check area of triangle + double const d_eps(std::numeric_limits<double>::epsilon()); + if (GeoLib::calcTriangleArea(p0, p1, p2) < d_eps) { + ERR("readTIN: Triangle %d has zero area.", id); + if (errors) + errors->push_back (std::string("readTIN: Triangle ") + + std::to_string(id) + std::string(" has zero area.")); + delete sfc; + return nullptr; + } + + // determine size pnt_vec to insert the correct ids + std::size_t pnt_pos(pnt_vec.size()); + pnt_vec.push_back(new GeoLib::Point(p0)); + pnt_vec.push_back(new GeoLib::Point(p1)); + pnt_vec.push_back(new GeoLib::Point(p2)); // create new Triangle sfc->addTriangle(pnt_pos, pnt_pos + 1, pnt_pos + 2); } if (sfc->getNTriangles() == 0) { WARN("readTIN(): No triangle found.", fname.c_str()); - if (errors) errors->push_back ("readTIN error because of no triangle found"); + if (errors) + errors->push_back ("readTIN error because of no triangle found"); delete sfc; return nullptr; } diff --git a/Tests/FileIO/TestGLIReader.cpp b/Tests/FileIO/TestGLIReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3bf6360c13292ebbe89c02a44d964ebdb5d124f --- /dev/null +++ b/Tests/FileIO/TestGLIReader.cpp @@ -0,0 +1,116 @@ +/** + * \date 2014-10-14 + * + * \copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * + */ + +#include <boost/filesystem.hpp> + +#include "gtest/gtest.h" + +#include "BaseLib/BuildInfo.h" + +// FileIO +#include "FileIO/Legacy/OGSIOVer4.h" + +// GeoLib +#include "GeoLib/GEOObjects.h" + +class OGSIOVer4InterfaceTest : public ::testing::Test +{ +public: + OGSIOVer4InterfaceTest() + : _gli_fname(BaseLib::BuildInfo::tests_tmp_path+"test.gli") + { + std::ofstream gli_out(_gli_fname); + gli_out << "#POINTS\n"; + gli_out << "0 0 0 0\n"; + gli_out << "#SURFACE\n"; + gli_out << " $NAME\n"; + gli_out << " Surface\n"; + gli_out << " $TIN\n"; + gli_out << " Surface.tin\n"; + gli_out << "#STOP\n"; + gli_out.close(); + } + + ~OGSIOVer4InterfaceTest() + { + boost::filesystem::remove(_gli_fname); + } + +protected: + std::string _gli_fname; +}; + +TEST_F(OGSIOVer4InterfaceTest, SimpleTIN) +{ + std::string tin_fname(BaseLib::BuildInfo::tests_tmp_path+"Surface.tin"); + std::ofstream tin_out (tin_fname); + tin_out << "0 0.0 0.0 0.0 1.0 0.0.0 0.0 0.0 1.0\n"; + tin_out << "1 0.0 0.0 0.0 1.0 0.0.0 0.0 1.0 1.0\n"; + tin_out.close(); + + // read geometry + GeoLib::GEOObjects geometries; + std::vector<std::string> errors; + std::string geometry_name("TestGeometry"); + FileIO::Legacy::readGLIFileV4(_gli_fname, &geometries, geometry_name, errors); + + std::vector<GeoLib::Surface*> const* + sfcs(geometries.getSurfaceVec(geometry_name)); + ASSERT_TRUE(sfcs != nullptr); + ASSERT_EQ(1u, geometries.getSurfaceVec(geometry_name)->size()); + ASSERT_EQ(2u, (*geometries.getSurfaceVec(geometry_name))[0]->getNTriangles()); + + boost::filesystem::remove(tin_fname); +} + +TEST_F(OGSIOVer4InterfaceTest, InvalidTIN) +{ + std::string tin_fname(BaseLib::BuildInfo::tests_tmp_path+"Surface.tin"); + std::ofstream tin_out (tin_fname); + tin_out << "0 0.0 0.0 0.0 1.0 0.0.0 0.0 0.0 1.0\n"; + tin_out << "1 0.0 0.0 0.0 1.0 0.0.0\n"; + tin_out.close(); + + // read geometry + GeoLib::GEOObjects geometries; + std::vector<std::string> errors; + std::string geometry_name("TestGeometry"); + FileIO::Legacy::readGLIFileV4(_gli_fname, &geometries, geometry_name, errors); + + std::vector<GeoLib::Surface*> const* + sfcs(geometries.getSurfaceVec(geometry_name)); + ASSERT_TRUE(sfcs == nullptr); + + boost::filesystem::remove(tin_fname); +} + +TEST_F(OGSIOVer4InterfaceTest, InvalidTIN_II) +{ + std::string tin_fname(BaseLib::BuildInfo::tests_tmp_path+"Surface.tin"); + std::ofstream tin_out (tin_fname); + tin_out << "0 0.0 0.0 0.0 1.0 0.0.0 0.0\n"; + tin_out << "1 0.0 0.0 0.0 1.0 0.0.0\n"; + tin_out.close(); + + // read geometry + GeoLib::GEOObjects geometries; + std::vector<std::string> errors; + std::string geometry_name("TestGeometry"); + FileIO::Legacy::readGLIFileV4(_gli_fname, &geometries, geometry_name, errors); + + std::vector<GeoLib::Surface*> const* + sfcs(geometries.getSurfaceVec(geometry_name)); + ASSERT_TRUE(sfcs == nullptr); + + boost::filesystem::remove(tin_fname); +} +