|
|
|||
File indexing completed on 2026-09-26 09:02:28
0001 // Created on: 1991-01-28 0002 // Created by: Remi Lequette 0003 // Copyright (c) 1991-1999 Matra Datavision 0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS 0005 // 0006 // This file is part of Open CASCADE Technology software library. 0007 // 0008 // This library is free software; you can redistribute it and/or modify it under 0009 // the terms of the GNU Lesser General Public License version 2.1 as published 0010 // by the Free Software Foundation, with special exception defined in the file 0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 0012 // distribution for complete text of the license and disclaimer of any warranty. 0013 // 0014 // Alternatively, this file may be used under the terms of Open CASCADE 0015 // commercial license or contractual agreement. 0016 0017 #ifndef _Bnd_Box_HeaderFile 0018 #define _Bnd_Box_HeaderFile 0019 0020 #include <Standard.hxx> 0021 #include <Standard_DefineAlloc.hxx> 0022 #include <Standard_Handle.hxx> 0023 0024 #include <gp_Pnt.hxx> 0025 0026 #include <algorithm> 0027 #include <cmath> 0028 #include <optional> 0029 0030 class gp_Pnt; 0031 class gp_Dir; 0032 class gp_Trsf; 0033 class gp_Lin; 0034 class gp_Pln; 0035 0036 //! Describes a bounding box in 3D space. 0037 //! A bounding box is parallel to the axes of the coordinates 0038 //! system. If it is finite, it is defined by the three intervals: 0039 //! - [ Xmin,Xmax ], 0040 //! - [ Ymin,Ymax ], 0041 //! - [ Zmin,Zmax ]. 0042 //! A bounding box may be infinite (i.e. open) in one or more 0043 //! directions. It is said to be: 0044 //! - OpenXmin if it is infinite on the negative side of the "X Direction"; 0045 //! - OpenXmax if it is infinite on the positive side of the "X Direction"; 0046 //! - OpenYmin if it is infinite on the negative side of the "Y Direction"; 0047 //! - OpenYmax if it is infinite on the positive side of the "Y Direction"; 0048 //! - OpenZmin if it is infinite on the negative side of the "Z Direction"; 0049 //! - OpenZmax if it is infinite on the positive side of the "Z Direction"; 0050 //! - WholeSpace if it is infinite in all six directions. In this 0051 //! case, any point of the space is inside the box; 0052 //! - Void if it is empty. In this case, there is no point included in the box. 0053 //! A bounding box is defined by: 0054 //! - six bounds (Xmin, Xmax, Ymin, Ymax, Zmin and 0055 //! Zmax) which limit the bounding box if it is finite, 0056 //! - eight flags (OpenXmin, OpenXmax, OpenYmin, 0057 //! OpenYmax, OpenZmin, OpenZmax, 0058 //! WholeSpace and Void) which describe the 0059 //! bounding box if it is infinite or empty, and 0060 //! - a gap, which is included on both sides in any direction 0061 //! when consulting the finite bounds of the box. 0062 class Bnd_Box 0063 { 0064 public: 0065 DEFINE_STANDARD_ALLOC 0066 0067 //! Structure containing the box limits (Xmin, Xmax, Ymin, Ymax, Zmin, Zmax). 0068 //! The values include the gap and account for open directions. 0069 struct Limits 0070 { 0071 double Xmin; //!< Minimum X coordinate 0072 double Xmax; //!< Maximum X coordinate 0073 double Ymin; //!< Minimum Y coordinate 0074 double Ymax; //!< Maximum Y coordinate 0075 double Zmin; //!< Minimum Z coordinate 0076 double Zmax; //!< Maximum Z coordinate 0077 }; 0078 0079 //! Creates an empty Box. 0080 //! The constructed box is qualified Void. Its gap is null. 0081 constexpr Bnd_Box() noexcept = default; 0082 0083 //! Creates a bounding box, it contains: 0084 //! - minimum/maximum point of bounding box, 0085 //! The constructed box is qualified Void. Its gap is null. 0086 constexpr Bnd_Box(const gp_Pnt& theMin, const gp_Pnt& theMax) 0087 : Xmin(theMin.X()), 0088 Xmax(theMax.X()), 0089 Ymin(theMin.Y()), 0090 Ymax(theMax.Y()), 0091 Zmin(theMin.Z()), 0092 Zmax(theMax.Z()), 0093 Gap(0.0), 0094 Flags(0) 0095 { 0096 } 0097 0098 //! Sets this bounding box so that it covers the whole of 3D space. 0099 //! It is infinitely long in all directions. 0100 void SetWhole() noexcept { Flags = WholeMask; } 0101 0102 //! Sets this bounding box so that it is empty. All points are outside a void box. 0103 void SetVoid() noexcept 0104 { 0105 Xmin = RealLast(); 0106 Xmax = -RealLast(); 0107 Ymin = RealLast(); 0108 Ymax = -RealLast(); 0109 Zmin = RealLast(); 0110 Zmax = -RealLast(); 0111 Gap = 0.0; 0112 Flags = VoidMask; 0113 } 0114 0115 //! Sets this bounding box so that it bounds 0116 //! - the point P. This involves first setting this bounding box 0117 //! to be void and then adding the point P. 0118 Standard_EXPORT void Set(const gp_Pnt& P); 0119 0120 //! Sets this bounding box so that it bounds 0121 //! the half-line defined by point P and direction D, i.e. all 0122 //! points M defined by M=P+u*D, where u is greater than 0123 //! or equal to 0, are inside the bounding volume. This 0124 //! involves first setting this box to be void and then adding the half-line. 0125 Standard_EXPORT void Set(const gp_Pnt& P, const gp_Dir& D); 0126 0127 //! Enlarges this bounding box, if required, so that it 0128 //! contains at least: 0129 //! - interval [ aXmin,aXmax ] in the "X Direction", 0130 //! - interval [ aYmin,aYmax ] in the "Y Direction", 0131 //! - interval [ aZmin,aZmax ] in the "Z Direction"; 0132 Standard_EXPORT void Update(const double aXmin, 0133 const double aYmin, 0134 const double aZmin, 0135 const double aXmax, 0136 const double aYmax, 0137 const double aZmax); 0138 0139 //! Adds a point of coordinates (X,Y,Z) to this bounding box. 0140 Standard_EXPORT void Update(const double X, const double Y, const double Z); 0141 0142 //! Returns the gap of this bounding box. 0143 [[nodiscard]] constexpr double GetGap() const noexcept { return Gap; } 0144 0145 //! Set the gap of this bounding box to abs(Tol). 0146 void SetGap(const double Tol) noexcept { Gap = std::abs(Tol); } 0147 0148 //! Enlarges the box with a tolerance value. 0149 //! (minvalues-std::abs(<tol>) and maxvalues+std::abs(<tol>)) 0150 //! This means that the minimum values of its X, Y and Z 0151 //! intervals of definition, when they are finite, are reduced by 0152 //! the absolute value of Tol, while the maximum values are 0153 //! increased by the same amount. 0154 void Enlarge(const double Tol) noexcept { Gap = (std::max)(Gap, std::abs(Tol)); } 0155 0156 //! Returns the bounds of this bounding box. The gap is included. 0157 //! If this bounding box is infinite (i.e. "open"), returned values 0158 //! may be equal to +/- Precision::Infinite(). 0159 //! Standard_ConstructionError exception will be thrown if the box is void. 0160 //! if IsVoid() 0161 Standard_EXPORT void Get(double& theXmin, 0162 double& theYmin, 0163 double& theZmin, 0164 double& theXmax, 0165 double& theYmax, 0166 double& theZmax) const; 0167 0168 //! Returns the bounds of this bounding box as a Limits structure. 0169 //! The gap is included. If this bounding box is infinite (i.e. "open"), 0170 //! returned values may be equal to +/- Precision::Infinite(). 0171 //! If the box is void, returns raw internal values. 0172 //! Can be used with C++17 structured bindings: 0173 //! @code 0174 //! auto [xmin, xmax, ymin, ymax, zmin, zmax] = aBox.Get(); 0175 //! @endcode 0176 [[nodiscard]] Standard_EXPORT Limits Get() const; 0177 0178 //! Returns the Xmin value (IsOpenXmin() ? -Precision::Infinite() : Xmin - GetGap()). 0179 [[nodiscard]] Standard_EXPORT double GetXMin() const; 0180 0181 //! Returns the Xmax value (IsOpenXmax() ? Precision::Infinite() : Xmax + GetGap()). 0182 [[nodiscard]] Standard_EXPORT double GetXMax() const; 0183 0184 //! Returns the Ymin value (IsOpenYmin() ? -Precision::Infinite() : Ymin - GetGap()). 0185 [[nodiscard]] Standard_EXPORT double GetYMin() const; 0186 0187 //! Returns the Ymax value (IsOpenYmax() ? Precision::Infinite() : Ymax + GetGap()). 0188 [[nodiscard]] Standard_EXPORT double GetYMax() const; 0189 0190 //! Returns the Zmin value (IsOpenZmin() ? -Precision::Infinite() : Zmin - GetGap()). 0191 [[nodiscard]] Standard_EXPORT double GetZMin() const; 0192 0193 //! Returns the Zmax value (IsOpenZmax() ? Precision::Infinite() : Zmax + GetGap()). 0194 [[nodiscard]] Standard_EXPORT double GetZMax() const; 0195 0196 //! Returns the lower corner of this bounding box. The gap is included. 0197 //! If this bounding box is infinite (i.e. "open"), returned values 0198 //! may be equal to +/- Precision::Infinite(). 0199 //! Standard_ConstructionError exception will be thrown if the box is void. 0200 //! if IsVoid() 0201 [[nodiscard]] Standard_EXPORT gp_Pnt CornerMin() const; 0202 0203 //! Returns the upper corner of this bounding box. The gap is included. 0204 //! If this bounding box is infinite (i.e. "open"), returned values 0205 //! may be equal to +/- Precision::Infinite(). 0206 //! Standard_ConstructionError exception will be thrown if the box is void. 0207 //! if IsVoid() 0208 [[nodiscard]] Standard_EXPORT gp_Pnt CornerMax() const; 0209 0210 //! Returns the center of this bounding box. The gap is included. 0211 //! If this bounding box is infinite (i.e. "open"), returned values 0212 //! may be equal to +/- Precision::Infinite(). 0213 //! Returns std::nullopt if the box is void. 0214 [[nodiscard]] Standard_EXPORT std::optional<gp_Pnt> Center() const; 0215 0216 //! The Box will be infinitely long in the Xmin 0217 //! direction. 0218 void OpenXmin() noexcept { Flags |= XminMask; } 0219 0220 //! The Box will be infinitely long in the Xmax 0221 //! direction. 0222 void OpenXmax() noexcept { Flags |= XmaxMask; } 0223 0224 //! The Box will be infinitely long in the Ymin 0225 //! direction. 0226 void OpenYmin() noexcept { Flags |= YminMask; } 0227 0228 //! The Box will be infinitely long in the Ymax 0229 //! direction. 0230 void OpenYmax() noexcept { Flags |= YmaxMask; } 0231 0232 //! The Box will be infinitely long in the Zmin 0233 //! direction. 0234 void OpenZmin() noexcept { Flags |= ZminMask; } 0235 0236 //! The Box will be infinitely long in the Zmax 0237 //! direction. 0238 void OpenZmax() noexcept { Flags |= ZmaxMask; } 0239 0240 //! Returns true if this bounding box has at least one open direction. 0241 [[nodiscard]] bool IsOpen() const noexcept { return (Flags & WholeMask) != 0; } 0242 0243 //! Returns true if this bounding box is open in the Xmin direction. 0244 [[nodiscard]] bool IsOpenXmin() const noexcept { return (Flags & XminMask) != 0; } 0245 0246 //! Returns true if this bounding box is open in the Xmax direction. 0247 [[nodiscard]] bool IsOpenXmax() const noexcept { return (Flags & XmaxMask) != 0; } 0248 0249 //! Returns true if this bounding box is open in the Ymin direction. 0250 [[nodiscard]] bool IsOpenYmin() const noexcept { return (Flags & YminMask) != 0; } 0251 0252 //! Returns true if this bounding box is open in the Ymax direction. 0253 [[nodiscard]] bool IsOpenYmax() const noexcept { return (Flags & YmaxMask) != 0; } 0254 0255 //! Returns true if this bounding box is open in the Zmin direction. 0256 [[nodiscard]] bool IsOpenZmin() const noexcept { return (Flags & ZminMask) != 0; } 0257 0258 //! Returns true if this bounding box is open in the Zmax direction. 0259 [[nodiscard]] bool IsOpenZmax() const noexcept { return (Flags & ZmaxMask) != 0; } 0260 0261 //! Returns true if this bounding box is infinite in all 6 directions (WholeSpace flag). 0262 [[nodiscard]] bool IsWhole() const noexcept { return (Flags & WholeMask) == WholeMask; } 0263 0264 //! Returns true if this bounding box is empty (Void flag). 0265 [[nodiscard]] bool IsVoid() const noexcept { return (Flags & VoidMask) != 0; } 0266 0267 //! true if xmax-xmin < tol. 0268 [[nodiscard]] Standard_EXPORT bool IsXThin(const double tol) const; 0269 0270 //! true if ymax-ymin < tol. 0271 [[nodiscard]] Standard_EXPORT bool IsYThin(const double tol) const; 0272 0273 //! true if zmax-zmin < tol. 0274 [[nodiscard]] Standard_EXPORT bool IsZThin(const double tol) const; 0275 0276 //! Returns true if IsXThin, IsYThin and IsZThin are all true, 0277 //! i.e. if the box is thin in all three dimensions. 0278 [[nodiscard]] Standard_EXPORT bool IsThin(const double tol) const; 0279 0280 //! Returns a bounding box which is the result of applying the 0281 //! transformation T to this bounding box. 0282 //! Warning 0283 //! Applying a geometric transformation (for example, a 0284 //! rotation) to a bounding box generally increases its 0285 //! dimensions. This is not optimal for algorithms which use it. 0286 [[nodiscard]] Standard_EXPORT Bnd_Box Transformed(const gp_Trsf& T) const; 0287 0288 //! Adds the box <Other> to <me>. 0289 Standard_EXPORT void Add(const Bnd_Box& Other); 0290 0291 //! Adds a Pnt to the box. 0292 Standard_EXPORT void Add(const gp_Pnt& P); 0293 0294 //! Extends <me> from the Pnt <P> in the direction <D>. 0295 Standard_EXPORT void Add(const gp_Pnt& P, const gp_Dir& D); 0296 0297 //! Extends the Box in the given Direction, i.e. adds 0298 //! an half-line. The box may become infinite in 0299 //! 1,2 or 3 directions. 0300 Standard_EXPORT void Add(const gp_Dir& D); 0301 0302 //! Returns True if the Pnt is out the box. 0303 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Pnt& P) const; 0304 0305 //! Returns False if the line intersects the box. 0306 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Lin& L) const; 0307 0308 //! Returns False if the plane intersects the box. 0309 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Pln& P) const; 0310 0311 //! Returns False if the <Box> intersects or is inside <me>. 0312 [[nodiscard]] Standard_EXPORT bool IsOut(const Bnd_Box& Other) const; 0313 0314 //! Returns False if the transformed <Box> intersects 0315 //! or is inside <me>. 0316 [[nodiscard]] Standard_EXPORT bool IsOut(const Bnd_Box& Other, const gp_Trsf& T) const; 0317 0318 //! Returns False if the transformed <Box> intersects 0319 //! or is inside the transformed box <me>. 0320 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Trsf& T1, 0321 const Bnd_Box& Other, 0322 const gp_Trsf& T2) const; 0323 0324 //! Returns False if the flat band lying between two parallel 0325 //! lines represented by their reference points <P1>, <P2> and 0326 //! direction <D> intersects the box. 0327 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Pnt& P1, 0328 const gp_Pnt& P2, 0329 const gp_Dir& D) const; 0330 0331 //! Returns True if the point is inside or on the boundary of this box. 0332 [[nodiscard]] bool Contains(const gp_Pnt& theP) const { return !IsOut(theP); } 0333 0334 //! Returns True if the other box intersects or is inside this box. 0335 [[nodiscard]] bool Intersects(const Bnd_Box& theOther) const { return !IsOut(theOther); } 0336 0337 //! Computes the minimum distance between two boxes. 0338 [[nodiscard]] Standard_EXPORT double Distance(const Bnd_Box& Other) const; 0339 0340 Standard_EXPORT void Dump() const; 0341 0342 //! Computes the squared diagonal of me. 0343 [[nodiscard]] double SquareExtent() const noexcept 0344 { 0345 if (IsVoid()) 0346 { 0347 return 0.0; 0348 } 0349 0350 const double aDx = Xmax - Xmin + Gap + Gap; 0351 const double aDy = Ymax - Ymin + Gap + Gap; 0352 const double aDz = Zmax - Zmin + Gap + Gap; 0353 return aDx * aDx + aDy * aDy + aDz * aDz; 0354 } 0355 0356 //! Returns a finite part of an infinite bounding box (returns self if this is already finite 0357 //! box). This can be a Void box in case if its sides has been defined as infinite (Open) without 0358 //! adding any finite points. WARNING! This method relies on Open flags, the infinite points added 0359 //! using Add() method will be returned as is. 0360 [[nodiscard]] Bnd_Box FinitePart() const noexcept 0361 { 0362 if (!HasFinitePart()) 0363 { 0364 return Bnd_Box(); 0365 } 0366 0367 Bnd_Box aBox; 0368 aBox.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); 0369 aBox.SetGap(Gap); 0370 return aBox; 0371 } 0372 0373 //! Returns TRUE if this box has finite part. 0374 [[nodiscard]] bool HasFinitePart() const noexcept { return !IsVoid() && Xmax >= Xmin; } 0375 0376 //! Dumps the content of me into the stream 0377 Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const; 0378 0379 //! Inits the content of me from the stream 0380 Standard_EXPORT bool InitFromJson(const Standard_SStream& theSStream, int& theStreamPos); 0381 0382 protected: 0383 //! Bit flags. 0384 enum MaskFlags 0385 { 0386 VoidMask = 0x01, 0387 XminMask = 0x02, 0388 XmaxMask = 0x04, 0389 YminMask = 0x08, 0390 YmaxMask = 0x10, 0391 ZminMask = 0x20, 0392 ZmaxMask = 0x40, 0393 WholeMask = 0x7e 0394 }; 0395 0396 private: 0397 double Xmin = RealLast(); 0398 double Xmax = -RealLast(); 0399 double Ymin = RealLast(); 0400 double Ymax = -RealLast(); 0401 double Zmin = RealLast(); 0402 double Zmax = -RealLast(); 0403 double Gap = 0.0; 0404 int Flags = VoidMask; 0405 }; 0406 0407 #endif // _Bnd_Box_HeaderFile
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|