From 5a386db5bb958611f6c446c9111268cb043d30b2 Mon Sep 17 00:00:00 2001
From: Thomas Fischer <thomas.fischer@ufz.de>
Date: Wed, 24 Oct 2012 12:19:42 +0200
Subject: [PATCH] changed implementation of class AABB to a class template

---
 GeoLib/AxisAlignedBoundingBox.cpp          | 97 ----------------------
 GeoLib/AxisAlignedBoundingBox.h            | 74 +++++++++--------
 GeoLib/Grid.h                              | 47 +++++------
 GeoLib/PointVec.h                          |  4 +-
 GeoLib/Polygon.h                           |  2 +-
 GeoLib/Surface.cpp                         |  4 +-
 GeoLib/Surface.h                           |  6 +-
 Gui/VtkVis/VtkConditionSource.cpp          |  2 +-
 MeshLib/Mesh2MeshPropertyInterpolation.cpp |  4 +-
 9 files changed, 71 insertions(+), 169 deletions(-)
 delete mode 100644 GeoLib/AxisAlignedBoundingBox.cpp

diff --git a/GeoLib/AxisAlignedBoundingBox.cpp b/GeoLib/AxisAlignedBoundingBox.cpp
deleted file mode 100644
index c23570c2156..00000000000
--- a/GeoLib/AxisAlignedBoundingBox.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Copyright (c) 2012, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- *
- *
- * \file AxisAlignedBoundingBox.cpp
- *
- * Created on 2010-04-22 by Thomas Fischer
- */
-
-#include "AxisAlignedBoundingBox.h"
-#include <cmath>
-#include <cstddef>
-#include <limits>
-
-namespace GeoLib
-{
-AABB::AABB()
-{
-	for (std::size_t k(0); k < 3; k++) {
-		_min_pnt[k] = std::numeric_limits<double>::max();
-		_max_pnt[k] = std::numeric_limits<double>::min();
-	}
-}
-
-AABB::AABB(AABB const& src) :
-	_min_pnt(src._min_pnt), _max_pnt(src._max_pnt)
-{}
-
-void AABB::update(GeoLib::Point const& pnt)
-{
-	for (size_t k(0); k<3; k++) {
-		if (pnt[k] < _min_pnt[k])
-			_min_pnt[k] = pnt[k];
-		if (_max_pnt[k] < pnt[k])
-			_max_pnt[k] = pnt[k];
-	}
-}
-
-void AABB::update (double x, double y, double z)
-{
-	if (x < _min_pnt[0])
-		_min_pnt[0] = x;
-	if (_max_pnt[0] < x)
-		_max_pnt[0] = x;
-	if (y < _min_pnt[1])
-		_min_pnt[1] = y;
-	if (_max_pnt[1] < y)
-		_max_pnt[1] = y;
-	if (z < _min_pnt[2])
-		_min_pnt[2] = z;
-	if (_max_pnt[2] < z)
-		_max_pnt[2] = z;
-}
-
-bool AABB::containsPoint (GeoLib::Point const & pnt, double eps) const
-{
-	return containsPoint (pnt[0], pnt[1], pnt[2], eps);
-}
-
-bool AABB::containsPoint (const double* pnt, double eps) const
-{
-	return containsPoint (pnt[0], pnt[1], pnt[2], eps);
-}
-
-bool AABB::containsPoint (double x, double y, double z, double eps) const
-{
-	if ((_min_pnt[0] <= x && x <= _max_pnt[0]) || std::fabs(_min_pnt[0] - x) < eps
-					|| std::fabs(x - _max_pnt[0]) < eps) {
-		if ((_min_pnt[1] <= y && y <= _max_pnt[1]) || std::fabs(_min_pnt[1] - y) < eps
-						|| std::fabs(y - _max_pnt[1]) < eps) {
-			if ((_min_pnt[2] <= z && z <= _max_pnt[2]) || std::fabs(_min_pnt[2] - z) < eps
-							|| std::fabs(z - _max_pnt[2]) < eps) {
-				return true;
-			} else {
-				return false;
-			}
-		} else {
-			return false;
-		}
-	} else return false;
-}
-
-bool AABB::containsAABB (AABB const& other_aabb) const
-{
-	GeoLib::Point const& min_other(other_aabb.getMinPoint());
-	GeoLib::Point const& max_other(other_aabb.getMaxPoint());
-	for (unsigned k(0); k<3; k++) {
-		if (_min_pnt[k] > min_other[k] || max_other[k] > _max_pnt[k])
-			return false;
-	}
-	return true;
-}
-
-} // end namespace GeoLib
diff --git a/GeoLib/AxisAlignedBoundingBox.h b/GeoLib/AxisAlignedBoundingBox.h
index 201ef8c04d9..f732df124ae 100644
--- a/GeoLib/AxisAlignedBoundingBox.h
+++ b/GeoLib/AxisAlignedBoundingBox.h
@@ -15,7 +15,7 @@
 
 #include "Point.h"
 #include <limits>
-#include <vector>
+#include <cstddef>
 
 namespace GeoLib
 {
@@ -24,21 +24,27 @@ namespace GeoLib
  * \ingroup GeoLib
  *
  * \brief Class AABB is an axis aligned bounding box around a given
- * set of geometric points.
+ * set of geometric points of (template) type PNT_TYPE.
  * */
+template <typename PNT_TYPE = GeoLib::Point>
 class AABB
 {
 public:
 	/**
 	 * construction of object, initialization the axis aligned bounding box
 	 * */
-	AABB();
+	AABB() :
+		_min_pnt(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max()),
+		_max_pnt(std::numeric_limits<double>::min(), std::numeric_limits<double>::min(), std::numeric_limits<double>::min())
+	{}
 
 	/**
 	 * copy constructor.
 	 * @param src an axis aligned bounding box
 	 */
-	AABB(AABB const& src);
+	AABB(AABB<PNT_TYPE> const& src) :
+		_min_pnt(src._min_pnt), _max_pnt(src._max_pnt)
+	{}
 
 	/**
 	 * Construction of object using input iterators. In contrast to give a vector
@@ -53,40 +59,32 @@ public:
 	{
 		InputIterator it(first);
 		while (it != last) {
-			this->update(*(reinterpret_cast<GeoLib::Point *const>(*it)));
+			update(*it);
 			it++;
 		}
 	}
 
-	void update(GeoLib::Point const & pnt);
-
-	/**
-	 * update axis aligned bounding box
-	 */
-	void update(const double* pnt)
+	void update(PNT_TYPE const & pnt)
 	{
-		update(pnt[0], pnt[1], pnt[2]);
+		for (size_t k(0); k<3; k++) {
+			if (pnt[k] < _min_pnt[k])
+				_min_pnt[k] = pnt[k];
+			if (_max_pnt[k] < pnt[k])
+				_max_pnt[k] = pnt[k];
+		}
 	}
 
 	/**
 	 * check if point is in the axis aligned bounding box
 	 * (employing containsPoint (double x, double y, double z))
 	 */
-	bool containsPoint(GeoLib::Point const & pnt,
-	                   double eps = std::numeric_limits<double>::epsilon()) const;
-
-	/**
-	 * wrapper for GeoLib::Point
-	 */
-	bool containsPoint(const double* pnt, double eps =
-	                            std::numeric_limits<double>::epsilon()) const;
-
-	/**
-	 * check if point described by its coordinates x, y, z is in
-	 * the axis aligned bounding box
-	 */
-	bool containsPoint(double x, double y, double z, double eps =
-					std::numeric_limits<double>::epsilon()) const;
+	bool containsPoint(PNT_TYPE const & pnt) const
+	{
+		if (pnt[0] < _min_pnt[0] || _max_pnt[0] < pnt[0]) return false;
+		if (pnt[1] < _min_pnt[1] || _max_pnt[1] < pnt[1]) return false;
+		if (pnt[2] < _min_pnt[2] || _max_pnt[2] < pnt[2]) return false;
+		return true;
+	}
 
 	/**
 	 * returns a point that coordinates are minimal for each dimension
@@ -105,21 +103,29 @@ public:
 	/**
 	 * Method checks if the given AABB object is contained within the
 	 * AABB represented by this object.
-	 * @param other the AABB to test with
+	 * @param other_aabb the AABB to test with
 	 * @return true if the other AABB is contained in the AABB
 	 * represented by this object
 	 */
-	bool containsAABB(AABB const& other) const;
+	bool containsAABB(AABB<PNT_TYPE> const& other_aabb) const
+	{
+		GeoLib::Point const& min_other(other_aabb.getMinPoint());
+		GeoLib::Point const& max_other(other_aabb.getMaxPoint());
+		for (unsigned k(0); k<3; k++) {
+			if (_min_pnt[k] > min_other[k] || max_other[k] > _max_pnt[k])
+				return false;
+		}
+		return true;
+	}
 
 protected:
 	GeoLib::Point _min_pnt;
 	GeoLib::Point _max_pnt;
-
 private:
-	/**
-	 * update axis aligned bounding box
-	 */
-	void update(double x, double y, double z);
+	void update(PNT_TYPE const * pnt)
+	{
+		update (*pnt);
+	}
 };
 } // end namespace
 
diff --git a/GeoLib/Grid.h b/GeoLib/Grid.h
index da8a896e385..c4230d689d1 100644
--- a/GeoLib/Grid.h
+++ b/GeoLib/Grid.h
@@ -27,7 +27,7 @@
 namespace GeoLib {
 
 template <typename POINT>
-class Grid : public GeoLib::AABB
+class Grid : public GeoLib::AABB<POINT>
 {
 public:
 	/**
@@ -47,26 +47,19 @@ public:
 	 */
 	template <typename InputIterator>
 	Grid(InputIterator first, InputIterator last, std::size_t max_num_per_grid_cell = 512) :
-		GeoLib::AABB(), _grid_cell_nodes_map(NULL)
+		GeoLib::AABB<POINT>(first, last), _grid_cell_nodes_map(NULL)
 	{
-		// compute axis aligned bounding box
-		InputIterator it(first);
-		std::size_t n_pnts(0);
-		while (it != last) {
-			n_pnts++;
-			this->update(copyOrAddress(*it)->getCoords());
-			it++;
-		}
+		std::size_t n_pnts(std::distance(first, last));
 
 		double delta[3] = { 0.0, 0.0, 0.0 };
 		for (std::size_t k(0); k < 3; k++) {
 			// make the bounding box a little bit bigger,
 			// such that the node with maximal coordinates fits into the grid
-			_max_pnt[k] *= (1.0 + 1e-6);
-			if (fabs(_max_pnt[k]) < std::numeric_limits<double>::epsilon()) {
-				_max_pnt[k] = (_max_pnt[k] - _min_pnt[k]) * (1.0 + 1e-6);
+			this->_max_pnt[k] *= (1.0 + 1e-6);
+			if (fabs(this->_max_pnt[k]) < std::numeric_limits<double>::epsilon()) {
+				this->_max_pnt[k] = (this->_max_pnt[k] - this->_min_pnt[k]) * (1.0 + 1e-6);
 			}
-			delta[k] = _max_pnt[k] - _min_pnt[k];
+			delta[k] = this->_max_pnt[k] - this->_min_pnt[k];
 		}
 
 		// *** condition: n_pnts / (_n_steps[0] * _n_steps[1] * _n_steps[2]) < max_num_per_grid_cell
@@ -134,12 +127,12 @@ public:
 		}
 
 		// fill the grid vectors
-		it = first;
+		InputIterator it(first);
 		while (it != last) {
 			double const* const pnt(copyOrAddress(*it)->getCoords());
-			const std::size_t i(static_cast<std::size_t> ((pnt[0] - _min_pnt[0]) * _inverse_step_sizes[0]));
-			const std::size_t j(static_cast<std::size_t> ((pnt[1] - _min_pnt[1]) * _inverse_step_sizes[1]));
-			const std::size_t k(static_cast<std::size_t> ((pnt[2] - _min_pnt[2]) * _inverse_step_sizes[2]));
+			const std::size_t i(static_cast<std::size_t> ((pnt[0] - this->_min_pnt[0]) * _inverse_step_sizes[0]));
+			const std::size_t j(static_cast<std::size_t> ((pnt[1] - this->_min_pnt[1]) * _inverse_step_sizes[1]));
+			const std::size_t k(static_cast<std::size_t> ((pnt[2] - this->_min_pnt[2]) * _inverse_step_sizes[2]));
 
 			if (i >= _n_steps[0] || j >= _n_steps[1] || k >= _n_steps[2]) {
 				std::cout << "error computing indices " << std::endl;
@@ -185,7 +178,7 @@ public:
 		std::size_t coords[3];
 		getGridCoords(pnt, coords);
 
-		double sqr_min_dist (MathLib::sqrDist(&_min_pnt, &_max_pnt));
+		double sqr_min_dist (MathLib::sqrDist(&this->_min_pnt, &this->_max_pnt));
 		POINT* nearest_pnt(NULL);
 
 		double dists[6];
@@ -380,8 +373,8 @@ void Grid<POINT>::createGridGeometry(GeoLib::GEOObjects* geo_obj) const
 {
 	std::vector<std::string> grid_names;
 
-	GeoLib::Point const& llf (getMinPoint());
-	GeoLib::Point const& urb (getMaxPoint());
+	GeoLib::Point const& llf (this->getMinPoint());
+	GeoLib::Point const& urb (this->getMaxPoint());
 
 	const double dx ((urb[0]-llf[0])/_n_steps[0]);
 	const double dy ((urb[1]-llf[1])/_n_steps[1]);
@@ -460,13 +453,13 @@ template <typename POINT>
 void Grid<POINT>::getGridCoords(double const*const pnt, std::size_t* coords) const
 {
 	for (std::size_t k(0); k<3; k++) {
-		if (pnt[k] < _min_pnt[k]) {
+		if (pnt[k] < this->_min_pnt[k]) {
 			coords[k] = 0;
 		} else {
-			if (pnt[k] > _max_pnt[k]) {
+			if (pnt[k] > this->_max_pnt[k]) {
 				coords[k] = _n_steps[k]-1;
 			} else {
-				coords[k] = static_cast<std::size_t>((pnt[k]-_min_pnt[k]) * _inverse_step_sizes[k]);
+				coords[k] = static_cast<std::size_t>((pnt[k]-this->_min_pnt[k]) * _inverse_step_sizes[k]);
 			}
 		}
 	}
@@ -476,13 +469,13 @@ template <typename POINT>
 void Grid<POINT>::getPointCellBorderDistances(double const*const pnt, double dists[6], std::size_t const* const coords) const
 {
 
-	dists[0] = (pnt[2] - _min_pnt[2] + coords[2]*_step_sizes[2]); // bottom
+	dists[0] = (pnt[2] - this->_min_pnt[2] + coords[2]*_step_sizes[2]); // bottom
 	dists[5] = (_step_sizes[2] - dists[0]); // top
 
-	dists[1] = (pnt[1] - _min_pnt[1] + coords[1]*_step_sizes[1]); // front
+	dists[1] = (pnt[1] - this->_min_pnt[1] + coords[1]*_step_sizes[1]); // front
 	dists[3] = (_step_sizes[1] - dists[1]); // back
 
-	dists[4] = (pnt[0] - _min_pnt[0] + coords[0]*_step_sizes[0]); // left
+	dists[4] = (pnt[0] - this->_min_pnt[0] + coords[0]*_step_sizes[0]); // left
 	dists[2] = (_step_sizes[0] - dists[4]); // right
 }
 
diff --git a/GeoLib/PointVec.h b/GeoLib/PointVec.h
index 64878c089f7..ab42691b775 100644
--- a/GeoLib/PointVec.h
+++ b/GeoLib/PointVec.h
@@ -104,7 +104,7 @@ public:
 	const std::vector<std::size_t>& getIDMap () const { return _pnt_id_map; }
 
 	double getShortestPointDistance () const;
-	const GeoLib::AABB& getAxisAlignedBoundingBox () const;
+	const GeoLib::AABB<GeoLib::Point>& getAxisAlignedBoundingBox () const;
 
 	/// Returns a subset of this point vector containing only the points specified in "subset" as PointWithID-objects
 	std::vector<GeoLib::Point*>* getSubset(const std::vector<std::size_t> &subset);
@@ -144,7 +144,7 @@ private:
 	double _sqr_shortest_dist;
 
 	void calculateAxisAlignedBoundingBox ();
-	AABB _aabb;
+	AABB<GeoLib::Point> _aabb;
 };
 } // end namespace
 
diff --git a/GeoLib/Polygon.h b/GeoLib/Polygon.h
index b2d48630ede..bb1d95197d3 100644
--- a/GeoLib/Polygon.h
+++ b/GeoLib/Polygon.h
@@ -127,7 +127,7 @@ private:
 	void splitPolygonAtIntersection (std::list<Polygon*>::iterator polygon_it);
 	void splitPolygonAtPoint (std::list<Polygon*>::iterator polygon_it);
 	std::list<Polygon*> _simple_polygon_list;
-	AABB _aabb;
+	AABB<GeoLib::Point> _aabb;
 };
 
 /**
diff --git a/GeoLib/Surface.cpp b/GeoLib/Surface.cpp
index da056527620..a5e21096b5a 100644
--- a/GeoLib/Surface.cpp
+++ b/GeoLib/Surface.cpp
@@ -93,9 +93,9 @@ const Triangle* Surface::operator[] (size_t i) const
 	return _sfc_triangles[i];
 }
 
-bool Surface::isPntInBV (const double *pnt, double eps) const
+bool Surface::isPntInBV (const double *pnt) const
 {
-	return _bv.containsPoint (pnt, eps);
+	return _bv.containsPoint (pnt);
 }
 
 bool Surface::isPntInSfc (const double *pnt) const
diff --git a/GeoLib/Surface.h b/GeoLib/Surface.h
index a0c6aa11642..8b48c904db8 100644
--- a/GeoLib/Surface.h
+++ b/GeoLib/Surface.h
@@ -56,7 +56,7 @@ public:
 	/**
 	 * is the given point in the bounding volume of the surface
 	 */
-	bool isPntInBV (const double *pnt, double eps = std::numeric_limits<double>::epsilon()) const;
+	bool isPntInBV (const double *pnt) const;
 
 	/**
 	 * is the given point pnt located in the surface
@@ -71,7 +71,7 @@ public:
 	 * method allows access to the internal axis aligned bounding box
 	 * @return axis aligned bounding box
 	 */
-	AABB const & getAABB () const { return _bv; }
+	AABB<GeoLib::Point> const & getAABB () const { return _bv; }
 
 protected:
 	/** a vector of pointers to Points */
@@ -79,7 +79,7 @@ protected:
 	/** position of pointers to the geometric points */
 	std::vector<Triangle*> _sfc_triangles;
 	/** bounding volume is an axis aligned bounding box */
-	AABB _bv;
+	AABB<GeoLib::Point> _bv;
 };
 
 }
diff --git a/Gui/VtkVis/VtkConditionSource.cpp b/Gui/VtkVis/VtkConditionSource.cpp
index 25812fa7ebc..39554ddbb37 100644
--- a/Gui/VtkVis/VtkConditionSource.cpp
+++ b/Gui/VtkVis/VtkConditionSource.cpp
@@ -253,7 +253,7 @@ int VtkConditionSource::RequestData( vtkInformation* request,
 		// draw a bounding box in case of of the conditions is "domain"
 		else if ((*_cond_vec)[n]->getGeomType() == GeoLib::GEODOMAIN)
 		{
-			GeoLib::AABB bounding_box (_points->begin(), _points->end());
+			GeoLib::AABB<GeoLib::Point> bounding_box (_points->begin(), _points->end());
 			std::vector<GeoLib::Point> box;
 			box.push_back(bounding_box.getMinPoint());
 			box.push_back(bounding_box.getMaxPoint());
diff --git a/MeshLib/Mesh2MeshPropertyInterpolation.cpp b/MeshLib/Mesh2MeshPropertyInterpolation.cpp
index 648709929c3..a44f349e253 100644
--- a/MeshLib/Mesh2MeshPropertyInterpolation.cpp
+++ b/MeshLib/Mesh2MeshPropertyInterpolation.cpp
@@ -46,8 +46,8 @@ bool Mesh2MeshPropertyInterpolation::setPropertiesForMesh(Mesh *dest_mesh, std::
 		return false;
 	}
 
-	GeoLib::AABB src_aabb(_src_mesh->getNodes().begin(), _src_mesh->getNodes().end());
-	GeoLib::AABB dest_aabb(dest_mesh->getNodes().begin(), dest_mesh->getNodes().end());
+	GeoLib::AABB<MeshLib::Node> src_aabb(_src_mesh->getNodes().begin(), _src_mesh->getNodes().end());
+	GeoLib::AABB<MeshLib::Node> dest_aabb(dest_mesh->getNodes().begin(), dest_mesh->getNodes().end());
 	if (!src_aabb.containsAABB(dest_aabb)) {
 		ERR ("MeshLib::Mesh2MeshPropertyInterpolation::setPropertiesForMesh() source mesh to small.");
 		return false;
-- 
GitLab