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