mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-10 09:30:48 +08:00
Foundation Classes - Optimize and fix Bnd package (#839)
- Fixed multiple bugs including uninitialized variables (zmin/zmax in IsOut(gp_Lin)), incorrect type usage (Standard_Integer → Standard_Boolean), and improper gap handling - Optimized performance-critical methods through branchless operations, early exits, and cached computations - Modernized codebase with C++17 features including constexpr constructors, noexcept specifications, and [[nodiscard]] attributes - Refactor Bnd_Box and Bnd_Box2d classes to introduce GetXMin, GetXMax, GetYMin, GetYMax, and GetZMin, GetZMax methods for improved clarity and encapsulation. - Add Limits struct to represent box limits in both classes.
This commit is contained in:
@@ -15,50 +15,107 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_Dump.hxx>
|
||||
|
||||
// set the flag to one
|
||||
#define ClearVoidFlag() (Flags &= ~VoidMask)
|
||||
|
||||
#include <Standard_Stream.hxx>
|
||||
// #include <Precision.hxx>
|
||||
#define Bnd_Precision_Infinite 1e+100
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Bnd_Box::Bnd_Box()
|
||||
// Equal to SetVoid();
|
||||
: Xmin(RealLast()),
|
||||
Xmax(-RealLast()),
|
||||
Ymin(RealLast()),
|
||||
Ymax(-RealLast()),
|
||||
Zmin(RealLast()),
|
||||
Zmax(-RealLast()),
|
||||
Gap(0.0),
|
||||
Flags(VoidMask)
|
||||
namespace
|
||||
{
|
||||
// Precision constant for infinite bounds
|
||||
constexpr Standard_Real THE_BND_PRECISION_INFINITE = 1e+100;
|
||||
|
||||
// Precomputed unit direction vectors for bounding box transformations
|
||||
constexpr gp_Dir THE_DIR_XMIN{gp_Dir::D::NX};
|
||||
constexpr gp_Dir THE_DIR_XMAX{gp_Dir::D::X};
|
||||
constexpr gp_Dir THE_DIR_YMIN{gp_Dir::D::NY};
|
||||
constexpr gp_Dir THE_DIR_YMAX{gp_Dir::D::Y};
|
||||
constexpr gp_Dir THE_DIR_ZMIN{gp_Dir::D::NZ};
|
||||
constexpr gp_Dir THE_DIR_ZMAX{gp_Dir::D::Z};
|
||||
|
||||
// Computes minimum squared distance between two 1D intervals
|
||||
inline Standard_Real DistMini2Box(const Standard_Real theR1Min,
|
||||
const Standard_Real theR1Max,
|
||||
const Standard_Real theR2Min,
|
||||
const Standard_Real theR2Max) noexcept
|
||||
{
|
||||
const Standard_Real aR1 = Square(theR1Min - theR2Max);
|
||||
const Standard_Real aR2 = Square(theR1Max - theR2Min);
|
||||
return std::min(aR1, aR2);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Bnd_Box::Bnd_Box(const gp_Pnt& theMin, const gp_Pnt& theMax)
|
||||
// Equal to Update(theMin.X(), theMin.Y(), theMin.Z(), theMax.X(), theMax.Y(), theMax.Z());
|
||||
: Xmin(theMin.X()),
|
||||
Xmax(theMax.X()),
|
||||
Ymin(theMin.Y()),
|
||||
Ymax(theMax.Y()),
|
||||
Zmin(theMin.Z()),
|
||||
Zmax(theMax.Z()),
|
||||
Gap(0.0),
|
||||
Flags(0)
|
||||
// Computes squared distance in one dimension, returns 0 if intervals overlap
|
||||
inline Standard_Real DistanceInDimension(const Standard_Real theMin1,
|
||||
const Standard_Real theMax1,
|
||||
const Standard_Real theMin2,
|
||||
const Standard_Real theMax2) noexcept
|
||||
{
|
||||
// Check if intervals overlap
|
||||
if ((theMin1 <= theMin2 && theMin2 <= theMax1) || (theMin2 <= theMin1 && theMin1 <= theMax2))
|
||||
return 0.0;
|
||||
return DistMini2Box(theMin1, theMax1, theMin2, theMax2);
|
||||
}
|
||||
|
||||
// Tests if a 2D segment is outside a 2D box
|
||||
Standard_Boolean IsSegmentOut(const Standard_Real theX1,
|
||||
const Standard_Real theY1,
|
||||
const Standard_Real theX2,
|
||||
const Standard_Real theY2,
|
||||
const Standard_Real theXs1,
|
||||
const Standard_Real theYs1,
|
||||
const Standard_Real theXs2,
|
||||
const Standard_Real theYs2) noexcept
|
||||
{
|
||||
constexpr Standard_Real anEps = RealSmall();
|
||||
const Standard_Real aXsMin = std::min(theXs1, theXs2);
|
||||
const Standard_Real aXsMax = std::max(theXs1, theXs2);
|
||||
const Standard_Real aYsMin = std::min(theYs1, theYs2);
|
||||
const Standard_Real aYsMax = std::max(theYs1, theYs2);
|
||||
|
||||
if (aYsMax - aYsMin < anEps && (theY1 - theYs1 < anEps && theYs1 - theY2 < anEps)
|
||||
&& ((aXsMin - theX1 < anEps && theX1 - aXsMax < anEps)
|
||||
|| (aXsMin - theX2 < anEps && theX2 - aXsMax < anEps)
|
||||
|| (theX1 - theXs1 < anEps && theXs1 - theX2 < anEps)))
|
||||
return Standard_False;
|
||||
if (aXsMax - aXsMin < anEps && (theX1 - theXs1 < anEps && theXs1 - theX2 < anEps)
|
||||
&& ((aYsMin - theY1 < anEps && theY1 - aYsMax < anEps)
|
||||
|| (aYsMin - theY2 < anEps && theY2 - aYsMax < anEps)
|
||||
|| (theY1 - theYs1 < anEps && theYs1 - theY2 < anEps)))
|
||||
return Standard_False;
|
||||
|
||||
if ((theXs1 < theX1 && theXs2 < theX1) || (theXs1 > theX2 && theXs2 > theX2)
|
||||
|| (theYs1 < theY1 && theYs2 < theY1) || (theYs1 > theY2 && theYs2 > theY2))
|
||||
return Standard_True;
|
||||
|
||||
if (std::abs(theXs2 - theXs1) > anEps)
|
||||
{
|
||||
const Standard_Real aYa =
|
||||
(std::min(theX1, theX2) - theXs1) * (theYs2 - theYs1) / (theXs2 - theXs1) + theYs1;
|
||||
const Standard_Real aYb =
|
||||
(std::max(theX1, theX2) - theXs1) * (theYs2 - theYs1) / (theXs2 - theXs1) + theYs1;
|
||||
if ((aYa < theY1 && aYb < theY1) || (aYa > theY2 && aYb > theY2))
|
||||
return Standard_True;
|
||||
}
|
||||
else if (std::abs(theYs2 - theYs1) > anEps)
|
||||
{
|
||||
const Standard_Real aXa =
|
||||
(std::min(theY1, theY2) - theYs1) * (theXs2 - theXs1) / (theYs2 - theYs1) + theXs1;
|
||||
const Standard_Real aXb =
|
||||
(std::max(theY1, theY2) - theYs1) * (theXs2 - theXs1) / (theYs2 - theYs1) + theXs1;
|
||||
if ((aXa < theX1 && aXb < theX1) || (aXa > theX2 && aXb > theX2))
|
||||
return Standard_True;
|
||||
}
|
||||
else
|
||||
return Standard_True;
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Bnd_Box::Set(const gp_Pnt& P)
|
||||
@@ -92,22 +149,16 @@ void Bnd_Box::Update(const Standard_Real x,
|
||||
Xmax = X;
|
||||
Ymax = Y;
|
||||
Zmax = Z;
|
||||
ClearVoidFlag();
|
||||
Flags &= ~VoidMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < Xmin)
|
||||
Xmin = x;
|
||||
if (X > Xmax)
|
||||
Xmax = X;
|
||||
if (y < Ymin)
|
||||
Ymin = y;
|
||||
if (Y > Ymax)
|
||||
Ymax = Y;
|
||||
if (z < Zmin)
|
||||
Zmin = z;
|
||||
if (Z > Zmax)
|
||||
Zmax = Z;
|
||||
Xmin = std::min(Xmin, x);
|
||||
Xmax = std::max(Xmax, X);
|
||||
Ymin = std::min(Ymin, y);
|
||||
Ymax = std::max(Ymax, Y);
|
||||
Zmin = std::min(Zmin, z);
|
||||
Zmax = std::max(Zmax, Z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,48 +174,21 @@ void Bnd_Box::Update(const Standard_Real X, const Standard_Real Y, const Standar
|
||||
Xmax = X;
|
||||
Ymax = Y;
|
||||
Zmax = Z;
|
||||
ClearVoidFlag();
|
||||
Flags &= ~VoidMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (X < Xmin)
|
||||
Xmin = X;
|
||||
else if (X > Xmax)
|
||||
Xmax = X;
|
||||
if (Y < Ymin)
|
||||
Ymin = Y;
|
||||
else if (Y > Ymax)
|
||||
Ymax = Y;
|
||||
if (Z < Zmin)
|
||||
Zmin = Z;
|
||||
else if (Z > Zmax)
|
||||
Zmax = Z;
|
||||
Xmin = std::min(Xmin, X);
|
||||
Xmax = std::max(Xmax, X);
|
||||
Ymin = std::min(Ymin, Y);
|
||||
Ymax = std::max(Ymax, Y);
|
||||
Zmin = std::min(Zmin, Z);
|
||||
Zmax = std::max(Zmax, Z);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetGap() const
|
||||
{
|
||||
return Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Bnd_Box::SetGap(const Standard_Real Tol)
|
||||
{
|
||||
Gap = Tol;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Bnd_Box::Enlarge(const Standard_Real Tol)
|
||||
{
|
||||
Gap = std::max(Gap, std::abs(Tol));
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Bnd_Box::Get(Standard_Real& theXmin,
|
||||
Standard_Real& theYmin,
|
||||
Standard_Real& theZmin,
|
||||
@@ -177,78 +201,87 @@ void Bnd_Box::Get(Standard_Real& theXmin,
|
||||
throw Standard_ConstructionError("Bnd_Box is void");
|
||||
}
|
||||
|
||||
if (IsOpenXmin())
|
||||
theXmin = -Bnd_Precision_Infinite;
|
||||
else
|
||||
theXmin = Xmin - Gap;
|
||||
if (IsOpenXmax())
|
||||
theXmax = Bnd_Precision_Infinite;
|
||||
else
|
||||
theXmax = Xmax + Gap;
|
||||
if (IsOpenYmin())
|
||||
theYmin = -Bnd_Precision_Infinite;
|
||||
else
|
||||
theYmin = Ymin - Gap;
|
||||
if (IsOpenYmax())
|
||||
theYmax = Bnd_Precision_Infinite;
|
||||
else
|
||||
theYmax = Ymax + Gap;
|
||||
if (IsOpenZmin())
|
||||
theZmin = -Bnd_Precision_Infinite;
|
||||
else
|
||||
theZmin = Zmin - Gap;
|
||||
if (IsOpenZmax())
|
||||
theZmax = Bnd_Precision_Infinite;
|
||||
else
|
||||
theZmax = Zmax + Gap;
|
||||
theXmin = GetXMin();
|
||||
theXmax = GetXMax();
|
||||
theYmin = GetYMin();
|
||||
theYmax = GetYMax();
|
||||
theZmin = GetZMin();
|
||||
theZmax = GetZMax();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Bnd_Box::Limits Bnd_Box::Get() const
|
||||
{
|
||||
return {GetXMin(), GetXMax(), GetYMin(), GetYMax(), GetZMin(), GetZMax()};
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetXMin() const
|
||||
{
|
||||
return IsOpenXmin() ? -THE_BND_PRECISION_INFINITE : Xmin - Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetXMax() const
|
||||
{
|
||||
return IsOpenXmax() ? THE_BND_PRECISION_INFINITE : Xmax + Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetYMin() const
|
||||
{
|
||||
return IsOpenYmin() ? -THE_BND_PRECISION_INFINITE : Ymin - Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetYMax() const
|
||||
{
|
||||
return IsOpenYmax() ? THE_BND_PRECISION_INFINITE : Ymax + Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetZMin() const
|
||||
{
|
||||
return IsOpenZmin() ? -THE_BND_PRECISION_INFINITE : Zmin - Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box::GetZMax() const
|
||||
{
|
||||
return IsOpenZmax() ? THE_BND_PRECISION_INFINITE : Zmax + Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
gp_Pnt Bnd_Box::CornerMin() const
|
||||
{
|
||||
gp_Pnt aCornerMin;
|
||||
if (IsVoid())
|
||||
{
|
||||
throw Standard_ConstructionError("Bnd_Box is void");
|
||||
}
|
||||
if (IsOpenXmin())
|
||||
aCornerMin.SetX(-Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMin.SetX(Xmin - Gap);
|
||||
if (IsOpenYmin())
|
||||
aCornerMin.SetY(-Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMin.SetY(Ymin - Gap);
|
||||
if (IsOpenZmin())
|
||||
aCornerMin.SetZ(-Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMin.SetZ(Zmin - Gap);
|
||||
return aCornerMin;
|
||||
return gp_Pnt(IsOpenXmin() ? -THE_BND_PRECISION_INFINITE : Xmin - Gap,
|
||||
IsOpenYmin() ? -THE_BND_PRECISION_INFINITE : Ymin - Gap,
|
||||
IsOpenZmin() ? -THE_BND_PRECISION_INFINITE : Zmin - Gap);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
gp_Pnt Bnd_Box::CornerMax() const
|
||||
{
|
||||
gp_Pnt aCornerMax;
|
||||
if (IsVoid())
|
||||
{
|
||||
throw Standard_ConstructionError("Bnd_Box is void");
|
||||
}
|
||||
if (IsOpenXmax())
|
||||
aCornerMax.SetX(Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMax.SetX(Xmax + Gap);
|
||||
if (IsOpenYmax())
|
||||
aCornerMax.SetY(Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMax.SetY(Ymax + Gap);
|
||||
if (IsOpenZmax())
|
||||
aCornerMax.SetZ(Bnd_Precision_Infinite);
|
||||
else
|
||||
aCornerMax.SetZ(Zmax + Gap);
|
||||
return aCornerMax;
|
||||
return gp_Pnt(IsOpenXmax() ? THE_BND_PRECISION_INFINITE : Xmax + Gap,
|
||||
IsOpenYmax() ? THE_BND_PRECISION_INFINITE : Ymax + Gap,
|
||||
IsOpenZmax() ? THE_BND_PRECISION_INFINITE : Zmax + Gap);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -306,11 +339,15 @@ Standard_Boolean Bnd_Box::IsZThin(const Standard_Real tol) const
|
||||
|
||||
Standard_Boolean Bnd_Box::IsThin(const Standard_Real tol) const
|
||||
{
|
||||
if (!IsXThin(tol))
|
||||
if (IsWhole())
|
||||
return Standard_False;
|
||||
if (!IsYThin(tol))
|
||||
if (IsVoid())
|
||||
return Standard_True;
|
||||
if (IsOpenXmin() || IsOpenXmax() || Xmax - Xmin >= tol)
|
||||
return Standard_False;
|
||||
if (!IsZThin(tol))
|
||||
if (IsOpenYmin() || IsOpenYmax() || Ymax - Ymin >= tol)
|
||||
return Standard_False;
|
||||
if (IsOpenZmin() || IsOpenZmax() || Zmax - Zmin >= tol)
|
||||
return Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -374,27 +411,27 @@ Bnd_Box Bnd_Box::Transformed(const gp_Trsf& T) const
|
||||
Standard_Integer aNbDirs = 0;
|
||||
if (IsOpenXmin())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(-1., 0., 0.);
|
||||
aDirs[aNbDirs++] = THE_DIR_XMIN;
|
||||
}
|
||||
if (IsOpenXmax())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(1., 0., 0.);
|
||||
aDirs[aNbDirs++] = THE_DIR_XMAX;
|
||||
}
|
||||
if (IsOpenYmin())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(0., -1., 0.);
|
||||
aDirs[aNbDirs++] = THE_DIR_YMIN;
|
||||
}
|
||||
if (IsOpenYmax())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(0., 1., 0.);
|
||||
aDirs[aNbDirs++] = THE_DIR_YMAX;
|
||||
}
|
||||
if (IsOpenZmin())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(0., 0., -1.);
|
||||
aDirs[aNbDirs++] = THE_DIR_ZMIN;
|
||||
}
|
||||
if (IsOpenZmax())
|
||||
{
|
||||
aDirs[aNbDirs++].SetCoord(0., 0., 1.);
|
||||
aDirs[aNbDirs++] = THE_DIR_ZMAX;
|
||||
}
|
||||
|
||||
for (Standard_Integer aDirIter = 0; aDirIter < aNbDirs; ++aDirIter)
|
||||
@@ -539,9 +576,8 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Pln& P) const
|
||||
{
|
||||
Standard_Real A, B, C, D;
|
||||
P.Coefficients(A, B, C, D);
|
||||
Standard_Real d = A * (Xmin - Gap) + B * (Ymin - Gap) + C * (Zmin - Gap) + D;
|
||||
// Standard_Boolean plus = d > 0;
|
||||
Standard_Integer plus = d > 0;
|
||||
Standard_Real d = A * (Xmin - Gap) + B * (Ymin - Gap) + C * (Zmin - Gap) + D;
|
||||
Standard_Boolean plus = d > 0;
|
||||
if (plus != ((A * (Xmin - Gap) + B * (Ymin - Gap) + C * (Zmax + Gap) + D) > 0))
|
||||
return Standard_False;
|
||||
if (plus != ((A * (Xmin - Gap) + B * (Ymax + Gap) + C * (Zmin - Gap) + D) > 0))
|
||||
@@ -571,13 +607,17 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Lin& L) const
|
||||
return Standard_True;
|
||||
else
|
||||
{
|
||||
Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax;
|
||||
Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
|
||||
Standard_Real parmin, parmax, par1, par2;
|
||||
Standard_Boolean xToSet, yToSet;
|
||||
Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
|
||||
Get(myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
|
||||
|
||||
if (std::abs(L.Direction().XYZ().X()) > 0.)
|
||||
const Standard_Real aDirX = std::abs(L.Direction().XYZ().X());
|
||||
const Standard_Real aDirY = std::abs(L.Direction().XYZ().Y());
|
||||
const Standard_Real aDirZ = std::abs(L.Direction().XYZ().Z());
|
||||
|
||||
if (aDirX > 0.)
|
||||
{
|
||||
par1 = (myXmin - L.Location().XYZ().X()) / L.Direction().XYZ().X();
|
||||
par2 = (myXmax - L.Location().XYZ().X()) / L.Direction().XYZ().X();
|
||||
@@ -593,12 +633,12 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Lin& L) const
|
||||
}
|
||||
xmin = L.Location().XYZ().X();
|
||||
xmax = L.Location().XYZ().X();
|
||||
parmin = -Bnd_Precision_Infinite;
|
||||
parmax = Bnd_Precision_Infinite;
|
||||
parmin = -THE_BND_PRECISION_INFINITE;
|
||||
parmax = THE_BND_PRECISION_INFINITE;
|
||||
xToSet = Standard_False;
|
||||
}
|
||||
|
||||
if (std::abs(L.Direction().XYZ().Y()) > 0.)
|
||||
if (aDirY > 0.)
|
||||
{
|
||||
par1 = (myYmin - L.Location().XYZ().Y()) / L.Direction().XYZ().Y();
|
||||
par2 = (myYmax - L.Location().XYZ().Y()) / L.Direction().XYZ().Y();
|
||||
@@ -621,7 +661,7 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Lin& L) const
|
||||
yToSet = Standard_False;
|
||||
}
|
||||
|
||||
if (std::abs(L.Direction().XYZ().Z()) > 0.)
|
||||
if (aDirZ > 0.)
|
||||
{
|
||||
par1 = (myZmin - L.Location().XYZ().Z()) / L.Direction().XYZ().Z();
|
||||
par2 = (myZmax - L.Location().XYZ().Z()) / L.Direction().XYZ().Z();
|
||||
@@ -673,50 +713,49 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Lin& L) const
|
||||
|
||||
Standard_Boolean Bnd_Box::IsOut(const Bnd_Box& Other) const
|
||||
{
|
||||
// modified by NIZNHY-PKV Fri Jul 08 11:03:43 2011f
|
||||
// Fast path for non-open boxes with early exit
|
||||
if (!Flags && !Other.Flags)
|
||||
{
|
||||
Standard_Boolean bRet;
|
||||
Standard_Real delta;
|
||||
//
|
||||
delta = Other.Gap + Gap;
|
||||
bRet = ((Xmin - Other.Xmax > delta) || (Other.Xmin - Xmax > delta)
|
||||
|| (Ymin - Other.Ymax > delta) || (Other.Ymin - Ymax > delta)
|
||||
|| (Zmin - Other.Zmax > delta) || (Other.Zmin - Zmax > delta));
|
||||
return bRet;
|
||||
const Standard_Real aDelta = Other.Gap + Gap;
|
||||
// Early exit on first separating axis found
|
||||
if (Xmin - Other.Xmax > aDelta)
|
||||
return Standard_True;
|
||||
if (Other.Xmin - Xmax > aDelta)
|
||||
return Standard_True;
|
||||
if (Ymin - Other.Ymax > aDelta)
|
||||
return Standard_True;
|
||||
if (Other.Ymin - Ymax > aDelta)
|
||||
return Standard_True;
|
||||
if (Zmin - Other.Zmax > aDelta)
|
||||
return Standard_True;
|
||||
if (Other.Zmin - Zmax > aDelta)
|
||||
return Standard_True;
|
||||
return Standard_False;
|
||||
}
|
||||
// modified by NIZNHY-PKV Fri Jul 08 11:03:46 2011t
|
||||
if (IsVoid())
|
||||
|
||||
// Handle special cases
|
||||
if (IsVoid() || Other.IsVoid())
|
||||
return Standard_True;
|
||||
if (Other.IsVoid())
|
||||
return Standard_True;
|
||||
if (IsWhole())
|
||||
return Standard_False;
|
||||
if (Other.IsWhole())
|
||||
if (IsWhole() || Other.IsWhole())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real delta = Other.Gap + Gap;
|
||||
const Standard_Real aDelta = Other.Gap + Gap;
|
||||
|
||||
if (!IsOpenXmin() && !Other.IsOpenXmax())
|
||||
if (Xmin - Other.Xmax > delta)
|
||||
return Standard_True;
|
||||
if (!IsOpenXmax() && !Other.IsOpenXmin())
|
||||
if (Other.Xmin - Xmax > delta)
|
||||
return Standard_True;
|
||||
// Check each axis with early exit
|
||||
if (!IsOpenXmin() && !Other.IsOpenXmax() && Xmin - Other.Xmax > aDelta)
|
||||
return Standard_True;
|
||||
if (!IsOpenXmax() && !Other.IsOpenXmin() && Other.Xmin - Xmax > aDelta)
|
||||
return Standard_True;
|
||||
|
||||
if (!IsOpenYmin() && !Other.IsOpenYmax())
|
||||
if (Ymin - Other.Ymax > delta)
|
||||
return Standard_True;
|
||||
if (!IsOpenYmax() && !Other.IsOpenYmin())
|
||||
if (Other.Ymin - Ymax > delta)
|
||||
return Standard_True;
|
||||
if (!IsOpenYmin() && !Other.IsOpenYmax() && Ymin - Other.Ymax > aDelta)
|
||||
return Standard_True;
|
||||
if (!IsOpenYmax() && !Other.IsOpenYmin() && Other.Ymin - Ymax > aDelta)
|
||||
return Standard_True;
|
||||
|
||||
if (!IsOpenZmin() && !Other.IsOpenZmax())
|
||||
if (Zmin - Other.Zmax > delta)
|
||||
return Standard_True;
|
||||
if (!IsOpenZmax() && !Other.IsOpenZmin())
|
||||
if (Other.Zmin - Zmax > delta)
|
||||
return Standard_True;
|
||||
if (!IsOpenZmin() && !Other.IsOpenZmax() && Zmin - Other.Zmax > aDelta)
|
||||
return Standard_True;
|
||||
if (!IsOpenZmax() && !Other.IsOpenZmin() && Other.Zmin - Zmax > aDelta)
|
||||
return Standard_True;
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -737,54 +776,6 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Trsf& T1, const Bnd_Box& Other, const g
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static Standard_Boolean IsSegmentOut(Standard_Real x1,
|
||||
Standard_Real y1,
|
||||
Standard_Real x2,
|
||||
Standard_Real y2,
|
||||
Standard_Real xs1,
|
||||
Standard_Real ys1,
|
||||
Standard_Real xs2,
|
||||
Standard_Real ys2)
|
||||
{
|
||||
constexpr Standard_Real eps = RealSmall();
|
||||
Standard_Real xsmin = std::min(xs1, xs2);
|
||||
Standard_Real xsmax = std::max(xs1, xs2);
|
||||
Standard_Real ysmin = std::min(ys1, ys2);
|
||||
Standard_Real ysmax = std::max(ys1, ys2);
|
||||
|
||||
if (ysmax - ysmin < eps && (y1 - ys1 < eps && ys1 - y2 < eps)
|
||||
&& ((xsmin - x1 < eps && x1 - xsmax < eps) || (xsmin - x2 < eps && x2 - xsmax < eps)
|
||||
|| (x1 - xs1 < eps && xs1 - x2 < eps)))
|
||||
return Standard_False;
|
||||
if (xsmax - xsmin < eps && (x1 - xs1 < eps && xs1 - x2 < eps)
|
||||
&& ((ysmin - y1 < eps && y1 - ysmax < eps) || (ysmin - y2 < eps && y2 - ysmax < eps)
|
||||
|| (y1 - ys1 < eps && ys1 - y2 < eps)))
|
||||
return Standard_False;
|
||||
|
||||
if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) || (ys1 < y1 && ys2 < y1)
|
||||
|| (ys1 > y2 && ys2 > y2))
|
||||
return Standard_True;
|
||||
|
||||
if (std::abs(xs2 - xs1) > eps)
|
||||
{
|
||||
Standard_Real ya = (std::min(x1, x2) - xs1) * (ys2 - ys1) / (xs2 - xs1) + ys1;
|
||||
Standard_Real yb = (std::max(x1, x2) - xs1) * (ys2 - ys1) / (xs2 - xs1) + ys1;
|
||||
if ((ya < y1 && yb < y1) || (ya > y2 && yb > y2))
|
||||
return Standard_True;
|
||||
}
|
||||
else if (std::abs(ys2 - ys1) > eps)
|
||||
{
|
||||
Standard_Real xa = (std::min(y1, y2) - ys1) * (xs2 - xs1) / (ys2 - ys1) + xs1;
|
||||
Standard_Real xb = (std::max(y1, y2) - ys1) * (xs2 - xs1) / (ys2 - ys1) + xs1;
|
||||
if ((xa < x1 && xb < x1) || (xa > x2 && xb > x2))
|
||||
return Standard_True;
|
||||
}
|
||||
else
|
||||
return Standard_True;
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const
|
||||
{
|
||||
|
||||
@@ -1009,53 +1000,19 @@ Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir
|
||||
// purpose : computes the minimum distance between two boxes
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Real DistMini2Box(const Standard_Real r1min,
|
||||
const Standard_Real r1max,
|
||||
const Standard_Real r2min,
|
||||
const Standard_Real r2max)
|
||||
{
|
||||
Standard_Real r1, r2;
|
||||
|
||||
r1 = Square(r1min - r2max);
|
||||
r2 = Square(r1max - r2min);
|
||||
return std::min(r1, r2);
|
||||
}
|
||||
|
||||
Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const
|
||||
{
|
||||
Standard_Real xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1;
|
||||
Standard_Real xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2;
|
||||
Standard_Real dist_x, dist_y, dist_z, dist_t;
|
||||
Standard_Real aXMinB1, aYMinB1, aZMinB1, aXMaxB1, aYMaxB1, aZMaxB1;
|
||||
Standard_Real aXMinB2, aYMinB2, aZMinB2, aXMaxB2, aYMaxB2, aZMaxB2;
|
||||
|
||||
Get(xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1);
|
||||
Other.Get(xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2);
|
||||
Get(aXMinB1, aYMinB1, aZMinB1, aXMaxB1, aYMaxB1, aZMaxB1);
|
||||
Other.Get(aXMinB2, aYMinB2, aZMinB2, aXMaxB2, aYMaxB2, aZMaxB2);
|
||||
|
||||
if (((xminB1 <= xminB2) && (xminB2 <= xmaxB1)) || ((xminB2 <= xminB1) && (xminB1 <= xmaxB2)))
|
||||
{
|
||||
dist_x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist_x = DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);
|
||||
}
|
||||
if (((yminB1 <= yminB2) && (yminB2 <= ymaxB1)) || ((yminB2 <= yminB1) && (yminB1 <= ymaxB2)))
|
||||
{
|
||||
dist_y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist_y = DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);
|
||||
}
|
||||
if (((zminB1 <= zminB2) && (zminB2 <= zmaxB1)) || ((zminB2 <= zminB1) && (zminB1 <= zmaxB2)))
|
||||
{
|
||||
dist_z = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist_z = DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);
|
||||
}
|
||||
dist_t = dist_x + dist_y + dist_z;
|
||||
return (std::sqrt(dist_t));
|
||||
const Standard_Real aDistX = DistanceInDimension(aXMinB1, aXMaxB1, aXMinB2, aXMaxB2);
|
||||
const Standard_Real aDistY = DistanceInDimension(aYMinB1, aYMaxB1, aYMinB2, aYMaxB2);
|
||||
const Standard_Real aDistZ = DistanceInDimension(aZMinB1, aZMaxB1, aZMinB2, aZMaxB2);
|
||||
|
||||
return std::sqrt(aDistX + aDistY + aDistZ);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
class gp_Pnt;
|
||||
class gp_Dir;
|
||||
class gp_Trsf;
|
||||
@@ -61,21 +65,53 @@ class Bnd_Box
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Structure containing the box limits (Xmin, Xmax, Ymin, Ymax, Zmin, Zmax).
|
||||
//! The values include the gap and account for open directions.
|
||||
struct Limits
|
||||
{
|
||||
double Xmin; //!< Minimum X coordinate
|
||||
double Xmax; //!< Maximum X coordinate
|
||||
double Ymin; //!< Minimum Y coordinate
|
||||
double Ymax; //!< Maximum Y coordinate
|
||||
double Zmin; //!< Minimum Z coordinate
|
||||
double Zmax; //!< Maximum Z coordinate
|
||||
};
|
||||
|
||||
//! Creates an empty Box.
|
||||
//! The constructed box is qualified Void. Its gap is null.
|
||||
Standard_EXPORT Bnd_Box();
|
||||
constexpr Bnd_Box()
|
||||
: Xmin(RealLast()),
|
||||
Xmax(-RealLast()),
|
||||
Ymin(RealLast()),
|
||||
Ymax(-RealLast()),
|
||||
Zmin(RealLast()),
|
||||
Zmax(-RealLast()),
|
||||
Gap(0.0),
|
||||
Flags(VoidMask)
|
||||
{
|
||||
}
|
||||
|
||||
//! Creates a bounding box, it contains:
|
||||
//! - minimum/maximum point of bounding box,
|
||||
//! The constructed box is qualified Void. Its gap is null.
|
||||
Standard_EXPORT Bnd_Box(const gp_Pnt& theMin, const gp_Pnt& theMax);
|
||||
constexpr Bnd_Box(const gp_Pnt& theMin, const gp_Pnt& theMax)
|
||||
: Xmin(theMin.X()),
|
||||
Xmax(theMax.X()),
|
||||
Ymin(theMin.Y()),
|
||||
Ymax(theMax.Y()),
|
||||
Zmin(theMin.Z()),
|
||||
Zmax(theMax.Z()),
|
||||
Gap(0.0),
|
||||
Flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
//! Sets this bounding box so that it covers the whole of 3D space.
|
||||
//! It is infinitely long in all directions.
|
||||
void SetWhole() { Flags = WholeMask; }
|
||||
void SetWhole() noexcept { Flags = WholeMask; }
|
||||
|
||||
//! Sets this bounding box so that it is empty. All points are outside a void box.
|
||||
void SetVoid()
|
||||
void SetVoid() noexcept
|
||||
{
|
||||
Xmin = RealLast();
|
||||
Xmax = -RealLast();
|
||||
@@ -115,10 +151,10 @@ public:
|
||||
Standard_EXPORT void Update(const Standard_Real X, const Standard_Real Y, const Standard_Real Z);
|
||||
|
||||
//! Returns the gap of this bounding box.
|
||||
Standard_EXPORT Standard_Real GetGap() const;
|
||||
[[nodiscard]] constexpr Standard_Real GetGap() const noexcept { return Gap; }
|
||||
|
||||
//! Set the gap of this bounding box to abs(Tol).
|
||||
Standard_EXPORT void SetGap(const Standard_Real Tol);
|
||||
void SetGap(const Standard_Real Tol) noexcept { Gap = std::abs(Tol); }
|
||||
|
||||
//! Enlarges the box with a tolerance value.
|
||||
//! (minvalues-std::abs(<tol>) and maxvalues+std::abs(<tol>))
|
||||
@@ -126,7 +162,7 @@ public:
|
||||
//! intervals of definition, when they are finite, are reduced by
|
||||
//! the absolute value of Tol, while the maximum values are
|
||||
//! increased by the same amount.
|
||||
Standard_EXPORT void Enlarge(const Standard_Real Tol);
|
||||
void Enlarge(const Standard_Real Tol) noexcept { Gap = std::max(Gap, std::abs(Tol)); }
|
||||
|
||||
//! Returns the bounds of this bounding box. The gap is included.
|
||||
//! If this bounding box is infinite (i.e. "open"), returned values
|
||||
@@ -140,83 +176,114 @@ public:
|
||||
Standard_Real& theYmax,
|
||||
Standard_Real& theZmax) const;
|
||||
|
||||
//! Returns the bounds of this bounding box as a Limits structure.
|
||||
//! The gap is included. If this bounding box is infinite (i.e. "open"),
|
||||
//! returned values may be equal to +/- Precision::Infinite().
|
||||
//! If the box is void, returns raw internal values.
|
||||
//! Can be used with C++17 structured bindings:
|
||||
//! @code
|
||||
//! auto [xmin, xmax, ymin, ymax, zmin, zmax] = aBox.Get();
|
||||
//! @endcode
|
||||
[[nodiscard]] Standard_EXPORT Limits Get() const;
|
||||
|
||||
//! Returns the Xmin value (IsOpenXmin() ? -Precision::Infinite() : Xmin - GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetXMin() const;
|
||||
|
||||
//! Returns the Xmax value (IsOpenXmax() ? Precision::Infinite() : Xmax + GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetXMax() const;
|
||||
|
||||
//! Returns the Ymin value (IsOpenYmin() ? -Precision::Infinite() : Ymin - GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetYMin() const;
|
||||
|
||||
//! Returns the Ymax value (IsOpenYmax() ? Precision::Infinite() : Ymax + GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetYMax() const;
|
||||
|
||||
//! Returns the Zmin value (IsOpenZmin() ? -Precision::Infinite() : Zmin - GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetZMin() const;
|
||||
|
||||
//! Returns the Zmax value (IsOpenZmax() ? Precision::Infinite() : Zmax + GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetZMax() const;
|
||||
|
||||
//! Returns the lower corner of this bounding box. The gap is included.
|
||||
//! If this bounding box is infinite (i.e. "open"), returned values
|
||||
//! may be equal to +/- Precision::Infinite().
|
||||
//! Standard_ConstructionError exception will be thrown if the box is void.
|
||||
//! if IsVoid()
|
||||
Standard_EXPORT gp_Pnt CornerMin() const;
|
||||
[[nodiscard]] Standard_EXPORT gp_Pnt CornerMin() const;
|
||||
|
||||
//! Returns the upper corner of this bounding box. The gap is included.
|
||||
//! If this bounding box is infinite (i.e. "open"), returned values
|
||||
//! may be equal to +/- Precision::Infinite().
|
||||
//! Standard_ConstructionError exception will be thrown if the box is void.
|
||||
//! if IsVoid()
|
||||
Standard_EXPORT gp_Pnt CornerMax() const;
|
||||
[[nodiscard]] Standard_EXPORT gp_Pnt CornerMax() const;
|
||||
|
||||
//! The Box will be infinitely long in the Xmin
|
||||
//! direction.
|
||||
void OpenXmin() { Flags |= XminMask; }
|
||||
void OpenXmin() noexcept { Flags |= XminMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Xmax
|
||||
//! direction.
|
||||
void OpenXmax() { Flags |= XmaxMask; }
|
||||
void OpenXmax() noexcept { Flags |= XmaxMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Ymin
|
||||
//! direction.
|
||||
void OpenYmin() { Flags |= YminMask; }
|
||||
void OpenYmin() noexcept { Flags |= YminMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Ymax
|
||||
//! direction.
|
||||
void OpenYmax() { Flags |= YmaxMask; }
|
||||
void OpenYmax() noexcept { Flags |= YmaxMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Zmin
|
||||
//! direction.
|
||||
void OpenZmin() { Flags |= ZminMask; }
|
||||
void OpenZmin() noexcept { Flags |= ZminMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Zmax
|
||||
//! direction.
|
||||
void OpenZmax() { Flags |= ZmaxMask; }
|
||||
void OpenZmax() noexcept { Flags |= ZmaxMask; }
|
||||
|
||||
//! Returns true if this bounding box has at least one open direction.
|
||||
Standard_Boolean IsOpen() const { return (Flags & WholeMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpen() const noexcept { return (Flags & WholeMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Xmin direction.
|
||||
Standard_Boolean IsOpenXmin() const { return (Flags & XminMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenXmin() const noexcept { return (Flags & XminMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Xmax direction.
|
||||
Standard_Boolean IsOpenXmax() const { return (Flags & XmaxMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenXmax() const noexcept { return (Flags & XmaxMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Ymix direction.
|
||||
Standard_Boolean IsOpenYmin() const { return (Flags & YminMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenYmin() const noexcept { return (Flags & YminMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Ymax direction.
|
||||
Standard_Boolean IsOpenYmax() const { return (Flags & YmaxMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenYmax() const noexcept { return (Flags & YmaxMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Zmin direction.
|
||||
Standard_Boolean IsOpenZmin() const { return (Flags & ZminMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenZmin() const noexcept { return (Flags & ZminMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Zmax direction.
|
||||
Standard_Boolean IsOpenZmax() const { return (Flags & ZmaxMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenZmax() const noexcept { return (Flags & ZmaxMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is infinite in all 6 directions (WholeSpace flag).
|
||||
Standard_Boolean IsWhole() const { return (Flags & WholeMask) == WholeMask; }
|
||||
[[nodiscard]] Standard_Boolean IsWhole() const noexcept
|
||||
{
|
||||
return (Flags & WholeMask) == WholeMask;
|
||||
}
|
||||
|
||||
//! Returns true if this bounding box is empty (Void flag).
|
||||
Standard_Boolean IsVoid() const { return (Flags & VoidMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsVoid() const noexcept { return (Flags & VoidMask) != 0; }
|
||||
|
||||
//! true if xmax-xmin < tol.
|
||||
Standard_EXPORT Standard_Boolean IsXThin(const Standard_Real tol) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsXThin(const Standard_Real tol) const;
|
||||
|
||||
//! true if ymax-ymin < tol.
|
||||
Standard_EXPORT Standard_Boolean IsYThin(const Standard_Real tol) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsYThin(const Standard_Real tol) const;
|
||||
|
||||
//! true if zmax-zmin < tol.
|
||||
Standard_EXPORT Standard_Boolean IsZThin(const Standard_Real tol) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsZThin(const Standard_Real tol) const;
|
||||
|
||||
//! Returns true if IsXThin, IsYThin and IsZThin are all true,
|
||||
//! i.e. if the box is thin in all three dimensions.
|
||||
Standard_EXPORT Standard_Boolean IsThin(const Standard_Real tol) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsThin(const Standard_Real tol) const;
|
||||
|
||||
//! Returns a bounding box which is the result of applying the
|
||||
//! transformation T to this bounding box.
|
||||
@@ -224,7 +291,7 @@ public:
|
||||
//! Applying a geometric transformation (for example, a
|
||||
//! rotation) to a bounding box generally increases its
|
||||
//! dimensions. This is not optimal for algorithms which use it.
|
||||
Standard_NODISCARD Standard_EXPORT Bnd_Box Transformed(const gp_Trsf& T) const;
|
||||
[[nodiscard]] Standard_EXPORT Bnd_Box Transformed(const gp_Trsf& T) const;
|
||||
|
||||
//! Adds the box <Other> to <me>.
|
||||
Standard_EXPORT void Add(const Bnd_Box& Other);
|
||||
@@ -241,39 +308,42 @@ public:
|
||||
Standard_EXPORT void Add(const gp_Dir& D);
|
||||
|
||||
//! Returns True if the Pnt is out the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& P) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& P) const;
|
||||
|
||||
//! Returns False if the line intersects the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Lin& L) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Lin& L) const;
|
||||
|
||||
//! Returns False if the plane intersects the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Pln& P) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Pln& P) const;
|
||||
|
||||
//! Returns False if the <Box> intersects or is inside <me>.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box& Other) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box& Other) const;
|
||||
|
||||
//! Returns False if the transformed <Box> intersects
|
||||
//! or is inside <me>.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box& Other, const gp_Trsf& T) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box& Other,
|
||||
const gp_Trsf& T) const;
|
||||
|
||||
//! Returns False if the transformed <Box> intersects
|
||||
//! or is inside the transformed box <me>.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Trsf& T1,
|
||||
const Bnd_Box& Other,
|
||||
const gp_Trsf& T2) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Trsf& T1,
|
||||
const Bnd_Box& Other,
|
||||
const gp_Trsf& T2) const;
|
||||
|
||||
//! Returns False if the flat band lying between two parallel
|
||||
//! lines represented by their reference points <P1>, <P2> and
|
||||
//! direction <D> intersects the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt& P1,
|
||||
const gp_Pnt& P2,
|
||||
const gp_Dir& D) const;
|
||||
|
||||
//! Computes the minimum distance between two boxes.
|
||||
Standard_EXPORT Standard_Real Distance(const Bnd_Box& Other) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real Distance(const Bnd_Box& Other) const;
|
||||
|
||||
Standard_EXPORT void Dump() const;
|
||||
|
||||
//! Computes the squared diagonal of me.
|
||||
Standard_Real SquareExtent() const
|
||||
[[nodiscard]] Standard_Real SquareExtent() const noexcept
|
||||
{
|
||||
if (IsVoid())
|
||||
{
|
||||
@@ -290,7 +360,7 @@ public:
|
||||
//! box). This can be a Void box in case if its sides has been defined as infinite (Open) without
|
||||
//! adding any finite points. WARNING! This method relies on Open flags, the infinite points added
|
||||
//! using Add() method will be returned as is.
|
||||
Bnd_Box FinitePart() const
|
||||
[[nodiscard]] Bnd_Box FinitePart() const noexcept
|
||||
{
|
||||
if (!HasFinitePart())
|
||||
{
|
||||
@@ -304,7 +374,10 @@ public:
|
||||
}
|
||||
|
||||
//! Returns TRUE if this box has finite part.
|
||||
Standard_Boolean HasFinitePart() const { return !IsVoid() && Xmax >= Xmin; }
|
||||
[[nodiscard]] Standard_Boolean HasFinitePart() const noexcept
|
||||
{
|
||||
return !IsVoid() && Xmax >= Xmin;
|
||||
}
|
||||
|
||||
//! Dumps the content of me into the stream
|
||||
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
|
||||
|
||||
@@ -15,12 +15,24 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Bnd_Box2d.hxx>
|
||||
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_Stream.hxx>
|
||||
|
||||
//-- #include <Precision.hxx> Precision::Infinite() -> 1e+100
|
||||
namespace
|
||||
{
|
||||
// Precision constant for infinite bounds
|
||||
constexpr Standard_Real THE_BND_PRECISION_INFINITE = 1e+100;
|
||||
|
||||
// Precomputed unit direction vectors for bounding box transformations
|
||||
constexpr gp_Dir2d THE_DIR_XMIN{gp_Dir2d::D::NX};
|
||||
constexpr gp_Dir2d THE_DIR_XMAX{gp_Dir2d::D::X};
|
||||
constexpr gp_Dir2d THE_DIR_YMIN{gp_Dir2d::D::NY};
|
||||
constexpr gp_Dir2d THE_DIR_YMAX{gp_Dir2d::D::Y};
|
||||
} // anonymous namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Bnd_Box2d::Update(const Standard_Real x,
|
||||
@@ -38,14 +50,14 @@ void Bnd_Box2d::Update(const Standard_Real x,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Flags & XminMask) && (x < Xmin))
|
||||
Xmin = x;
|
||||
if (!(Flags & XmaxMask) && (X > Xmax))
|
||||
Xmax = X;
|
||||
if (!(Flags & YminMask) && (y < Ymin))
|
||||
Ymin = y;
|
||||
if (!(Flags & YmaxMask) && (Y > Ymax))
|
||||
Ymax = Y;
|
||||
if (!(Flags & XminMask))
|
||||
Xmin = std::min(Xmin, x);
|
||||
if (!(Flags & XmaxMask))
|
||||
Xmax = std::max(Xmax, X);
|
||||
if (!(Flags & YminMask))
|
||||
Ymin = std::min(Ymin, y);
|
||||
if (!(Flags & YmaxMask))
|
||||
Ymax = std::max(Ymax, Y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,14 +75,14 @@ void Bnd_Box2d::Update(const Standard_Real X, const Standard_Real Y)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Flags & XminMask) && (X < Xmin))
|
||||
Xmin = X;
|
||||
else if (!(Flags & XmaxMask) && (X > Xmax))
|
||||
Xmax = X;
|
||||
if (!(Flags & YminMask) && (Y < Ymin))
|
||||
Ymin = Y;
|
||||
else if (!(Flags & YmaxMask) && (Y > Ymax))
|
||||
Ymax = Y;
|
||||
if (!(Flags & XminMask))
|
||||
Xmin = std::min(Xmin, X);
|
||||
if (!(Flags & XmaxMask))
|
||||
Xmax = std::max(Xmax, X);
|
||||
if (!(Flags & YminMask))
|
||||
Ymin = std::min(Ymin, Y);
|
||||
if (!(Flags & YmaxMask))
|
||||
Ymax = std::max(Ymax, Y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,122 +92,139 @@ void Bnd_Box2d::Get(Standard_Real& x, Standard_Real& y, Standard_Real& Xm, Stand
|
||||
{
|
||||
if (Flags & VoidMask)
|
||||
throw Standard_ConstructionError("Bnd_Box is void");
|
||||
Standard_Real pinf = 1e+100; //-- Precision::Infinite();
|
||||
if (Flags & XminMask)
|
||||
x = -pinf;
|
||||
else
|
||||
x = Xmin - Gap;
|
||||
if (Flags & XmaxMask)
|
||||
Xm = pinf;
|
||||
else
|
||||
Xm = Xmax + Gap;
|
||||
if (Flags & YminMask)
|
||||
y = -pinf;
|
||||
else
|
||||
y = Ymin - Gap;
|
||||
if (Flags & YmaxMask)
|
||||
Ym = pinf;
|
||||
else
|
||||
Ym = Ymax + Gap;
|
||||
|
||||
x = GetXMin();
|
||||
Xm = GetXMax();
|
||||
y = GetYMin();
|
||||
Ym = GetYMax();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Bnd_Box2d::Limits Bnd_Box2d::Get() const
|
||||
{
|
||||
return {GetXMin(), GetXMax(), GetYMin(), GetYMax()};
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box2d::GetXMin() const
|
||||
{
|
||||
return (Flags & XminMask) ? -THE_BND_PRECISION_INFINITE : Xmin - Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box2d::GetXMax() const
|
||||
{
|
||||
return (Flags & XmaxMask) ? THE_BND_PRECISION_INFINITE : Xmax + Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box2d::GetYMin() const
|
||||
{
|
||||
return (Flags & YminMask) ? -THE_BND_PRECISION_INFINITE : Ymin - Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Real Bnd_Box2d::GetYMax() const
|
||||
{
|
||||
return (Flags & YmaxMask) ? THE_BND_PRECISION_INFINITE : Ymax + Gap;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Bnd_Box2d Bnd_Box2d::Transformed(const gp_Trsf2d& T) const
|
||||
{
|
||||
gp_TrsfForm F = T.Form();
|
||||
Bnd_Box2d newb(*this);
|
||||
const gp_TrsfForm aF = T.Form();
|
||||
Bnd_Box2d aNewBox(*this);
|
||||
if (IsVoid())
|
||||
return newb;
|
||||
return aNewBox;
|
||||
|
||||
if (F == gp_Identity)
|
||||
if (aF == gp_Identity)
|
||||
{
|
||||
}
|
||||
else if (F == gp_Translation)
|
||||
else if (aF == gp_Translation)
|
||||
{
|
||||
Standard_Real DX, DY;
|
||||
(T.TranslationPart()).Coord(DX, DY);
|
||||
Standard_Real aDX, aDY;
|
||||
(T.TranslationPart()).Coord(aDX, aDY);
|
||||
if (!(Flags & XminMask))
|
||||
newb.Xmin += DX;
|
||||
aNewBox.Xmin += aDX;
|
||||
if (!(Flags & XmaxMask))
|
||||
newb.Xmax += DX;
|
||||
aNewBox.Xmax += aDX;
|
||||
if (!(Flags & YminMask))
|
||||
newb.Ymin += DY;
|
||||
aNewBox.Ymin += aDY;
|
||||
if (!(Flags & YmaxMask))
|
||||
newb.Ymax += DY;
|
||||
aNewBox.Ymax += aDY;
|
||||
}
|
||||
else
|
||||
{
|
||||
gp_Pnt2d P[4];
|
||||
Standard_Boolean Vertex[4];
|
||||
Standard_Integer i;
|
||||
Vertex[0] = Standard_True;
|
||||
Vertex[1] = Standard_True;
|
||||
Vertex[2] = Standard_True;
|
||||
Vertex[3] = Standard_True;
|
||||
gp_Dir2d D[6];
|
||||
// Standard_Integer vertices = 0;
|
||||
Standard_Integer directions = 0;
|
||||
gp_Pnt2d aP[4];
|
||||
Standard_Boolean aVertex[4];
|
||||
aVertex[0] = Standard_True;
|
||||
aVertex[1] = Standard_True;
|
||||
aVertex[2] = Standard_True;
|
||||
aVertex[3] = Standard_True;
|
||||
gp_Dir2d aD[6];
|
||||
Standard_Integer aNbDirs = 0;
|
||||
|
||||
if (Flags & XminMask)
|
||||
{
|
||||
D[directions].SetCoord(-1., 0.);
|
||||
directions++;
|
||||
Vertex[0] = Vertex[2] = Standard_False;
|
||||
aD[aNbDirs++] = THE_DIR_XMIN;
|
||||
aVertex[0] = aVertex[2] = Standard_False;
|
||||
}
|
||||
if (Flags & XmaxMask)
|
||||
{
|
||||
D[directions].SetCoord(1., 0.);
|
||||
directions++;
|
||||
Vertex[1] = Vertex[3] = Standard_False;
|
||||
aD[aNbDirs++] = THE_DIR_XMAX;
|
||||
aVertex[1] = aVertex[3] = Standard_False;
|
||||
}
|
||||
if (Flags & YminMask)
|
||||
{
|
||||
D[directions].SetCoord(0., -1.);
|
||||
directions++;
|
||||
Vertex[0] = Vertex[1] = Standard_False;
|
||||
aD[aNbDirs++] = THE_DIR_YMIN;
|
||||
aVertex[0] = aVertex[1] = Standard_False;
|
||||
}
|
||||
if (Flags & YmaxMask)
|
||||
{
|
||||
D[directions].SetCoord(0., 1.);
|
||||
directions++;
|
||||
Vertex[2] = Vertex[3] = Standard_False;
|
||||
aD[aNbDirs++] = THE_DIR_YMAX;
|
||||
aVertex[2] = aVertex[3] = Standard_False;
|
||||
}
|
||||
|
||||
newb.SetVoid();
|
||||
aNewBox.SetVoid();
|
||||
|
||||
for (i = 0; i < directions; i++)
|
||||
for (Standard_Integer i = 0; i < aNbDirs; i++)
|
||||
{
|
||||
D[i].Transform(T);
|
||||
newb.Add(D[i]);
|
||||
aD[i].Transform(T);
|
||||
aNewBox.Add(aD[i]);
|
||||
}
|
||||
P[0].SetCoord(Xmin, Ymin);
|
||||
P[1].SetCoord(Xmax, Ymin);
|
||||
P[2].SetCoord(Xmin, Ymax);
|
||||
P[3].SetCoord(Xmax, Ymax);
|
||||
if (Vertex[0])
|
||||
aP[0].SetCoord(Xmin, Ymin);
|
||||
aP[1].SetCoord(Xmax, Ymin);
|
||||
aP[2].SetCoord(Xmin, Ymax);
|
||||
aP[3].SetCoord(Xmax, Ymax);
|
||||
if (aVertex[0])
|
||||
{
|
||||
P[0].Transform(T);
|
||||
newb.Add(P[0]);
|
||||
aP[0].Transform(T);
|
||||
aNewBox.Add(aP[0]);
|
||||
}
|
||||
if (Vertex[1])
|
||||
if (aVertex[1])
|
||||
{
|
||||
P[1].Transform(T);
|
||||
newb.Add(P[1]);
|
||||
aP[1].Transform(T);
|
||||
aNewBox.Add(aP[1]);
|
||||
}
|
||||
if (Vertex[2])
|
||||
if (aVertex[2])
|
||||
{
|
||||
P[2].Transform(T);
|
||||
newb.Add(P[2]);
|
||||
aP[2].Transform(T);
|
||||
aNewBox.Add(aP[2]);
|
||||
}
|
||||
if (Vertex[3])
|
||||
if (aVertex[3])
|
||||
{
|
||||
P[3].Transform(T);
|
||||
newb.Add(P[3]);
|
||||
aP[3].Transform(T);
|
||||
aNewBox.Add(aP[3]);
|
||||
}
|
||||
newb.Gap = Gap;
|
||||
aNewBox.Gap = Gap;
|
||||
}
|
||||
return newb;
|
||||
return aNewBox;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
class gp_Dir2d;
|
||||
class gp_Trsf2d;
|
||||
|
||||
@@ -53,13 +57,23 @@ class Bnd_Box2d
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Structure containing the 2D box limits (Xmin, Xmax, Ymin, Ymax).
|
||||
//! The values include the gap and account for open directions.
|
||||
struct Limits
|
||||
{
|
||||
double Xmin; //!< Minimum X coordinate
|
||||
double Xmax; //!< Maximum X coordinate
|
||||
double Ymin; //!< Minimum Y coordinate
|
||||
double Ymax; //!< Maximum Y coordinate
|
||||
};
|
||||
|
||||
//! Creates an empty 2D bounding box.
|
||||
//! The constructed box is qualified Void. Its gap is null.
|
||||
Bnd_Box2d()
|
||||
: Xmin(0.),
|
||||
Xmax(0.),
|
||||
Ymin(0.),
|
||||
Ymax(0.),
|
||||
constexpr Bnd_Box2d()
|
||||
: Xmin(RealLast()),
|
||||
Xmax(-RealLast()),
|
||||
Ymin(RealLast()),
|
||||
Ymax(-RealLast()),
|
||||
Gap(0.),
|
||||
Flags(VoidMask)
|
||||
{
|
||||
@@ -67,13 +81,17 @@ public:
|
||||
|
||||
//! Sets this bounding box so that it covers the whole 2D
|
||||
//! space, i.e. it is infinite in all directions.
|
||||
void SetWhole() { Flags = WholeMask; }
|
||||
void SetWhole() noexcept { Flags = WholeMask; }
|
||||
|
||||
//! Sets this 2D bounding box so that it is empty. All points are outside a void box.
|
||||
void SetVoid()
|
||||
void SetVoid() noexcept
|
||||
{
|
||||
Flags = VoidMask;
|
||||
Xmin = RealLast();
|
||||
Xmax = -RealLast();
|
||||
Ymin = RealLast();
|
||||
Ymax = -RealLast();
|
||||
Gap = 0.0;
|
||||
Flags = VoidMask;
|
||||
}
|
||||
|
||||
//! Sets this 2D bounding box so that it bounds
|
||||
@@ -111,22 +129,17 @@ public:
|
||||
Standard_EXPORT void Update(const Standard_Real X, const Standard_Real Y);
|
||||
|
||||
//! Returns the gap of this 2D bounding box.
|
||||
Standard_Real GetGap() const { return Gap; }
|
||||
[[nodiscard]] constexpr Standard_Real GetGap() const noexcept { return Gap; }
|
||||
|
||||
//! Set the gap of this 2D bounding box to abs(Tol).
|
||||
void SetGap(const Standard_Real Tol) { Gap = Tol; }
|
||||
void SetGap(const Standard_Real Tol) noexcept { Gap = std::abs(Tol); }
|
||||
|
||||
//! Enlarges the box with a tolerance value.
|
||||
//! This means that the minimum values of its X and Y
|
||||
//! intervals of definition, when they are finite, are reduced by
|
||||
//! the absolute value of Tol, while the maximum values are
|
||||
//! increased by the same amount.
|
||||
void Enlarge(const Standard_Real theTol)
|
||||
{
|
||||
Standard_Real aTol = theTol < 0.0 ? -theTol : theTol;
|
||||
if (Gap < aTol)
|
||||
Gap = aTol;
|
||||
}
|
||||
void Enlarge(const Standard_Real theTol) noexcept { Gap = std::max(Gap, std::abs(theTol)); }
|
||||
|
||||
//! Returns the bounds of this 2D bounding box.
|
||||
//! The gap is included. If this bounding box is infinite (i.e. "open"), returned values
|
||||
@@ -137,36 +150,61 @@ public:
|
||||
Standard_Real& aXmax,
|
||||
Standard_Real& aYmax) const;
|
||||
|
||||
//! Returns the bounds of this 2D bounding box as a Limits structure.
|
||||
//! The gap is included. If this bounding box is infinite (i.e. "open"),
|
||||
//! returned values may be equal to +/- Precision::Infinite().
|
||||
//! If the box is void, returns raw internal values.
|
||||
//! Can be used with C++17 structured bindings:
|
||||
//! @code
|
||||
//! auto [xmin, xmax, ymin, ymax] = aBox.Get();
|
||||
//! @endcode
|
||||
[[nodiscard]] Standard_EXPORT Limits Get() const;
|
||||
|
||||
//! Returns the Xmin value (IsOpenXmin() ? -Precision::Infinite() : Xmin - GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetXMin() const;
|
||||
|
||||
//! Returns the Xmax value (IsOpenXmax() ? Precision::Infinite() : Xmax + GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetXMax() const;
|
||||
|
||||
//! Returns the Ymin value (IsOpenYmin() ? -Precision::Infinite() : Ymin - GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetYMin() const;
|
||||
|
||||
//! Returns the Ymax value (IsOpenYmax() ? Precision::Infinite() : Ymax + GetGap()).
|
||||
[[nodiscard]] Standard_EXPORT Standard_Real GetYMax() const;
|
||||
|
||||
//! The Box will be infinitely long in the Xmin direction.
|
||||
void OpenXmin() { Flags |= XminMask; }
|
||||
void OpenXmin() noexcept { Flags |= XminMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Xmax direction.
|
||||
void OpenXmax() { Flags |= XmaxMask; }
|
||||
void OpenXmax() noexcept { Flags |= XmaxMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Ymin direction.
|
||||
void OpenYmin() { Flags |= YminMask; }
|
||||
void OpenYmin() noexcept { Flags |= YminMask; }
|
||||
|
||||
//! The Box will be infinitely long in the Ymax direction.
|
||||
void OpenYmax() { Flags |= YmaxMask; }
|
||||
void OpenYmax() noexcept { Flags |= YmaxMask; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Xmin direction.
|
||||
Standard_Boolean IsOpenXmin() const { return (Flags & XminMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenXmin() const noexcept { return (Flags & XminMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Xmax direction.
|
||||
Standard_Boolean IsOpenXmax() const { return (Flags & XmaxMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenXmax() const noexcept { return (Flags & XmaxMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Ymin direction.
|
||||
Standard_Boolean IsOpenYmin() const { return (Flags & YminMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenYmin() const noexcept { return (Flags & YminMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is open in the Ymax direction.
|
||||
Standard_Boolean IsOpenYmax() const { return (Flags & YmaxMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsOpenYmax() const noexcept { return (Flags & YmaxMask) != 0; }
|
||||
|
||||
//! Returns true if this bounding box is infinite in all 4
|
||||
//! directions (Whole Space flag).
|
||||
Standard_Boolean IsWhole() const { return (Flags & WholeMask) == WholeMask; }
|
||||
[[nodiscard]] Standard_Boolean IsWhole() const noexcept
|
||||
{
|
||||
return (Flags & WholeMask) == WholeMask;
|
||||
}
|
||||
|
||||
//! Returns true if this 2D bounding box is empty (Void flag).
|
||||
Standard_Boolean IsVoid() const { return (Flags & VoidMask) != 0; }
|
||||
[[nodiscard]] Standard_Boolean IsVoid() const noexcept { return (Flags & VoidMask) != 0; }
|
||||
|
||||
//! Returns a bounding box which is the result of applying the
|
||||
//! transformation T to this bounding box.
|
||||
@@ -174,16 +212,16 @@ public:
|
||||
//! Applying a geometric transformation (for example, a
|
||||
//! rotation) to a bounding box generally increases its
|
||||
//! dimensions. This is not optimal for algorithms which use it.
|
||||
Standard_NODISCARD Standard_EXPORT Bnd_Box2d Transformed(const gp_Trsf2d& T) const;
|
||||
[[nodiscard]] Standard_EXPORT Bnd_Box2d Transformed(const gp_Trsf2d& T) const;
|
||||
|
||||
//! Adds the 2d box <Other> to <me>.
|
||||
Standard_EXPORT void Add(const Bnd_Box2d& Other);
|
||||
|
||||
//! Adds the 2d point.
|
||||
void Add(const gp_Pnt2d& thePnt) { Update(thePnt.X(), thePnt.Y()); }
|
||||
void Add(const gp_Pnt2d& thePnt) noexcept { Update(thePnt.X(), thePnt.Y()); }
|
||||
|
||||
//! Extends bounding box from thePnt in the direction theDir.
|
||||
void Add(const gp_Pnt2d& thePnt, const gp_Dir2d& theDir)
|
||||
void Add(const gp_Pnt2d& thePnt, const gp_Dir2d& theDir) noexcept
|
||||
{
|
||||
Add(thePnt);
|
||||
Add(theDir);
|
||||
@@ -195,19 +233,21 @@ public:
|
||||
Standard_EXPORT void Add(const gp_Dir2d& D);
|
||||
|
||||
//! Returns True if the 2d pnt <P> is out <me>.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt2d& P) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt2d& P) const;
|
||||
|
||||
//! Returns True if the line doesn't intersect the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Lin2d& theL) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Lin2d& theL) const;
|
||||
|
||||
//! Returns True if the segment doesn't intersect the box.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt2d& theP0, const gp_Pnt2d& theP1) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt2d& theP0,
|
||||
const gp_Pnt2d& theP1) const;
|
||||
|
||||
//! Returns True if <Box2d> is out <me>.
|
||||
Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box2d& Other) const;
|
||||
[[nodiscard]] Standard_EXPORT Standard_Boolean IsOut(const Bnd_Box2d& Other) const;
|
||||
|
||||
//! Returns True if transformed <Box2d> is out <me>.
|
||||
Standard_Boolean IsOut(const Bnd_Box2d& theOther, const gp_Trsf2d& theTrsf) const
|
||||
[[nodiscard]] Standard_Boolean IsOut(const Bnd_Box2d& theOther,
|
||||
const gp_Trsf2d& theTrsf) const noexcept
|
||||
{
|
||||
return IsOut(theOther.Transformed(theTrsf));
|
||||
}
|
||||
@@ -215,7 +255,9 @@ public:
|
||||
//! Compares a transformed bounding with a transformed
|
||||
//! bounding. The default implementation is to make a copy
|
||||
//! of <me> and <Other>, to transform them and to test.
|
||||
Standard_Boolean IsOut(const gp_Trsf2d& T1, const Bnd_Box2d& Other, const gp_Trsf2d& T2) const
|
||||
[[nodiscard]] Standard_Boolean IsOut(const gp_Trsf2d& T1,
|
||||
const Bnd_Box2d& Other,
|
||||
const gp_Trsf2d& T2) const noexcept
|
||||
{
|
||||
return Transformed(T1).IsOut(Other.Transformed(T2));
|
||||
}
|
||||
@@ -223,7 +265,7 @@ public:
|
||||
Standard_EXPORT void Dump() const;
|
||||
|
||||
//! Computes the squared diagonal of me.
|
||||
Standard_Real SquareExtent() const
|
||||
[[nodiscard]] Standard_Real SquareExtent() const noexcept
|
||||
{
|
||||
if (IsVoid())
|
||||
return 0.0;
|
||||
|
||||
@@ -205,9 +205,9 @@ TEST(Bnd_BoxTest, CornerMethodsVoidBox)
|
||||
{
|
||||
Bnd_Box aBox; // void box
|
||||
|
||||
EXPECT_THROW(aBox.CornerMin(), Standard_ConstructionError)
|
||||
EXPECT_THROW((void)aBox.CornerMin(), Standard_ConstructionError)
|
||||
<< "CornerMin should throw for void box";
|
||||
EXPECT_THROW(aBox.CornerMax(), Standard_ConstructionError)
|
||||
EXPECT_THROW((void)aBox.CornerMax(), Standard_ConstructionError)
|
||||
<< "CornerMax should throw for void box";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user