1 // Created on: 1991-03-08
2 // Created by: Christophe MARION
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 #include <Bnd_Box.hxx>
18 #include <gp_Dir.hxx>
19 #include <gp_Lin.hxx>
20 #include <gp_Pln.hxx>
21 #include <gp_Pnt.hxx>
22 #include <gp_Trsf.hxx>
23 #include <Standard_ConstructionError.hxx>
24 #include <Standard_Dump.hxx>
25 
26 // set the flag to one
27 #define ClearVoidFlag() ( Flags &= ~VoidMask )
28 
29 #include <Standard_Stream.hxx>
30 #include <gp.hxx>
31 // #include <Precision.hxx>
32 #define Bnd_Precision_Infinite 1e+100
33 
34 //=======================================================================
35 //function : Bnd_Box
36 //purpose  :
37 //=======================================================================
Bnd_Box()38 Bnd_Box::Bnd_Box()
39 : Xmin (RealLast()), Xmax (-RealLast()),
40   Ymin (RealLast()), Ymax (-RealLast()),
41   Zmin (RealLast()), Zmax (-RealLast()),
42   Gap (0.0)
43 {
44   SetVoid();
45 }
46 
47 //=======================================================================
48 //function : Bnd_Box
49 //purpose  :
50 //=======================================================================
Bnd_Box(const gp_Pnt theMin,const gp_Pnt theMax)51 Bnd_Box::Bnd_Box (const gp_Pnt theMin, const gp_Pnt theMax)
52 : Gap (0.0)
53 {
54   SetVoid();
55   Update (theMin.X(), theMin.Y(), theMin.Z(), theMax.X(), theMax.Y(), theMax.Z());
56 }
57 
58 
59 //=======================================================================
60 //function : Set
61 //purpose  :
62 //=======================================================================
63 
Set(const gp_Pnt & P)64 void Bnd_Box::Set(const gp_Pnt& P)
65 {
66   SetVoid();
67   Add(P);
68 }
69 
70 //=======================================================================
71 //function : Set
72 //purpose  :
73 //=======================================================================
74 
Set(const gp_Pnt & P,const gp_Dir & D)75 void Bnd_Box::Set(const gp_Pnt& P, const gp_Dir& D)
76 {
77   SetVoid();
78   Add(P,D);
79 }
80 
81 
82 //=======================================================================
83 //function : Update
84 //purpose  :
85 //=======================================================================
86 
Update(const Standard_Real x,const Standard_Real y,const Standard_Real z,const Standard_Real X,const Standard_Real Y,const Standard_Real Z)87 void Bnd_Box::Update (const Standard_Real x,
88 		      const Standard_Real y,
89 		      const Standard_Real z,
90 		      const Standard_Real X,
91 		      const Standard_Real Y,
92 		      const Standard_Real Z)
93 {
94   if (IsVoid())
95   {
96     Xmin = x;
97     Ymin = y;
98     Zmin = z;
99     Xmax = X;
100     Ymax = Y;
101     Zmax = Z;
102     ClearVoidFlag();
103   }
104   else
105   {
106     if (x < Xmin) Xmin = x;
107     if (X > Xmax) Xmax = X;
108     if (y < Ymin) Ymin = y;
109     if (Y > Ymax) Ymax = Y;
110     if (z < Zmin) Zmin = z;
111     if (Z > Zmax) Zmax = Z;
112   }
113 }
114 
115 //=======================================================================
116 //function : Update
117 //purpose  :
118 //=======================================================================
119 
Update(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)120 void Bnd_Box::Update (const Standard_Real X,
121 		      const Standard_Real Y,
122 		      const Standard_Real Z)
123 {
124   if (IsVoid())
125   {
126     Xmin = X;
127     Ymin = Y;
128     Zmin = Z;
129     Xmax = X;
130     Ymax = Y;
131     Zmax = Z;
132     ClearVoidFlag();
133   }
134   else {
135     if      (X < Xmin) Xmin = X;
136     else if (X > Xmax) Xmax = X;
137     if      (Y < Ymin) Ymin = Y;
138     else if (Y > Ymax) Ymax = Y;
139     if      (Z < Zmin) Zmin = Z;
140     else if (Z > Zmax) Zmax = Z;
141   }
142 }
143 
144 //=======================================================================
145 //function : GetGap
146 //purpose  :
147 //=======================================================================
148 
GetGap() const149 Standard_Real Bnd_Box::GetGap () const
150 {
151   return Gap;
152 }
153 
154 //=======================================================================
155 //function : SetGap
156 //purpose  :
157 //=======================================================================
158 
SetGap(const Standard_Real Tol)159 void Bnd_Box::SetGap (const Standard_Real Tol)
160 {
161   Gap = Tol;
162 }
163 
164 //=======================================================================
165 //function : Enlarge
166 //purpose  :
167 //=======================================================================
168 
Enlarge(const Standard_Real Tol)169 void Bnd_Box::Enlarge (const Standard_Real Tol)
170 {
171   Gap=Max(Gap, Abs(Tol));
172 }
173 
174 //=======================================================================
175 //function : Get
176 //purpose  :
177 //=======================================================================
178 
Get(Standard_Real & theXmin,Standard_Real & theYmin,Standard_Real & theZmin,Standard_Real & theXmax,Standard_Real & theYmax,Standard_Real & theZmax) const179 void Bnd_Box::Get (Standard_Real& theXmin,
180                    Standard_Real& theYmin,
181                    Standard_Real& theZmin,
182                    Standard_Real& theXmax,
183                    Standard_Real& theYmax,
184                    Standard_Real& theZmax) const
185 {
186   if (IsVoid())
187   {
188     throw Standard_ConstructionError("Bnd_Box is void");
189   }
190 
191   if (IsOpenXmin()) theXmin = -Bnd_Precision_Infinite;
192   else              theXmin = Xmin - Gap;
193   if (IsOpenXmax()) theXmax = Bnd_Precision_Infinite;
194   else              theXmax = Xmax + Gap;
195   if (IsOpenYmin()) theYmin = -Bnd_Precision_Infinite;
196   else              theYmin = Ymin - Gap;
197   if (IsOpenYmax()) theYmax = Bnd_Precision_Infinite;
198   else              theYmax = Ymax + Gap;
199   if (IsOpenZmin()) theZmin = -Bnd_Precision_Infinite;
200   else              theZmin = Zmin - Gap;
201   if (IsOpenZmax()) theZmax = Bnd_Precision_Infinite;
202   else              theZmax = Zmax + Gap;
203 }
204 
205 //=======================================================================
206 //function : CornerMin
207 //purpose  :
208 //=======================================================================
209 
CornerMin() const210 gp_Pnt Bnd_Box::CornerMin() const
211 {
212   gp_Pnt aCornerMin;
213   if (IsVoid())
214   {
215     throw Standard_ConstructionError("Bnd_Box is void");
216   }
217   if (IsOpenXmin()) aCornerMin.SetX (-Bnd_Precision_Infinite);
218   else              aCornerMin.SetX (Xmin - Gap);
219   if (IsOpenYmin()) aCornerMin.SetY (-Bnd_Precision_Infinite);
220   else              aCornerMin.SetY (Ymin - Gap);
221   if (IsOpenZmin()) aCornerMin.SetZ (-Bnd_Precision_Infinite);
222   else              aCornerMin.SetZ (Zmin - Gap);
223   return aCornerMin;
224 }
225 
226 //=======================================================================
227 //function : CornerMax
228 //purpose  :
229 //=======================================================================
230 
CornerMax() const231 gp_Pnt Bnd_Box::CornerMax() const
232 {
233   gp_Pnt aCornerMax;
234   if (IsVoid())
235   {
236     throw Standard_ConstructionError("Bnd_Box is void");
237   }
238   if (IsOpenXmax()) aCornerMax.SetX (Bnd_Precision_Infinite);
239   else              aCornerMax.SetX (Xmax + Gap);
240   if (IsOpenYmin()) aCornerMax.SetY (Bnd_Precision_Infinite);
241   else              aCornerMax.SetY (Ymax + Gap);
242   if (IsOpenZmin()) aCornerMax.SetZ (Bnd_Precision_Infinite);
243   else              aCornerMax.SetZ (Zmax + Gap);
244   return aCornerMax;
245 }
246 
247 //=======================================================================
248 //function : IsXThin
249 //purpose  :
250 //=======================================================================
251 
IsXThin(const Standard_Real tol) const252 Standard_Boolean Bnd_Box::IsXThin (const Standard_Real tol) const
253 {
254   if (IsWhole())       return Standard_False;
255   if (IsVoid())        return Standard_True;
256   if (IsOpenXmin())    return Standard_False;
257   if (IsOpenXmax())    return Standard_False;
258   if (Xmax-Xmin < tol) return Standard_True;
259   return Standard_False;
260 }
261 
262 //=======================================================================
263 //function : IsYThin
264 //purpose  :
265 //=======================================================================
266 
IsYThin(const Standard_Real tol) const267 Standard_Boolean Bnd_Box::IsYThin (const Standard_Real tol) const
268 {
269   if (IsWhole())       return Standard_False;
270   if (IsVoid())        return Standard_True;
271   if (IsOpenYmin())    return Standard_False;
272   if (IsOpenYmax())    return Standard_False;
273   if (Ymax-Ymin < tol) return Standard_True;
274   return Standard_False;
275 }
276 
277 //=======================================================================
278 //function : IsZThin
279 //purpose  :
280 //=======================================================================
281 
IsZThin(const Standard_Real tol) const282 Standard_Boolean Bnd_Box::IsZThin (const Standard_Real tol) const
283 {
284   if (IsWhole())       return Standard_False;
285   if (IsVoid())        return Standard_True;
286   if (IsOpenZmin())    return Standard_False;
287   if (IsOpenZmax())    return Standard_False;
288   if (Zmax-Zmin < tol) return Standard_True;
289   return Standard_False;
290 }
291 
292 //=======================================================================
293 //function : IsThin
294 //purpose  :
295 //=======================================================================
296 
IsThin(const Standard_Real tol) const297 Standard_Boolean Bnd_Box::IsThin (const Standard_Real tol) const
298 {
299   if (!IsXThin(tol)) return Standard_False;
300   if (!IsYThin(tol)) return Standard_False;
301   if (!IsZThin(tol)) return Standard_False;
302   return Standard_True;
303 }
304 
305 //=======================================================================
306 //function : Transformed
307 //purpose  :
308 //=======================================================================
309 
Transformed(const gp_Trsf & T) const310 Bnd_Box Bnd_Box::Transformed (const gp_Trsf& T) const
311 {
312   if (IsVoid())
313   {
314     return Bnd_Box();
315   }
316   else if (T.Form() == gp_Identity)
317   {
318     return *this;
319   }
320   else if (T.Form() == gp_Translation)
321   {
322     if (!HasFinitePart())
323     {
324       return *this;
325     }
326 
327     const gp_XYZ& aDelta = T.TranslationPart();
328     Bnd_Box aNewBox (*this);
329     aNewBox.Xmin += aDelta.X();
330     aNewBox.Xmax += aDelta.X();
331     aNewBox.Ymin += aDelta.Y();
332     aNewBox.Ymax += aDelta.Y();
333     aNewBox.Zmin += aDelta.Z();
334     aNewBox.Zmax += aDelta.Z();
335     return aNewBox;
336   }
337 
338   Bnd_Box aNewBox;
339   if (HasFinitePart())
340   {
341     gp_Pnt aCorners[8] =
342     {
343       gp_Pnt (Xmin, Ymin, Zmin),
344       gp_Pnt (Xmax, Ymin, Zmin),
345       gp_Pnt (Xmin, Ymax, Zmin),
346       gp_Pnt (Xmax, Ymax, Zmin),
347       gp_Pnt (Xmin, Ymin, Zmax),
348       gp_Pnt (Xmax, Ymin, Zmax),
349       gp_Pnt (Xmin, Ymax, Zmax),
350       gp_Pnt (Xmax, Ymax, Zmax),
351     };
352     for (Standard_Integer aCornerIter = 0; aCornerIter < 8; ++aCornerIter)
353     {
354       aCorners[aCornerIter].Transform (T);
355       aNewBox.Add (aCorners[aCornerIter]);
356     }
357   }
358   aNewBox.Gap = Gap;
359   if (!IsOpen())
360   {
361     return aNewBox;
362   }
363 
364   gp_Dir aDirs[6];
365   Standard_Integer aNbDirs = 0;
366   if (IsOpenXmin())
367   {
368     aDirs[aNbDirs++].SetCoord(-1., 0., 0.);
369   }
370   if (IsOpenXmax())
371   {
372     aDirs[aNbDirs++].SetCoord( 1., 0., 0.);
373   }
374   if (IsOpenYmin())
375   {
376     aDirs[aNbDirs++].SetCoord( 0.,-1., 0.);
377   }
378   if (IsOpenYmax())
379   {
380     aDirs[aNbDirs++].SetCoord( 0., 1., 0.);
381   }
382   if (IsOpenZmin())
383   {
384     aDirs[aNbDirs++].SetCoord( 0., 0.,-1.);
385   }
386   if (IsOpenZmax())
387   {
388     aDirs[aNbDirs++].SetCoord( 0., 0., 1.);
389   }
390 
391   for (Standard_Integer aDirIter = 0; aDirIter < aNbDirs; ++aDirIter)
392   {
393     aDirs[aDirIter].Transform (T);
394     aNewBox.Add (aDirs[aDirIter]);
395   }
396 
397   return aNewBox;
398 }
399 
400 //=======================================================================
401 //function : Add
402 //purpose  :
403 //=======================================================================
404 
Add(const Bnd_Box & Other)405 void Bnd_Box::Add (const Bnd_Box& Other)
406 {
407   if (Other.IsVoid())
408   {
409     return;
410   }
411   else if (IsVoid())
412   {
413     *this = Other;
414     return;
415   }
416 
417   if (Xmin > Other.Xmin) Xmin = Other.Xmin;
418   if (Xmax < Other.Xmax) Xmax = Other.Xmax;
419   if (Ymin > Other.Ymin) Ymin = Other.Ymin;
420   if (Ymax < Other.Ymax) Ymax = Other.Ymax;
421   if (Zmin > Other.Zmin) Zmin = Other.Zmin;
422   if (Zmax < Other.Zmax) Zmax = Other.Zmax;
423   Gap = Max (Gap, Other.Gap);
424 
425   if (IsWhole())
426   {
427     return;
428   }
429   else if (Other.IsWhole())
430   {
431     SetWhole();
432     return;
433   }
434 
435   if (Other.IsOpenXmin()) OpenXmin();
436   if (Other.IsOpenXmax()) OpenXmax();
437   if (Other.IsOpenYmin()) OpenYmin();
438   if (Other.IsOpenYmax()) OpenYmax();
439   if (Other.IsOpenZmin()) OpenZmin();
440   if (Other.IsOpenZmax()) OpenZmax();
441 }
442 
443 //=======================================================================
444 //function : Add
445 //purpose  :
446 //=======================================================================
447 
Add(const gp_Pnt & P)448 void Bnd_Box::Add (const gp_Pnt& P)
449 {
450   Standard_Real X,Y,Z;
451   P.Coord(X,Y,Z);
452   Update(X,Y,Z);
453 }
454 
455 //=======================================================================
456 //function : Add
457 //purpose  :
458 //=======================================================================
459 
Add(const gp_Pnt & P,const gp_Dir & D)460 void Bnd_Box::Add (const gp_Pnt& P, const gp_Dir& D)
461 {
462   Add(P);
463   Add(D);
464 }
465 
466 
467 //=======================================================================
468 //function : Add
469 //purpose  :
470 //=======================================================================
471 
Add(const gp_Dir & D)472 void Bnd_Box::Add (const gp_Dir& D)
473 {
474   Standard_Real DX,DY,DZ;
475   D.Coord(DX,DY,DZ);
476 
477   if (DX < -RealEpsilon())
478     OpenXmin();
479   else if (DX > RealEpsilon())
480     OpenXmax();
481 
482   if (DY < -RealEpsilon())
483     OpenYmin();
484   else if (DY > RealEpsilon())
485     OpenYmax();
486 
487   if (DZ < -RealEpsilon())
488     OpenZmin();
489   else if (DZ > RealEpsilon())
490     OpenZmax();
491 }
492 
493 //=======================================================================
494 //function : IsOut
495 //purpose  :
496 //=======================================================================
497 
IsOut(const gp_Pnt & P) const498 Standard_Boolean Bnd_Box::IsOut (const gp_Pnt& P) const
499 {
500   if        (IsWhole())  return Standard_False;
501   else if   (IsVoid())   return Standard_True;
502   else {
503     Standard_Real X,Y,Z;
504     P.Coord(X,Y,Z);
505     if      (!IsOpenXmin() && (X < (Xmin-Gap))) return Standard_True;
506     else if (!IsOpenXmax() && (X > (Xmax+Gap))) return Standard_True;
507     else if (!IsOpenYmin() && (Y < (Ymin-Gap))) return Standard_True;
508     else if (!IsOpenYmax() && (Y > (Ymax+Gap))) return Standard_True;
509     else if (!IsOpenZmin() && (Z < (Zmin-Gap))) return Standard_True;
510     else if (!IsOpenZmax() && (Z > (Zmax+Gap))) return Standard_True;
511     else return Standard_False;
512   }
513 }
514 
515 
516 //=======================================================================
517 //function : IsOut
518 //purpose  :
519 //=======================================================================
520 
IsOut(const gp_Pln & P) const521 Standard_Boolean Bnd_Box::IsOut (const gp_Pln& P) const
522 {
523   if        (IsWhole())  return Standard_False;
524   else if   (IsVoid())   return Standard_True;
525   else {
526     Standard_Real A,B,C,D;
527     P.Coefficients (A, B ,C ,D);
528     Standard_Real d = A * (Xmin-Gap) + B * (Ymin-Gap) + C * (Zmin-Gap) + D;
529 //    Standard_Boolean plus = d > 0;
530     Standard_Integer plus = d > 0;
531     if (plus != ((A*(Xmin-Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
532       return Standard_False;
533     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
534       return Standard_False;
535     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
536       return Standard_False;
537     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmin-Gap) + D) > 0))
538       return Standard_False;
539     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
540       return Standard_False;
541     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
542       return Standard_False;
543     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
544       return Standard_False;
545     else return Standard_True;
546   }
547 }
548 
549 //=======================================================================
550 //function : IsOut
551 //purpose  :
552 //=======================================================================
553 
IsOut(const gp_Lin & L) const554 Standard_Boolean Bnd_Box::IsOut (const gp_Lin& L) const
555 {
556   if        (IsWhole())  return Standard_False;
557   else if   (IsVoid())   return Standard_True;
558   else {
559     Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax;
560     Standard_Real parmin, parmax, par1, par2;
561     Standard_Boolean xToSet, yToSet;
562     Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
563     Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
564 
565     if (Abs(L.Direction().XYZ().X())>0.) {
566       par1=(myXmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
567       par2=(myXmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
568       parmin=Min(par1, par2);
569       parmax=Max(par1, par2);
570       xToSet=Standard_True;
571     }
572     else {
573       if (L.Location().XYZ().X()<myXmin || myXmax<L.Location().XYZ().X()) {
574 	return Standard_True;
575       }
576       xmin=L.Location().XYZ().X();
577       xmax=L.Location().XYZ().X();
578       parmin=-Bnd_Precision_Infinite;
579       parmax=Bnd_Precision_Infinite;
580       xToSet=Standard_False;
581     }
582 
583     if (Abs(L.Direction().XYZ().Y())>0.) {
584       par1=(myYmin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
585       par2=(myYmax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
586       //=================DET change 06/03/01====================
587       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
588 	return Standard_True;
589       //========================================================
590       parmin=Max(parmin, Min(par1,par2));
591       parmax=Min(parmax, Max(par1,par2));
592       yToSet=Standard_True;
593     }
594     else {
595       if (L.Location().XYZ().Y()<myYmin || myYmax<L.Location().XYZ().Y()) {
596 	return Standard_True;
597       }
598       ymin=L.Location().XYZ().Y();
599       ymax=L.Location().XYZ().Y();
600       yToSet=Standard_False;
601     }
602 
603     if (Abs(L.Direction().XYZ().Z())>0.) {
604       par1=(myZmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
605       par2=(myZmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
606       //=================DET change 06/03/01====================
607       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
608 	return Standard_True;
609       //========================================================
610       parmin=Max(parmin, Min(par1,par2));
611       parmax=Min(parmax, Max(par1,par2));
612       par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z();
613       par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z();
614       zmin=Min(par1, par2);
615       zmax=Max(par1, par2);
616     }
617     else {
618       if (L.Location().XYZ().Z()<myZmin || myZmax<L.Location().XYZ().Z())
619 	return Standard_True;
620       zmin=L.Location().XYZ().Z();
621       zmax=L.Location().XYZ().Z();
622     }
623     if (zmax<myZmin || myZmax<zmin) return Standard_True;
624 
625     if (xToSet) {
626       par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X();
627       par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X();
628       xmin=Min(par1, par2);
629       xmax=Max(par1, par2);
630     }
631     if (xmax<myXmin || myXmax<xmin) return Standard_True;
632 
633     if (yToSet) {
634       par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y();
635       par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y();
636       ymin=Min(par1, par2);
637       ymax=Max(par1, par2);
638     }
639     if (ymax<myYmin || myYmax<ymin) return Standard_True;
640   }
641   return Standard_False;
642 }
643 
644 //=======================================================================
645 //function : IsOut
646 //purpose  :
647 //=======================================================================
648 
IsOut(const Bnd_Box & Other) const649 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other) const
650 {
651   //modified by NIZNHY-PKV Fri Jul 08 11:03:43 2011f
652   if (!Flags && !Other.Flags) {
653     Standard_Boolean bRet;
654     Standard_Real delta;
655     //
656     delta = Other.Gap + Gap;
657     bRet=((Xmin - Other.Xmax > delta) ||
658 	  (Other.Xmin - Xmax > delta) ||
659 	  (Ymin - Other.Ymax > delta) ||
660 	  (Other.Ymin - Ymax > delta) ||
661 	  (Zmin - Other.Zmax > delta) ||
662 	  (Other.Zmin - Zmax > delta));
663     return bRet;
664   }
665   //modified by NIZNHY-PKV Fri Jul 08 11:03:46 2011t
666   if   (IsVoid())         return Standard_True;
667   if   (Other.IsVoid())   return Standard_True;
668   if   (IsWhole())        return Standard_False;
669   if   (Other.IsWhole())  return Standard_False;
670 
671   Standard_Real delta = Other.Gap + Gap;
672 
673   if (!IsOpenXmin() && !Other.IsOpenXmax())
674     if (Xmin - Other.Xmax > delta) return Standard_True;
675   if (!IsOpenXmax() && !Other.IsOpenXmin())
676     if (Other.Xmin - Xmax > delta) return Standard_True;
677 
678   if (!IsOpenYmin() && !Other.IsOpenYmax())
679     if (Ymin - Other.Ymax > delta) return Standard_True;
680   if (!IsOpenYmax() && !Other.IsOpenYmin())
681     if (Other.Ymin - Ymax > delta) return Standard_True;
682 
683   if (!IsOpenZmin() && !Other.IsOpenZmax())
684     if (Zmin - Other.Zmax > delta) return Standard_True;
685   if (!IsOpenZmax() && !Other.IsOpenZmin())
686     if (Other.Zmin - Zmax > delta) return Standard_True;
687 
688   return Standard_False;
689 }
690 
691 //=======================================================================
692 //function : IsOut
693 //purpose  :
694 //=======================================================================
695 
IsOut(const Bnd_Box & Other,const gp_Trsf & T) const696 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other,
697 				 const gp_Trsf& T) const
698 {
699   return IsOut(Other.Transformed(T));
700 }
701 
702 //=======================================================================
703 //function : IsOut
704 //purpose  :
705 //=======================================================================
706 
IsOut(const gp_Trsf & T1,const Bnd_Box & Other,const gp_Trsf & T2) const707 Standard_Boolean Bnd_Box::IsOut (const gp_Trsf& T1,
708 				 const Bnd_Box& Other,
709 				 const gp_Trsf& T2) const
710 {
711   return Transformed(T1).IsOut(Other.Transformed(T2));
712 }
713 
714 
715 //=======================================================================
716 //function : IsSegmentOut
717 //purpose  :
718 //=======================================================================
719 
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)720 static Standard_Boolean IsSegmentOut(Standard_Real x1,Standard_Real y1,
721                                      Standard_Real x2,Standard_Real y2,
722                                      Standard_Real xs1,Standard_Real ys1,
723                                      Standard_Real xs2,Standard_Real ys2)
724 {
725   Standard_Real eps = RealSmall();
726   Standard_Real xsmin = Min (xs1, xs2);
727   Standard_Real xsmax = Max (xs1, xs2);
728   Standard_Real ysmin = Min (ys1, ys2);
729   Standard_Real ysmax = Max (ys1, ys2);
730 
731   if (ysmax-ysmin < eps && (y1-ys1 < eps && ys1-y2 < eps) &&
732       ((xsmin-x1 < eps && x1-xsmax < eps) ||
733        (xsmin-x2 < eps && x2-xsmax < eps) ||
734        (x1-xs1 < eps && xs1-x2 < eps)))
735     return Standard_False;
736   if (xsmax-xsmin < eps && (x1-xs1 < eps && xs1-x2 < eps) &&
737       ((ysmin-y1 < eps && y1-ysmax < eps) ||
738        (ysmin-y2 < eps && y2-ysmax < eps) ||
739        (y1-ys1 < eps && ys1-y2 < eps)))
740     return Standard_False;
741 
742   if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) ||
743       (ys1 < y1 && ys2 < y1) || (ys1 > y2 && ys2 > y2) )
744     return Standard_True;
745 
746   if (Abs(xs2-xs1) > eps)
747   {
748     Standard_Real ya = ( Min(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
749     Standard_Real yb = ( Max(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
750     if ( (ya < y1 && yb < y1) || (ya > y2 && yb > y2) ) return Standard_True;
751   }
752   else if (Abs(ys2-ys1) > eps)
753   {
754     Standard_Real xa = ( Min(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
755     Standard_Real xb = ( Max(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
756     if ( (xa < x1 && xb < x1) || (xa > x2 && xb > x2) ) return Standard_True;
757   }
758   else
759     return Standard_True;
760 
761   return Standard_False;
762 }
763 
IsOut(const gp_Pnt & P1,const gp_Pnt & P2,const gp_Dir & D) const764 Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const
765 {
766 
767   if        (IsWhole())  return Standard_False;
768   else if   (IsVoid())   return Standard_True;
769 
770   Standard_Real eps = RealSmall();
771   Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
772   Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
773 
774   if(Abs(D.X()) < eps && Abs(D.Y()) < eps)
775     return IsSegmentOut(myXmin, myYmin, myXmax, myYmax, P1.X(), P1.Y(), P2.X(), P2.Y());
776 
777   if(Abs(D.X()) < eps && Abs(D.Z()) < eps)
778     return IsSegmentOut(myXmin, myZmin, myXmax, myZmax, P1.X(), P1.Z(), P2.X(), P2.Z());
779 
780   if(Abs(D.Y()) < eps && Abs(D.Z()) < eps)
781     return IsSegmentOut(myYmin, myZmin, myYmax, myZmax, P1.Y(), P1.Z(), P2.Y(), P2.Z());
782 
783   if(Abs(D.X()) < eps)
784   {
785     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
786                      P1.X(),(myYmin-P1.Y())*D.Z()/D.Y()+P1.Z(),
787                      P2.X(),(myYmin-P2.Y())*D.Z()/D.Y()+P2.Z()))
788       return Standard_False;
789 
790     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
791                      P1.X(),(myYmax-P1.Y())*D.Z()/D.Y()+P1.Z(),
792                      P2.X(),(myYmax-P2.Y())*D.Z()/D.Y()+P2.Z()))
793       return Standard_False;
794 
795     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
796                      P1.X(),(myZmin-P1.Z())*D.Y()/D.Z()+P1.Y(),
797                      P2.X(),(myZmin-P2.Z())*D.Y()/D.Z()+P2.Y()))
798       return Standard_False;
799 
800     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
801                      P1.X(),(myZmax-P1.Z())*D.Y()/D.Z()+P1.Y(),
802                      P2.X(),(myZmax-P2.Z())*D.Y()/D.Z()+P2.Y()))
803       return Standard_False;
804 
805     return Standard_True;
806   }//if(D.X() == 0)
807 
808   if(Abs(D.Y()) < eps)
809   {
810     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
811                      P1.Y(),(myXmin-P1.X())*D.Z()/D.X()+P1.Z(),
812                      P2.Y(),(myXmin-P2.X())*D.Z()/D.X()+P2.Z()))
813       return Standard_False;
814 
815     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
816                      P1.Y(),(myXmax-P1.X())*D.Z()/D.X()+P1.Z(),
817                      P2.Y(),(myXmax-P2.X())*D.Z()/D.X()+P2.Z()))
818       return Standard_False;
819 
820     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
821                      P1.Y(),(myZmin-P1.Z())*D.X()/D.Z()+P1.X(),
822                      P2.Y(),(myZmin-P2.Z())*D.X()/D.Z()+P2.X()))
823       return Standard_False;
824 
825     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
826                      P1.Y(),(myZmax-P1.Z())*D.X()/D.Z()+P1.X(),
827                      P2.Y(),(myZmax-P2.Z())*D.X()/D.Z()+P2.X()))
828       return Standard_False;
829 
830     return Standard_True;
831   }//if(D.Y() == 0)
832 
833   if(Abs(D.Z()) < eps)
834   {
835     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
836                      P1.Z(),(myYmax-P1.Y())*D.X()/D.Y()+P1.X(),
837                      P2.Z(),(myYmax-P2.Y())*D.X()/D.Y()+P2.X()))
838       return Standard_False;
839 
840     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
841                      P1.Z(),(myYmin-P1.Y())*D.X()/D.Y()+P1.X(),
842                      P2.Z(),(myYmin-P2.Y())*D.X()/D.Y()+P2.X()))
843       return Standard_False;
844 
845     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
846                      P1.Z(),(myXmax-P1.X())*D.Y()/D.X()+P1.Y(),
847                      P2.Z(),(myXmax-P2.X())*D.Y()/D.X()+P2.Y()))
848       return Standard_False;
849 
850     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
851                      P1.Z(),(myXmin-P1.X())*D.Y()/D.X()+P1.Y(),
852                      P2.Z(),(myXmin-P2.X())*D.Y()/D.X()+P2.Y()))
853       return Standard_False;
854 
855     return Standard_True;
856   }//if(D.Z() == 0)
857 
858   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
859                    (myYmin - P1.Y())/D.Y()*D.X() + P1.X(),
860                    (myYmin - P1.Y())/D.Y()*D.Z() + P1.Z(),
861                    (myYmin - P2.Y())/D.Y()*D.X() + P2.X(),
862                    (myYmin - P2.Y())/D.Y()*D.Z() + P2.Z()))
863     return Standard_False;
864 
865   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
866                    (myYmax - P1.Y())/D.Y()*D.X() + P1.X(),
867                    (myYmax - P1.Y())/D.Y()*D.Z() + P1.Z(),
868                    (myYmax - P2.Y())/D.Y()*D.X() + P2.X(),
869                    (myYmax - P2.Y())/D.Y()*D.Z() + P2.Z()))
870     return Standard_False;
871 
872   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
873                    (myZmin - P1.Z())/D.Z()*D.X() + P1.X(),
874                    (myZmin - P1.Z())/D.Z()*D.Y() + P1.Y(),
875                    (myZmin - P2.Z())/D.Z()*D.X() + P2.X(),
876                    (myZmin - P2.Z())/D.Z()*D.Y() + P2.Y()))
877     return Standard_False;
878 
879   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
880                    (myZmax - P1.Z())/D.Z()*D.X() + P1.X(),
881                    (myZmax - P1.Z())/D.Z()*D.Y() + P1.Y(),
882                    (myZmax - P2.Z())/D.Z()*D.X() + P2.X(),
883                    (myZmax - P2.Z())/D.Z()*D.Y() + P2.Y()))
884     return Standard_False;
885 
886   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
887                    (myXmin - P1.X())/D.X()*D.Z() + P1.Z(),
888                    (myXmin - P1.X())/D.X()*D.Y() + P1.Y(),
889                    (myXmin - P2.X())/D.X()*D.Z() + P2.Z(),
890                    (myXmin - P2.X())/D.X()*D.Y() + P2.Y()))
891     return Standard_False;
892 
893   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
894                    (myXmax - P1.X())/D.X()*D.Z() + P1.Z(),
895                    (myXmax - P1.X())/D.X()*D.Y() + P1.Y(),
896                    (myXmax - P2.X())/D.X()*D.Z() + P2.Z(),
897                    (myXmax - P2.X())/D.X()*D.Y() + P2.Y()))
898     return Standard_False;
899 
900   return Standard_True;
901 
902 }
903 
904 //=======================================================================
905 //function : Distance
906 //purpose  : computes the minimum distance between two boxes
907 //=======================================================================
908 
DistMini2Box(const Standard_Real r1min,const Standard_Real r1max,const Standard_Real r2min,const Standard_Real r2max)909 static Standard_Real DistMini2Box( const Standard_Real r1min, const  Standard_Real r1max,  const Standard_Real r2min, const  Standard_Real r2max)
910 {  Standard_Real   r1, r2;
911 
912    r1 = Square(r1min - r2max);
913    r2 = Square(r1max - r2min);
914    return (Min( r1, r2 ));
915 }
916 
917 
918 
Distance(const Bnd_Box & Other) const919 Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const
920 {  Standard_Real   xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1;
921    Standard_Real   xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2;
922    Standard_Real   dist_x, dist_y, dist_z, dist_t;
923 
924    Get( xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1);
925    Other.Get( xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2);
926 
927    if ( ((xminB1<= xminB2)&&( xminB2 <= xmaxB1)) || ((xminB2<= xminB1)&&( xminB1 <= xmaxB2)) )
928       { dist_x=0; }
929       else { dist_x= DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);}
930    if ( ((yminB1<= yminB2)&&( yminB2 <= ymaxB1)) || ((yminB2<= yminB1)&&( yminB1 <= ymaxB2)) )
931       { dist_y=0; }
932       else { dist_y= DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);}
933    if ( ((zminB1<= zminB2)&&( zminB2 <= zmaxB1)) || ((zminB2<= zminB1)&&( zminB1 <= zmaxB2)) )
934       { dist_z=0; }
935       else { dist_z= DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);}
936    dist_t = dist_x+ dist_y+ dist_z;
937    return( Sqrt ( dist_t));
938 }
939 
940 //=======================================================================
941 //function : Dump
942 //purpose  :
943 //=======================================================================
944 
Dump() const945 void Bnd_Box::Dump () const
946 {
947   std::cout << "Box3D : ";
948   if      (IsVoid())  std::cout << "Void";
949   else if (IsWhole()) std::cout << "Whole";
950   else {
951     std::cout << "\n Xmin : ";
952     if (IsOpenXmin()) std::cout << "Infinite";
953     else              std::cout << Xmin;
954     std::cout << "\n Xmax : ";
955     if (IsOpenXmax()) std::cout << "Infinite";
956     else              std::cout << Xmax;
957     std::cout << "\n Ymin : ";
958     if (IsOpenYmin()) std::cout << "Infinite";
959     else              std::cout << Ymin;
960     std::cout << "\n Ymax : ";
961     if (IsOpenYmax()) std::cout << "Infinite";
962     else              std::cout << Ymax;
963     std::cout << "\n Zmin : ";
964     if (IsOpenZmin()) std::cout << "Infinite";
965     else              std::cout << Zmin;
966     std::cout << "\n Zmax : ";
967     if (IsOpenZmax()) std::cout << "Infinite";
968     else              std::cout << Zmax;
969   }
970   std::cout << "\n Gap : " << Gap;
971   std::cout << "\n";
972 }
973 
974 //=======================================================================
975 //function : DumpJson
976 //purpose  :
977 //=======================================================================
DumpJson(Standard_OStream & theOStream,Standard_Integer) const978 void Bnd_Box::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
979 {
980   OCCT_DUMP_FIELD_VALUES_NUMERICAL (theOStream, "CornerMin", 3, Xmin, Ymin, Zmin)
981   OCCT_DUMP_FIELD_VALUES_NUMERICAL (theOStream, "CornerMax", 3, Xmax, Ymax, Zmax)
982 
983   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Gap)
984   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Flags)
985 }
986 
987 //=======================================================================
988 //function : InitFromJson
989 //purpose  :
990 //=======================================================================
InitFromJson(const Standard_SStream & theSStream,Standard_Integer & theStreamPos)991 Standard_Boolean Bnd_Box::InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos)
992 {
993   Standard_Integer aPos = theStreamPos;
994 
995   TCollection_AsciiString aStreamStr = Standard_Dump::Text (theSStream);
996   OCCT_INIT_VECTOR_CLASS (aStreamStr, "CornerMin", aPos, 3, &Xmin, &Ymin, &Zmin)
997   OCCT_INIT_VECTOR_CLASS (aStreamStr, "CornerMax", aPos, 3, &Xmax, &Ymax, &Zmax)
998 
999   OCCT_INIT_FIELD_VALUE_REAL (aStreamStr, aPos, Gap);
1000   OCCT_INIT_FIELD_VALUE_INTEGER (aStreamStr, aPos, Flags);
1001 
1002   theStreamPos = aPos;
1003   return Standard_True;
1004 }
1005