1 // Created on: 1991-01-28 2 // Created by: Remi Lequette 3 // Copyright (c) 1991-1999 Matra Datavision 4 // Copyright (c) 1999-2014 OPEN CASCADE SAS 5 // 6 // This file is part of Open CASCADE Technology software library. 7 // 8 // This library is free software; you can redistribute it and/or modify it under 9 // the terms of the GNU Lesser General Public License version 2.1 as published 10 // by the Free Software Foundation, with special exception defined in the file 11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 12 // distribution for complete text of the license and disclaimer of any warranty. 13 // 14 // Alternatively, this file may be used under the terms of Open CASCADE 15 // commercial license or contractual agreement. 16 17 #ifndef _Bnd_Box_HeaderFile 18 #define _Bnd_Box_HeaderFile 19 20 #include <Standard.hxx> 21 #include <Standard_DefineAlloc.hxx> 22 #include <Standard_Handle.hxx> 23 24 #include <gp_Pnt.hxx> 25 #include <Standard_Real.hxx> 26 #include <Standard_Integer.hxx> 27 #include <Standard_Boolean.hxx> 28 class gp_Pnt; 29 class gp_Dir; 30 class gp_Trsf; 31 class gp_Lin; 32 class gp_Pln; 33 34 35 //! Describes a bounding box in 3D space. 36 //! A bounding box is parallel to the axes of the coordinates 37 //! system. If it is finite, it is defined by the three intervals: 38 //! - [ Xmin,Xmax ], 39 //! - [ Ymin,Ymax ], 40 //! - [ Zmin,Zmax ]. 41 //! A bounding box may be infinite (i.e. open) in one or more 42 //! directions. It is said to be: 43 //! - OpenXmin if it is infinite on the negative side of the "X Direction"; 44 //! - OpenXmax if it is infinite on the positive side of the "X Direction"; 45 //! - OpenYmin if it is infinite on the negative side of the "Y Direction"; 46 //! - OpenYmax if it is infinite on the positive side of the "Y Direction"; 47 //! - OpenZmin if it is infinite on the negative side of the "Z Direction"; 48 //! - OpenZmax if it is infinite on the positive side of the "Z Direction"; 49 //! - WholeSpace if it is infinite in all six directions. In this 50 //! case, any point of the space is inside the box; 51 //! - Void if it is empty. In this case, there is no point included in the box. 52 //! A bounding box is defined by: 53 //! - six bounds (Xmin, Xmax, Ymin, Ymax, Zmin and 54 //! Zmax) which limit the bounding box if it is finite, 55 //! - eight flags (OpenXmin, OpenXmax, OpenYmin, 56 //! OpenYmax, OpenZmin, OpenZmax, 57 //! WholeSpace and Void) which describe the 58 //! bounding box if it is infinite or empty, and 59 //! - a gap, which is included on both sides in any direction 60 //! when consulting the finite bounds of the box. 61 class Bnd_Box 62 { 63 public: 64 65 DEFINE_STANDARD_ALLOC 66 67 68 //! Creates an empty Box. 69 //! The constructed box is qualified Void. Its gap is null. 70 Standard_EXPORT Bnd_Box(); 71 72 //! Creates a bounding box, it contains: 73 //! - minimum/maximum point of bounding box, 74 //! The constructed box is qualified Void. Its gap is null. 75 Standard_EXPORT Bnd_Box (const gp_Pnt theMin, const gp_Pnt theMax); 76 77 //! Sets this bounding box so that it covers the whole of 3D space. 78 //! It is infinitely long in all directions. SetWhole()79 void SetWhole() { Flags = WholeMask; } 80 81 //! Sets this bounding box so that it is empty. All points are outside a void box. SetVoid()82 void SetVoid() 83 { 84 Xmin = RealLast(); 85 Xmax = -RealLast(); 86 Ymin = RealLast(); 87 Ymax = -RealLast(); 88 Zmin = RealLast(); 89 Zmax = -RealLast(); 90 Flags = VoidMask; 91 Gap = 0.0; 92 } 93 94 //! Sets this bounding box so that it bounds 95 //! - the point P. This involves first setting this bounding box 96 //! to be void and then adding the point P. 97 Standard_EXPORT void Set (const gp_Pnt& P); 98 99 //! Sets this bounding box so that it bounds 100 //! the half-line defined by point P and direction D, i.e. all 101 //! points M defined by M=P+u*D, where u is greater than 102 //! or equal to 0, are inside the bounding volume. This 103 //! involves first setting this box to be void and then adding the half-line. 104 Standard_EXPORT void Set (const gp_Pnt& P, const gp_Dir& D); 105 106 //! Enlarges this bounding box, if required, so that it 107 //! contains at least: 108 //! - interval [ aXmin,aXmax ] in the "X Direction", 109 //! - interval [ aYmin,aYmax ] in the "Y Direction", 110 //! - interval [ aZmin,aZmax ] in the "Z Direction"; 111 Standard_EXPORT void Update (const Standard_Real aXmin, const Standard_Real aYmin, const Standard_Real aZmin, const Standard_Real aXmax, const Standard_Real aYmax, const Standard_Real aZmax); 112 113 //! Adds a point of coordinates (X,Y,Z) to this bounding box. 114 Standard_EXPORT void Update (const Standard_Real X, const Standard_Real Y, const Standard_Real Z); 115 116 //! Returns the gap of this bounding box. 117 Standard_EXPORT Standard_Real GetGap() const; 118 119 //! Set the gap of this bounding box to abs(Tol). 120 Standard_EXPORT void SetGap (const Standard_Real Tol); 121 122 //! Enlarges the box with a tolerance value. 123 //! (minvalues-Abs(<tol>) and maxvalues+Abs(<tol>)) 124 //! This means that the minimum values of its X, Y and Z 125 //! intervals of definition, when they are finite, are reduced by 126 //! the absolute value of Tol, while the maximum values are 127 //! increased by the same amount. 128 Standard_EXPORT void Enlarge (const Standard_Real Tol); 129 130 //! Returns the bounds of this bounding box. The gap is included. 131 //! If this bounding box is infinite (i.e. "open"), returned values 132 //! may be equal to +/- Precision::Infinite(). 133 //! Standard_ConstructionError exception will be thrown if the box is void. 134 //! if IsVoid() 135 Standard_EXPORT void Get (Standard_Real& theXmin, Standard_Real& theYmin, Standard_Real& theZmin, Standard_Real& theXmax, Standard_Real& theYmax, Standard_Real& theZmax) const; 136 137 //! Returns the lower corner of this bounding box. The gap is included. 138 //! If this bounding box is infinite (i.e. "open"), returned values 139 //! may be equal to +/- Precision::Infinite(). 140 //! Standard_ConstructionError exception will be thrown if the box is void. 141 //! if IsVoid() 142 Standard_EXPORT gp_Pnt CornerMin() const; 143 144 //! Returns the upper corner of this bounding box. The gap is included. 145 //! If this bounding box is infinite (i.e. "open"), returned values 146 //! may be equal to +/- Precision::Infinite(). 147 //! Standard_ConstructionError exception will be thrown if the box is void. 148 //! if IsVoid() 149 Standard_EXPORT gp_Pnt CornerMax() const; 150 151 //! The Box will be infinitely long in the Xmin 152 //! direction. OpenXmin()153 void OpenXmin() { Flags |= XminMask; } 154 155 //! The Box will be infinitely long in the Xmax 156 //! direction. OpenXmax()157 void OpenXmax() { Flags |= XmaxMask; } 158 159 //! The Box will be infinitely long in the Ymin 160 //! direction. OpenYmin()161 void OpenYmin() { Flags |= YminMask; } 162 163 //! The Box will be infinitely long in the Ymax 164 //! direction. OpenYmax()165 void OpenYmax() { Flags |= YmaxMask; } 166 167 //! The Box will be infinitely long in the Zmin 168 //! direction. OpenZmin()169 void OpenZmin() { Flags |= ZminMask; } 170 171 //! The Box will be infinitely long in the Zmax 172 //! direction. OpenZmax()173 void OpenZmax() { Flags |= ZmaxMask; } 174 175 //! Returns true if this bounding box has at least one open direction. IsOpen() const176 Standard_Boolean IsOpen() const { return (Flags & WholeMask) != 0; } 177 178 //! Returns true if this bounding box is open in the Xmin direction. IsOpenXmin() const179 Standard_Boolean IsOpenXmin() const { return (Flags & XminMask) != 0; } 180 181 //! Returns true if this bounding box is open in the Xmax direction. IsOpenXmax() const182 Standard_Boolean IsOpenXmax() const { return (Flags & XmaxMask) != 0; } 183 184 //! Returns true if this bounding box is open in the Ymix direction. IsOpenYmin() const185 Standard_Boolean IsOpenYmin() const { return (Flags & YminMask) != 0; } 186 187 //! Returns true if this bounding box is open in the Ymax direction. IsOpenYmax() const188 Standard_Boolean IsOpenYmax() const { return (Flags & YmaxMask) != 0; } 189 190 //! Returns true if this bounding box is open in the Zmin direction. IsOpenZmin() const191 Standard_Boolean IsOpenZmin() const { return (Flags & ZminMask) != 0; } 192 193 //! Returns true if this bounding box is open in the Zmax direction. IsOpenZmax() const194 Standard_Boolean IsOpenZmax() const { return (Flags & ZmaxMask) != 0; } 195 196 //! Returns true if this bounding box is infinite in all 6 directions (WholeSpace flag). IsWhole() const197 Standard_Boolean IsWhole() const { return (Flags & WholeMask) == WholeMask; } 198 199 //! Returns true if this bounding box is empty (Void flag). IsVoid() const200 Standard_Boolean IsVoid() const { return (Flags & VoidMask) != 0; } 201 202 //! true if xmax-xmin < tol. 203 Standard_EXPORT Standard_Boolean IsXThin (const Standard_Real tol) const; 204 205 //! true if ymax-ymin < tol. 206 Standard_EXPORT Standard_Boolean IsYThin (const Standard_Real tol) const; 207 208 //! true if zmax-zmin < tol. 209 Standard_EXPORT Standard_Boolean IsZThin (const Standard_Real tol) const; 210 211 //! Returns true if IsXThin, IsYThin and IsZThin are all true, 212 //! i.e. if the box is thin in all three dimensions. 213 Standard_EXPORT Standard_Boolean IsThin (const Standard_Real tol) const; 214 215 //! Returns a bounding box which is the result of applying the 216 //! transformation T to this bounding box. 217 //! Warning 218 //! Applying a geometric transformation (for example, a 219 //! rotation) to a bounding box generally increases its 220 //! dimensions. This is not optimal for algorithms which use it. 221 Standard_NODISCARD Standard_EXPORT Bnd_Box Transformed (const gp_Trsf& T) const; 222 223 //! Adds the box <Other> to <me>. 224 Standard_EXPORT void Add (const Bnd_Box& Other); 225 226 //! Adds a Pnt to the box. 227 Standard_EXPORT void Add (const gp_Pnt& P); 228 229 //! Extends <me> from the Pnt <P> in the direction <D>. 230 Standard_EXPORT void Add (const gp_Pnt& P, const gp_Dir& D); 231 232 //! Extends the Box in the given Direction, i.e. adds 233 //! an half-line. The box may become infinite in 234 //! 1,2 or 3 directions. 235 Standard_EXPORT void Add (const gp_Dir& D); 236 237 //! Returns True if the Pnt is out the box. 238 Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt& P) const; 239 240 //! Returns False if the line intersects the box. 241 Standard_EXPORT Standard_Boolean IsOut (const gp_Lin& L) const; 242 243 //! Returns False if the plane intersects the box. 244 Standard_EXPORT Standard_Boolean IsOut (const gp_Pln& P) const; 245 246 //! Returns False if the <Box> intersects or is inside <me>. 247 Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box& Other) const; 248 249 //! Returns False if the transformed <Box> intersects 250 //! or is inside <me>. 251 Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box& Other, const gp_Trsf& T) const; 252 253 //! Returns False if the transformed <Box> intersects 254 //! or is inside the transformed box <me>. 255 Standard_EXPORT Standard_Boolean IsOut (const gp_Trsf& T1, const Bnd_Box& Other, const gp_Trsf& T2) const; 256 257 //! Returns False if the flat band lying between two parallel 258 //! lines represented by their reference points <P1>, <P2> and 259 //! direction <D> intersects the box. 260 Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const; 261 262 //! Computes the minimum distance between two boxes. 263 Standard_EXPORT Standard_Real Distance (const Bnd_Box& Other) const; 264 265 Standard_EXPORT void Dump() const; 266 267 //! Computes the squared diagonal of me. SquareExtent() const268 Standard_Real SquareExtent() const 269 { 270 if (IsVoid()) 271 { 272 return 0.0; 273 } 274 275 const Standard_Real aDx = Xmax - Xmin + Gap + Gap; 276 const Standard_Real aDy = Ymax - Ymin + Gap + Gap; 277 const Standard_Real aDz = Zmax - Zmin + Gap + Gap; 278 return aDx * aDx + aDy * aDy + aDz * aDz; 279 } 280 281 //! Returns a finite part of an infinite bounding box (returns self if this is already finite box). 282 //! This can be a Void box in case if its sides has been defined as infinite (Open) without adding any finite points. 283 //! WARNING! This method relies on Open flags, the infinite points added using Add() method will be returned as is. FinitePart() const284 Bnd_Box FinitePart() const 285 { 286 if (!HasFinitePart()) 287 { 288 return Bnd_Box(); 289 } 290 291 Bnd_Box aBox; 292 aBox.Update (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); 293 aBox.SetGap (Gap); 294 return aBox; 295 } 296 297 //! Returns TRUE if this box has finite part. HasFinitePart() const298 Standard_Boolean HasFinitePart() const 299 { 300 return !IsVoid() 301 && Xmax >= Xmin; 302 } 303 304 //! Dumps the content of me into the stream 305 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; 306 307 //! Inits the content of me from the stream 308 Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos); 309 310 protected: 311 312 //! Bit flags. 313 enum MaskFlags 314 { 315 VoidMask = 0x01, 316 XminMask = 0x02, 317 XmaxMask = 0x04, 318 YminMask = 0x08, 319 YmaxMask = 0x10, 320 ZminMask = 0x20, 321 ZmaxMask = 0x40, 322 WholeMask = 0x7e 323 }; 324 325 private: 326 327 Standard_Real Xmin; 328 Standard_Real Xmax; 329 Standard_Real Ymin; 330 Standard_Real Ymax; 331 Standard_Real Zmin; 332 Standard_Real Zmax; 333 Standard_Real Gap; 334 Standard_Integer Flags; 335 336 }; 337 338 #endif // _Bnd_Box_HeaderFile 339