Skip to content
Snippets Groups Projects
Commit 54463328 authored by Tom Fischer's avatar Tom Fischer
Browse files

Merge pull request #1237 from TomFischer/GeoLibImprovements

[GL] Impl. of copy constructor of Surface and minor improvements
parents dd7a91d3 df4def96
No related branches found
No related tags found
No related merge requests found
/** /**
* \file
* \author Thomas Fischer
* \date 2010-04-22
* \brief Implementation of the Surface class.
* *
* \copyright * \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
...@@ -15,7 +11,7 @@ ...@@ -15,7 +11,7 @@
#include <list> #include <list>
// ThirdParty/logog // ThirdParty/logog
#include "logog/include/logog.hpp" #include <logog/include/logog.hpp>
#include "Surface.h" #include "Surface.h"
...@@ -31,20 +27,38 @@ ...@@ -31,20 +27,38 @@
namespace GeoLib namespace GeoLib
{ {
Surface::Surface (const std::vector<Point*> &pnt_vec) : Surface::Surface(const std::vector<Point*>& pnt_vec)
GeoObject(), _sfc_pnts(pnt_vec), _bounding_volume(nullptr), : GeoObject(),
_surface_grid(nullptr) _sfc_pnts(pnt_vec),
{} _bounding_volume(nullptr),
_surface_grid(nullptr)
{
}
Surface::Surface(Surface const& src)
: _sfc_pnts(src._sfc_pnts),
_bounding_volume(new AABB(*(src._bounding_volume))),
_surface_grid(nullptr)
{
_sfc_triangles.reserve(src._sfc_triangles.size());
std::transform(src._sfc_triangles.cbegin(),
src._sfc_triangles.cend(),
std::back_inserter(_sfc_triangles),
[](Triangle* t) { return new Triangle(*t); });
}
Surface::~Surface () Surface::~Surface()
{ {
for (std::size_t k(0); k < _sfc_triangles.size(); k++) for (std::size_t k(0); k < _sfc_triangles.size(); k++)
delete _sfc_triangles[k]; delete _sfc_triangles[k];
} }
void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) void Surface::addTriangle(std::size_t pnt_a,
std::size_t pnt_b,
std::size_t pnt_c)
{ {
assert (pnt_a < _sfc_pnts.size() && pnt_b < _sfc_pnts.size() && pnt_c < _sfc_pnts.size()); assert(pnt_a < _sfc_pnts.size() && pnt_b < _sfc_pnts.size() &&
pnt_c < _sfc_pnts.size());
// Check if two points of the triangle have identical IDs // Check if two points of the triangle have identical IDs
if (pnt_a == pnt_b || pnt_a == pnt_c || pnt_b == pnt_c) if (pnt_a == pnt_b || pnt_a == pnt_c || pnt_b == pnt_c)
...@@ -54,92 +68,108 @@ void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_ ...@@ -54,92 +68,108 @@ void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_
_surface_grid.reset(); _surface_grid.reset();
_sfc_triangles.push_back(new Triangle(_sfc_pnts, pnt_a, pnt_b, pnt_c)); _sfc_triangles.push_back(new Triangle(_sfc_pnts, pnt_a, pnt_b, pnt_c));
if (!_bounding_volume) { if (!_bounding_volume)
{
std::vector<std::size_t> ids(3); std::vector<std::size_t> ids(3);
ids[0] = pnt_a; ids[0] = pnt_a;
ids[1] = pnt_b; ids[1] = pnt_b;
ids[2] = pnt_c; ids[2] = pnt_c;
_bounding_volume.reset(new AABB(_sfc_pnts, ids)); _bounding_volume.reset(new AABB(_sfc_pnts, ids));
} else { }
else
{
_bounding_volume->update(*_sfc_pnts[pnt_a]); _bounding_volume->update(*_sfc_pnts[pnt_a]);
_bounding_volume->update(*_sfc_pnts[pnt_b]); _bounding_volume->update(*_sfc_pnts[pnt_b]);
_bounding_volume->update(*_sfc_pnts[pnt_c]); _bounding_volume->update(*_sfc_pnts[pnt_c]);
} }
} }
Surface* Surface::createSurface(const Polyline &ply) Surface* Surface::createSurface(const Polyline& ply)
{ {
if (!ply.isClosed()) { if (!ply.isClosed())
{
WARN("Error in Surface::createSurface() - Polyline is not closed."); WARN("Error in Surface::createSurface() - Polyline is not closed.");
return nullptr; return nullptr;
} }
if (ply.getNumberOfPoints() > 2) { if (ply.getNumberOfPoints() <= 2)
// create empty surface {
Surface *sfc(new Surface(ply.getPointsVec())); WARN(
"Error in Surface::createSurface() - Polyline consists of less "
Polygon* polygon (new Polygon (ply)); "than three points and therefore cannot be triangulated.");
polygon->computeListOfSimplePolygons (); return nullptr;
}
// create surfaces from simple polygons
const std::list<GeoLib::Polygon*>& list_of_simple_polygons (polygon->getListOfSimplePolygons());
for (std::list<GeoLib::Polygon*>::const_iterator simple_polygon_it (list_of_simple_polygons.begin());
simple_polygon_it != list_of_simple_polygons.end(); ++simple_polygon_it) {
std::list<GeoLib::Triangle> triangles;
GeoLib::EarClippingTriangulation(*simple_polygon_it, triangles);
// add Triangles to Surface // create empty surface
std::list<GeoLib::Triangle>::const_iterator it (triangles.begin()); Surface* sfc(new Surface(ply.getPointsVec()));
while (it != triangles.end()) {
sfc->addTriangle ((*it)[0], (*it)[1], (*it)[2]); Polygon* polygon(new Polygon(ply));
++it; polygon->computeListOfSimplePolygons();
}
} // create surfaces from simple polygons
delete polygon; const std::list<GeoLib::Polygon*>& list_of_simple_polygons(
if (sfc->getNTriangles() == 0) { polygon->getListOfSimplePolygons());
WARN("Surface::createSurface(): Triangulation does not contain any triangle."); for (std::list<GeoLib::Polygon*>::const_iterator simple_polygon_it(
delete sfc; list_of_simple_polygons.begin());
return nullptr; simple_polygon_it != list_of_simple_polygons.end();
++simple_polygon_it)
{
std::list<GeoLib::Triangle> triangles;
GeoLib::EarClippingTriangulation(*simple_polygon_it, triangles);
// add Triangles to Surface
std::list<GeoLib::Triangle>::const_iterator it(triangles.begin());
while (it != triangles.end())
{
sfc->addTriangle((*it)[0], (*it)[1], (*it)[2]);
++it;
} }
return sfc; }
} else { delete polygon;
WARN("Error in Surface::createSurface() - Polyline consists of less than three points and therefore cannot be triangulated."); if (sfc->getNTriangles() == 0)
{
WARN(
"Surface::createSurface(): Triangulation does not contain any "
"triangle.");
delete sfc;
return nullptr; return nullptr;
} }
return sfc;
} }
std::size_t Surface::getNTriangles () const std::size_t Surface::getNTriangles() const
{ {
return _sfc_triangles.size(); return _sfc_triangles.size();
} }
const Triangle* Surface::operator[] (std::size_t i) const const Triangle* Surface::operator[](std::size_t i) const
{ {
assert (i < _sfc_triangles.size()); assert(i < _sfc_triangles.size());
return _sfc_triangles[i]; return _sfc_triangles[i];
} }
bool Surface::isPntInBoundingVolume(MathLib::Point3d const& pnt) const bool Surface::isPntInBoundingVolume(MathLib::Point3d const& pnt) const
{ {
return _bounding_volume->containsPoint (pnt); return _bounding_volume->containsPoint(pnt);
} }
bool Surface::isPntInSfc(MathLib::Point3d const& pnt) const bool Surface::isPntInSfc(MathLib::Point3d const& pnt) const
{ {
// Mutable _surface_grid is constructed if method is called the first time. // Mutable _surface_grid is constructed if method is called the first time.
if (_surface_grid == nullptr) { if (_surface_grid == nullptr)
{
_surface_grid.reset(new SurfaceGrid(this)); _surface_grid.reset(new SurfaceGrid(this));
} }
return _surface_grid->isPointInSurface( return _surface_grid->isPointInSurface(
pnt, std::numeric_limits<double>::epsilon()); pnt, std::numeric_limits<double>::epsilon());
} }
const Triangle* Surface::findTriangle (MathLib::Point3d const& pnt) const const Triangle* Surface::findTriangle(MathLib::Point3d const& pnt) const
{ {
for (std::size_t k(0); k<_sfc_triangles.size(); k++) { for (std::size_t k(0); k < _sfc_triangles.size(); k++)
if (_sfc_triangles[k]->containsPoint (pnt)) { {
if (_sfc_triangles[k]->containsPoint(pnt))
{
return _sfc_triangles[k]; return _sfc_triangles[k];
} }
} }
......
/** /**
* \file
* \author Thomas Fischer
* \date 2010-01-22
* \brief Definition of the Surface class.
* *
* \copyright * \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
...@@ -36,31 +32,36 @@ class SurfaceGrid; ...@@ -36,31 +32,36 @@ class SurfaceGrid;
* to a vector of (pointers to) points (_sfc_pnts) and a vector that stores * to a vector of (pointers to) points (_sfc_pnts) and a vector that stores
* the Triangles consisting of points from _sfc_pnts. * the Triangles consisting of points from _sfc_pnts.
* */ * */
class Surface : public GeoObject class Surface final : public GeoObject
{ {
public: public:
Surface(const std::vector<Point*> &pnt_vec); explicit Surface(const std::vector<Point*>& pnt_vec);
virtual ~Surface (); Surface(Surface const& src);
~Surface();
/// return a geometry type Surface(Surface && src) = delete;
virtual GEOTYPE getGeoType() const {return GEOTYPE::SURFACE;} Surface& operator=(Surface const& src) = delete;
Surface& operator=(Surface && src) = delete;
/// return a geometry type
GEOTYPE getGeoType() const override { return GEOTYPE::SURFACE; }
/** /**
* adds three indices describing a triangle and updates the bounding box * adds three indices describing a triangle and updates the bounding box
* */ * */
void addTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c); void addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c);
/// Triangulates a new surface based on closed polyline. /// Triangulates a new surface based on closed polyline.
static Surface* createSurface(const Polyline &ply); static Surface* createSurface(const Polyline& ply);
/** /**
* returns the number of triangles describing the Surface * returns the number of triangles describing the Surface
* */ * */
std::size_t getNTriangles () const; std::size_t getNTriangles() const;
/** \brief const access operator for the access to the i-th Triangle of the surface. /** \brief const access operator for the access to the i-th Triangle of the
* surface.
*/ */
const Triangle* operator[] (std::size_t i) const; const Triangle* operator[](std::size_t i) const;
/** /**
* is the given point in the bounding volume of the surface * is the given point in the bounding volume of the surface
...@@ -82,17 +83,15 @@ public: ...@@ -82,17 +83,15 @@ public:
*/ */
const Triangle* findTriangle(MathLib::Point3d const& pnt) const; const Triangle* findTriangle(MathLib::Point3d const& pnt) const;
const std::vector<Point*> *getPointVec() const { return &_sfc_pnts; } const std::vector<Point*>* getPointVec() const { return &_sfc_pnts; }
/** /**
* method allows access to the internal axis aligned bounding box * method allows access to the internal axis aligned bounding box
* @return axis aligned bounding box * @return axis aligned bounding box
*/ */
AABB const& getAABB () const { return *_bounding_volume; } AABB const& getAABB() const { return *_bounding_volume; }
protected: protected:
/** a vector of pointers to Points */ /** a vector of pointers to Points */
const std::vector<Point*> &_sfc_pnts; const std::vector<Point*>& _sfc_pnts;
/** position of pointers to the geometric points */ /** position of pointers to the geometric points */
std::vector<Triangle*> _sfc_triangles; std::vector<Triangle*> _sfc_triangles;
/** bounding volume is an axis aligned bounding box */ /** bounding volume is an axis aligned bounding box */
...@@ -103,7 +102,6 @@ protected: ...@@ -103,7 +102,6 @@ protected:
/// called and a valid surface grid is not existing. /// called and a valid surface grid is not existing.
mutable std::unique_ptr<SurfaceGrid> _surface_grid; mutable std::unique_ptr<SurfaceGrid> _surface_grid;
}; };
} }
#endif /* SURFACE_H_ */ #endif /* SURFACE_H_ */
/** /**
* \file
* \author Thomas Fischer
* \date 2010-06-06
* \brief Implementation of the Triangle class.
* *
* \copyright * \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
...@@ -21,29 +17,12 @@ ...@@ -21,29 +17,12 @@
namespace GeoLib { namespace GeoLib {
Triangle::Triangle (std::vector<Point *> const &pnt_vec) :
_pnts(pnt_vec), _initialized (false), _longest_edge (0.0)
{
assert(!_pnts.empty());
_pnt_ids[0] = std::numeric_limits<std::size_t>::max();
_pnt_ids[1] = std::numeric_limits<std::size_t>::max();
_pnt_ids[2] = std::numeric_limits<std::size_t>::max();
}
Triangle::Triangle (std::vector<Point *> const &pnt_vec, Triangle::Triangle (std::vector<Point *> const &pnt_vec,
std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) : std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) :
_pnts(pnt_vec), _initialized (true), _longest_edge (0.0) _pnts(pnt_vec), _pnt_ids( {{pnt_a, pnt_b, pnt_c}} )
{ {
assert(!_pnts.empty()); assert(!_pnts.empty());
_pnt_ids[0] = pnt_a; assert (pnt_a < _pnts.size() && pnt_b < _pnts.size() && pnt_c < _pnts.size());
_pnt_ids[1] = pnt_b;
_pnt_ids[2] = pnt_c;
_longest_edge = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[1]]);
double tmp (MathLib::sqrDist (*_pnts[_pnt_ids[1]], *_pnts[_pnt_ids[2]]));
if (tmp > _longest_edge) _longest_edge = tmp;
tmp = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[2]]);
if (tmp > _longest_edge) _longest_edge = tmp;
_longest_edge = sqrt (_longest_edge);
} }
void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c)
...@@ -52,13 +31,6 @@ void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pn ...@@ -52,13 +31,6 @@ void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pn
_pnt_ids[0] = pnt_a; _pnt_ids[0] = pnt_a;
_pnt_ids[1] = pnt_b; _pnt_ids[1] = pnt_b;
_pnt_ids[2] = pnt_c; _pnt_ids[2] = pnt_c;
_longest_edge = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[1]]);
double tmp (MathLib::sqrDist (*_pnts[_pnt_ids[1]], *_pnts[_pnt_ids[2]]));
if (tmp > _longest_edge) _longest_edge = tmp;
tmp = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[2]]);
if (tmp > _longest_edge) _longest_edge = tmp;
_longest_edge = sqrt (_longest_edge);
} }
bool Triangle::containsPoint(MathLib::Point3d const& q, double eps) const bool Triangle::containsPoint(MathLib::Point3d const& q, double eps) const
...@@ -90,7 +62,9 @@ bool Triangle::containsPoint2D (Point const& pnt) const ...@@ -90,7 +62,9 @@ bool Triangle::containsPoint2D (Point const& pnt) const
const double upper (1+delta); const double upper (1+delta);
// check if u0 and u1 fulfills the condition (with some delta) // check if u0 and u1 fulfills the condition (with some delta)
if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper && y[0] + y[1] <= upper) { if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper &&
y[0] + y[1] <= upper)
{
return true; return true;
} }
return false; return false;
......
/** /**
* \file
* \author Thomas Fischer
* \date 2010-03-23
* \brief Definition of the Triangle class.
* *
* \copyright * \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
...@@ -26,21 +22,19 @@ class Point; ...@@ -26,21 +22,19 @@ class Point;
/** \brief Class Triangle consists of a reference to a point vector and /** \brief Class Triangle consists of a reference to a point vector and
* a vector that stores the indices in the point vector. * a vector that stores the indices in the point vector.
* A surface is composed by triangles. The class Surface stores the position * A surface is composed by triangles. The class Surface stores the position
* of pointers to the points of triangles in the m_sfc_pnt_ids vector. * of pointers to the points of triangles in the _pnt_ids vector.
* */ * */
class Triangle class Triangle final
{ {
public: public:
/**
* construction of object, initialization of reference to point vector
*/
Triangle (std::vector<Point *> const &pnt_vec);
/** /**
* construction of object, initialization of reference to point vector, * construction of object, initialization of reference to point vector,
* saves the three indices describing a triangle * saves the three indices describing a triangle
*/ */
Triangle (std::vector<Point *> const &pnt_vec, std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c); Triangle(std::vector<Point*> const& pnt_vec,
std::size_t pnt_a,
std::size_t pnt_b,
std::size_t pnt_c);
/** /**
* saves three indices describing a triangle * saves three indices describing a triangle
...@@ -50,7 +44,8 @@ public: ...@@ -50,7 +44,8 @@ public:
/** \brief const access operator to access the index /** \brief const access operator to access the index
* of the i-th triangle point * of the i-th triangle point
*/ */
const std::size_t& operator[] (std::size_t i) const { const std::size_t& operator[](std::size_t i) const
{
assert (i < 3); assert (i < 3);
return _pnt_ids[i]; return _pnt_ids[i];
} }
...@@ -58,7 +53,8 @@ public: ...@@ -58,7 +53,8 @@ public:
/** /**
* \brief const access operator to access the i-th triangle Point * \brief const access operator to access the i-th triangle Point
*/ */
const Point* getPoint (std::size_t i) const { const Point* getPoint(std::size_t i) const
{
assert (i < 3); assert (i < 3);
return _pnts[_pnt_ids[i]]; return _pnts[_pnt_ids[i]];
} }
...@@ -69,7 +65,9 @@ public: ...@@ -69,7 +65,9 @@ public:
* @param eps Checks the 'epsilon'-neighbourhood * @param eps Checks the 'epsilon'-neighbourhood
* @return true, if point is in triangle, else false * @return true, if point is in triangle, else false
*/ */
bool containsPoint(MathLib::Point3d const& q, double eps = std::numeric_limits<float>::epsilon()) const; bool containsPoint(
MathLib::Point3d const& q,
double eps = std::numeric_limits<float>::epsilon()) const;
/** /**
* projects the triangle points to the x-y-plane and * projects the triangle points to the x-y-plane and
...@@ -77,15 +75,13 @@ public: ...@@ -77,15 +75,13 @@ public:
* @param pnt the point to test for * @param pnt the point to test for
* @return true, if the point is into the projected triangle * @return true, if the point is into the projected triangle
*/ */
bool containsPoint2D (Point const& pnt) const; bool containsPoint2D(Point const& pnt) const;
protected: private:
/** a vector of pointers to points */ /// a vector of pointers to points the triangle is based on
const std::vector<Point*> &_pnts; std::vector<Point*> const& _pnts;
/** position of pointers to the geometric points */ /// position of pointers to the geometric points
std::size_t _pnt_ids[3]; std::array<std::size_t, 3> _pnt_ids;
bool _initialized;
double _longest_edge;
}; };
void getPlaneCoefficients(Triangle const& tri, double c[3]); void getPlaneCoefficients(Triangle const& tri, double c[3]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment