diff --git a/GeoLib/Surface.cpp b/GeoLib/Surface.cpp index fd464f92be176f434e2d8a3c183a91e43ef133ad..3e7cac6b9322d4c96253aa139573b99aa2bddac5 100644 --- a/GeoLib/Surface.cpp +++ b/GeoLib/Surface.cpp @@ -40,8 +40,6 @@ Surface::~Surface () { for (std::size_t k(0); k < _sfc_triangles.size(); k++) delete _sfc_triangles[k]; - delete _bounding_volume; - delete _surface_grid; } void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) @@ -52,31 +50,20 @@ void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_ if (pnt_a == pnt_b || pnt_a == pnt_c || pnt_b == pnt_c) return; + // Adding a new triangle invalides the surface grid. + _surface_grid.reset(); + _sfc_triangles.push_back(new Triangle(_sfc_pnts, pnt_a, pnt_b, pnt_c)); if (!_bounding_volume) { std::vector<std::size_t> ids(3); ids[0] = pnt_a; ids[1] = pnt_b; ids[2] = pnt_c; - _bounding_volume = new AABB(_sfc_pnts, ids); - if (_surface_grid == nullptr) { - _surface_grid = new SurfaceGrid(this); - } + _bounding_volume.reset(new AABB(_sfc_pnts, ids)); } else { - bool bbx_updated(_bounding_volume->update(*_sfc_pnts[pnt_a])); - bbx_updated = bbx_updated || _bounding_volume->update(*_sfc_pnts[pnt_b]); - bbx_updated = bbx_updated || _bounding_volume->update(*_sfc_pnts[pnt_c]); - if (bbx_updated) { - delete _surface_grid; - _surface_grid = new SurfaceGrid(this); - } else { - if (! _surface_grid->sortTriangleInGridCells(_sfc_triangles.back())) { - ERR("Fatal: Could not insert triangle into surface grid. " - "To keep things consistent, the triangle is removed from " - "the surface!"); - _sfc_triangles.pop_back(); - } - } + _bounding_volume->update(*_sfc_pnts[pnt_a]); + _bounding_volume->update(*_sfc_pnts[pnt_b]); + _bounding_volume->update(*_sfc_pnts[pnt_c]); } } @@ -141,6 +128,10 @@ bool Surface::isPntInBoundingVolume(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. + if (_surface_grid == nullptr) { + _surface_grid.reset(new SurfaceGrid(this)); + } return _surface_grid->isPointInSurface( pnt, std::numeric_limits<double>::epsilon()); } diff --git a/GeoLib/Surface.h b/GeoLib/Surface.h index d655b28df7d0e669fdff95ed379924413d32c43c..67908462a60a469275c3cf4810733778ba900725 100644 --- a/GeoLib/Surface.h +++ b/GeoLib/Surface.h @@ -16,6 +16,7 @@ #define SURFACE_H_ #include <vector> +#include <memory> #include "GeoObject.h" #include "Point.h" @@ -95,9 +96,12 @@ protected: /** position of pointers to the geometric points */ std::vector<Triangle*> _sfc_triangles; /** bounding volume is an axis aligned bounding box */ - AABB *_bounding_volume; - /** a helper structure to accelerate the search */ - SurfaceGrid * _surface_grid; + std::unique_ptr<AABB> _bounding_volume; + /// The surface grid is a helper data structure to accelerate the point + /// search. The method addTriangle() invalidates/resets the surface grid. + /// A valid surface grid is created in case the const method isPntInSfc() is + /// called and a valid surface grid is not existing. + mutable std::unique_ptr<SurfaceGrid> _surface_grid; }; } diff --git a/GeoLib/SurfaceGrid.cpp b/GeoLib/SurfaceGrid.cpp index 4981b6f75c42e155b5336dbeef98a2a507fd0fe6..62e4cf991e875a2691fbb1d12d877418b8faec7e 100644 --- a/GeoLib/SurfaceGrid.cpp +++ b/GeoLib/SurfaceGrid.cpp @@ -120,10 +120,11 @@ void SurfaceGrid::sortTrianglesInGridCells(Surface const*const sfc) Point const& p0(*((*sfc)[l]->getPoint(0))); Point const& p1(*((*sfc)[l]->getPoint(1))); Point const& p2(*((*sfc)[l]->getPoint(2))); - DBUG("Sorting triangle %d [(%f,%f,%f), (%f,%f,%f), (%f,%f,%f) into " + ERR("Sorting triangle %d [(%f,%f,%f), (%f,%f,%f), (%f,%f,%f) into " "grid.", l, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2] ); + std::abort(); } } } diff --git a/GeoLib/SurfaceGrid.h b/GeoLib/SurfaceGrid.h index a7c9aa0e9005d5185458fb8bcce2be0452e360a1..e67588e49bac085108f59dc7becbc59af948d39c 100644 --- a/GeoLib/SurfaceGrid.h +++ b/GeoLib/SurfaceGrid.h @@ -34,7 +34,6 @@ public: double eps = std::numeric_limits<double>::epsilon()) const; private: - friend GeoLib::Surface; void sortTrianglesInGridCells(GeoLib::Surface const*const surface); bool sortTriangleInGridCells(GeoLib::Triangle const*const triangle); boost::optional<std::array<std::size_t,3>>