// Created on: 2013-12-20 // Created by: Denis BOGOLEPOV // Copyright (c) 2013-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _BVH_Box_Header #define _BVH_Box_Header #include #include //! Defines axis aligned bounding box (AABB) based on BVH vectors. //! \tparam T Numeric data type //! \tparam N Vector dimension template class BVH_Box { public: typedef typename BVH::VectorType::Type BVH_VecNt; public: //! Creates uninitialized bounding box. BVH_Box() : myIsInited (Standard_False) {} //! Creates bounding box of given point. BVH_Box (const BVH_VecNt& thePoint) : myMinPoint (thePoint), myMaxPoint (thePoint), myIsInited (Standard_True) {} //! Creates copy of another bounding box. BVH_Box (const BVH_Box& theBox) : myMinPoint (theBox.myMinPoint), myMaxPoint (theBox.myMaxPoint), myIsInited (theBox.myIsInited) {} //! Creates bounding box from corner points. BVH_Box (const BVH_VecNt& theMinPoint, const BVH_VecNt& theMaxPoint) : myMinPoint (theMinPoint), myMaxPoint (theMaxPoint), myIsInited (Standard_True) {} public: //! Clears bounding box. void Clear(); //! Is bounding box valid? Standard_Boolean IsValid() const; //! Appends new point to the bounding box. void Add (const BVH_VecNt& thePoint); //! Combines bounding box with another one. void Combine (const BVH_Box& theVolume); //! Returns minimum point of bounding box. const BVH_VecNt& CornerMin() const; //! Returns maximum point of bounding box. const BVH_VecNt& CornerMax() const; //! Returns minimum point of bounding box. BVH_VecNt& CornerMin(); //! Returns maximum point of bounding box. BVH_VecNt& CornerMax(); //! Returns surface area of bounding box. //! If the box is degenerated into line, returns the perimeter instead. T Area() const; //! Returns diagonal of bounding box. BVH_VecNt Size() const; //! Returns center of bounding box. BVH_VecNt Center() const; //! Returns center of bounding box along the given axis. T Center (const Standard_Integer theAxis) const; protected: BVH_VecNt myMinPoint; //!< Minimum point of bounding box BVH_VecNt myMaxPoint; //!< Maximum point of bounding box Standard_Boolean myIsInited; //!< Is bounding box initialized? }; namespace BVH { //! Tool class for calculating box center along the given axis. //! \tparam T Numeric data type //! \tparam N Vector dimension template struct CenterAxis { // Not implemented }; template struct CenterAxis { static T Center (const BVH_Box& theBox, const Standard_Integer theAxis) { if (theAxis == 0) { return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); } else if (theAxis == 1) { return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); } return static_cast (0.0); } }; template struct CenterAxis { static T Center (const BVH_Box& theBox, const Standard_Integer theAxis) { if (theAxis == 0) { return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); } else if (theAxis == 1) { return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); } else if (theAxis == 2) { return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast (0.5); } return static_cast (0.0); } }; template struct CenterAxis { static T Center (const BVH_Box& theBox, const Standard_Integer theAxis) { if (theAxis == 0) { return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast (0.5); } else if (theAxis == 1) { return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast (0.5); } else if (theAxis == 2) { return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast (0.5); } return static_cast (0.0); } }; //! Tool class for calculating surface area of the box. //! \tparam T Numeric data type //! \tparam N Vector dimension template struct SurfaceCalculator { // Not implemented }; template struct SurfaceCalculator { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { const T anArea = theSize.x() * theSize.y(); if (anArea < std::numeric_limits::epsilon()) { return theSize.x() + theSize.y(); } return anArea; } }; template struct SurfaceCalculator { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { const T anArea = ( theSize.x() * theSize.y() + theSize.x() * theSize.z() + theSize.z() * theSize.y() ) * static_cast (2.0); if (anArea < std::numeric_limits::epsilon()) { return theSize.x() + theSize.y() + theSize.z(); } return anArea; } }; template struct SurfaceCalculator { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { const T anArea = ( theSize.x() * theSize.y() + theSize.x() * theSize.z() + theSize.z() * theSize.y() ) * static_cast (2.0); if (anArea < std::numeric_limits::epsilon()) { return theSize.x() + theSize.y() + theSize.z(); } return anArea; } }; //! Tool class for calculate component-wise vector minimum //! and maximum (optimized version). //! \tparam T Numeric data type //! \tparam N Vector dimension template struct BoxMinMax { typedef typename BVH::VectorType::Type BVH_VecNt; static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) { theVec1.x() = Min (theVec1.x(), theVec2.x()); theVec1.y() = Min (theVec1.y(), theVec2.y()); theVec1.z() = Min (theVec1.z(), theVec2.z()); } static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) { theVec1.x() = Max (theVec1.x(), theVec2.x()); theVec1.y() = Max (theVec1.y(), theVec2.y()); theVec1.z() = Max (theVec1.z(), theVec2.z()); } }; template struct BoxMinMax { typedef typename BVH::VectorType::Type BVH_VecNt; static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) { theVec1.x() = Min (theVec1.x(), theVec2.x()); theVec1.y() = Min (theVec1.y(), theVec2.y()); } static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) { theVec1.x() = Max (theVec1.x(), theVec2.x()); theVec1.y() = Max (theVec1.y(), theVec2.y()); } }; } #include #endif // _BVH_Box_Header