- Replaced macro-based template system with C++ templates for `Bnd_B2` and `Bnd_B3` classes
- Fixed incorrect use of Y-coordinate instead of Z-coordinate in transformation methods
- Added comprehensive GTest test coverage for both 2D and 3D bounding box classes
#include <VrmlData_ListOfNode.hxx>
#include <VrmlData_DataMapOfShapeAppearance.hxx>
-#include <Bnd_B3f.hxx>
+#include <Bnd_B3.hxx>
#include <gp_Trsf.hxx>
class TopoDS_Shape;
--- /dev/null
+// Created on: 2005-09-08
+// Created by: Alexander GRIGORIEV
+// Copyright (c) 2005-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 _Bnd_B2_HeaderFile
+#define _Bnd_B2_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_ShortReal.hxx>
+#include <gp_XY.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Trsf2d.hxx>
+#include <gp_Ax2d.hxx>
+
+//! Template class for 2D bounding box.
+//! This is a base template that is instantiated for Standard_Real and Standard_ShortReal.
+template <typename RealType>
+class Bnd_B2
+{
+public:
+ DEFINE_STANDARD_ALLOC
+
+ //! Empty constructor.
+ Bnd_B2();
+
+ //! Constructor.
+ Bnd_B2(const gp_XY& theCenter, const gp_XY& theHSize);
+
+ //! Returns True if the box is void (non-initialized).
+ Standard_Boolean IsVoid() const;
+
+ //! Reset the box data.
+ void Clear();
+
+ //! Update the box by a point.
+ void Add(const gp_XY& thePnt);
+
+ //! Update the box by a point.
+ void Add(const gp_Pnt2d& thePnt);
+
+ //! Update the box by another box.
+ void Add(const Bnd_B2<RealType>& theBox);
+
+ //! Query a box corner: (Center - HSize). You must make sure that
+ //! the box is NOT VOID (see IsVoid()), otherwise the method returns
+ //! irrelevant result.
+ gp_XY CornerMin() const;
+
+ //! Query a box corner: (Center + HSize). You must make sure that
+ //! the box is NOT VOID (see IsVoid()), otherwise the method returns
+ //! irrelevant result.
+ gp_XY CornerMax() const;
+
+ //! Query the square diagonal. If the box is VOID (see method IsVoid())
+ //! then a very big real value is returned.
+ Standard_Real SquareExtent() const;
+
+ //! Extend the Box by the absolute value of theDiff.
+ void Enlarge(const Standard_Real theDiff);
+
+ //! Limit the Box by the internals of theOtherBox.
+ //! Returns True if the limitation takes place, otherwise False
+ //! indicating that the boxes do not intersect.
+ Standard_Boolean Limit(const Bnd_B2<RealType>& theOtherBox);
+
+ //! Transform the bounding box with the given transformation.
+ //! The resulting box will be larger if theTrsf contains rotation.
+ Standard_NODISCARD Bnd_B2<RealType> Transformed(const gp_Trsf2d& theTrsf) const;
+
+ //! Check the given point for the inclusion in the Box.
+ //! Returns True if the point is outside.
+ Standard_Boolean IsOut(const gp_XY& thePnt) const;
+
+ //! Check a circle for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes.
+ Standard_Boolean IsOut(const gp_XY& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Boolean isCircleHollow = Standard_False) const;
+
+ //! Check the given box for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes.
+ Standard_Boolean IsOut(const Bnd_B2<RealType>& theOtherBox) const;
+
+ //! Check the given box oriented by the given transformation
+ //! for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes.
+ Standard_Boolean IsOut(const Bnd_B2<RealType>& theOtherBox, const gp_Trsf2d& theTrsf) const;
+
+ //! Check the given Line for the intersection with the current box.
+ //! Returns True if there is no intersection.
+ Standard_Boolean IsOut(const gp_Ax2d& theLine) const;
+
+ //! Check the Segment defined by the couple of input points
+ //! for the intersection with the current box.
+ //! Returns True if there is no intersection.
+ Standard_Boolean IsOut(const gp_XY& theP0, const gp_XY& theP1) const;
+
+ //! Check that the box 'this' is inside the given box 'theBox'. Returns
+ //! True if 'this' box is fully inside 'theBox'.
+ Standard_Boolean IsIn(const Bnd_B2<RealType>& theBox) const;
+
+ //! Check that the box 'this' is inside the given box 'theBox'
+ //! transformed by 'theTrsf'. Returns True if 'this' box is fully
+ //! inside the transformed 'theBox'.
+ Standard_Boolean IsIn(const Bnd_B2<RealType>& theBox, const gp_Trsf2d& theTrsf) const;
+
+ //! Set the Center coordinates
+ void SetCenter(const gp_XY& theCenter);
+
+ //! Set the HSize (half-diagonal) coordinates.
+ //! All components of theHSize must be non-negative.
+ void SetHSize(const gp_XY& theHSize);
+
+protected:
+ static Standard_Boolean compareDist(const RealType aHSize[2], const RealType aDist[2])
+ {
+ return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
+ }
+
+ static Standard_Boolean compareDistD(const gp_XY& aHSize, const gp_XY& aDist)
+ {
+ return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
+ }
+
+ //! Constant representing a very large value for void box initialization
+ static constexpr RealType THE_RealLast = RealType(1e30);
+
+private:
+ RealType myCenter[2];
+ RealType myHSize[2];
+};
+
+//=================================================================================================
+
+template <typename RealType>
+inline Bnd_B2<RealType>::Bnd_B2()
+{
+ Clear();
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Bnd_B2<RealType>::Bnd_B2(const gp_XY& theCenter, const gp_XY& theHSize)
+{
+ myCenter[0] = RealType(theCenter.X());
+ myCenter[1] = RealType(theCenter.Y());
+ myHSize[0] = RealType(theHSize.X());
+ myHSize[1] = RealType(theHSize.Y());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::Clear()
+{
+ myCenter[0] = THE_RealLast;
+ myCenter[1] = THE_RealLast;
+ myHSize[0] = -THE_RealLast;
+ myHSize[1] = -THE_RealLast;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B2<RealType>::IsVoid() const
+{
+ return (myHSize[0] < -1e-5);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::Add(const gp_Pnt2d& thePnt)
+{
+ Add(thePnt.XY());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::Add(const Bnd_B2<RealType>& theBox)
+{
+ if (theBox.IsVoid() == Standard_False)
+ {
+ Add(theBox.CornerMin());
+ Add(theBox.CornerMax());
+ }
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline gp_XY Bnd_B2<RealType>::CornerMin() const
+{
+ return gp_XY(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline gp_XY Bnd_B2<RealType>::CornerMax() const
+{
+ return gp_XY(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Real Bnd_B2<RealType>::SquareExtent() const
+{
+ return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::SetCenter(const gp_XY& theCenter)
+{
+ myCenter[0] = RealType(theCenter.X());
+ myCenter[1] = RealType(theCenter.Y());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::SetHSize(const gp_XY& theHSize)
+{
+ myHSize[0] = RealType(theHSize.X());
+ myHSize[1] = RealType(theHSize.Y());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B2<RealType>::Enlarge(const Standard_Real aDiff)
+{
+ const RealType aD = RealType(Abs(aDiff));
+ myHSize[0] += aD;
+ myHSize[1] += aD;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B2<RealType>::IsOut(const gp_XY& thePnt) const
+{
+ return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0]
+ || Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B2<RealType>::IsOut(const Bnd_B2<RealType>& theBox) const
+{
+ return (Abs(theBox.myCenter[0] - myCenter[0]) > theBox.myHSize[0] + myHSize[0]
+ || Abs(theBox.myCenter[1] - myCenter[1]) > theBox.myHSize[1] + myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B2<RealType>::IsIn(const Bnd_B2<RealType>& theBox) const
+{
+ return (Abs(theBox.myCenter[0] - myCenter[0]) < theBox.myHSize[0] - myHSize[0]
+ && Abs(theBox.myCenter[1] - myCenter[1]) < theBox.myHSize[1] - myHSize[1]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+void Bnd_B2<RealType>::Add(const gp_XY& thePnt)
+{
+ if (IsVoid())
+ {
+ myCenter[0] = RealType(thePnt.X());
+ myCenter[1] = RealType(thePnt.Y());
+ myHSize[0] = 0.;
+ myHSize[1] = 0.;
+ }
+ else
+ {
+ const RealType aDiff[2] = {RealType(thePnt.X()) - myCenter[0],
+ RealType(thePnt.Y()) - myCenter[1]};
+ if (aDiff[0] > myHSize[0])
+ {
+ const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
+ myCenter[0] += aShift;
+ myHSize[0] += aShift;
+ }
+ else if (aDiff[0] < -myHSize[0])
+ {
+ const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
+ myCenter[0] += aShift;
+ myHSize[0] -= aShift;
+ }
+ if (aDiff[1] > myHSize[1])
+ {
+ const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
+ myCenter[1] += aShift;
+ myHSize[1] += aShift;
+ }
+ else if (aDiff[1] < -myHSize[1])
+ {
+ const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
+ myCenter[1] += aShift;
+ myHSize[1] -= aShift;
+ }
+ }
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::Limit(const Bnd_B2<RealType>& theBox)
+{
+ Standard_Boolean aResult(Standard_False);
+ const RealType diffC[2] = {theBox.myCenter[0] - myCenter[0], theBox.myCenter[1] - myCenter[1]};
+ const RealType sumH[2] = {theBox.myHSize[0] + myHSize[0], theBox.myHSize[1] + myHSize[1]};
+ // check the condition IsOut
+ if (compareDist(sumH, diffC) == Standard_False)
+ {
+ const RealType diffH[2] = {theBox.myHSize[0] - myHSize[0], theBox.myHSize[1] - myHSize[1]};
+ if (diffC[0] - diffH[0] > 0.)
+ {
+ const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
+ myCenter[0] += aShift;
+ myHSize[0] -= aShift;
+ }
+ else if (diffC[0] + diffH[0] < 0.)
+ {
+ const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
+ myCenter[0] += aShift;
+ myHSize[0] += aShift;
+ }
+ if (diffC[1] - diffH[1] > 0.)
+ {
+ const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
+ myCenter[1] += aShift;
+ myHSize[1] -= aShift;
+ }
+ else if (diffC[1] + diffH[1] < 0.)
+ {
+ const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
+ myCenter[1] += aShift;
+ myHSize[1] += aShift;
+ }
+ aResult = Standard_True;
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Bnd_B2<RealType> Bnd_B2<RealType>::Transformed(const gp_Trsf2d& theTrsf) const
+{
+ Bnd_B2<RealType> aResult;
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Identity)
+ aResult = *this;
+ else if (aForm == gp_Translation || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult.myCenter[0] = (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
+ aResult.myCenter[1] = (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
+ aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
+ aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
+ }
+ else
+ {
+ gp_XY aCenter((Standard_Real)myCenter[0], (Standard_Real)myCenter[1]);
+ theTrsf.Transforms(aCenter);
+ aResult.myCenter[0] = (RealType)aCenter.X();
+ aResult.myCenter[1] = (RealType)aCenter.Y();
+
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+ aResult.myHSize[0] =
+ (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0] + Abs(aMat[1]) * myHSize[1]));
+ aResult.myHSize[1] =
+ (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0] + Abs(aMat[3]) * myHSize[1]));
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::IsOut(const gp_XY& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Boolean isCircleHollow) const
+{
+ Standard_Boolean aResult(Standard_True);
+ if (isCircleHollow == Standard_False)
+ {
+ // vector from the center of the circle to the nearest box face
+ const Standard_Real aDist[2] = {
+ Abs(theCenter.X() - Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
+ Abs(theCenter.Y() - Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])};
+ Standard_Real aD(0.);
+ if (aDist[0] > 0.)
+ aD = aDist[0] * aDist[0];
+ if (aDist[1] > 0.)
+ aD += aDist[1] * aDist[1];
+ aResult = (aD > theRadius * theRadius);
+ }
+ else
+ {
+ const Standard_Real aDistC[2] = {Abs(theCenter.X() - Standard_Real(myCenter[0])),
+ Abs(theCenter.Y() - Standard_Real(myCenter[1]))};
+ // vector from the center of the circle to the nearest box face
+ Standard_Real aDist[2] = {aDistC[0] - Standard_Real(myHSize[0]),
+ aDistC[1] - Standard_Real(myHSize[1])};
+ Standard_Real aD(0.);
+ if (aDist[0] > 0.)
+ aD = aDist[0] * aDist[0];
+ if (aDist[1] > 0.)
+ aD += aDist[1] * aDist[1];
+ if (aD < theRadius * theRadius)
+ {
+ // the box intersects the solid circle; check if it is completely
+ // inside the circle (in such case return isOut==True)
+ aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
+ aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
+ if (aDist[0] * aDist[0] + aDist[1] * aDist[1] > theRadius * theRadius)
+ aResult = Standard_False;
+ }
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::IsOut(const Bnd_B2<RealType>& theBox,
+ const gp_Trsf2d& theTrsf) const
+{
+ Standard_Boolean aResult(Standard_False);
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult =
+ (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
+ > RealType(theBox.myHSize[0] * aScaleAbs) + myHSize[0]
+ || Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
+ > RealType(theBox.myHSize[1] * aScaleAbs) + myHSize[1]);
+ }
+ else
+ {
+ // theBox is transformed and we check the resulting (enlarged) box against
+ // 'this' box.
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+
+ gp_XY aCenter((Standard_Real)theBox.myCenter[0], (Standard_Real)theBox.myCenter[1]);
+ theTrsf.Transforms(aCenter);
+ const Standard_Real aDist[2] = {aCenter.X() - (Standard_Real)myCenter[0],
+ aCenter.Y() - (Standard_Real)myCenter[1]};
+ const Standard_Real aMatAbs[4] = {Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])};
+ if (Abs(aDist[0])
+ > (aScaleAbs * (aMatAbs[0] * theBox.myHSize[0] + aMatAbs[1] * theBox.myHSize[1])
+ + (Standard_Real)myHSize[0])
+ || Abs(aDist[1])
+ > (aScaleAbs * (aMatAbs[2] * theBox.myHSize[0] + aMatAbs[3] * theBox.myHSize[1])
+ + (Standard_Real)myHSize[1]))
+ aResult = Standard_True;
+
+ else
+ {
+ // theBox is rotated, scaled and translated. We apply the reverse
+ // translation and scaling then check against the rotated box 'this'
+ if ((Abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
+ > theBox.myHSize[0] * aScaleAbs + (aMatAbs[0] * myHSize[0] + aMatAbs[2] * myHSize[1]))
+ || (Abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
+ > theBox.myHSize[1] * aScaleAbs
+ + (aMatAbs[1] * myHSize[0] + aMatAbs[3] * myHSize[1])))
+ aResult = Standard_True;
+ }
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::IsOut(const gp_Ax2d& theLine) const
+{
+ if (IsVoid())
+ return Standard_True;
+ // Intersect the line containing the segment.
+ const Standard_Real aProd[3] = {
+ theLine.Direction().XY()
+ ^ (gp_XY(myCenter[0] - theLine.Location().X(), myCenter[1] - theLine.Location().Y())),
+ theLine.Direction().X() * Standard_Real(myHSize[1]),
+ theLine.Direction().Y() * Standard_Real(myHSize[0])};
+ return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::IsOut(const gp_XY& theP0, const gp_XY& theP1) const
+{
+ Standard_Boolean aResult(Standard_True);
+ if (IsVoid() == Standard_False)
+ {
+ // Intersect the line containing the segment.
+ const gp_XY aSegDelta(theP1 - theP0);
+ const Standard_Real aProd[3] = {aSegDelta ^ (gp_XY(myCenter[0], myCenter[1]) - theP0),
+ aSegDelta.X() * Standard_Real(myHSize[1]),
+ aSegDelta.Y() * Standard_Real(myHSize[0])};
+ if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
+ {
+ // Intersection with line detected; check the segment as bounding box
+ const gp_XY aHSeg(0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
+ const gp_XY aHSegAbs(Abs(aHSeg.X()), Abs(aHSeg.Y()));
+ aResult =
+ compareDistD(gp_XY((Standard_Real)myHSize[0], (Standard_Real)myHSize[1]) + aHSegAbs,
+ theP0 + aHSeg - gp_XY((Standard_Real)myCenter[0], (Standard_Real)myCenter[1]));
+ }
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B2<RealType>::IsIn(const Bnd_B2<RealType>& theBox,
+ const gp_Trsf2d& theTrsf) const
+{
+ Standard_Boolean aResult(Standard_False);
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult =
+ (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
+ < RealType(theBox.myHSize[0] * aScaleAbs) - myHSize[0]
+ && Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
+ < RealType(theBox.myHSize[1] * aScaleAbs) - myHSize[1]);
+ }
+ else
+ {
+ // theBox is rotated, scaled and translated. We apply the reverse
+ // translation and scaling then check against the rotated box 'this'
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+ gp_XY aCenter((Standard_Real)theBox.myCenter[0], (Standard_Real)theBox.myCenter[1]);
+ theTrsf.Transforms(aCenter);
+ const Standard_Real aDist[2] = {aCenter.X() - (Standard_Real)myCenter[0],
+ aCenter.Y() - (Standard_Real)myCenter[1]};
+ if ((Abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
+ < theBox.myHSize[0] * aScaleAbs - (Abs(aMat[0]) * myHSize[0] + Abs(aMat[2]) * myHSize[1]))
+ && (Abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
+ < theBox.myHSize[1] * aScaleAbs
+ - (Abs(aMat[1]) * myHSize[0] + Abs(aMat[3]) * myHSize[1])))
+ aResult = Standard_True;
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+//! 2D bounding box with double precision
+using Bnd_B2d = Bnd_B2<Standard_Real>;
+
+//! 2D bounding box with single precision
+using Bnd_B2f = Bnd_B2<Standard_ShortReal>;
+
+#endif // _Bnd_B2_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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 _Bnd_B2d_HeaderFile
-#define _Bnd_B2d_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <gp_XY.hxx>
-class gp_XY;
-class gp_Pnt2d;
-class gp_Trsf2d;
-class gp_Ax2d;
-
-class Bnd_B2d
-{
-public:
- DEFINE_STANDARD_ALLOC
-
- //! Empty constructor.
- Bnd_B2d();
-
- //! Constructor.
- Bnd_B2d(const gp_XY& theCenter, const gp_XY& theHSize);
-
- //! Returns True if the box is void (non-initialized).
- Standard_Boolean IsVoid() const;
-
- //! Reset the box data.
- void Clear();
-
- //! Update the box by a point.
- Standard_EXPORT void Add(const gp_XY& thePnt);
-
- //! Update the box by a point.
- void Add(const gp_Pnt2d& thePnt);
-
- //! Update the box by another box.
- void Add(const Bnd_B2d& theBox);
-
- //! Query a box corner: (Center - HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XY CornerMin() const;
-
- //! Query a box corner: (Center + HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XY CornerMax() const;
-
- //! Query the square diagonal. If the box is VOID (see method IsVoid())
- //! then a very big real value is returned.
- Standard_Real SquareExtent() const;
-
- //! Extend the Box by the absolute value of theDiff.
- void Enlarge(const Standard_Real theDiff);
-
- //! Limit the Box by the internals of theOtherBox.
- //! Returns True if the limitation takes place, otherwise False
- //! indicating that the boxes do not intersect.
- Standard_EXPORT Standard_Boolean Limit(const Bnd_B2d& theOtherBox);
-
- //! Transform the bounding box with the given transformation.
- //! The resulting box will be larger if theTrsf contains rotation.
- Standard_NODISCARD Standard_EXPORT Bnd_B2d Transformed(const gp_Trsf2d& theTrsf) const;
-
- //! Check the given point for the inclusion in the Box.
- //! Returns True if the point is outside.
- Standard_Boolean IsOut(const gp_XY& thePnt) const;
-
- //! Check a circle for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean
- IsOut(const gp_XY& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isCircleHollow = Standard_False) const;
-
- //! Check the given box for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_Boolean IsOut(const Bnd_B2d& theOtherBox) const;
-
- //! Check the given box oriented by the given transformation
- //! for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean IsOut(const Bnd_B2d& theOtherBox,
- const gp_Trsf2d& theTrsf) const;
-
- //! Check the given Line for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax2d& theLine) const;
-
- //! Check the Segment defined by the couple of input points
- //! for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_XY& theP0, const gp_XY& theP1) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'. Returns
- //! True if 'this' box is fully inside 'theBox'.
- Standard_Boolean IsIn(const Bnd_B2d& theBox) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'
- //! transformed by 'theTrsf'. Returns True if 'this' box is fully
- //! inside the transformed 'theBox'.
- Standard_EXPORT Standard_Boolean IsIn(const Bnd_B2d& theBox, const gp_Trsf2d& theTrsf) const;
-
- //! Set the Center coordinates
- void SetCenter(const gp_XY& theCenter);
-
- //! Set the HSize (half-diagonal) coordinates.
- //! All components of theHSize must be non-negative.
- void SetHSize(const gp_XY& theHSize);
-
-protected:
- Standard_Real myCenter[2];
- Standard_Real myHSize[2];
-
-private:
-};
-
-#define RealType Standard_Real
-#define RealType_hxx <Standard_Real.hxx>
-#define Bnd_B2x Bnd_B2d
-#define Bnd_B2x_hxx <Bnd_B2d.hxx>
-
-#include <Bnd_B2x.lxx>
-
-#undef RealType
-#undef RealType_hxx
-#undef Bnd_B2x
-#undef Bnd_B2x_hxx
-
-#endif // _Bnd_B2d_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <Bnd_B2d.hxx>
-
-#include <gp_XY.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Trsf2d.hxx>
-#include <gp_Ax2d.hxx>
-
-#define RealType Standard_Real
-#define RealType_hxx <Standard_Real.hxx>
-#define Bnd_B2x Bnd_B2d
-#define Bnd_B2x_hxx <Bnd_B2d.hxx>
-#include <Bnd_B2x.gxx>
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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 _Bnd_B2f_HeaderFile
-#define _Bnd_B2f_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_ShortReal.hxx>
-#include <gp_XY.hxx>
-class gp_XY;
-class gp_Pnt2d;
-class gp_Trsf2d;
-class gp_Ax2d;
-
-class Bnd_B2f
-{
-public:
- DEFINE_STANDARD_ALLOC
-
- //! Empty constructor.
- Bnd_B2f();
-
- //! Constructor.
- Bnd_B2f(const gp_XY& theCenter, const gp_XY& theHSize);
-
- //! Returns True if the box is void (non-initialized).
- Standard_Boolean IsVoid() const;
-
- //! Reset the box data.
- void Clear();
-
- //! Update the box by a point.
- Standard_EXPORT void Add(const gp_XY& thePnt);
-
- //! Update the box by a point.
- void Add(const gp_Pnt2d& thePnt);
-
- //! Update the box by another box.
- void Add(const Bnd_B2f& theBox);
-
- //! Query a box corner: (Center - HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XY CornerMin() const;
-
- //! Query a box corner: (Center + HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XY CornerMax() const;
-
- //! Query the square diagonal. If the box is VOID (see method IsVoid())
- //! then a very big real value is returned.
- Standard_Real SquareExtent() const;
-
- //! Extend the Box by the absolute value of theDiff.
- void Enlarge(const Standard_Real theDiff);
-
- //! Limit the Box by the internals of theOtherBox.
- //! Returns True if the limitation takes place, otherwise False
- //! indicating that the boxes do not intersect.
- Standard_EXPORT Standard_Boolean Limit(const Bnd_B2f& theOtherBox);
-
- //! Transform the bounding box with the given transformation.
- //! The resulting box will be larger if theTrsf contains rotation.
- Standard_NODISCARD Standard_EXPORT Bnd_B2f Transformed(const gp_Trsf2d& theTrsf) const;
-
- //! Check the given point for the inclusion in the Box.
- //! Returns True if the point is outside.
- Standard_Boolean IsOut(const gp_XY& thePnt) const;
-
- //! Check a circle for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean
- IsOut(const gp_XY& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isCircleHollow = Standard_False) const;
-
- //! Check the given box for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_Boolean IsOut(const Bnd_B2f& theOtherBox) const;
-
- //! Check the given box oriented by the given transformation
- //! for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean IsOut(const Bnd_B2f& theOtherBox,
- const gp_Trsf2d& theTrsf) const;
-
- //! Check the given Line for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax2d& theLine) const;
-
- //! Check the Segment defined by the couple of input points
- //! for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_XY& theP0, const gp_XY& theP1) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'. Returns
- //! True if 'this' box is fully inside 'theBox'.
- Standard_Boolean IsIn(const Bnd_B2f& theBox) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'
- //! transformed by 'theTrsf'. Returns True if 'this' box is fully
- //! inside the transformed 'theBox'.
- Standard_EXPORT Standard_Boolean IsIn(const Bnd_B2f& theBox, const gp_Trsf2d& theTrsf) const;
-
- //! Set the Center coordinates
- void SetCenter(const gp_XY& theCenter);
-
- //! Set the HSize (half-diagonal) coordinates.
- //! All components of theHSize must be non-negative.
- void SetHSize(const gp_XY& theHSize);
-
-protected:
- Standard_ShortReal myCenter[2];
- Standard_ShortReal myHSize[2];
-
-private:
-};
-
-#define RealType Standard_ShortReal
-#define RealType_hxx <Standard_ShortReal.hxx>
-#define Bnd_B2x Bnd_B2f
-#define Bnd_B2x_hxx <Bnd_B2f.hxx>
-
-#include <Bnd_B2x.lxx>
-
-#undef RealType
-#undef RealType_hxx
-#undef Bnd_B2x
-#undef Bnd_B2x_hxx
-
-#endif // _Bnd_B2f_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <Bnd_B2f.hxx>
-
-#include <gp_XY.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Trsf2d.hxx>
-#include <gp_Ax2d.hxx>
-
-#define RealType Standard_ShortReal
-#define RealType_hxx <Standard_ShortReal.hxx>
-#define Bnd_B2x Bnd_B2f
-#define Bnd_B2x_hxx <Bnd_B2f.hxx>
-#include <Bnd_B2x.gxx>
+++ /dev/null
-// Created on: 2005-09-08
-// Created by: Alexander GRIGORIEV
-// Copyright (c) 2005-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.
-
-inline Standard_Boolean _compareDist(const RealType aHSize[2], const RealType aDist[2])
-{
- return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
-}
-
-inline Standard_Boolean _compareDistD(const gp_XY& aHSize, const gp_XY& aDist)
-{
- return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
-}
-
-//=======================================================================
-// function : Add
-// purpose : Update the box by a point
-//=======================================================================
-
-void Bnd_B2x::Add(const gp_XY& thePnt)
-{
- if (IsVoid())
- {
- myCenter[0] = RealType(thePnt.X());
- myCenter[1] = RealType(thePnt.Y());
- myHSize[0] = 0.;
- myHSize[1] = 0.;
- }
- else
- {
- const RealType aDiff[2] = {RealType(thePnt.X()) - myCenter[0],
- RealType(thePnt.Y()) - myCenter[1]};
- if (aDiff[0] > myHSize[0])
- {
- const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
- myCenter[0] += aShift;
- myHSize[0] += aShift;
- }
- else if (aDiff[0] < -myHSize[0])
- {
- const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
- myCenter[0] += aShift;
- myHSize[0] -= aShift;
- }
- if (aDiff[1] > myHSize[1])
- {
- const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
- myCenter[1] += aShift;
- myHSize[1] += aShift;
- }
- else if (aDiff[1] < -myHSize[1])
- {
- const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
- myCenter[1] += aShift;
- myHSize[1] -= aShift;
- }
- }
-}
-
-//=======================================================================
-// function : Limit
-// purpose : limit the current box with the internals of theBox
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::Limit(const Bnd_B2x& theBox)
-{
- Standard_Boolean aResult(Standard_False);
- const RealType diffC[2] = {theBox.myCenter[0] - myCenter[0], theBox.myCenter[1] - myCenter[1]};
- const RealType sumH[2] = {theBox.myHSize[0] + myHSize[0], theBox.myHSize[1] + myHSize[1]};
- // check the condition IsOut
- if (_compareDist(sumH, diffC) == Standard_False)
- {
- const RealType diffH[2] = {theBox.myHSize[0] - myHSize[0], theBox.myHSize[1] - myHSize[1]};
- if (diffC[0] - diffH[0] > 0.)
- {
- const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
- myCenter[0] += aShift;
- myHSize[0] -= aShift;
- }
- else if (diffC[0] + diffH[0] < 0.)
- {
- const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
- myCenter[0] += aShift;
- myHSize[0] += aShift;
- }
- if (diffC[1] - diffH[1] > 0.)
- {
- const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
- myCenter[1] += aShift;
- myHSize[1] -= aShift;
- }
- else if (diffC[1] + diffH[1] < 0.)
- {
- const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
- myCenter[1] += aShift;
- myHSize[1] += aShift;
- }
- aResult = Standard_True;
- }
- return aResult;
-}
-
-//=================================================================================================
-
-Bnd_B2x Bnd_B2x::Transformed(const gp_Trsf2d& theTrsf) const
-{
- Bnd_B2x aResult;
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Identity)
- aResult = *this;
- else if (aForm == gp_Translation || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult.myCenter[0] = (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
- aResult.myCenter[1] = (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
- aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
- aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
- }
- else
- {
- gp_XY aCenter((Standard_Real)myCenter[0], (Standard_Real)myCenter[1]);
- theTrsf.Transforms(aCenter);
- aResult.myCenter[0] = (RealType)aCenter.X();
- aResult.myCenter[1] = (RealType)aCenter.Y();
-
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
- aResult.myHSize[0] =
- (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0] + Abs(aMat[1]) * myHSize[1]));
- aResult.myHSize[1] =
- (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0] + Abs(aMat[3]) * myHSize[1]));
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - Circle
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::IsOut(const gp_XY& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isCircleHollow) const
-{
- Standard_Boolean aResult(Standard_True);
- if (isCircleHollow == Standard_False)
- {
- // vector from the center of the circle to the nearest box face
- const Standard_Real aDist[2] = {
- Abs(theCenter.X() - Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
- Abs(theCenter.Y() - Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])};
- Standard_Real aD(0.);
- if (aDist[0] > 0.)
- aD = aDist[0] * aDist[0];
- if (aDist[1] > 0.)
- aD += aDist[1] * aDist[1];
- aResult = (aD > theRadius * theRadius);
- }
- else
- {
- const Standard_Real aDistC[2] = {Abs(theCenter.X() - Standard_Real(myCenter[0])),
- Abs(theCenter.Y() - Standard_Real(myCenter[1]))};
- // vector from the center of the circle to the nearest box face
- Standard_Real aDist[2] = {aDistC[0] - Standard_Real(myHSize[0]),
- aDistC[1] - Standard_Real(myHSize[1])};
- Standard_Real aD(0.);
- if (aDist[0] > 0.)
- aD = aDist[0] * aDist[0];
- if (aDist[1] > 0.)
- aD += aDist[1] * aDist[1];
- if (aD < theRadius * theRadius)
- {
- // the box intersects the solid circle; check if it is completely
- // inside the circle (in such case return isOut==True)
- aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
- aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
- if (aDist[0] * aDist[0] + aDist[1] * aDist[1] > theRadius * theRadius)
- aResult = Standard_False;
- }
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - transformed Box
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::IsOut(const Bnd_B2x& theBox, const gp_Trsf2d& theTrsf) const
-{
- Standard_Boolean aResult(Standard_False);
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult =
- (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
- > RealType(theBox.myHSize[0] * aScaleAbs) + myHSize[0]
- || Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
- > RealType(theBox.myHSize[1] * aScaleAbs) + myHSize[1]);
- }
- else
- {
- // theBox is transformed and we check the resulting (enlarged) box against
- // 'this' box.
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
-
- gp_XY aCenter((Standard_Real)theBox.myCenter[0], (Standard_Real)theBox.myCenter[1]);
- theTrsf.Transforms(aCenter);
- const Standard_Real aDist[2] = {aCenter.X() - (Standard_Real)myCenter[0],
- aCenter.Y() - (Standard_Real)myCenter[1]};
- const Standard_Real aMatAbs[4] = {Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])};
- if (Abs(aDist[0])
- > (aScaleAbs * (aMatAbs[0] * theBox.myHSize[0] + aMatAbs[1] * theBox.myHSize[1])
- + (Standard_Real)myHSize[0])
- || Abs(aDist[1])
- > (aScaleAbs * (aMatAbs[2] * theBox.myHSize[0] + aMatAbs[3] * theBox.myHSize[1])
- + (Standard_Real)myHSize[1]))
- aResult = Standard_True;
-
- else
- {
- // theBox is rotated, scaled and translated. We apply the reverse
- // translation and scaling then check against the rotated box 'this'
- if ((Abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
- > theBox.myHSize[0] * aScaleAbs + (aMatAbs[0] * myHSize[0] + aMatAbs[2] * myHSize[1]))
- || (Abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
- > theBox.myHSize[1] * aScaleAbs
- + (aMatAbs[1] * myHSize[0] + aMatAbs[3] * myHSize[1])))
- aResult = Standard_True;
- }
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - Line
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::IsOut(const gp_Ax2d& theLine) const
-{
- if (IsVoid())
- return Standard_True;
- // Intersect the line containing the segment.
- const Standard_Real aProd[3] = {
- theLine.Direction().XY()
- ^ (gp_XY(myCenter[0] - theLine.Location().X(), myCenter[1] - theLine.Location().Y())),
- theLine.Direction().X() * Standard_Real(myHSize[1]),
- theLine.Direction().Y() * Standard_Real(myHSize[0])};
- return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - Segment
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::IsOut(const gp_XY& theP0, const gp_XY& theP1) const
-{
- Standard_Boolean aResult(Standard_True);
- if (IsVoid() == Standard_False)
- {
- // Intersect the line containing the segment.
- const gp_XY aSegDelta(theP1 - theP0);
- const Standard_Real aProd[3] = {aSegDelta ^ (gp_XY(myCenter[0], myCenter[1]) - theP0),
- aSegDelta.X() * Standard_Real(myHSize[1]),
- aSegDelta.Y() * Standard_Real(myHSize[0])};
- if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
- {
- // Intersection with line detected; check the segment as bounding box
- const gp_XY aHSeg(0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
- const gp_XY aHSegAbs(Abs(aHSeg.X()), Abs(aHSeg.Y()));
- aResult = _compareDistD(
- gp_XY((Standard_Real)myHSize[0], (Standard_Real)myHSize[1]) + aHSegAbs,
- theP0 + aHSeg - gp_XY((Standard_Real)myCenter[0], (Standard_Real)myCenter[1]));
- }
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsIn
-// purpose : Test the complete inclusion of this box in transformed theOtherBox
-//=======================================================================
-
-Standard_Boolean Bnd_B2x::IsIn(const Bnd_B2x& theBox, const gp_Trsf2d& theTrsf) const
-{
- Standard_Boolean aResult(Standard_False);
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult =
- (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
- < RealType(theBox.myHSize[0] * aScaleAbs) - myHSize[0]
- && Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
- < RealType(theBox.myHSize[1] * aScaleAbs) - myHSize[1]);
- }
- else
- {
- // theBox is rotated, scaled and translated. We apply the reverse
- // translation and scaling then check against the rotated box 'this'
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
- gp_XY aCenter((Standard_Real)theBox.myCenter[0], (Standard_Real)theBox.myCenter[1]);
- theTrsf.Transforms(aCenter);
- const Standard_Real aDist[2] = {aCenter.X() - (Standard_Real)myCenter[0],
- aCenter.Y() - (Standard_Real)myCenter[1]};
- if ((Abs(aMat[0] * aDist[0] + aMat[2] * aDist[1])
- < theBox.myHSize[0] * aScaleAbs - (Abs(aMat[0]) * myHSize[0] + Abs(aMat[2]) * myHSize[1]))
- && (Abs(aMat[1] * aDist[0] + aMat[3] * aDist[1])
- < theBox.myHSize[1] * aScaleAbs
- - (Abs(aMat[1]) * myHSize[0] + Abs(aMat[3]) * myHSize[1])))
- aResult = Standard_True;
- }
- return aResult;
-}
+++ /dev/null
-// Created on: 2005-09-08
-// Created by: Alexander GRIGORIEV
-// Copyright (c) 2005-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.
-
-#include <gp_Pnt2d.hxx>
-
-#ifndef Bnd_B2x_RealLast
- #define Bnd_B2x_RealLast RealType(1e30);
-#endif
-
-/**
- * Empty constructor
- */
-inline Bnd_B2x::Bnd_B2x()
-{
- Clear();
-}
-
-/**
- * Constructor.
- * @param theCenter
- * Center of the created box
- * @param theHSize
- * Half-diagonal of the box, both X and Y should be non-negative
- */
-inline Bnd_B2x::Bnd_B2x(const gp_XY& theCenter, const gp_XY& theHSize)
-{
- myCenter[0] = RealType(theCenter.X());
- myCenter[1] = RealType(theCenter.Y());
- myHSize[0] = RealType(theHSize.X());
- myHSize[1] = RealType(theHSize.Y());
-}
-
-/**
- * Reset the box data.
- */
-inline void Bnd_B2x::Clear()
-{
- myCenter[0] = Bnd_B2x_RealLast;
- myCenter[1] = Bnd_B2x_RealLast;
- myHSize[0] = -Bnd_B2x_RealLast;
- myHSize[1] = -Bnd_B2x_RealLast;
-}
-
-/**
- * Check if the box is empty.
- */
-inline Standard_Boolean Bnd_B2x::IsVoid() const
-{
- return (myHSize[0] < -1e-5);
-}
-
-/**
- * Update the box by point.
- */
-inline void Bnd_B2x::Add(const gp_Pnt2d& thePnt)
-{
- Add(thePnt.XY());
-}
-
-/**
- * Update the box by another box.
- */
-inline void Bnd_B2x::Add(const Bnd_B2x& theBox)
-{
- if (theBox.IsVoid() == Standard_False)
- {
- Add(theBox.CornerMin());
- Add(theBox.CornerMax());
- }
-}
-
-/**
- * Query a box corner.
- */
-inline gp_XY Bnd_B2x::CornerMin() const
-{
- return gp_XY(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1]);
-}
-
-/**
- * Query a box corner.
- */
-inline gp_XY Bnd_B2x::CornerMax() const
-{
- return gp_XY(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1]);
-}
-
-/**
- * Query the square diagonal.
- */
-inline Standard_Real Bnd_B2x::SquareExtent() const
-{
- return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1]);
-}
-
-/**
- * Set the Center coordinates.
- */
-inline void Bnd_B2x::SetCenter(const gp_XY& theCenter)
-{
- myCenter[0] = RealType(theCenter.X());
- myCenter[1] = RealType(theCenter.Y());
-}
-
-/**
- * Set the HSize coordinates.
- */
-inline void Bnd_B2x::SetHSize(const gp_XY& theHSize)
-{
- myHSize[0] = RealType(theHSize.X());
- myHSize[1] = RealType(theHSize.Y());
-}
-
-/**
- * Increase the box.
- * @param aDiff
- * absolute value of this parameter is added to the box size in all dimensions.
- */
-inline void Bnd_B2x::Enlarge(const Standard_Real aDiff)
-{
- const RealType aD = RealType(Abs(aDiff));
- myHSize[0] += aD;
- myHSize[1] += aD;
-}
-
-/**
- * Intersection Box - Point
- */
-inline Standard_Boolean Bnd_B2x::IsOut(const gp_XY& thePnt) const
-{
- return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0]
- || Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]);
-}
-
-/**
- * Intersection Box-Box.
- */
-inline Standard_Boolean Bnd_B2x::IsOut(const Bnd_B2x& theBox) const
-{
- return (Abs(theBox.myCenter[0] - myCenter[0]) > theBox.myHSize[0] + myHSize[0]
- || Abs(theBox.myCenter[1] - myCenter[1]) > theBox.myHSize[1] + myHSize[1]);
-}
-
-/**
- * Test the complete inclusion of this box in theBox.
- */
-inline Standard_Boolean Bnd_B2x::IsIn(const Bnd_B2x& theBox) const
-{
- return (Abs(theBox.myCenter[0] - myCenter[0]) < theBox.myHSize[0] - myHSize[0]
- && Abs(theBox.myCenter[1] - myCenter[1]) < theBox.myHSize[1] - myHSize[1]);
-}
--- /dev/null
+// Created on: 2005-09-08
+// Created by: Alexander GRIGORIEV
+// Copyright (c) 2005-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 _Bnd_B3_HeaderFile
+#define _Bnd_B3_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_ShortReal.hxx>
+#include <gp.hxx>
+#include <gp_XYZ.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Ax3.hxx>
+
+//! Template class for 3D bounding box.
+//! This is a base template that is instantiated for Standard_Real and Standard_ShortReal.
+template <typename RealType>
+class Bnd_B3
+{
+public:
+ DEFINE_STANDARD_ALLOC
+
+ //! Empty constructor.
+ Bnd_B3();
+
+ //! Constructor.
+ Bnd_B3(const gp_XYZ& theCenter, const gp_XYZ& theHSize);
+
+ //! Returns True if the box is void (non-initialized).
+ Standard_Boolean IsVoid() const;
+
+ //! Reset the box data.
+ void Clear();
+
+ //! Update the box by a point.
+ void Add(const gp_XYZ& thePnt);
+
+ //! Update the box by a point.
+ void Add(const gp_Pnt& thePnt);
+
+ //! Update the box by another box.
+ void Add(const Bnd_B3<RealType>& theBox);
+
+ //! Query the lower corner: (Center - HSize). You must make sure that
+ //! the box is NOT VOID (see IsVoid()), otherwise the method returns
+ //! irrelevant result.
+ gp_XYZ CornerMin() const;
+
+ //! Query the upper corner: (Center + HSize). You must make sure that
+ //! the box is NOT VOID (see IsVoid()), otherwise the method returns
+ //! irrelevant result.
+ gp_XYZ CornerMax() const;
+
+ //! Query the square diagonal. If the box is VOID (see method IsVoid())
+ //! then a very big real value is returned.
+ Standard_Real SquareExtent() const;
+
+ //! Extend the Box by the absolute value of theDiff.
+ void Enlarge(const Standard_Real theDiff);
+
+ //! Limit the Box by the internals of theOtherBox.
+ //! Returns True if the limitation takes place, otherwise False
+ //! indicating that the boxes do not intersect.
+ Standard_Boolean Limit(const Bnd_B3<RealType>& theOtherBox);
+
+ //! Transform the bounding box with the given transformation.
+ //! The resulting box will be larger if theTrsf contains rotation.
+ Standard_NODISCARD Bnd_B3<RealType> Transformed(const gp_Trsf& theTrsf) const;
+
+ //! Check the given point for the inclusion in the Box.
+ //! Returns True if the point is outside.
+ Standard_Boolean IsOut(const gp_XYZ& thePnt) const;
+
+ //! Check a sphere for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes. If the
+ //! parameter 'IsSphereHollow' is True, then the intersection is not
+ //! reported for a box that is completely inside the sphere (otherwise
+ //! this method would report an intersection).
+ Standard_Boolean IsOut(const gp_XYZ& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Boolean isSphereHollow = Standard_False) const;
+
+ //! Check the given box for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes.
+ Standard_Boolean IsOut(const Bnd_B3<RealType>& theOtherBox) const;
+
+ //! Check the given box oriented by the given transformation
+ //! for the intersection with the current box.
+ //! Returns True if there is no intersection between boxes.
+ Standard_Boolean IsOut(const Bnd_B3<RealType>& theOtherBox, const gp_Trsf& theTrsf) const;
+
+ //! Check the given Line for the intersection with the current box.
+ //! Returns True if there is no intersection.
+ //! isRay==True means intersection check with the positive half-line
+ //! theOverthickness is the addition to the size of the current box
+ //! (may be negative). If positive, it can be treated as the thickness
+ //! of the line 'theLine' or the radius of the cylinder along 'theLine'
+ Standard_Boolean IsOut(const gp_Ax1& theLine,
+ const Standard_Boolean isRay = Standard_False,
+ const Standard_Real theOverthickness = 0.0) const;
+
+ //! Check the given Plane for the intersection with the current box.
+ //! Returns True if there is no intersection.
+ Standard_Boolean IsOut(const gp_Ax3& thePlane) const;
+
+ //! Check that the box 'this' is inside the given box 'theBox'. Returns
+ //! True if 'this' box is fully inside 'theBox'.
+ Standard_Boolean IsIn(const Bnd_B3<RealType>& theBox) const;
+
+ //! Check that the box 'this' is inside the given box 'theBox'
+ //! transformed by 'theTrsf'. Returns True if 'this' box is fully
+ //! inside the transformed 'theBox'.
+ Standard_Boolean IsIn(const Bnd_B3<RealType>& theBox, const gp_Trsf& theTrsf) const;
+
+ //! Set the Center coordinates
+ void SetCenter(const gp_XYZ& theCenter);
+
+ //! Set the HSize (half-diagonal) coordinates.
+ //! All components of theHSize must be non-negative.
+ void SetHSize(const gp_XYZ& theHSize);
+
+protected:
+ static Standard_Boolean compareDist(const RealType aHSize[3], const RealType aDist[3])
+ {
+ return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1] || Abs(aDist[2]) > aHSize[2]);
+ }
+
+ static Standard_Boolean compareDistD(const gp_XYZ& aHSize, const gp_XYZ& aDist)
+ {
+ return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y()
+ || Abs(aDist.Z()) > aHSize.Z());
+ }
+
+ //! Constant representing a very large value for void box initialization
+ static constexpr RealType THE_RealLast = RealType(1e30);
+
+private:
+ RealType myCenter[3];
+ RealType myHSize[3];
+};
+
+//=================================================================================================
+
+template <typename RealType>
+inline Bnd_B3<RealType>::Bnd_B3()
+{
+ Clear();
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Bnd_B3<RealType>::Bnd_B3(const gp_XYZ& theCenter, const gp_XYZ& theHSize)
+{
+ myCenter[0] = RealType(theCenter.X());
+ myCenter[1] = RealType(theCenter.Y());
+ myCenter[2] = RealType(theCenter.Z());
+ myHSize[0] = RealType(theHSize.X());
+ myHSize[1] = RealType(theHSize.Y());
+ myHSize[2] = RealType(theHSize.Z());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::Clear()
+{
+ myCenter[0] = THE_RealLast;
+ myCenter[1] = THE_RealLast;
+ myCenter[2] = THE_RealLast;
+ myHSize[0] = -THE_RealLast;
+ myHSize[1] = -THE_RealLast;
+ myHSize[2] = -THE_RealLast;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B3<RealType>::IsVoid() const
+{
+ return (myHSize[0] < -1e-5);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::Add(const gp_Pnt& thePnt)
+{
+ Add(thePnt.XYZ());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::Add(const Bnd_B3<RealType>& theBox)
+{
+ if (theBox.IsVoid() == Standard_False)
+ {
+ Add(theBox.CornerMin());
+ Add(theBox.CornerMax());
+ }
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline gp_XYZ Bnd_B3<RealType>::CornerMin() const
+{
+ return gp_XYZ(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1], myCenter[2] - myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline gp_XYZ Bnd_B3<RealType>::CornerMax() const
+{
+ return gp_XYZ(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1], myCenter[2] + myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Real Bnd_B3<RealType>::SquareExtent() const
+{
+ return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1] + myHSize[2] * myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::SetCenter(const gp_XYZ& theCenter)
+{
+ myCenter[0] = RealType(theCenter.X());
+ myCenter[1] = RealType(theCenter.Y());
+ myCenter[2] = RealType(theCenter.Z());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::SetHSize(const gp_XYZ& theHSize)
+{
+ myHSize[0] = RealType(theHSize.X());
+ myHSize[1] = RealType(theHSize.Y());
+ myHSize[2] = RealType(theHSize.Z());
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline void Bnd_B3<RealType>::Enlarge(const Standard_Real aDiff)
+{
+ const Standard_Real aD = Abs(aDiff);
+ myHSize[0] += RealType(aD);
+ myHSize[1] += RealType(aD);
+ myHSize[2] += RealType(aD);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B3<RealType>::IsOut(const gp_XYZ& thePnt) const
+{
+ return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0]
+ || Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]
+ || Abs(RealType(thePnt.Z()) - myCenter[2]) > myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B3<RealType>::IsOut(const Bnd_B3<RealType>& theBox) const
+{
+ return (Abs(theBox.myCenter[0] - myCenter[0]) > theBox.myHSize[0] + myHSize[0]
+ || Abs(theBox.myCenter[1] - myCenter[1]) > theBox.myHSize[1] + myHSize[1]
+ || Abs(theBox.myCenter[2] - myCenter[2]) > theBox.myHSize[2] + myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+inline Standard_Boolean Bnd_B3<RealType>::IsIn(const Bnd_B3<RealType>& theBox) const
+{
+ return (Abs(theBox.myCenter[0] - myCenter[0]) < theBox.myHSize[0] - myHSize[0]
+ && Abs(theBox.myCenter[1] - myCenter[1]) < theBox.myHSize[1] - myHSize[1]
+ && Abs(theBox.myCenter[2] - myCenter[2]) < theBox.myHSize[2] - myHSize[2]);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+void Bnd_B3<RealType>::Add(const gp_XYZ& thePnt)
+{
+ if (IsVoid())
+ {
+ myCenter[0] = RealType(thePnt.X());
+ myCenter[1] = RealType(thePnt.Y());
+ myCenter[2] = RealType(thePnt.Z());
+ myHSize[0] = 0.;
+ myHSize[1] = 0.;
+ myHSize[2] = 0.;
+ }
+ else
+ {
+ const RealType aDiff[3] = {RealType(thePnt.X()) - myCenter[0],
+ RealType(thePnt.Y()) - myCenter[1],
+ RealType(thePnt.Z()) - myCenter[2]};
+ if (aDiff[0] > myHSize[0])
+ {
+ const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
+ myCenter[0] += aShift;
+ myHSize[0] += aShift;
+ }
+ else if (aDiff[0] < -myHSize[0])
+ {
+ const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
+ myCenter[0] += aShift;
+ myHSize[0] -= aShift;
+ }
+ if (aDiff[1] > myHSize[1])
+ {
+ const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
+ myCenter[1] += aShift;
+ myHSize[1] += aShift;
+ }
+ else if (aDiff[1] < -myHSize[1])
+ {
+ const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
+ myCenter[1] += aShift;
+ myHSize[1] -= aShift;
+ }
+ if (aDiff[2] > myHSize[2])
+ {
+ const RealType aShift = (aDiff[2] - myHSize[2]) / 2;
+ myCenter[2] += aShift;
+ myHSize[2] += aShift;
+ }
+ else if (aDiff[2] < -myHSize[2])
+ {
+ const RealType aShift = (aDiff[2] + myHSize[2]) / 2;
+ myCenter[2] += aShift;
+ myHSize[2] -= aShift;
+ }
+ }
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::Limit(const Bnd_B3<RealType>& theBox)
+{
+ Standard_Boolean aResult(Standard_False);
+ const RealType diffC[3] = {theBox.myCenter[0] - myCenter[0],
+ theBox.myCenter[1] - myCenter[1],
+ theBox.myCenter[2] - myCenter[2]};
+ const RealType sumH[3] = {theBox.myHSize[0] + myHSize[0],
+ theBox.myHSize[1] + myHSize[1],
+ theBox.myHSize[2] + myHSize[2]};
+ // check the condition IsOut
+ if (compareDist(sumH, diffC) == Standard_False)
+ {
+ const RealType diffH[3] = {theBox.myHSize[0] - myHSize[0],
+ theBox.myHSize[1] - myHSize[1],
+ theBox.myHSize[2] - myHSize[2]};
+ if (diffC[0] - diffH[0] > 0.)
+ {
+ const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
+ myCenter[0] += aShift;
+ myHSize[0] -= aShift;
+ }
+ else if (diffC[0] + diffH[0] < 0.)
+ {
+ const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
+ myCenter[0] += aShift;
+ myHSize[0] += aShift;
+ }
+ if (diffC[1] - diffH[1] > 0.)
+ {
+ const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
+ myCenter[1] += aShift;
+ myHSize[1] -= aShift;
+ }
+ else if (diffC[1] + diffH[1] < 0.)
+ {
+ const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
+ myCenter[1] += aShift;
+ myHSize[1] += aShift;
+ }
+ if (diffC[2] - diffH[2] > 0.)
+ {
+ const RealType aShift = (diffC[2] - diffH[2]) / 2; // positive
+ myCenter[2] += aShift;
+ myHSize[2] -= aShift;
+ }
+ else if (diffC[2] + diffH[2] < 0.)
+ {
+ const RealType aShift = (diffC[2] + diffH[2]) / 2; // negative
+ myCenter[2] += aShift;
+ myHSize[2] += aShift;
+ }
+ aResult = Standard_True;
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Bnd_B3<RealType> Bnd_B3<RealType>::Transformed(const gp_Trsf& theTrsf) const
+{
+ Bnd_B3<RealType> aResult;
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Identity)
+ aResult = *this;
+ else if (aForm == gp_Translation || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult.myCenter[0] = (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
+ aResult.myCenter[1] = (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
+ aResult.myCenter[2] = (RealType)(myCenter[2] * aScale + theTrsf.TranslationPart().Z());
+ aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
+ aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
+ aResult.myHSize[2] = (RealType)(myHSize[2] * aScaleAbs);
+ }
+ else
+ {
+ gp_XYZ aCenter((Standard_Real)myCenter[0],
+ (Standard_Real)myCenter[1],
+ (Standard_Real)myCenter[2]);
+ theTrsf.Transforms(aCenter);
+ aResult.myCenter[0] = (RealType)aCenter.X();
+ aResult.myCenter[1] = (RealType)aCenter.Y();
+ aResult.myCenter[2] = (RealType)aCenter.Z();
+
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+ aResult.myHSize[0] = (RealType)(aScaleAbs
+ * (Abs(aMat[0]) * myHSize[0] + Abs(aMat[1]) * myHSize[1]
+ + Abs(aMat[2]) * myHSize[2]));
+ aResult.myHSize[1] = (RealType)(aScaleAbs
+ * (Abs(aMat[3]) * myHSize[0] + Abs(aMat[4]) * myHSize[1]
+ + Abs(aMat[5]) * myHSize[2]));
+ aResult.myHSize[2] = (RealType)(aScaleAbs
+ * (Abs(aMat[6]) * myHSize[0] + Abs(aMat[7]) * myHSize[1]
+ + Abs(aMat[8]) * myHSize[2]));
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::IsOut(const gp_XYZ& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Boolean isSphereHollow) const
+{
+ Standard_Boolean aResult(Standard_True);
+ if (isSphereHollow == Standard_False)
+ {
+ // vector from the center of the sphere to the nearest box face
+ const Standard_Real aDist[3] = {
+ Abs(theCenter.X() - Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
+ Abs(theCenter.Y() - Standard_Real(myCenter[1])) - Standard_Real(myHSize[1]),
+ Abs(theCenter.Z() - Standard_Real(myCenter[2])) - Standard_Real(myHSize[2])};
+ Standard_Real aD(0.);
+ if (aDist[0] > 0.)
+ aD = aDist[0] * aDist[0];
+ if (aDist[1] > 0.)
+ aD += aDist[1] * aDist[1];
+ if (aDist[2] > 0.)
+ aD += aDist[2] * aDist[2];
+ aResult = (aD > theRadius * theRadius);
+ }
+ else
+ {
+ const Standard_Real aDistC[3] = {Abs(theCenter.X() - Standard_Real(myCenter[0])),
+ Abs(theCenter.Y() - Standard_Real(myCenter[1])),
+ Abs(theCenter.Z() - Standard_Real(myCenter[2]))};
+ // vector from the center of the sphere to the nearest box face
+ Standard_Real aDist[3] = {aDistC[0] - Standard_Real(myHSize[0]),
+ aDistC[1] - Standard_Real(myHSize[1]),
+ aDistC[2] - Standard_Real(myHSize[2])};
+ Standard_Real aD(0.);
+ if (aDist[0] > 0.)
+ aD = aDist[0] * aDist[0];
+ if (aDist[1] > 0.)
+ aD += aDist[1] * aDist[1];
+ if (aDist[2] > 0.)
+ aD += aDist[2] * aDist[2];
+ if (aD < theRadius * theRadius)
+ {
+ // the box intersects the solid sphere; check if it is completely
+ // inside the circle (in such case return isOut==True)
+ aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
+ aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
+ aDist[2] = aDistC[2] + Standard_Real(myHSize[2]);
+ if (aDist[0] * aDist[0] + aDist[1] * aDist[1] + aDist[2] * aDist[2] > theRadius * theRadius)
+ aResult = Standard_False;
+ }
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::IsOut(const Bnd_B3<RealType>& theBox,
+ const gp_Trsf& theTrsf) const
+{
+ Standard_Boolean aResult(Standard_False);
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult =
+ (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
+ > RealType(theBox.myHSize[0] * aScaleAbs) + myHSize[0]
+ || Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
+ > RealType(theBox.myHSize[1] * aScaleAbs) + myHSize[1]
+ || Abs(RealType(theBox.myCenter[2] * aScale + theTrsf.TranslationPart().Z()) - myCenter[2])
+ > RealType(theBox.myHSize[2] * aScaleAbs) + myHSize[2]);
+ }
+ else
+ {
+ // theBox is transformed and we check the resulting (enlarged) box against
+ // 'this' box.
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+
+ gp_XYZ aCenter((Standard_Real)theBox.myCenter[0],
+ (Standard_Real)theBox.myCenter[1],
+ (Standard_Real)theBox.myCenter[2]);
+ theTrsf.Transforms(aCenter);
+ const Standard_Real aDist[3] = {aCenter.X() - (Standard_Real)myCenter[0],
+ aCenter.Y() - (Standard_Real)myCenter[1],
+ aCenter.Z() - (Standard_Real)myCenter[2]};
+ const Standard_Real aMatAbs[9] = {Abs(aMat[0]),
+ Abs(aMat[1]),
+ Abs(aMat[2]),
+ Abs(aMat[3]),
+ Abs(aMat[4]),
+ Abs(aMat[5]),
+ Abs(aMat[6]),
+ Abs(aMat[7]),
+ Abs(aMat[8])};
+ if (Abs(aDist[0]) > (aScaleAbs
+ * (aMatAbs[0] * theBox.myHSize[0] + aMatAbs[1] * theBox.myHSize[1]
+ + aMatAbs[2] * theBox.myHSize[2])
+ + (Standard_Real)myHSize[0])
+ || Abs(aDist[1]) > (aScaleAbs
+ * (aMatAbs[3] * theBox.myHSize[0] + aMatAbs[4] * theBox.myHSize[1]
+ + aMatAbs[5] * theBox.myHSize[2])
+ + (Standard_Real)myHSize[1])
+ || Abs(aDist[2]) > (aScaleAbs
+ * (aMatAbs[6] * theBox.myHSize[0] + aMatAbs[7] * theBox.myHSize[1]
+ + aMatAbs[8] * theBox.myHSize[2])
+ + (Standard_Real)myHSize[2]))
+ aResult = Standard_True;
+
+ else
+ {
+ // theBox is rotated, scaled and translated. We apply the reverse
+ // translation and scaling then check against the rotated box 'this'
+ if ((Abs(aMat[0] * aDist[0] + aMat[3] * aDist[1] + aMat[6] * aDist[2])
+ > theBox.myHSize[0] * aScaleAbs
+ + (aMatAbs[0] * myHSize[0] + aMatAbs[3] * myHSize[1] + aMatAbs[6] * myHSize[2]))
+ || (Abs(aMat[1] * aDist[0] + aMat[4] * aDist[1] + aMat[7] * aDist[2])
+ > theBox.myHSize[1] * aScaleAbs
+ + (aMatAbs[1] * myHSize[0] + aMatAbs[4] * myHSize[1] + aMatAbs[7] * myHSize[2]))
+ || (Abs(aMat[2] * aDist[0] + aMat[5] * aDist[1] + aMat[8] * aDist[2])
+ > theBox.myHSize[2] * aScaleAbs
+ + (aMatAbs[2] * myHSize[0] + aMatAbs[5] * myHSize[1] + aMatAbs[8] * myHSize[2])))
+ aResult = Standard_True;
+ }
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::IsOut(const gp_Ax3& thePlane) const
+{
+ if (IsVoid())
+ return Standard_True;
+ const gp_XYZ& anOrigin = thePlane.Location().XYZ();
+ const gp_XYZ& aDir = thePlane.Direction().XYZ();
+ const gp_XYZ aBoxCenter((Standard_Real)myCenter[0],
+ (Standard_Real)myCenter[1],
+ (Standard_Real)myCenter[2]);
+ const Standard_Real aDist0 = (aBoxCenter - anOrigin) * aDir;
+ // Find the signed distances from two opposite corners of the box to the plane
+ // If the distances are not the same sign, then the plane crosses the box
+ const Standard_Real aDist1 = // proj of HSize on aDir
+ Standard_Real(myHSize[0]) * Abs(aDir.X()) + Standard_Real(myHSize[1]) * Abs(aDir.Y())
+ + Standard_Real(myHSize[2]) * Abs(aDir.Z());
+ return ((aDist0 + aDist1) * (aDist0 - aDist1) > 0.);
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::IsOut(const gp_Ax1& theLine,
+ const Standard_Boolean isRay,
+ const Standard_Real theOverthickness) const
+{
+ const Standard_Real aRes = gp::Resolution() * 100.;
+ if (IsVoid())
+ return Standard_True;
+ Standard_Real anInter0[2] = {-RealLast(), RealLast()}, anInter1[2] = {-RealLast(), RealLast()};
+ const gp_XYZ& aDir = theLine.Direction().XYZ();
+ const gp_XYZ aDiff((Standard_Real)myCenter[0] - theLine.Location().X(),
+ (Standard_Real)myCenter[1] - theLine.Location().Y(),
+ (Standard_Real)myCenter[2] - theLine.Location().Z());
+
+ // Find the parameter interval in X dimension
+ Standard_Real aHSize = (Standard_Real)myHSize[0] + theOverthickness;
+ if (aDir.X() > aRes)
+ {
+ anInter0[0] = (aDiff.X() - aHSize) / aDir.X();
+ anInter0[1] = (aDiff.X() + aHSize) / aDir.X();
+ }
+ else if (aDir.X() < -aRes)
+ {
+ anInter0[0] = (aDiff.X() + aHSize) / aDir.X();
+ anInter0[1] = (aDiff.X() - aHSize) / aDir.X();
+ }
+ else
+ // the line is orthogonal to OX axis. Test for inclusion in box limits
+ if (Abs(aDiff.X()) > aHSize)
+ return Standard_True;
+
+ // Find the parameter interval in Y dimension
+ aHSize = (Standard_Real)myHSize[1] + theOverthickness;
+ if (aDir.Y() > aRes)
+ {
+ anInter1[0] = (aDiff.Y() - aHSize) / aDir.Y();
+ anInter1[1] = (aDiff.Y() + aHSize) / aDir.Y();
+ }
+ else if (aDir.Y() < -aRes)
+ {
+ anInter1[0] = (aDiff.Y() + aHSize) / aDir.Y();
+ anInter1[1] = (aDiff.Y() - aHSize) / aDir.Y();
+ }
+ else
+ // the line is orthogonal to OY axis. Test for inclusion in box limits
+ if (Abs(aDiff.Y()) > aHSize)
+ return Standard_True;
+
+ // Intersect Y-interval with X-interval
+ if (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes))
+ return Standard_True;
+ if (anInter1[0] > anInter0[0])
+ anInter0[0] = anInter1[0];
+ if (anInter1[1] < anInter0[1])
+ anInter0[1] = anInter1[1];
+ if (isRay && anInter0[1] < -aRes)
+ return Standard_True;
+
+ // Find the parameter interval in Z dimension
+ aHSize = (Standard_Real)myHSize[2] + theOverthickness;
+ if (aDir.Z() > aRes)
+ {
+ anInter1[0] = (aDiff.Z() - aHSize) / aDir.Z();
+ anInter1[1] = (aDiff.Z() + aHSize) / aDir.Z();
+ }
+ else if (aDir.Z() < -aRes)
+ {
+ anInter1[0] = (aDiff.Z() + aHSize) / aDir.Z();
+ anInter1[1] = (aDiff.Z() - aHSize) / aDir.Z();
+ }
+ else
+ // the line is orthogonal to OZ axis. Test for inclusion in box limits
+ return (Abs(aDiff.Z()) > aHSize);
+ if (isRay && anInter1[1] < -aRes)
+ return Standard_True;
+
+ return (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes));
+}
+
+//=================================================================================================
+
+template <typename RealType>
+Standard_Boolean Bnd_B3<RealType>::IsIn(const Bnd_B3<RealType>& theBox,
+ const gp_Trsf& theTrsf) const
+{
+ Standard_Boolean aResult(Standard_False);
+ const gp_TrsfForm aForm = theTrsf.Form();
+ const Standard_Real aScale = theTrsf.ScaleFactor();
+ const Standard_Real aScaleAbs = Abs(aScale);
+ if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
+ {
+ aResult =
+ (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
+ < RealType(theBox.myHSize[0] * aScaleAbs) - myHSize[0]
+ && Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
+ < RealType(theBox.myHSize[1] * aScaleAbs) - myHSize[1]
+ && Abs(RealType(theBox.myCenter[2] * aScale + theTrsf.TranslationPart().Z()) - myCenter[2])
+ < RealType(theBox.myHSize[2] * aScaleAbs) - myHSize[2]);
+ }
+ else
+ {
+ // theBox is rotated, scaled and translated. We apply the reverse
+ // translation and scaling then check against the rotated box 'this'
+ const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
+ gp_XYZ aCenter((Standard_Real)theBox.myCenter[0],
+ (Standard_Real)theBox.myCenter[1],
+ (Standard_Real)theBox.myCenter[2]);
+ theTrsf.Transforms(aCenter);
+ const Standard_Real aDist[3] = {aCenter.X() - (Standard_Real)myCenter[0],
+ aCenter.Y() - (Standard_Real)myCenter[1],
+ aCenter.Z() - (Standard_Real)myCenter[2]};
+ if ((Abs(aMat[0] * aDist[0] + aMat[3] * aDist[1] + aMat[6] * aDist[2])
+ < theBox.myHSize[0] * aScaleAbs
+ - (Abs(aMat[0]) * myHSize[0] + Abs(aMat[3]) * myHSize[1] + Abs(aMat[6]) * myHSize[2]))
+ && (Abs(aMat[1] * aDist[0] + aMat[4] * aDist[1] + aMat[7] * aDist[2])
+ < theBox.myHSize[1] * aScaleAbs
+ - (Abs(aMat[1]) * myHSize[0] + Abs(aMat[4]) * myHSize[1]
+ + Abs(aMat[7]) * myHSize[2]))
+ && (Abs(aMat[2] * aDist[0] + aMat[5] * aDist[1] + aMat[8] * aDist[2])
+ < theBox.myHSize[2] * aScaleAbs
+ - (Abs(aMat[2]) * myHSize[0] + Abs(aMat[5]) * myHSize[1]
+ + Abs(aMat[8]) * myHSize[2])))
+ aResult = Standard_True;
+ }
+ return aResult;
+}
+
+//=================================================================================================
+
+//! 3D bounding box with double precision
+using Bnd_B3d = Bnd_B3<Standard_Real>;
+
+//! 3D bounding box with single precision
+using Bnd_B3f = Bnd_B3<Standard_ShortReal>;
+
+#endif // _Bnd_B3_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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 _Bnd_B3d_HeaderFile
-#define _Bnd_B3d_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <gp_XYZ.hxx>
-class gp_XYZ;
-class gp_Pnt;
-class gp_Trsf;
-class gp_Ax1;
-class gp_Ax3;
-
-class Bnd_B3d
-{
-public:
- DEFINE_STANDARD_ALLOC
-
- //! Empty constructor.
- Bnd_B3d();
-
- //! Constructor.
- Bnd_B3d(const gp_XYZ& theCenter, const gp_XYZ& theHSize);
-
- //! Returns True if the box is void (non-initialized).
- Standard_Boolean IsVoid() const;
-
- //! Reset the box data.
- void Clear();
-
- //! Update the box by a point.
- Standard_EXPORT void Add(const gp_XYZ& thePnt);
-
- //! Update the box by a point.
- void Add(const gp_Pnt& thePnt);
-
- //! Update the box by another box.
- void Add(const Bnd_B3d& theBox);
-
- //! Query the lower corner: (Center - HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XYZ CornerMin() const;
-
- //! Query the upper corner: (Center + HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XYZ CornerMax() const;
-
- //! Query the square diagonal. If the box is VOID (see method IsVoid())
- //! then a very big real value is returned.
- Standard_Real SquareExtent() const;
-
- //! Extend the Box by the absolute value of theDiff.
- void Enlarge(const Standard_Real theDiff);
-
- //! Limit the Box by the internals of theOtherBox.
- //! Returns True if the limitation takes place, otherwise False
- //! indicating that the boxes do not intersect.
- Standard_EXPORT Standard_Boolean Limit(const Bnd_B3d& theOtherBox);
-
- //! Transform the bounding box with the given transformation.
- //! The resulting box will be larger if theTrsf contains rotation.
- Standard_NODISCARD Standard_EXPORT Bnd_B3d Transformed(const gp_Trsf& theTrsf) const;
-
- //! Check the given point for the inclusion in the Box.
- //! Returns True if the point is outside.
- Standard_Boolean IsOut(const gp_XYZ& thePnt) const;
-
- //! Check a sphere for the intersection with the current box.
- //! Returns True if there is no intersection between boxes. If the
- //! parameter 'IsSphereHollow' is True, then the intersection is not
- //! reported for a box that is completely inside the sphere (otherwise
- //! this method would report an intersection).
- Standard_EXPORT Standard_Boolean
- IsOut(const gp_XYZ& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isSphereHollow = Standard_False) const;
-
- //! Check the given box for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_Boolean IsOut(const Bnd_B3d& theOtherBox) const;
-
- //! Check the given box oriented by the given transformation
- //! for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean IsOut(const Bnd_B3d& theOtherBox, const gp_Trsf& theTrsf) const;
-
- //! Check the given Line for the intersection with the current box.
- //! Returns True if there is no intersection.
- //! isRay==True means intersection check with the positive half-line
- //! theOverthickness is the addition to the size of the current box
- //! (may be negative). If positive, it can be treated as the thickness
- //! of the line 'theLine' or the radius of the cylinder along 'theLine'
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax1& theLine,
- const Standard_Boolean isRay = Standard_False,
- const Standard_Real theOverthickness = 0.0) const;
-
- //! Check the given Plane for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax3& thePlane) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'. Returns
- //! True if 'this' box is fully inside 'theBox'.
- Standard_Boolean IsIn(const Bnd_B3d& theBox) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'
- //! transformed by 'theTrsf'. Returns True if 'this' box is fully
- //! inside the transformed 'theBox'.
- Standard_EXPORT Standard_Boolean IsIn(const Bnd_B3d& theBox, const gp_Trsf& theTrsf) const;
-
- //! Set the Center coordinates
- void SetCenter(const gp_XYZ& theCenter);
-
- //! Set the HSize (half-diagonal) coordinates.
- //! All components of theHSize must be non-negative.
- void SetHSize(const gp_XYZ& theHSize);
-
-protected:
- Standard_Real myCenter[3];
- Standard_Real myHSize[3];
-
-private:
-};
-
-#define RealType Standard_Real
-#define RealType_hxx <Standard_Real.hxx>
-#define Bnd_B3x Bnd_B3d
-#define Bnd_B3x_hxx <Bnd_B3d.hxx>
-
-#include <Bnd_B3x.lxx>
-
-#undef RealType
-#undef RealType_hxx
-#undef Bnd_B3x
-#undef Bnd_B3x_hxx
-
-#endif // _Bnd_B3d_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <Bnd_B3d.hxx>
-
-#include <gp_XYZ.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Ax3.hxx>
-
-#define RealType Standard_Real
-#define RealType_hxx <Standard_Real.hxx>
-#define Bnd_B3x Bnd_B3d
-#define Bnd_B3x_hxx <Bnd_B3d.hxx>
-#include <Bnd_B3x.gxx>
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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 _Bnd_B3f_HeaderFile
-#define _Bnd_B3f_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-
-class gp_XYZ;
-class gp_Pnt;
-class gp_Trsf;
-class gp_Ax1;
-class gp_Ax3;
-
-class Bnd_B3f
-{
-public:
- DEFINE_STANDARD_ALLOC
-
- //! Empty constructor.
- Bnd_B3f();
-
- //! Constructor.
- Bnd_B3f(const gp_XYZ& theCenter, const gp_XYZ& theHSize);
-
- //! Returns True if the box is void (non-initialized).
- Standard_Boolean IsVoid() const;
-
- //! Reset the box data.
- void Clear();
-
- //! Update the box by a point.
- Standard_EXPORT void Add(const gp_XYZ& thePnt);
-
- //! Update the box by a point.
- void Add(const gp_Pnt& thePnt);
-
- //! Update the box by another box.
- void Add(const Bnd_B3f& theBox);
-
- //! Query the lower corner: (Center - HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XYZ CornerMin() const;
-
- //! Query the upper corner: (Center + HSize). You must make sure that
- //! the box is NOT VOID (see IsVoid()), otherwise the method returns
- //! irrelevant result.
- gp_XYZ CornerMax() const;
-
- //! Query the square diagonal. If the box is VOID (see method IsVoid())
- //! then a very big real value is returned.
- Standard_Real SquareExtent() const;
-
- //! Extend the Box by the absolute value of theDiff.
- void Enlarge(const Standard_Real theDiff);
-
- //! Limit the Box by the internals of theOtherBox.
- //! Returns True if the limitation takes place, otherwise False
- //! indicating that the boxes do not intersect.
- Standard_EXPORT Standard_Boolean Limit(const Bnd_B3f& theOtherBox);
-
- //! Transform the bounding box with the given transformation.
- //! The resulting box will be larger if theTrsf contains rotation.
- Standard_NODISCARD Standard_EXPORT Bnd_B3f Transformed(const gp_Trsf& theTrsf) const;
-
- //! Check the given point for the inclusion in the Box.
- //! Returns True if the point is outside.
- Standard_Boolean IsOut(const gp_XYZ& thePnt) const;
-
- //! Check a sphere for the intersection with the current box.
- //! Returns True if there is no intersection between boxes. If the
- //! parameter 'IsSphereHollow' is True, then the intersection is not
- //! reported for a box that is completely inside the sphere (otherwise
- //! this method would report an intersection).
- Standard_EXPORT Standard_Boolean
- IsOut(const gp_XYZ& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isSphereHollow = Standard_False) const;
-
- //! Check the given box for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_Boolean IsOut(const Bnd_B3f& theOtherBox) const;
-
- //! Check the given box oriented by the given transformation
- //! for the intersection with the current box.
- //! Returns True if there is no intersection between boxes.
- Standard_EXPORT Standard_Boolean IsOut(const Bnd_B3f& theOtherBox, const gp_Trsf& theTrsf) const;
-
- //! Check the given Line for the intersection with the current box.
- //! Returns True if there is no intersection.
- //! isRay==True means intersection check with the positive half-line
- //! theOverthickness is the addition to the size of the current box
- //! (may be negative). If positive, it can be treated as the thickness
- //! of the line 'theLine' or the radius of the cylinder along 'theLine'
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax1& theLine,
- const Standard_Boolean isRay = Standard_False,
- const Standard_Real theOverthickness = 0.0) const;
-
- //! Check the given Plane for the intersection with the current box.
- //! Returns True if there is no intersection.
- Standard_EXPORT Standard_Boolean IsOut(const gp_Ax3& thePlane) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'. Returns
- //! True if 'this' box is fully inside 'theBox'.
- Standard_Boolean IsIn(const Bnd_B3f& theBox) const;
-
- //! Check that the box 'this' is inside the given box 'theBox'
- //! transformed by 'theTrsf'. Returns True if 'this' box is fully
- //! inside the transformed 'theBox'.
- Standard_EXPORT Standard_Boolean IsIn(const Bnd_B3f& theBox, const gp_Trsf& theTrsf) const;
-
- //! Set the Center coordinates
- void SetCenter(const gp_XYZ& theCenter);
-
- //! Set the HSize (half-diagonal) coordinates.
- //! All components of theHSize must be non-negative.
- void SetHSize(const gp_XYZ& theHSize);
-
-protected:
- Standard_ShortReal myCenter[3];
- Standard_ShortReal myHSize[3];
-
-private:
-};
-
-#define RealType Standard_ShortReal
-#define RealType_hxx <Standard_ShortReal.hxx>
-#define Bnd_B3x Bnd_B3f
-#define Bnd_B3x_hxx <Bnd_B3f.hxx>
-
-#include <Bnd_B3x.lxx>
-
-#undef RealType
-#undef RealType_hxx
-#undef Bnd_B3x
-#undef Bnd_B3x_hxx
-
-#endif // _Bnd_B3f_HeaderFile
+++ /dev/null
-// Created on: 1991-01-08
-// Created by: Didier Piffault
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <Bnd_B3f.hxx>
-
-#include <gp_XYZ.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Ax3.hxx>
-
-#define RealType Standard_ShortReal
-#define RealType_hxx <Standard_ShortReal.hxx>
-#define Bnd_B3x Bnd_B3f
-#define Bnd_B3x_hxx <Bnd_B3f.hxx>
-#include <Bnd_B3x.gxx>
+++ /dev/null
-// Created on: 2005-09-08
-// Created by: Alexander GRIGORIEV
-// Copyright (c) 2005-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.
-
-inline Standard_Boolean _compareDist(const RealType aHSize[3], const RealType aDist[3])
-{
- return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1] || Abs(aDist[2]) > aHSize[2]);
-}
-
-inline Standard_Boolean _compareDistD(const gp_XYZ& aHSize, const gp_XYZ& aDist)
-{
- return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y()
- || Abs(aDist.Z()) > aHSize.Z());
-}
-
-//=======================================================================
-// function : Add
-// purpose : Update the box by a point
-//=======================================================================
-
-void Bnd_B3x::Add(const gp_XYZ& thePnt)
-{
- if (IsVoid())
- {
- myCenter[0] = RealType(thePnt.X());
- myCenter[1] = RealType(thePnt.Y());
- myCenter[2] = RealType(thePnt.Z());
- myHSize[0] = 0.;
- myHSize[1] = 0.;
- myHSize[2] = 0.;
- }
- else
- {
- const RealType aDiff[3] = {RealType(thePnt.X()) - myCenter[0],
- RealType(thePnt.Y()) - myCenter[1],
- RealType(thePnt.Z()) - myCenter[2]};
- if (aDiff[0] > myHSize[0])
- {
- const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
- myCenter[0] += aShift;
- myHSize[0] += aShift;
- }
- else if (aDiff[0] < -myHSize[0])
- {
- const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
- myCenter[0] += aShift;
- myHSize[0] -= aShift;
- }
- if (aDiff[1] > myHSize[1])
- {
- const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
- myCenter[1] += aShift;
- myHSize[1] += aShift;
- }
- else if (aDiff[1] < -myHSize[1])
- {
- const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
- myCenter[1] += aShift;
- myHSize[1] -= aShift;
- }
- if (aDiff[2] > myHSize[2])
- {
- const RealType aShift = (aDiff[2] - myHSize[2]) / 2;
- myCenter[2] += aShift;
- myHSize[2] += aShift;
- }
- else if (aDiff[2] < -myHSize[2])
- {
- const RealType aShift = (aDiff[2] + myHSize[2]) / 2;
- myCenter[2] += aShift;
- myHSize[2] -= aShift;
- }
- }
-}
-
-//=======================================================================
-// function : Limit
-// purpose : limit the current box with the internals of theBox
-//=======================================================================
-
-Standard_Boolean Bnd_B3x::Limit(const Bnd_B3x& theBox)
-{
- Standard_Boolean aResult(Standard_False);
- const RealType diffC[3] = {theBox.myCenter[0] - myCenter[0],
- theBox.myCenter[1] - myCenter[1],
- theBox.myCenter[2] - myCenter[2]};
- const RealType sumH[3] = {theBox.myHSize[0] + myHSize[0],
- theBox.myHSize[1] + myHSize[1],
- theBox.myHSize[2] + myHSize[2]};
- // check the condition IsOut
- if (_compareDist(sumH, diffC) == Standard_False)
- {
- const RealType diffH[3] = {theBox.myHSize[0] - myHSize[0],
- theBox.myHSize[1] - myHSize[1],
- theBox.myHSize[2] - myHSize[2]};
- if (diffC[0] - diffH[0] > 0.)
- {
- const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
- myCenter[0] += aShift;
- myHSize[0] -= aShift;
- }
- else if (diffC[0] + diffH[0] < 0.)
- {
- const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
- myCenter[0] += aShift;
- myHSize[0] += aShift;
- }
- if (diffC[1] - diffH[1] > 0.)
- {
- const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
- myCenter[1] += aShift;
- myHSize[1] -= aShift;
- }
- else if (diffC[1] + diffH[1] < 0.)
- {
- const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
- myCenter[1] += aShift;
- myHSize[1] += aShift;
- }
- if (diffC[2] - diffH[2] > 0.)
- {
- const RealType aShift = (diffC[2] - diffH[2]) / 2; // positive
- myCenter[2] += aShift;
- myHSize[2] -= aShift;
- }
- else if (diffC[2] + diffH[2] < 0.)
- {
- const RealType aShift = (diffC[2] + diffH[2]) / 2; // negative
- myCenter[2] += aShift;
- myHSize[2] += aShift;
- }
- aResult = Standard_True;
- }
- return aResult;
-}
-
-//=================================================================================================
-
-Bnd_B3x Bnd_B3x::Transformed(const gp_Trsf& theTrsf) const
-{
- Bnd_B3x aResult;
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Identity)
- aResult = *this;
- else if (aForm == gp_Translation || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult.myCenter[0] = (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
- aResult.myCenter[1] = (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
- aResult.myCenter[2] = (RealType)(myCenter[2] * aScale + theTrsf.TranslationPart().Z());
- aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
- aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
- aResult.myHSize[2] = (RealType)(myHSize[2] * aScaleAbs);
- }
- else
- {
- gp_XYZ aCenter((Standard_Real)myCenter[0],
- (Standard_Real)myCenter[1],
- (Standard_Real)myCenter[2]);
- theTrsf.Transforms(aCenter);
- aResult.myCenter[0] = (RealType)aCenter.X();
- aResult.myCenter[1] = (RealType)aCenter.Y();
- aResult.myCenter[2] = (RealType)aCenter.Z();
-
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
- aResult.myHSize[0] = (RealType)(aScaleAbs
- * (Abs(aMat[0]) * myHSize[0] + Abs(aMat[1]) * myHSize[1]
- + Abs(aMat[2]) * myHSize[2]));
- aResult.myHSize[1] = (RealType)(aScaleAbs
- * (Abs(aMat[3]) * myHSize[0] + Abs(aMat[4]) * myHSize[1]
- + Abs(aMat[5]) * myHSize[2]));
- aResult.myHSize[2] = (RealType)(aScaleAbs
- * (Abs(aMat[6]) * myHSize[0] + Abs(aMat[7]) * myHSize[1]
- + Abs(aMat[8]) * myHSize[2]));
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - Sphere
-//=======================================================================
-
-Standard_Boolean Bnd_B3x::IsOut(const gp_XYZ& theCenter,
- const Standard_Real theRadius,
- const Standard_Boolean isSphereHollow) const
-{
- Standard_Boolean aResult(Standard_True);
- if (isSphereHollow == Standard_False)
- {
- // vector from the center of the sphere to the nearest box face
- const Standard_Real aDist[3] = {
- Abs(theCenter.X() - Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
- Abs(theCenter.Y() - Standard_Real(myCenter[1])) - Standard_Real(myHSize[1]),
- Abs(theCenter.Z() - Standard_Real(myCenter[2])) - Standard_Real(myHSize[2])};
- Standard_Real aD(0.);
- if (aDist[0] > 0.)
- aD = aDist[0] * aDist[0];
- if (aDist[1] > 0.)
- aD += aDist[1] * aDist[1];
- if (aDist[2] > 0.)
- aD += aDist[2] * aDist[2];
- aResult = (aD > theRadius * theRadius);
- }
- else
- {
- const Standard_Real aDistC[3] = {Abs(theCenter.X() - Standard_Real(myCenter[0])),
- Abs(theCenter.Y() - Standard_Real(myCenter[1])),
- Abs(theCenter.Z() - Standard_Real(myCenter[2]))};
- // vector from the center of the sphere to the nearest box face
- Standard_Real aDist[3] = {aDistC[0] - Standard_Real(myHSize[0]),
- aDistC[1] - Standard_Real(myHSize[1]),
- aDistC[2] - Standard_Real(myHSize[2])};
- Standard_Real aD(0.);
- if (aDist[0] > 0.)
- aD = aDist[0] * aDist[0];
- if (aDist[1] > 0.)
- aD += aDist[1] * aDist[1];
- if (aDist[2] > 0.)
- aD += aDist[2] * aDist[2];
- if (aD < theRadius * theRadius)
- {
- // the box intersects the solid sphere; check if it is completely
- // inside the circle (in such case return isOut==True)
- aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
- aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
- aDist[2] = aDistC[2] + Standard_Real(myHSize[2]);
- if (aDist[0] * aDist[0] + aDist[1] * aDist[1] + aDist[2] * aDist[2] > theRadius * theRadius)
- aResult = Standard_False;
- }
- }
- return aResult;
-}
-
-//=======================================================================
-// function : IsOut
-// purpose : Intersection Box - transformed Box
-//=======================================================================
-
-Standard_Boolean Bnd_B3x::IsOut(const Bnd_B3x& theBox, const gp_Trsf& theTrsf) const
-{
- Standard_Boolean aResult(Standard_False);
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult =
- (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
- > RealType(theBox.myHSize[0] * aScaleAbs) + myHSize[0]
- || Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
- > RealType(theBox.myHSize[1] * aScaleAbs) + myHSize[1]
- || Abs(RealType(theBox.myCenter[2] * aScale + theTrsf.TranslationPart().Y()) - myCenter[2])
- > RealType(theBox.myHSize[2] * aScaleAbs) + myHSize[2]);
- }
- else
- {
- // theBox is transformed and we check the resulting (enlarged) box against
- // 'this' box.
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
-
- gp_XYZ aCenter((Standard_Real)theBox.myCenter[0],
- (Standard_Real)theBox.myCenter[1],
- (Standard_Real)theBox.myCenter[2]);
- theTrsf.Transforms(aCenter);
- const Standard_Real aDist[3] = {aCenter.X() - (Standard_Real)myCenter[0],
- aCenter.Y() - (Standard_Real)myCenter[1],
- aCenter.Z() - (Standard_Real)myCenter[2]};
- const Standard_Real aMatAbs[9] = {Abs(aMat[0]),
- Abs(aMat[1]),
- Abs(aMat[2]),
- Abs(aMat[3]),
- Abs(aMat[4]),
- Abs(aMat[5]),
- Abs(aMat[6]),
- Abs(aMat[7]),
- Abs(aMat[8])};
- if (Abs(aDist[0]) > (aScaleAbs
- * (aMatAbs[0] * theBox.myHSize[0] + aMatAbs[1] * theBox.myHSize[1]
- + aMatAbs[2] * theBox.myHSize[2])
- + (Standard_Real)myHSize[0])
- || Abs(aDist[1]) > (aScaleAbs
- * (aMatAbs[3] * theBox.myHSize[0] + aMatAbs[4] * theBox.myHSize[1]
- + aMatAbs[5] * theBox.myHSize[2])
- + (Standard_Real)myHSize[1])
- || Abs(aDist[2]) > (aScaleAbs
- * (aMatAbs[6] * theBox.myHSize[0] + aMatAbs[7] * theBox.myHSize[1]
- + aMatAbs[8] * theBox.myHSize[2])
- + (Standard_Real)myHSize[2]))
- aResult = Standard_True;
-
- else
- {
- // theBox is rotated, scaled and translated. We apply the reverse
- // translation and scaling then check against the rotated box 'this'
- if ((Abs(aMat[0] * aDist[0] + aMat[3] * aDist[1] + aMat[6] * aDist[2])
- > theBox.myHSize[0] * aScaleAbs
- + (aMatAbs[0] * myHSize[0] + aMatAbs[3] * myHSize[1] + aMatAbs[6] * myHSize[2]))
- || (Abs(aMat[1] * aDist[0] + aMat[4] * aDist[1] + aMat[7] * aDist[2])
- > theBox.myHSize[1] * aScaleAbs
- + (aMatAbs[1] * myHSize[0] + aMatAbs[4] * myHSize[1] + aMatAbs[7] * myHSize[2]))
- || (Abs(aMat[2] * aDist[0] + aMat[5] * aDist[1] + aMat[8] * aDist[2])
- > theBox.myHSize[2] * aScaleAbs
- + (aMatAbs[2] * myHSize[0] + aMatAbs[5] * myHSize[1] + aMatAbs[8] * myHSize[2])))
- aResult = Standard_True;
- }
- }
- return aResult;
-}
-
-//=================================================================================================
-
-Standard_Boolean Bnd_B3x::IsOut(const gp_Ax3& thePlane) const
-{
- if (IsVoid())
- return Standard_True;
- const gp_XYZ& anOrigin = thePlane.Location().XYZ();
- const gp_XYZ& aDir = thePlane.Direction().XYZ();
- const gp_XYZ aBoxCenter((Standard_Real)myCenter[0],
- (Standard_Real)myCenter[1],
- (Standard_Real)myCenter[2]);
- const Standard_Real aDist0 = (aBoxCenter - anOrigin) * aDir;
- // Find the signed distances from two opposite corners of the box to the plane
- // If the distances are not the same sign, then the plane crosses the box
- const Standard_Real aDist1 = // proj of HSize on aDir
- Standard_Real(myHSize[0]) * Abs(aDir.X()) + Standard_Real(myHSize[1]) * Abs(aDir.Y())
- + Standard_Real(myHSize[2]) * Abs(aDir.Z());
- return ((aDist0 + aDist1) * (aDist0 - aDist1) > 0.);
-}
-
-//=================================================================================================
-
-Standard_Boolean Bnd_B3x::IsOut(const gp_Ax1& theLine,
- const Standard_Boolean isRay,
- const Standard_Real theOverthickness) const
-{
- const Standard_Real aRes = gp::Resolution() * 100.;
- if (IsVoid())
- return Standard_True;
- Standard_Real anInter0[2] = {-RealLast(), RealLast()}, anInter1[2] = {-RealLast(), RealLast()};
- const gp_XYZ& aDir = theLine.Direction().XYZ();
- const gp_XYZ aDiff((Standard_Real)myCenter[0] - theLine.Location().X(),
- (Standard_Real)myCenter[1] - theLine.Location().Y(),
- (Standard_Real)myCenter[2] - theLine.Location().Z());
-
- // Find the parameter interval in X dimension
- Standard_Real aHSize = (Standard_Real)myHSize[0] + theOverthickness;
- if (aDir.X() > aRes)
- {
- anInter0[0] = (aDiff.X() - aHSize) / aDir.X();
- anInter0[1] = (aDiff.X() + aHSize) / aDir.X();
- }
- else if (aDir.X() < -aRes)
- {
- anInter0[0] = (aDiff.X() + aHSize) / aDir.X();
- anInter0[1] = (aDiff.X() - aHSize) / aDir.X();
- }
- else
- // the line is orthogonal to OX axis. Test for inclusion in box limits
- if (Abs(aDiff.X()) > aHSize)
- return Standard_True;
-
- // Find the parameter interval in Y dimension
- aHSize = (Standard_Real)myHSize[1] + theOverthickness;
- if (aDir.Y() > aRes)
- {
- anInter1[0] = (aDiff.Y() - aHSize) / aDir.Y();
- anInter1[1] = (aDiff.Y() + aHSize) / aDir.Y();
- }
- else if (aDir.Y() < -aRes)
- {
- anInter1[0] = (aDiff.Y() + aHSize) / aDir.Y();
- anInter1[1] = (aDiff.Y() - aHSize) / aDir.Y();
- }
- else
- // the line is orthogonal to OY axis. Test for inclusion in box limits
- if (Abs(aDiff.Y()) > aHSize)
- return Standard_True;
-
- // Intersect Y-interval with X-interval
- if (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes))
- return Standard_True;
- if (anInter1[0] > anInter0[0])
- anInter0[0] = anInter1[0];
- if (anInter1[1] < anInter0[1])
- anInter0[1] = anInter1[1];
- if (isRay && anInter0[1] < -aRes)
- return Standard_True;
-
- // Find the parameter interval in Z dimension
- aHSize = (Standard_Real)myHSize[2] + theOverthickness;
- if (aDir.Z() > aRes)
- {
- anInter1[0] = (aDiff.Z() - aHSize) / aDir.Z();
- anInter1[1] = (aDiff.Z() + aHSize) / aDir.Z();
- }
- else if (aDir.Z() < -aRes)
- {
- anInter1[0] = (aDiff.Z() + aHSize) / aDir.Z();
- anInter1[1] = (aDiff.Z() - aHSize) / aDir.Z();
- }
- else
- // the line is orthogonal to OZ axis. Test for inclusion in box limits
- return (Abs(aDiff.Z()) > aHSize);
- if (isRay && anInter1[1] < -aRes)
- return Standard_True;
-
- return (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes));
-}
-
-//=======================================================================
-// function : IsIn
-// purpose : Test the complete inclusion of this box in transformed theOtherBox
-//=======================================================================
-
-Standard_Boolean Bnd_B3x::IsIn(const Bnd_B3x& theBox, const gp_Trsf& theTrsf) const
-{
- Standard_Boolean aResult(Standard_False);
- const gp_TrsfForm aForm = theTrsf.Form();
- const Standard_Real aScale = theTrsf.ScaleFactor();
- const Standard_Real aScaleAbs = Abs(aScale);
- if (aForm == gp_Translation || aForm == gp_Identity || aForm == gp_PntMirror || aForm == gp_Scale)
- {
- aResult =
- (Abs(RealType(theBox.myCenter[0] * aScale + theTrsf.TranslationPart().X()) - myCenter[0])
- < RealType(theBox.myHSize[0] * aScaleAbs) - myHSize[0]
- && Abs(RealType(theBox.myCenter[1] * aScale + theTrsf.TranslationPart().Y()) - myCenter[1])
- < RealType(theBox.myHSize[1] * aScaleAbs) - myHSize[1]
- && Abs(RealType(theBox.myCenter[2] * aScale + theTrsf.TranslationPart().Y()) - myCenter[2])
- < RealType(theBox.myHSize[2] * aScaleAbs) - myHSize[2]);
- }
- else
- {
- // theBox is rotated, scaled and translated. We apply the reverse
- // translation and scaling then check against the rotated box 'this'
- const Standard_Real* aMat = &theTrsf.HVectorialPart().Value(1, 1);
- gp_XYZ aCenter((Standard_Real)theBox.myCenter[0],
- (Standard_Real)theBox.myCenter[1],
- (Standard_Real)theBox.myCenter[2]);
- theTrsf.Transforms(aCenter);
- const Standard_Real aDist[3] = {aCenter.X() - (Standard_Real)myCenter[0],
- aCenter.Y() - (Standard_Real)myCenter[1],
- aCenter.Z() - (Standard_Real)myCenter[2]};
- if ((Abs(aMat[0] * aDist[0] + aMat[3] * aDist[1] + aMat[6] * aDist[2])
- < theBox.myHSize[0] * aScaleAbs
- - (Abs(aMat[0]) * myHSize[0] + Abs(aMat[3]) * myHSize[1] + Abs(aMat[6]) * myHSize[2]))
- && (Abs(aMat[1] * aDist[0] + aMat[4] * aDist[1] + aMat[7] * aDist[2])
- < theBox.myHSize[1] * aScaleAbs
- - (Abs(aMat[1]) * myHSize[0] + Abs(aMat[4]) * myHSize[1]
- + Abs(aMat[7]) * myHSize[2]))
- && (Abs(aMat[2] * aDist[0] + aMat[5] * aDist[1] + aMat[8] * aDist[2])
- < theBox.myHSize[2] * aScaleAbs
- - (Abs(aMat[2]) * myHSize[0] + Abs(aMat[5]) * myHSize[1]
- + Abs(aMat[8]) * myHSize[2])))
- aResult = Standard_True;
- }
- return aResult;
-}
+++ /dev/null
-// Created on: 2005-09-08
-// Created by: Alexander GRIGORIEV
-// Copyright (c) 2005-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.
-
-#include <gp_Pnt.hxx>
-
-#ifndef Bnd_B3x_RealLast
- #define Bnd_B3x_RealLast RealType(1e30);
-#endif
-
-/**
- * Empty constructor
- */
-inline Bnd_B3x::Bnd_B3x()
-{
- Clear();
-}
-
-/**
- * Constructor.
- * @param theCenter
- * Center of the created box
- * @param theHSize
- * Half-diagonal of the box, both X and Y should be non-negative
- */
-inline Bnd_B3x::Bnd_B3x(const gp_XYZ& theCenter, const gp_XYZ& theHSize)
-{
- myCenter[0] = RealType(theCenter.X());
- myCenter[1] = RealType(theCenter.Y());
- myCenter[2] = RealType(theCenter.Z());
- myHSize[0] = RealType(theHSize.X());
- myHSize[1] = RealType(theHSize.Y());
- myHSize[2] = RealType(theHSize.Z());
-}
-
-/**
- * Reset the box data.
- */
-inline void Bnd_B3x::Clear()
-{
- myCenter[0] = Bnd_B3x_RealLast;
- myCenter[1] = Bnd_B3x_RealLast;
- myCenter[2] = Bnd_B3x_RealLast;
- myHSize[0] = -Bnd_B3x_RealLast;
- myHSize[1] = -Bnd_B3x_RealLast;
- myHSize[2] = -Bnd_B3x_RealLast;
-}
-
-/**
- * Check if the box is empty.
- */
-inline Standard_Boolean Bnd_B3x::IsVoid() const
-{
- return (myHSize[0] < -1e-5);
-}
-
-/**
- * Update the box by point.
- */
-inline void Bnd_B3x::Add(const gp_Pnt& thePnt)
-{
- Add(thePnt.XYZ());
-}
-
-/**
- * Update the box by another box.
- */
-inline void Bnd_B3x::Add(const Bnd_B3x& theBox)
-{
- if (theBox.IsVoid() == Standard_False)
- {
- Add(theBox.CornerMin());
- Add(theBox.CornerMax());
- }
-}
-
-/**
- * Query a box corner.
- */
-inline gp_XYZ Bnd_B3x::CornerMin() const
-{
- return gp_XYZ(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1], myCenter[2] - myHSize[2]);
-}
-
-/**
- * Query a box corner.
- */
-inline gp_XYZ Bnd_B3x::CornerMax() const
-{
- return gp_XYZ(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1], myCenter[2] + myHSize[2]);
-}
-
-/**
- * Query the square diagonal.
- */
-inline Standard_Real Bnd_B3x::SquareExtent() const
-{
- return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1] + myHSize[2] * myHSize[2]);
-}
-
-/**
- * Set the Center coordinates.
- */
-inline void Bnd_B3x::SetCenter(const gp_XYZ& theCenter)
-{
- myCenter[0] = RealType(theCenter.X());
- myCenter[1] = RealType(theCenter.Y());
- myCenter[2] = RealType(theCenter.Z());
-}
-
-/**
- * Set the Center coordinates.
- */
-inline void Bnd_B3x::SetHSize(const gp_XYZ& theHSize)
-{
- myHSize[0] = RealType(theHSize.X());
- myHSize[1] = RealType(theHSize.Y());
- myHSize[2] = RealType(theHSize.Z());
-}
-
-/**
- * Increase the box.
- * @param aDiff
- * absolute value of this parameter is added to the box size in all dimensions.
- */
-inline void Bnd_B3x::Enlarge(const Standard_Real aDiff)
-{
- const Standard_Real aD = Abs(aDiff);
- myHSize[0] += RealType(aD);
- myHSize[1] += RealType(aD);
- myHSize[2] += RealType(aD);
-}
-
-/**
- * Intersection Box - Point
- */
-inline Standard_Boolean Bnd_B3x::IsOut(const gp_XYZ& thePnt) const
-{
- return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0]
- || Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]
- || Abs(RealType(thePnt.Z()) - myCenter[2]) > myHSize[2]);
-}
-
-/**
- * Intersection Box-Box.
- */
-inline Standard_Boolean Bnd_B3x::IsOut(const Bnd_B3x& theBox) const
-{
- return (Abs(theBox.myCenter[0] - myCenter[0]) > theBox.myHSize[0] + myHSize[0]
- || Abs(theBox.myCenter[1] - myCenter[1]) > theBox.myHSize[1] + myHSize[1]
- || Abs(theBox.myCenter[2] - myCenter[2]) > theBox.myHSize[2] + myHSize[2]);
-}
-
-/**
- * Test the complete inclusion of this box in theBox.
- */
-inline Standard_Boolean Bnd_B3x::IsIn(const Bnd_B3x& theBox) const
-{
- return (Abs(theBox.myCenter[0] - myCenter[0]) < theBox.myHSize[0] - myHSize[0]
- && Abs(theBox.myCenter[1] - myCenter[1]) < theBox.myHSize[1] - myHSize[1]
- && Abs(theBox.myCenter[2] - myCenter[2]) < theBox.myHSize[2] - myHSize[2]);
-}
Bnd_Array1OfBox.hxx
Bnd_Array1OfBox2d.hxx
Bnd_Array1OfSphere.hxx
- Bnd_B2d.hxx
- Bnd_B2d_0.cxx
- Bnd_B2f.hxx
- Bnd_B2f_0.cxx
- Bnd_B2x.gxx
- Bnd_B2x.lxx
- Bnd_B3d.hxx
- Bnd_B3d_0.cxx
- Bnd_B3f.hxx
- Bnd_B3f_0.cxx
- Bnd_B3x.gxx
- Bnd_B3x.lxx
+ Bnd_B2.hxx
+ Bnd_B3.hxx
Bnd_BoundSortBox.cxx
Bnd_BoundSortBox.hxx
Bnd_Box.cxx
--- /dev/null
+// Copyright (c) 2025 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.
+
+#include <gtest/gtest.h>
+
+#include <Bnd_B2.hxx>
+#include <gp_XY.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Trsf2d.hxx>
+#include <gp_Ax2d.hxx>
+#include <Precision.hxx>
+
+TEST(Bnd_B2dTest, DefaultConstructor)
+{
+ Bnd_B2d aBox;
+ EXPECT_TRUE(aBox.IsVoid());
+}
+
+TEST(Bnd_B2dTest, ConstructorWithCenterAndHSize)
+{
+ gp_XY aCenter(5.0, 10.0);
+ gp_XY aHSize(2.0, 3.0);
+
+ Bnd_B2d aBox(aCenter, aHSize);
+
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XY aMin = aBox.CornerMin();
+ gp_XY aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 13.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, Clear)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+ EXPECT_FALSE(aBox.IsVoid());
+
+ aBox.Clear();
+ EXPECT_TRUE(aBox.IsVoid());
+}
+
+TEST(Bnd_B2dTest, AddPoint)
+{
+ Bnd_B2d aBox;
+
+ aBox.Add(gp_XY(1.0, 2.0));
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XY aMin = aBox.CornerMin();
+ gp_XY aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 2.0, Precision::Confusion());
+
+ aBox.Add(gp_XY(4.0, 5.0));
+ aMin = aBox.CornerMin();
+ aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, AddPnt2d)
+{
+ Bnd_B2d aBox;
+ aBox.Add(gp_Pnt2d(1.0, 2.0));
+
+ EXPECT_FALSE(aBox.IsVoid());
+ gp_XY aMin = aBox.CornerMin();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, AddBox)
+{
+ Bnd_B2d aBox1(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+ Bnd_B2d aBox2(gp_XY(3.0, 3.0), gp_XY(1.0, 1.0));
+
+ aBox1.Add(aBox2);
+
+ gp_XY aMin = aBox1.CornerMin();
+ gp_XY aMax = aBox1.CornerMax();
+ EXPECT_NEAR(aMin.X(), -1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), -1.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 4.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, SquareExtent)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(3.0, 4.0));
+ Standard_Real aSqExtent = aBox.SquareExtent();
+
+ // Square diagonal = 4 * (3^2 + 4^2) = 4 * 25 = 100
+ EXPECT_NEAR(aSqExtent, 100.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, Enlarge)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+ aBox.Enlarge(0.5);
+
+ gp_XY aMin = aBox.CornerMin();
+ gp_XY aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), -1.5, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), -1.5, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 1.5, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 1.5, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, Limit)
+{
+ // Test limiting a large box by a smaller box inside it
+ // aBox1: (-5, -5) to (5, 5)
+ // aBox2: (0, 0) to (4, 4)
+ Bnd_B2d aBox1(gp_XY(0.0, 0.0), gp_XY(5.0, 5.0));
+ Bnd_B2d aBox2(gp_XY(2.0, 2.0), gp_XY(2.0, 2.0));
+
+ Standard_Boolean isLimited = aBox1.Limit(aBox2);
+ EXPECT_TRUE(isLimited);
+
+ // After limiting, aBox1's min corner should align with aBox2's min corner
+ gp_XY aMin = aBox1.CornerMin();
+ gp_XY aMax = aBox1.CornerMax();
+ EXPECT_NEAR(aMin.X(), 0.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 0.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 5.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+
+ // Test with non-intersecting boxes
+ Bnd_B2d aBox3(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+ Bnd_B2d aBox4(gp_XY(10.0, 10.0), gp_XY(1.0, 1.0));
+ Standard_Boolean isLimited2 = aBox3.Limit(aBox4);
+ EXPECT_FALSE(isLimited2);
+}
+
+TEST(Bnd_B2dTest, IsOutPoint)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+
+ EXPECT_FALSE(aBox.IsOut(gp_XY(0.0, 0.0)));
+ EXPECT_FALSE(aBox.IsOut(gp_XY(0.5, 0.5)));
+ EXPECT_TRUE(aBox.IsOut(gp_XY(2.0, 0.0)));
+ EXPECT_TRUE(aBox.IsOut(gp_XY(0.0, 2.0)));
+}
+
+TEST(Bnd_B2dTest, IsOutCircle)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+
+ // Circle at (0, 0) with small radius - should intersect
+ EXPECT_FALSE(aBox.IsOut(gp_XY(0.0, 0.0), 0.5));
+
+ // Circle far away - should not intersect
+ EXPECT_TRUE(aBox.IsOut(gp_XY(10.0, 10.0), 1.0));
+}
+
+TEST(Bnd_B2dTest, IsOutBox)
+{
+ Bnd_B2d aBox1(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+ Bnd_B2d aBox2(gp_XY(0.5, 0.5), gp_XY(1.0, 1.0));
+ Bnd_B2d aBox3(gp_XY(5.0, 5.0), gp_XY(1.0, 1.0));
+
+ EXPECT_FALSE(aBox1.IsOut(aBox2));
+ EXPECT_TRUE(aBox1.IsOut(aBox3));
+}
+
+TEST(Bnd_B2dTest, IsOutLine)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+
+ // Line passing through box
+ gp_Ax2d aLine1(gp_Pnt2d(-2.0, 0.0), gp_Dir2d(1.0, 0.0));
+ EXPECT_FALSE(aBox.IsOut(aLine1));
+
+ // Line not intersecting box
+ gp_Ax2d aLine2(gp_Pnt2d(-2.0, 5.0), gp_Dir2d(1.0, 0.0));
+ EXPECT_TRUE(aBox.IsOut(aLine2));
+}
+
+TEST(Bnd_B2dTest, IsOutSegment)
+{
+ Bnd_B2d aBox(gp_XY(0.0, 0.0), gp_XY(1.0, 1.0));
+
+ // Segment intersecting box
+ EXPECT_FALSE(aBox.IsOut(gp_XY(-2.0, 0.0), gp_XY(2.0, 0.0)));
+
+ // Segment not intersecting box
+ EXPECT_TRUE(aBox.IsOut(gp_XY(5.0, 5.0), gp_XY(6.0, 6.0)));
+}
+
+TEST(Bnd_B2dTest, IsInBox)
+{
+ Bnd_B2d aBox1(gp_XY(0.0, 0.0), gp_XY(0.5, 0.5));
+ Bnd_B2d aBox2(gp_XY(0.0, 0.0), gp_XY(2.0, 2.0));
+
+ EXPECT_TRUE(aBox1.IsIn(aBox2));
+ EXPECT_FALSE(aBox2.IsIn(aBox1));
+}
+
+TEST(Bnd_B2dTest, Transformed)
+{
+ Bnd_B2d aBox(gp_XY(1.0, 1.0), gp_XY(1.0, 1.0));
+
+ gp_Trsf2d aTrsf;
+ aTrsf.SetTranslation(gp_Vec2d(2.0, 3.0));
+
+ Bnd_B2d aTransformedBox = aBox.Transformed(aTrsf);
+
+ gp_XY aMin = aTransformedBox.CornerMin();
+ gp_XY aMax = aTransformedBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2dTest, SetCenterAndHSize)
+{
+ Bnd_B2d aBox;
+
+ aBox.SetCenter(gp_XY(5.0, 10.0));
+ aBox.SetHSize(gp_XY(2.0, 3.0));
+
+ gp_XY aMin = aBox.CornerMin();
+ gp_XY aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 13.0, Precision::Confusion());
+}
+
+TEST(Bnd_B2fTest, FloatPrecision)
+{
+ Bnd_B2f aBox(gp_XY(1.0f, 2.0f), gp_XY(0.5f, 0.5f));
+
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XY aMin = aBox.CornerMin();
+ gp_XY aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 0.5, 1e-5);
+ EXPECT_NEAR(aMin.Y(), 1.5, 1e-5);
+ EXPECT_NEAR(aMax.X(), 1.5, 1e-5);
+ EXPECT_NEAR(aMax.Y(), 2.5, 1e-5);
+}
--- /dev/null
+// Copyright (c) 2025 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.
+
+#include <gtest/gtest.h>
+
+#include <Bnd_B3.hxx>
+#include <gp_XYZ.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Ax3.hxx>
+#include <Precision.hxx>
+
+TEST(Bnd_B3dTest, DefaultConstructor)
+{
+ Bnd_B3d aBox;
+ EXPECT_TRUE(aBox.IsVoid());
+}
+
+TEST(Bnd_B3dTest, ConstructorWithCenterAndHSize)
+{
+ gp_XYZ aCenter(5.0, 10.0, 15.0);
+ gp_XYZ aHSize(2.0, 3.0, 4.0);
+
+ Bnd_B3d aBox(aCenter, aHSize);
+
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XYZ aMin = aBox.CornerMin();
+ gp_XYZ aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 11.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 13.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 19.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, Clear)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+ EXPECT_FALSE(aBox.IsVoid());
+
+ aBox.Clear();
+ EXPECT_TRUE(aBox.IsVoid());
+}
+
+TEST(Bnd_B3dTest, AddPoint)
+{
+ Bnd_B3d aBox;
+
+ aBox.Add(gp_XYZ(1.0, 2.0, 3.0));
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XYZ aMin = aBox.CornerMin();
+ gp_XYZ aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 3.0, Precision::Confusion());
+
+ aBox.Add(gp_XYZ(4.0, 5.0, 6.0));
+ aMin = aBox.CornerMin();
+ aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 6.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, AddPnt)
+{
+ Bnd_B3d aBox;
+ aBox.Add(gp_Pnt(1.0, 2.0, 3.0));
+
+ EXPECT_FALSE(aBox.IsVoid());
+ gp_XYZ aMin = aBox.CornerMin();
+ EXPECT_NEAR(aMin.X(), 1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 3.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, AddBox)
+{
+ Bnd_B3d aBox1(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+ Bnd_B3d aBox2(gp_XYZ(3.0, 3.0, 3.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ aBox1.Add(aBox2);
+
+ gp_XYZ aMin = aBox1.CornerMin();
+ gp_XYZ aMax = aBox1.CornerMax();
+ EXPECT_NEAR(aMin.X(), -1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), -1.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), -1.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 4.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, SquareExtent)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(3.0, 4.0, 5.0));
+ Standard_Real aSqExtent = aBox.SquareExtent();
+
+ // Square diagonal = 4 * (3^2 + 4^2 + 5^2) = 4 * 50 = 200
+ EXPECT_NEAR(aSqExtent, 200.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, Enlarge)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+ aBox.Enlarge(0.5);
+
+ gp_XYZ aMin = aBox.CornerMin();
+ gp_XYZ aMax = aBox.CornerMax();
+ EXPECT_NEAR(aMin.X(), -1.5, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), -1.5, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), -1.5, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 1.5, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 1.5, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 1.5, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, Limit)
+{
+ // Test limiting a large box by a smaller box inside it
+ // aBox1: (-5, -5, -5) to (5, 5, 5)
+ // aBox2: (0, 0, 0) to (4, 4, 4)
+ Bnd_B3d aBox1(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(5.0, 5.0, 5.0));
+ Bnd_B3d aBox2(gp_XYZ(2.0, 2.0, 2.0), gp_XYZ(2.0, 2.0, 2.0));
+
+ Standard_Boolean isLimited = aBox1.Limit(aBox2);
+ EXPECT_TRUE(isLimited);
+
+ // After limiting, aBox1's min corner should align with aBox2's min corner
+ gp_XYZ aMin = aBox1.CornerMin();
+ gp_XYZ aMax = aBox1.CornerMax();
+ EXPECT_NEAR(aMin.X(), 0.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 0.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 0.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 5.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 5.0, Precision::Confusion());
+
+ // Test with non-intersecting boxes
+ Bnd_B3d aBox3(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+ Bnd_B3d aBox4(gp_XYZ(10.0, 10.0, 10.0), gp_XYZ(1.0, 1.0, 1.0));
+ Standard_Boolean isLimited2 = aBox3.Limit(aBox4);
+ EXPECT_FALSE(isLimited2);
+}
+
+TEST(Bnd_B3dTest, IsOutPoint)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ EXPECT_FALSE(aBox.IsOut(gp_XYZ(0.0, 0.0, 0.0)));
+ EXPECT_FALSE(aBox.IsOut(gp_XYZ(0.5, 0.5, 0.5)));
+ EXPECT_TRUE(aBox.IsOut(gp_XYZ(2.0, 0.0, 0.0)));
+ EXPECT_TRUE(aBox.IsOut(gp_XYZ(0.0, 2.0, 0.0)));
+ EXPECT_TRUE(aBox.IsOut(gp_XYZ(0.0, 0.0, 2.0)));
+}
+
+TEST(Bnd_B3dTest, IsOutSphere)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ // Sphere at (0, 0, 0) with small radius - should intersect
+ EXPECT_FALSE(aBox.IsOut(gp_XYZ(0.0, 0.0, 0.0), 0.5));
+
+ // Sphere far away - should not intersect
+ EXPECT_TRUE(aBox.IsOut(gp_XYZ(10.0, 10.0, 10.0), 1.0));
+}
+
+TEST(Bnd_B3dTest, IsOutBox)
+{
+ Bnd_B3d aBox1(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+ Bnd_B3d aBox2(gp_XYZ(0.5, 0.5, 0.5), gp_XYZ(1.0, 1.0, 1.0));
+ Bnd_B3d aBox3(gp_XYZ(5.0, 5.0, 5.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ EXPECT_FALSE(aBox1.IsOut(aBox2));
+ EXPECT_TRUE(aBox1.IsOut(aBox3));
+}
+
+TEST(Bnd_B3dTest, IsOutLine)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ // Line passing through box
+ gp_Ax1 aLine1(gp_Pnt(-2.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
+ EXPECT_FALSE(aBox.IsOut(aLine1));
+
+ // Line not intersecting box
+ gp_Ax1 aLine2(gp_Pnt(-2.0, 5.0, 5.0), gp_Dir(1.0, 0.0, 0.0));
+ EXPECT_TRUE(aBox.IsOut(aLine2));
+}
+
+TEST(Bnd_B3dTest, IsOutPlane)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ // Plane passing through box
+ gp_Ax3 aPlane1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
+ EXPECT_FALSE(aBox.IsOut(aPlane1));
+
+ // Plane not intersecting box
+ gp_Ax3 aPlane2(gp_Pnt(0.0, 0.0, 5.0), gp_Dir(0.0, 0.0, 1.0));
+ EXPECT_TRUE(aBox.IsOut(aPlane2));
+}
+
+TEST(Bnd_B3dTest, IsInBox)
+{
+ Bnd_B3d aBox1(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(0.5, 0.5, 0.5));
+ Bnd_B3d aBox2(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(2.0, 2.0, 2.0));
+
+ EXPECT_TRUE(aBox1.IsIn(aBox2));
+ EXPECT_FALSE(aBox2.IsIn(aBox1));
+}
+
+TEST(Bnd_B3dTest, Transformed)
+{
+ Bnd_B3d aBox(gp_XYZ(1.0, 1.0, 1.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ gp_Trsf aTrsf;
+ aTrsf.SetTranslation(gp_Vec(2.0, 3.0, 4.0));
+
+ Bnd_B3d aTransformedBox = aBox.Transformed(aTrsf);
+
+ gp_XYZ aMin = aTransformedBox.CornerMin();
+ gp_XYZ aMax = aTransformedBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 2.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 4.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 5.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 6.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3dTest, TransformedWithRotation)
+{
+ Bnd_B3d aBox(gp_XYZ(1.0, 0.0, 0.0), gp_XYZ(0.5, 0.5, 0.5));
+
+ gp_Trsf aTrsf;
+ aTrsf.SetRotation(gp_Ax1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), M_PI / 2.0);
+
+ Bnd_B3d aTransformedBox = aBox.Transformed(aTrsf);
+
+ // After 90 degree rotation around Z-axis, the center should be at (0, 1, 0)
+ gp_XYZ aMin = aTransformedBox.CornerMin();
+ gp_XYZ aMax = aTransformedBox.CornerMax();
+
+ // The rotated box should have its center near (0, 1, 0)
+ // and half-size should remain approximately the same (with some expansion for rotation)
+ EXPECT_NEAR((aMin.X() + aMax.X()) / 2.0, 0.0, 1e-10);
+ EXPECT_NEAR((aMin.Y() + aMax.Y()) / 2.0, 1.0, 1e-10);
+ EXPECT_NEAR((aMin.Z() + aMax.Z()) / 2.0, 0.0, 1e-10);
+}
+
+TEST(Bnd_B3dTest, SetCenterAndHSize)
+{
+ Bnd_B3d aBox;
+
+ aBox.SetCenter(gp_XYZ(5.0, 10.0, 15.0));
+ aBox.SetHSize(gp_XYZ(2.0, 3.0, 4.0));
+
+ gp_XYZ aMin = aBox.CornerMin();
+ gp_XYZ aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 3.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Y(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMin.Z(), 11.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.X(), 7.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Y(), 13.0, Precision::Confusion());
+ EXPECT_NEAR(aMax.Z(), 19.0, Precision::Confusion());
+}
+
+TEST(Bnd_B3fTest, FloatPrecision)
+{
+ Bnd_B3f aBox(gp_XYZ(1.0f, 2.0f, 3.0f), gp_XYZ(0.5f, 0.5f, 0.5f));
+
+ EXPECT_FALSE(aBox.IsVoid());
+
+ gp_XYZ aMin = aBox.CornerMin();
+ gp_XYZ aMax = aBox.CornerMax();
+
+ EXPECT_NEAR(aMin.X(), 0.5, 1e-5);
+ EXPECT_NEAR(aMin.Y(), 1.5, 1e-5);
+ EXPECT_NEAR(aMin.Z(), 2.5, 1e-5);
+ EXPECT_NEAR(aMax.X(), 1.5, 1e-5);
+ EXPECT_NEAR(aMax.Y(), 2.5, 1e-5);
+ EXPECT_NEAR(aMax.Z(), 3.5, 1e-5);
+}
+
+TEST(Bnd_B3dTest, IsOutRay)
+{
+ Bnd_B3d aBox(gp_XYZ(1.0, 1.0, 1.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ // Ray starting before the box and pointing towards it
+ gp_Ax1 aRay1(gp_Pnt(-1.0, 1.0, 1.0), gp_Dir(1.0, 0.0, 0.0));
+ EXPECT_FALSE(aBox.IsOut(aRay1, Standard_True));
+
+ // Ray starting inside the box
+ gp_Ax1 aRay2(gp_Pnt(1.0, 1.0, 1.0), gp_Dir(1.0, 0.0, 0.0));
+ EXPECT_FALSE(aBox.IsOut(aRay2, Standard_True));
+
+ // Ray pointing away from the box
+ gp_Ax1 aRay3(gp_Pnt(-1.0, 1.0, 1.0), gp_Dir(-1.0, 0.0, 0.0));
+ EXPECT_TRUE(aBox.IsOut(aRay3, Standard_True));
+}
+
+TEST(Bnd_B3dTest, IsOutLineWithOverthickness)
+{
+ Bnd_B3d aBox(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(1.0, 1.0, 1.0));
+
+ // Line passing just outside the box, but within overthickness
+ gp_Ax1 aLine(gp_Pnt(-2.0, 1.2, 0.0), gp_Dir(1.0, 0.0, 0.0));
+
+ // Without overthickness, should be out
+ EXPECT_TRUE(aBox.IsOut(aLine, Standard_False, 0.0));
+
+ // With sufficient overthickness, should intersect
+ EXPECT_FALSE(aBox.IsOut(aLine, Standard_False, 0.3));
+}
set(OCCT_TKMath_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKMath_GTests_FILES
+ Bnd_B2_Test.cxx
+ Bnd_B3_Test.cxx
Bnd_BoundSortBox_Test.cxx
Bnd_Box_Test.cxx
Bnd_OBB_Test.cxx
#include <Precision.hxx>
#include <Bnd_Box2d.hxx>
-#include <Bnd_B2d.hxx>
+#include <Bnd_B2.hxx>
#include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx>
#include <BRepMesh_GeomTool.hxx>
#include <Message_ProgressRange.hxx>
-class Bnd_B2d;
class Bnd_Box2d;
class BRepMesh_Vertex;
#include <NCollection_UBTreeFiller.hxx>
#include <NCollection_IndexedMap.hxx>
#include <BRepMesh_Vertex.hxx>
-#include <Bnd_B2d.hxx>
+#include <Bnd_B2.hxx>
#include <BRepMesh_Circle.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_PairOfIndex.hxx>