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 (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
......@@ -15,7 +11,7 @@
#include <list>
// ThirdParty/logog
#include "logog/include/logog.hpp"
#include <logog/include/logog.hpp>
#include "Surface.h"
......@@ -31,20 +27,38 @@
namespace GeoLib
{
Surface::Surface (const std::vector<Point*> &pnt_vec) :
GeoObject(), _sfc_pnts(pnt_vec), _bounding_volume(nullptr),
_surface_grid(nullptr)
{}
Surface::Surface(const std::vector<Point*>& pnt_vec)
: GeoObject(),
_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++)
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
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_
_surface_grid.reset();
_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);
ids[0] = pnt_a;
ids[1] = pnt_b;
ids[2] = pnt_c;
_bounding_volume.reset(new AABB(_sfc_pnts, ids));
} else {
}
else
{
_bounding_volume->update(*_sfc_pnts[pnt_a]);
_bounding_volume->update(*_sfc_pnts[pnt_b]);
_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.");
return nullptr;
}
if (ply.getNumberOfPoints() > 2) {
// create empty surface
Surface *sfc(new Surface(ply.getPointsVec()));
Polygon* polygon (new Polygon (ply));
polygon->computeListOfSimplePolygons ();
// 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);
if (ply.getNumberOfPoints() <= 2)
{
WARN(
"Error in Surface::createSurface() - Polyline consists of less "
"than three points and therefore cannot be triangulated.");
return nullptr;
}
// 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;
}
}
delete polygon;
if (sfc->getNTriangles() == 0) {
WARN("Surface::createSurface(): Triangulation does not contain any triangle.");
delete sfc;
return nullptr;
// create empty surface
Surface* sfc(new Surface(ply.getPointsVec()));
Polygon* polygon(new Polygon(ply));
polygon->computeListOfSimplePolygons();
// 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
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 {
WARN("Error in Surface::createSurface() - Polyline consists of less than three points and therefore cannot be triangulated.");
}
delete polygon;
if (sfc->getNTriangles() == 0)
{
WARN(
"Surface::createSurface(): Triangulation does not contain any "
"triangle.");
delete sfc;
return nullptr;
}
return sfc;
}
std::size_t Surface::getNTriangles () const
std::size_t Surface::getNTriangles() const
{
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];
}
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
{
// 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));
}
return _surface_grid->isPointInSurface(
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++) {
if (_sfc_triangles[k]->containsPoint (pnt)) {
for (std::size_t k(0); k < _sfc_triangles.size(); k++)
{
if (_sfc_triangles[k]->containsPoint(pnt))
{
return _sfc_triangles[k];
}
}
......
/**
* \file
* \author Thomas Fischer
* \date 2010-01-22
* \brief Definition of the Surface class.
*
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
......@@ -36,31 +32,36 @@ class SurfaceGrid;
* to a vector of (pointers to) points (_sfc_pnts) and a vector that stores
* the Triangles consisting of points from _sfc_pnts.
* */
class Surface : public GeoObject
class Surface final : public GeoObject
{
public:
Surface(const std::vector<Point*> &pnt_vec);
virtual ~Surface ();
explicit Surface(const std::vector<Point*>& pnt_vec);
Surface(Surface const& src);
~Surface();
/// return a geometry type
virtual GEOTYPE getGeoType() const {return GEOTYPE::SURFACE;}
Surface(Surface && src) = delete;
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
* */
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.
static Surface* createSurface(const Polyline &ply);
static Surface* createSurface(const Polyline& ply);
/**
* 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
......@@ -82,17 +83,15 @@ public:
*/
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
* @return axis aligned bounding box
*/
AABB const& getAABB () const { return *_bounding_volume; }
AABB const& getAABB() const { return *_bounding_volume; }
protected:
/** 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 */
std::vector<Triangle*> _sfc_triangles;
/** bounding volume is an axis aligned bounding box */
......@@ -103,7 +102,6 @@ protected:
/// called and a valid surface grid is not existing.
mutable std::unique_ptr<SurfaceGrid> _surface_grid;
};
}
#endif /* SURFACE_H_ */
/**
* \file
* \author Thomas Fischer
* \date 2010-06-06
* \brief Implementation of the Triangle class.
*
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
......@@ -21,29 +17,12 @@
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,
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());
_pnt_ids[0] = pnt_a;
_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);
assert (pnt_a < _pnts.size() && pnt_b < _pnts.size() && pnt_c < _pnts.size());
}
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
_pnt_ids[0] = pnt_a;
_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);
}
bool Triangle::containsPoint(MathLib::Point3d const& q, double eps) const
......@@ -90,7 +62,9 @@ bool Triangle::containsPoint2D (Point const& pnt) const
const double upper (1+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 false;
......
/**
* \file
* \author Thomas Fischer
* \date 2010-03-23
* \brief Definition of the Triangle class.
*
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
......@@ -26,21 +22,19 @@ class Point;
/** \brief Class Triangle consists of a reference to a point vector and
* a vector that stores the indices in the point vector.
* 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:
/**
* 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,
* 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
......@@ -50,7 +44,8 @@ public:
/** \brief const access operator to access the index
* 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);
return _pnt_ids[i];
}
......@@ -58,7 +53,8 @@ public:
/**
* \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);
return _pnts[_pnt_ids[i]];
}
......@@ -69,7 +65,9 @@ public:
* @param eps Checks the 'epsilon'-neighbourhood
* @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
......@@ -77,15 +75,13 @@ public:
* @param pnt the point to test for
* @return true, if the point is into the projected triangle
*/
bool containsPoint2D (Point const& pnt) const;
bool containsPoint2D(Point const& pnt) const;
protected:
/** a vector of pointers to points */
const std::vector<Point*> &_pnts;
/** position of pointers to the geometric points */
std::size_t _pnt_ids[3];
bool _initialized;
double _longest_edge;
private:
/// a vector of pointers to points the triangle is based on
std::vector<Point*> const& _pnts;
/// position of pointers to the geometric points
std::array<std::size_t, 3> _pnt_ids;
};
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