- 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.
// 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);
}
-//=================================================================================================
+// 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);
+}
-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)
+// 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
//=================================================================================================
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);
}
}
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
+void Bnd_Box::Get(Standard_Real& theXmin,
+ Standard_Real& theYmin,
+ Standard_Real& theZmin,
+ Standard_Real& theXmax,
+ Standard_Real& theYmax,
+ Standard_Real& theZmax) const
{
- return Gap;
+ if (IsVoid())
+ {
+ throw Standard_ConstructionError("Bnd_Box is void");
+ }
+
+ theXmin = GetXMin();
+ theXmax = GetXMax();
+ theYmin = GetYMin();
+ theYmax = GetYMax();
+ theZmin = GetZMin();
+ theZmax = GetZMax();
}
//=================================================================================================
-void Bnd_Box::SetGap(const Standard_Real Tol)
+Bnd_Box::Limits Bnd_Box::Get() const
{
- Gap = Tol;
+ return {GetXMin(), GetXMax(), GetYMin(), GetYMax(), GetZMin(), GetZMax()};
}
//=================================================================================================
-void Bnd_Box::Enlarge(const Standard_Real Tol)
+Standard_Real Bnd_Box::GetXMin() const
{
- Gap = std::max(Gap, std::abs(Tol));
+ return IsOpenXmin() ? -THE_BND_PRECISION_INFINITE : Xmin - Gap;
}
//=================================================================================================
-void Bnd_Box::Get(Standard_Real& theXmin,
- Standard_Real& theYmin,
- Standard_Real& theZmin,
- Standard_Real& theXmax,
- Standard_Real& theYmax,
- Standard_Real& theZmax) const
+Standard_Real Bnd_Box::GetXMax() const
{
- if (IsVoid())
- {
- throw Standard_ConstructionError("Bnd_Box is void");
- }
+ return IsOpenXmax() ? THE_BND_PRECISION_INFINITE : Xmax + Gap;
+}
- 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;
+//=================================================================================================
+
+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);
}
//=================================================================================================
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;
}
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)
{
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))
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();
}
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();
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();
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())
- return Standard_True;
- if (Other.IsVoid())
+
+ // Handle special cases
+ if (IsVoid() || 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;
}
//=================================================================================================
-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
{
// 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);
}
//=================================================================================================
#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;
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();
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>))
//! 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
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.
//! 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);
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())
{
//! 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())
{
}
//! 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;
// 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,
}
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);
}
}
}
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);
}
}
{
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;
}
//=================================================================================================
#include <Standard_Real.hxx>
#include <Standard_Integer.hxx>
#include <Standard_Boolean.hxx>
+
+#include <algorithm>
+#include <cmath>
+
class gp_Dir2d;
class gp_Trsf2d;
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)
{
//! 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
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
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.
//! 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);
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));
}
//! 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));
}
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;
{
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";
}