X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FBVH%2FBVH_Box.hxx;h=920c278a4141b8e58e59a387c188f9f52a0bfe92;hp=95c2d7c108b10cd6d075b72e502ade52853fcbc4;hb=7c1a82100041c3b397b8e44925cee83d985e7804;hpb=679d38788d7360568e8dee6f2832d86a02800af9 diff --git a/src/BVH/BVH_Box.hxx b/src/BVH/BVH_Box.hxx index 95c2d7c108..920c278a41 100644 --- a/src/BVH/BVH_Box.hxx +++ b/src/BVH/BVH_Box.hxx @@ -16,7 +16,11 @@ #ifndef _BVH_Box_Header #define _BVH_Box_Header +#include #include +#include + +#include //! Defines axis aligned bounding box (AABB) based on BVH vectors. //! \tparam T Numeric data type @@ -55,41 +59,136 @@ public: public: //! Clears bounding box. - void Clear(); + void Clear() { myIsInited = Standard_False; } //! Is bounding box valid? - Standard_Boolean IsValid() const; + Standard_Boolean IsValid() const { return myIsInited; } //! Appends new point to the bounding box. - void Add (const BVH_VecNt& thePoint); + void Add (const BVH_VecNt& thePoint) + { + if (!myIsInited) + { + myMinPoint = thePoint; + myMaxPoint = thePoint; + myIsInited = Standard_True; + } + else + { + myMinPoint = myMinPoint.cwiseMin (thePoint); + myMaxPoint = myMaxPoint.cwiseMax (thePoint); + } + } //! Combines bounding box with another one. - void Combine (const BVH_Box& theVolume); + void Combine (const BVH_Box& theBox); //! Returns minimum point of bounding box. - const BVH_VecNt& CornerMin() const; + const BVH_VecNt& CornerMin() const { return myMinPoint; } //! Returns maximum point of bounding box. - const BVH_VecNt& CornerMax() const; + const BVH_VecNt& CornerMax() const { return myMaxPoint; } //! Returns minimum point of bounding box. - BVH_VecNt& CornerMin(); + BVH_VecNt& CornerMin() { return myMinPoint; } //! Returns maximum point of bounding box. - BVH_VecNt& CornerMax(); + BVH_VecNt& CornerMax() { return myMaxPoint; } //! 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; + BVH_VecNt Size() const { return myMaxPoint - myMinPoint; } //! Returns center of bounding box. - BVH_VecNt Center() const; + BVH_VecNt Center() const { return (myMinPoint + myMaxPoint) * static_cast (0.5); } //! Returns center of bounding box along the given axis. T Center (const Standard_Integer theAxis) const; +public: + + //! Checks if the Box is out of the other box. + Standard_Boolean IsOut (const BVH_Box& theOther) const + { + if (!theOther.IsValid()) + return Standard_True; + + return IsOut (theOther.myMinPoint, theOther.myMaxPoint); + } + + //! Checks if the Box is out of the other box defined by two points. + Standard_Boolean IsOut (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint) const + { + if (!IsValid()) + return Standard_True; + + int n = Min (N, 3); + for (int i = 0; i < n; ++i) + { + if (myMinPoint[i] > theMaxPoint[i] || + myMaxPoint[i] < theMinPoint[i]) + return Standard_True; + } + return Standard_False; + } + + //! Checks if the Box fully contains the other box. + Standard_Boolean Contains (const BVH_Box& theOther, + Standard_Boolean& hasOverlap) const + { + hasOverlap = Standard_False; + if (!theOther.IsValid()) + return Standard_False; + + return Contains (theOther.myMinPoint, theOther.myMaxPoint, hasOverlap); + } + + //! Checks if the Box is fully contains the other box. + Standard_Boolean Contains (const BVH_VecNt& theMinPoint, + const BVH_VecNt& theMaxPoint, + Standard_Boolean& hasOverlap) const + { + hasOverlap = Standard_False; + if (!IsValid()) + return Standard_False; + + Standard_Boolean isInside = Standard_True; + + int n = Min (N, 3); + for (int i = 0; i < n; ++i) + { + hasOverlap = (myMinPoint[i] <= theMaxPoint[i] && + myMaxPoint[i] >= theMinPoint[i]); + if (!hasOverlap) + return Standard_False; + + isInside = isInside && (myMinPoint[i] <= theMinPoint[i] && + myMaxPoint[i] >= theMaxPoint[i]); + } + return isInside; + } + + //! Checks if the Point is out of the box. + Standard_Boolean IsOut (const BVH_VecNt& thePoint) const + { + if (!IsValid()) + return Standard_True; + + int n = Min (N, 3); + for (int i = 0; i < n; ++i) + { + if (thePoint[i] < myMinPoint[i] || + thePoint[i] > myMaxPoint[i]) + return Standard_True; + } + return Standard_False; + } + + protected: BVH_VecNt myMinPoint; //!< Minimum point of bounding box @@ -182,7 +281,14 @@ namespace BVH { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { - return theSize.x() * theSize.y(); + const T anArea = theSize.x() * theSize.y(); + + if (anArea < std::numeric_limits::epsilon()) + { + return theSize.x() + theSize.y(); + } + + return anArea; } }; @@ -191,9 +297,18 @@ namespace BVH { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { - return ( theSize.x() * theSize.y() + - theSize.x() * theSize.z() + - theSize.z() * theSize.y() ) * static_cast (2.0); + 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; } }; @@ -202,9 +317,18 @@ namespace BVH { static T Area (const typename BVH_Box::BVH_VecNt& theSize) { - return ( theSize.x() * theSize.y() + - theSize.x() * theSize.z() + - theSize.z() * theSize.y() ) * static_cast (2.0); + 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; } }; @@ -251,6 +375,47 @@ namespace BVH }; } -#include +// ======================================================================= +// function : Combine +// purpose : +// ======================================================================= +template +void BVH_Box::Combine (const BVH_Box& theBox) +{ + if (theBox.myIsInited) + { + if (!myIsInited) + { + myMinPoint = theBox.myMinPoint; + myMaxPoint = theBox.myMaxPoint; + myIsInited = Standard_True; + } + else + { + BVH::BoxMinMax::CwiseMin (myMinPoint, theBox.myMinPoint); + BVH::BoxMinMax::CwiseMax (myMaxPoint, theBox.myMaxPoint); + } + } +} + +// ======================================================================= +// function : Area +// purpose : +// ======================================================================= +template +T BVH_Box::Area() const +{ + return !myIsInited ? static_cast (0.0) : BVH::SurfaceCalculator::Area (myMaxPoint - myMinPoint); +} + +// ======================================================================= +// function : Center +// purpose : +// ======================================================================= +template +T BVH_Box::Center (const Standard_Integer theAxis) const +{ + return BVH::CenterAxis::Center (*this, theAxis); +} #endif // _BVH_Box_Header