From: Pasukhin Dmitry Date: Wed, 12 Nov 2025 18:46:10 +0000 (+0000) Subject: Foundation Classes - Migrate Bnd_B2x and Bnd_B3x from macro-template to C++ templates... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=44df7106f33c6383196fbc73e0a00d12cf50b875;p=occt.git Foundation Classes - Migrate Bnd_B2x and Bnd_B3x from macro-template to C++ templates (#820) - 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 --- diff --git a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Group.hxx b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Group.hxx index e32a0df5f0..ad5cb384cc 100644 --- a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Group.hxx +++ b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Group.hxx @@ -18,7 +18,7 @@ #include #include -#include +#include #include class TopoDS_Shape; diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2.hxx new file mode 100644 index 0000000000..243e60c542 --- /dev/null +++ b/src/FoundationClasses/TKMath/Bnd/Bnd_B2.hxx @@ -0,0 +1,586 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include + +//! Template class for 2D bounding box. +//! This is a base template that is instantiated for Standard_Real and Standard_ShortReal. +template +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& 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& theOtherBox); + + //! Transform the bounding box with the given transformation. + //! The resulting box will be larger if theTrsf contains rotation. + Standard_NODISCARD Bnd_B2 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& 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& 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& 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& 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 +inline Bnd_B2::Bnd_B2() +{ + Clear(); +} + +//================================================================================================= + +template +inline Bnd_B2::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 +inline void Bnd_B2::Clear() +{ + myCenter[0] = THE_RealLast; + myCenter[1] = THE_RealLast; + myHSize[0] = -THE_RealLast; + myHSize[1] = -THE_RealLast; +} + +//================================================================================================= + +template +inline Standard_Boolean Bnd_B2::IsVoid() const +{ + return (myHSize[0] < -1e-5); +} + +//================================================================================================= + +template +inline void Bnd_B2::Add(const gp_Pnt2d& thePnt) +{ + Add(thePnt.XY()); +} + +//================================================================================================= + +template +inline void Bnd_B2::Add(const Bnd_B2& theBox) +{ + if (theBox.IsVoid() == Standard_False) + { + Add(theBox.CornerMin()); + Add(theBox.CornerMax()); + } +} + +//================================================================================================= + +template +inline gp_XY Bnd_B2::CornerMin() const +{ + return gp_XY(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1]); +} + +//================================================================================================= + +template +inline gp_XY Bnd_B2::CornerMax() const +{ + return gp_XY(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1]); +} + +//================================================================================================= + +template +inline Standard_Real Bnd_B2::SquareExtent() const +{ + return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1]); +} + +//================================================================================================= + +template +inline void Bnd_B2::SetCenter(const gp_XY& theCenter) +{ + myCenter[0] = RealType(theCenter.X()); + myCenter[1] = RealType(theCenter.Y()); +} + +//================================================================================================= + +template +inline void Bnd_B2::SetHSize(const gp_XY& theHSize) +{ + myHSize[0] = RealType(theHSize.X()); + myHSize[1] = RealType(theHSize.Y()); +} + +//================================================================================================= + +template +inline void Bnd_B2::Enlarge(const Standard_Real aDiff) +{ + const RealType aD = RealType(Abs(aDiff)); + myHSize[0] += aD; + myHSize[1] += aD; +} + +//================================================================================================= + +template +inline Standard_Boolean Bnd_B2::IsOut(const gp_XY& thePnt) const +{ + return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0] + || Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]); +} + +//================================================================================================= + +template +inline Standard_Boolean Bnd_B2::IsOut(const Bnd_B2& 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 +inline Standard_Boolean Bnd_B2::IsIn(const Bnd_B2& 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 +void Bnd_B2::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 +Standard_Boolean Bnd_B2::Limit(const Bnd_B2& 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 +Bnd_B2 Bnd_B2::Transformed(const gp_Trsf2d& theTrsf) const +{ + Bnd_B2 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 +Standard_Boolean Bnd_B2::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 +Standard_Boolean Bnd_B2::IsOut(const Bnd_B2& 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 +Standard_Boolean Bnd_B2::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 +Standard_Boolean Bnd_B2::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 +Standard_Boolean Bnd_B2::IsIn(const Bnd_B2& 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; + +//! 2D bounding box with single precision +using Bnd_B2f = Bnd_B2; + +#endif // _Bnd_B2_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2d.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2d.hxx deleted file mode 100644 index 94e5f33b99..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2d.hxx +++ /dev/null @@ -1,149 +0,0 @@ -// 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 -#include -#include - -#include -#include -#include -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 -#define Bnd_B2x Bnd_B2d -#define Bnd_B2x_hxx - -#include - -#undef RealType -#undef RealType_hxx -#undef Bnd_B2x -#undef Bnd_B2x_hxx - -#endif // _Bnd_B2d_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2d_0.cxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2d_0.cxx deleted file mode 100644 index 0a2c50d901..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2d_0.cxx +++ /dev/null @@ -1,28 +0,0 @@ -// 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 - -#include -#include -#include -#include - -#define RealType Standard_Real -#define RealType_hxx -#define Bnd_B2x Bnd_B2d -#define Bnd_B2x_hxx -#include diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2f.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2f.hxx deleted file mode 100644 index 9d62f4f16b..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2f.hxx +++ /dev/null @@ -1,148 +0,0 @@ -// 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 -#include -#include - -#include -#include -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 -#define Bnd_B2x Bnd_B2f -#define Bnd_B2x_hxx - -#include - -#undef RealType -#undef RealType_hxx -#undef Bnd_B2x -#undef Bnd_B2x_hxx - -#endif // _Bnd_B2f_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2f_0.cxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2f_0.cxx deleted file mode 100644 index 767f43d9a5..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2f_0.cxx +++ /dev/null @@ -1,28 +0,0 @@ -// 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 - -#include -#include -#include -#include - -#define RealType Standard_ShortReal -#define RealType_hxx -#define Bnd_B2x Bnd_B2f -#define Bnd_B2x_hxx -#include diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.gxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.gxx deleted file mode 100644 index 1e183233ff..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.gxx +++ /dev/null @@ -1,330 +0,0 @@ -// 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; -} diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.lxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.lxx deleted file mode 100644 index 629ab6a00c..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B2x.lxx +++ /dev/null @@ -1,163 +0,0 @@ -// 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 - -#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]); -} diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3.hxx new file mode 100644 index 0000000000..b42e4238e9 --- /dev/null +++ b/src/FoundationClasses/TKMath/Bnd/Bnd_B3.hxx @@ -0,0 +1,752 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//! Template class for 3D bounding box. +//! This is a base template that is instantiated for Standard_Real and Standard_ShortReal. +template +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& 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& theOtherBox); + + //! Transform the bounding box with the given transformation. + //! The resulting box will be larger if theTrsf contains rotation. + Standard_NODISCARD Bnd_B3 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& 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& 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& 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& 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 +inline Bnd_B3::Bnd_B3() +{ + Clear(); +} + +//================================================================================================= + +template +inline Bnd_B3::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 +inline void Bnd_B3::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 +inline Standard_Boolean Bnd_B3::IsVoid() const +{ + return (myHSize[0] < -1e-5); +} + +//================================================================================================= + +template +inline void Bnd_B3::Add(const gp_Pnt& thePnt) +{ + Add(thePnt.XYZ()); +} + +//================================================================================================= + +template +inline void Bnd_B3::Add(const Bnd_B3& theBox) +{ + if (theBox.IsVoid() == Standard_False) + { + Add(theBox.CornerMin()); + Add(theBox.CornerMax()); + } +} + +//================================================================================================= + +template +inline gp_XYZ Bnd_B3::CornerMin() const +{ + return gp_XYZ(myCenter[0] - myHSize[0], myCenter[1] - myHSize[1], myCenter[2] - myHSize[2]); +} + +//================================================================================================= + +template +inline gp_XYZ Bnd_B3::CornerMax() const +{ + return gp_XYZ(myCenter[0] + myHSize[0], myCenter[1] + myHSize[1], myCenter[2] + myHSize[2]); +} + +//================================================================================================= + +template +inline Standard_Real Bnd_B3::SquareExtent() const +{ + return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1] + myHSize[2] * myHSize[2]); +} + +//================================================================================================= + +template +inline void Bnd_B3::SetCenter(const gp_XYZ& theCenter) +{ + myCenter[0] = RealType(theCenter.X()); + myCenter[1] = RealType(theCenter.Y()); + myCenter[2] = RealType(theCenter.Z()); +} + +//================================================================================================= + +template +inline void Bnd_B3::SetHSize(const gp_XYZ& theHSize) +{ + myHSize[0] = RealType(theHSize.X()); + myHSize[1] = RealType(theHSize.Y()); + myHSize[2] = RealType(theHSize.Z()); +} + +//================================================================================================= + +template +inline void Bnd_B3::Enlarge(const Standard_Real aDiff) +{ + const Standard_Real aD = Abs(aDiff); + myHSize[0] += RealType(aD); + myHSize[1] += RealType(aD); + myHSize[2] += RealType(aD); +} + +//================================================================================================= + +template +inline Standard_Boolean Bnd_B3::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 +inline Standard_Boolean Bnd_B3::IsOut(const Bnd_B3& 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 +inline Standard_Boolean Bnd_B3::IsIn(const Bnd_B3& 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 +void Bnd_B3::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 +Standard_Boolean Bnd_B3::Limit(const Bnd_B3& 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 +Bnd_B3 Bnd_B3::Transformed(const gp_Trsf& theTrsf) const +{ + Bnd_B3 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 +Standard_Boolean Bnd_B3::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 +Standard_Boolean Bnd_B3::IsOut(const Bnd_B3& 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 +Standard_Boolean Bnd_B3::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 +Standard_Boolean Bnd_B3::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 +Standard_Boolean Bnd_B3::IsIn(const Bnd_B3& 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; + +//! 3D bounding box with single precision +using Bnd_B3f = Bnd_B3; + +#endif // _Bnd_B3_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3d.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3d.hxx deleted file mode 100644 index 648d03662c..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3d.hxx +++ /dev/null @@ -1,157 +0,0 @@ -// 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 -#include -#include - -#include -#include -#include -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 -#define Bnd_B3x Bnd_B3d -#define Bnd_B3x_hxx - -#include - -#undef RealType -#undef RealType_hxx -#undef Bnd_B3x -#undef Bnd_B3x_hxx - -#endif // _Bnd_B3d_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3d_0.cxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3d_0.cxx deleted file mode 100644 index 88a4fdcaa3..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3d_0.cxx +++ /dev/null @@ -1,29 +0,0 @@ -// 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 - -#include -#include -#include -#include -#include - -#define RealType Standard_Real -#define RealType_hxx -#define Bnd_B3x Bnd_B3d -#define Bnd_B3x_hxx -#include diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3f.hxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3f.hxx deleted file mode 100644 index 31bb0309f0..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3f.hxx +++ /dev/null @@ -1,153 +0,0 @@ -// 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 -#include - -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 -#define Bnd_B3x Bnd_B3f -#define Bnd_B3x_hxx - -#include - -#undef RealType -#undef RealType_hxx -#undef Bnd_B3x -#undef Bnd_B3x_hxx - -#endif // _Bnd_B3f_HeaderFile diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3f_0.cxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3f_0.cxx deleted file mode 100644 index e676a57817..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3f_0.cxx +++ /dev/null @@ -1,29 +0,0 @@ -// 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 - -#include -#include -#include -#include -#include - -#define RealType Standard_ShortReal -#define RealType_hxx -#define Bnd_B3x Bnd_B3f -#define Bnd_B3x_hxx -#include diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.gxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.gxx deleted file mode 100644 index 74dae7a23d..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.gxx +++ /dev/null @@ -1,470 +0,0 @@ -// 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; -} diff --git a/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.lxx b/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.lxx deleted file mode 100644 index 2c3c275158..0000000000 --- a/src/FoundationClasses/TKMath/Bnd/Bnd_B3x.lxx +++ /dev/null @@ -1,173 +0,0 @@ -// 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 - -#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]); -} diff --git a/src/FoundationClasses/TKMath/Bnd/FILES.cmake b/src/FoundationClasses/TKMath/Bnd/FILES.cmake index 22e3058e99..101b943d44 100644 --- a/src/FoundationClasses/TKMath/Bnd/FILES.cmake +++ b/src/FoundationClasses/TKMath/Bnd/FILES.cmake @@ -5,18 +5,8 @@ set(OCCT_Bnd_FILES 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 diff --git a/src/FoundationClasses/TKMath/GTests/Bnd_B2_Test.cxx b/src/FoundationClasses/TKMath/GTests/Bnd_B2_Test.cxx new file mode 100644 index 0000000000..47acb41a4a --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Bnd_B2_Test.cxx @@ -0,0 +1,264 @@ +// 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 + +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/src/FoundationClasses/TKMath/GTests/Bnd_B3_Test.cxx b/src/FoundationClasses/TKMath/GTests/Bnd_B3_Test.cxx new file mode 100644 index 0000000000..47b8dcb991 --- /dev/null +++ b/src/FoundationClasses/TKMath/GTests/Bnd_B3_Test.cxx @@ -0,0 +1,338 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include + +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)); +} diff --git a/src/FoundationClasses/TKMath/GTests/FILES.cmake b/src/FoundationClasses/TKMath/GTests/FILES.cmake index 742b4517ff..615955d3ad 100644 --- a/src/FoundationClasses/TKMath/GTests/FILES.cmake +++ b/src/FoundationClasses/TKMath/GTests/FILES.cmake @@ -2,6 +2,8 @@ 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 diff --git a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.cxx b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.cxx index 93eb7a76e3..d216a50527 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.cxx @@ -22,7 +22,7 @@ #include #include -#include +#include #include diff --git a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.hxx b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.hxx index efda565a4a..e96173abee 100644 --- a/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.hxx +++ b/src/ModelingAlgorithms/TKMesh/BRepMesh/BRepMesh_Delaun.hxx @@ -26,7 +26,6 @@ #include #include -class Bnd_B2d; class Bnd_Box2d; class BRepMesh_Vertex; diff --git a/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Types.hxx b/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Types.hxx index 80cad59dc5..c724ac517a 100644 --- a/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Types.hxx +++ b/src/ModelingAlgorithms/TKMesh/IMeshData/IMeshData_Types.hxx @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include