0024177: Eliminate CLang compiler warning -Wlogical-op-parentheses (&& within ||)
[occt.git] / src / Bnd / Bnd_Box.cxx
1 // Created on: 1991-03-08
2 // Created by: Christophe MARION
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 #include <Bnd_Box.ixx>
22
23 #define VoidMask  0x01
24 #define XminMask  0x02
25 #define XmaxMask  0x04
26 #define YminMask  0x08
27 #define YmaxMask  0x10
28 #define ZminMask  0x20
29 #define ZmaxMask  0x40
30 #define WholeMask 0x7e
31
32 // Standard_True if the flag is one
33 #define VoidFlag()  ( Flags & VoidMask )
34 #define XminFlag()  ( Flags & XminMask )
35 #define XmaxFlag()  ( Flags & XmaxMask )
36 #define YminFlag()  ( Flags & YminMask )
37 #define YmaxFlag()  ( Flags & YmaxMask )
38 #define ZminFlag()  ( Flags & ZminMask )
39 #define ZmaxFlag()  ( Flags & ZmaxMask )
40 #define WholeFlag() ( (Flags & WholeMask) == WholeMask )
41
42 // set the flag to one
43 #define SetVoidFlag()  ( Flags = VoidMask )
44 #define SetXminFlag()  ( Flags |= XminMask )
45 #define SetXmaxFlag()  ( Flags |= XmaxMask )
46 #define SetYminFlag()  ( Flags |= YminMask )
47 #define SetYmaxFlag()  ( Flags |= YmaxMask )
48 #define SetZminFlag()  ( Flags |= ZminMask )
49 #define SetZmaxFlag()  ( Flags |= ZmaxMask )
50 #define SetWholeFlag() ( Flags = WholeMask )
51
52 #define ClearVoidFlag() ( Flags &= ~VoidMask )
53
54 #include <Standard_Stream.hxx>
55 #include <gp.hxx>
56 // #include <Precision.hxx>
57 #define Bnd_Precision_Infinite 1e+100
58
59 //=======================================================================
60 //function : Bnd_Box
61 //purpose  : 
62 //=======================================================================
63
64 Bnd_Box::Bnd_Box()
65      : Xmin(0.), Xmax(0.), Ymin(0.), Ymax(0.),  Zmin(0.), Zmax(0.), Gap(0.)
66 {
67   SetVoid();
68 }
69
70 //=======================================================================
71 //function : SetWhole
72 //purpose  : 
73 //=======================================================================
74
75 void Bnd_Box::SetWhole ()
76 {
77   SetWholeFlag();
78 }
79
80 //=======================================================================
81 //function : SetVoid
82 //purpose  : 
83 //=======================================================================
84
85 void Bnd_Box::SetVoid ()
86 {
87   SetVoidFlag();
88   Gap=0.;
89 }
90
91 //=======================================================================
92 //function : Set
93 //purpose  : 
94 //=======================================================================
95
96 void Bnd_Box::Set(const gp_Pnt& P)
97 {
98   SetVoid();
99   Add(P);
100 }
101
102 //=======================================================================
103 //function : Set
104 //purpose  : 
105 //=======================================================================
106
107 void Bnd_Box::Set(const gp_Pnt& P, const gp_Dir& D)
108 {
109   SetVoid();
110   Add(P,D);
111 }
112
113
114 //=======================================================================
115 //function : Update
116 //purpose  : 
117 //=======================================================================
118
119 void Bnd_Box::Update (const Standard_Real x,
120                       const Standard_Real y, 
121                       const Standard_Real z, 
122                       const Standard_Real X,
123                       const Standard_Real Y, 
124                       const Standard_Real Z)
125 {
126   if (VoidFlag()) {
127     Xmin = x;
128     Ymin = y;
129     Zmin = z;
130     Xmax = X;
131     Ymax = Y;
132     Zmax = Z;
133     ClearVoidFlag();
134   }
135   else {
136     if (!XminFlag() && (x < Xmin)) Xmin = x;
137     if (!XmaxFlag() && (X > Xmax)) Xmax = X;
138     if (!YminFlag() && (y < Ymin)) Ymin = y;
139     if (!YmaxFlag() && (Y > Ymax)) Ymax = Y;
140     if (!ZminFlag() && (z < Zmin)) Zmin = z;
141     if (!ZmaxFlag() && (Z > Zmax)) Zmax = Z;
142   }
143 }
144
145 //=======================================================================
146 //function : Update
147 //purpose  : 
148 //=======================================================================
149
150 void Bnd_Box::Update (const Standard_Real X,
151                       const Standard_Real Y,
152                       const Standard_Real Z)
153 {
154   if (VoidFlag()) {
155     Xmin = X;
156     Ymin = Y;
157     Zmin = Z;
158     Xmax = X;
159     Ymax = Y;
160     Zmax = Z;
161     ClearVoidFlag();
162   }
163   else {
164     if      (!XminFlag() && (X < Xmin)) Xmin = X;
165     else if (!XmaxFlag() && (X > Xmax)) Xmax = X;
166     if      (!YminFlag() && (Y < Ymin)) Ymin = Y;
167     else if (!YmaxFlag() && (Y > Ymax)) Ymax = Y;
168     if      (!ZminFlag() && (Z < Zmin)) Zmin = Z;
169     else if (!ZmaxFlag() && (Z > Zmax)) Zmax = Z;
170   }
171 }
172
173 //=======================================================================
174 //function : GetGap
175 //purpose  : 
176 //=======================================================================
177
178 Standard_Real Bnd_Box::GetGap () const
179 {
180   return Gap;
181 }
182
183 //=======================================================================
184 //function : SetGap
185 //purpose  : 
186 //=======================================================================
187
188 void Bnd_Box::SetGap (const Standard_Real Tol)
189 {
190   Gap = Tol;
191 }
192
193 //=======================================================================
194 //function : Enlarge
195 //purpose  : 
196 //=======================================================================
197
198 void Bnd_Box::Enlarge (const Standard_Real Tol)
199 {
200   Gap=Max(Gap, Abs(Tol));
201 }
202
203 //=======================================================================
204 //function : Get
205 //purpose  : 
206 //=======================================================================
207
208 void Bnd_Box::Get (Standard_Real& x, 
209                    Standard_Real& y, 
210                    Standard_Real& z, 
211                    Standard_Real& X, 
212                    Standard_Real& Y, 
213                    Standard_Real& Z) const
214 {
215   if(VoidFlag())
216     Standard_ConstructionError::Raise("Bnd_Box is void");
217   if (XminFlag())  x = -Bnd_Precision_Infinite;
218   else             x = Xmin-Gap;
219   if (XmaxFlag())  X = Bnd_Precision_Infinite;
220   else             X = Xmax+Gap;
221   if (YminFlag())  y = -Bnd_Precision_Infinite;
222   else             y = Ymin-Gap;
223   if (YmaxFlag())  Y = Bnd_Precision_Infinite;
224   else             Y = Ymax+Gap;
225   if (ZminFlag())  z = -Bnd_Precision_Infinite;
226   else             z = Zmin-Gap;
227   if (ZmaxFlag())  Z = Bnd_Precision_Infinite;
228   else             Z = Zmax+Gap;
229 }
230
231 //=======================================================================
232 //function : OpenXmin
233 //purpose  : 
234 //=======================================================================
235
236 void Bnd_Box::OpenXmin ()
237 {
238   SetXminFlag();
239 }
240
241 //=======================================================================
242 //function : OpenXmax
243 //purpose  : 
244 //=======================================================================
245
246 void Bnd_Box::OpenXmax ()
247 {
248   SetXmaxFlag();
249 }
250
251 //=======================================================================
252 //function : OpenYmin
253 //purpose  : 
254 //=======================================================================
255
256 void Bnd_Box::OpenYmin ()
257 {
258   SetYminFlag();
259 }
260
261 //=======================================================================
262 //function : OpenYmax
263 //purpose  : 
264 //=======================================================================
265
266 void Bnd_Box::OpenYmax ()
267 {
268   SetYmaxFlag();
269 }
270
271 //=======================================================================
272 //function : OpenZmin
273 //purpose  : 
274 //=======================================================================
275
276 void Bnd_Box::OpenZmin ()
277 {
278   SetZminFlag();
279 }
280
281 //=======================================================================
282 //function : OpenZmax
283 //purpose  : 
284 //=======================================================================
285
286 void Bnd_Box::OpenZmax ()
287 {
288   SetZmaxFlag();
289 }
290
291 //=======================================================================
292 //function : IsOpenXmin
293 //purpose  : 
294 //=======================================================================
295
296 Standard_Boolean Bnd_Box::IsOpenXmin () const
297 {
298   return XminFlag();
299 }
300
301 //=======================================================================
302 //function : IsOpenXmax
303 //purpose  : 
304 //=======================================================================
305
306 Standard_Boolean Bnd_Box::IsOpenXmax () const
307 {
308   return XmaxFlag();
309 }
310
311 //=======================================================================
312 //function : IsOpenYmin
313 //purpose  : 
314 //=======================================================================
315
316 Standard_Boolean Bnd_Box::IsOpenYmin () const
317 {
318   return YminFlag();
319 }
320
321 //=======================================================================
322 //function : IsOpenYmax
323 //purpose  : 
324 //=======================================================================
325
326 Standard_Boolean Bnd_Box::IsOpenYmax () const
327 {
328   return YmaxFlag();
329 }
330
331 //=======================================================================
332 //function : IsOpenZmin
333 //purpose  : 
334 //=======================================================================
335
336 Standard_Boolean Bnd_Box::IsOpenZmin () const
337 {
338   return ZminFlag();
339 }
340
341 //=======================================================================
342 //function : IsOpenZmax
343 //purpose  : 
344 //=======================================================================
345
346 Standard_Boolean Bnd_Box::IsOpenZmax () const
347 {
348   return ZmaxFlag();
349 }
350
351 //=======================================================================
352 //function : IsWhole
353 //purpose  : 
354 //=======================================================================
355
356 Standard_Boolean Bnd_Box::IsWhole () const
357 {
358   return WholeFlag();
359 }
360
361 //=======================================================================
362 //function : IsVoid
363 //purpose  : 
364 //=======================================================================
365
366 Standard_Boolean Bnd_Box::IsVoid () const
367 {
368   return VoidFlag();
369 }
370
371 //=======================================================================
372 //function : IsXThin
373 //purpose  : 
374 //=======================================================================
375
376 Standard_Boolean Bnd_Box::IsXThin (const Standard_Real tol) const
377 {
378   if (IsWhole())       return Standard_False;
379   if (IsVoid())        return Standard_True;
380   if (XminFlag())      return Standard_False;
381   if (XmaxFlag())      return Standard_False;
382   if (Xmax-Xmin < tol) return Standard_True;
383   return Standard_False;
384 }
385
386 //=======================================================================
387 //function : IsYThin
388 //purpose  : 
389 //=======================================================================
390
391 Standard_Boolean Bnd_Box::IsYThin (const Standard_Real tol) const
392 {
393   if (IsWhole())       return Standard_False;
394   if (IsVoid())        return Standard_True;
395   if (YminFlag())      return Standard_False;
396   if (YmaxFlag())      return Standard_False;
397   if (Ymax-Ymin < tol) return Standard_True;
398   return Standard_False;
399 }
400
401 //=======================================================================
402 //function : IsZThin
403 //purpose  : 
404 //=======================================================================
405
406 Standard_Boolean Bnd_Box::IsZThin (const Standard_Real tol) const
407 {
408   if (IsWhole())       return Standard_False;
409   if (IsVoid())        return Standard_True;
410   if (ZminFlag())      return Standard_False;
411   if (ZmaxFlag())      return Standard_False;
412   if (Zmax-Zmin < tol) return Standard_True;
413   return Standard_False;
414 }
415
416 //=======================================================================
417 //function : IsThin
418 //purpose  : 
419 //=======================================================================
420
421 Standard_Boolean Bnd_Box::IsThin (const Standard_Real tol) const
422 {
423   if (!IsXThin(tol)) return Standard_False;
424   if (!IsYThin(tol)) return Standard_False;
425   if (!IsZThin(tol)) return Standard_False;
426   return Standard_True;
427 }
428
429 //=======================================================================
430 //function : Transformed
431 //purpose  : 
432 //=======================================================================
433
434 Bnd_Box Bnd_Box::Transformed (const gp_Trsf& T) const
435 {
436   gp_TrsfForm F = T.Form();
437   Bnd_Box newb(*this);
438   if ( IsVoid() ) return newb;
439
440   if      (F == gp_Identity) {}
441   else if (F == gp_Translation) {
442     Standard_Real DX,DY,DZ;
443     (T.TranslationPart()).Coord(DX,DY,DZ);
444     if (!XminFlag())  newb.Xmin += DX;
445     if (!XmaxFlag())  newb.Xmax += DX;
446     if (!YminFlag())  newb.Ymin += DY;
447     if (!YmaxFlag())  newb.Ymax += DY;
448     if (!ZminFlag())  newb.Zmin += DZ;
449     if (!ZmaxFlag())  newb.Zmax += DZ;
450   }
451   else {
452     gp_Pnt P[8];
453     Standard_Boolean Vertex[8];
454     Standard_Integer i;
455     for (i=0;i<8;i++) Vertex[i] = Standard_True;
456     gp_Dir D[6];
457 //    Standard_Integer vertices = 0;
458     Standard_Integer directions = 0;
459
460     if (XminFlag()) {
461       directions++;
462       D[directions-1].SetCoord(-1., 0., 0.);
463       Vertex[0] = Vertex[2] = Vertex[4] = Vertex[6] = Standard_False;
464     }
465     if (XmaxFlag()) {
466       directions++;
467       D[directions-1].SetCoord( 1., 0., 0.);
468       Vertex[1] = Vertex[3] = Vertex[5] = Vertex[7] = Standard_False;
469     }
470     if (YminFlag()) {
471       directions++;
472       D[directions-1].SetCoord( 0.,-1., 0.);
473       Vertex[0] = Vertex[1] = Vertex[4] = Vertex[5] = Standard_False;
474     }
475     if (YmaxFlag()) {
476       directions++;
477       D[directions-1].SetCoord( 0., 1., 0.);
478       Vertex[2] = Vertex[3] = Vertex[6] = Vertex[7] = Standard_False;
479     }
480     if (ZminFlag()) {
481       directions++;
482       D[directions-1].SetCoord( 0., 0.,-1.);
483       Vertex[0] = Vertex[1] = Vertex[2] = Vertex[3] = Standard_False;
484     }
485     if (ZmaxFlag()) {
486       directions++;
487       D[directions-1].SetCoord( 0., 0., 1.);
488       Vertex[4] = Vertex[5] = Vertex[6] = Vertex[7] = Standard_False;
489     }
490
491     newb.SetVoid();
492     for (i=0;i<directions;i++) {
493       D[i].Transform(T);
494       newb.Add(D[i]);
495     }
496     P[0].SetCoord(Xmin,Ymin,Zmin);
497     P[1].SetCoord(Xmax,Ymin,Zmin);
498     P[2].SetCoord(Xmin,Ymax,Zmin);
499     P[3].SetCoord(Xmax,Ymax,Zmin);
500     P[4].SetCoord(Xmin,Ymin,Zmax);
501     P[5].SetCoord(Xmax,Ymin,Zmax);
502     P[6].SetCoord(Xmin,Ymax,Zmax);
503     P[7].SetCoord(Xmax,Ymax,Zmax);
504     for (i=0;i<8;i++) {
505       if (Vertex[i]) {
506         P[i].Transform(T);
507         newb.Add(P[i]);
508       }
509     }
510     newb.Gap=Gap;
511   }
512   return newb;
513 }
514
515 //=======================================================================
516 //function : Add
517 //purpose  : 
518 //=======================================================================
519
520 void Bnd_Box::Add (const Bnd_Box& Other)
521 {
522   if (IsWhole()) return;
523   else if (Other.IsVoid()) return; 
524   else if (Other.IsWhole()) SetWhole();
525   else if (IsVoid()) (*this) = Other;
526   else
527   {
528     if ( ! IsOpenXmin() )
529     {
530       if (Other.IsOpenXmin()) OpenXmin();
531       else if (Xmin > Other.Xmin) Xmin = Other.Xmin;
532     }
533     if ( ! IsOpenXmax() )
534     {
535       if (Other.IsOpenXmax()) OpenXmax();
536       else if (Xmax < Other.Xmax) Xmax = Other.Xmax;
537     }
538     if ( ! IsOpenYmin() )
539     {
540       if (Other.IsOpenYmin()) OpenYmin();
541       else if (Ymin > Other.Ymin) Ymin = Other.Ymin;
542     }
543     if ( ! IsOpenYmax() )
544     {
545       if (Other.IsOpenYmax()) OpenYmax();
546       else if (Ymax < Other.Ymax) Ymax = Other.Ymax;
547     }
548     if ( ! IsOpenZmin() )
549     {
550       if (Other.IsOpenZmin()) OpenZmin();
551       else if (Zmin > Other.Zmin) Zmin = Other.Zmin;
552     }
553     if ( ! IsOpenZmax() )
554     {
555       if (Other.IsOpenZmax()) OpenZmax();
556       else if (Zmax < Other.Zmax) Zmax = Other.Zmax;
557     }
558     Gap = Max (Gap, Other.Gap);
559   }
560 }
561
562 //=======================================================================
563 //function : Add
564 //purpose  : 
565 //=======================================================================
566
567 void Bnd_Box::Add (const gp_Pnt& P)
568 {
569   Standard_Real X,Y,Z;
570   P.Coord(X,Y,Z);
571   Update(X,Y,Z);
572 }
573
574 //=======================================================================
575 //function : Add
576 //purpose  : 
577 //=======================================================================
578
579 void Bnd_Box::Add (const gp_Pnt& P, const gp_Dir& D)
580 {
581   Add(P);
582   Add(D);
583 }
584
585
586 //=======================================================================
587 //function : Add
588 //purpose  : 
589 //=======================================================================
590
591 void Bnd_Box::Add (const gp_Dir& D)
592 {
593   Standard_Real DX,DY,DZ;
594   D.Coord(DX,DY,DZ);
595
596   if (DX < -RealEpsilon()) 
597     OpenXmin();
598   else if (DX > RealEpsilon()) 
599     OpenXmax();
600
601   if (DY < -RealEpsilon())
602     OpenYmin();
603   else if (DY > RealEpsilon())
604     OpenYmax();
605
606   if (DZ < -RealEpsilon())
607     OpenZmin();
608   else if (DZ > RealEpsilon())
609     OpenZmax();
610 }
611
612 //=======================================================================
613 //function : IsOut
614 //purpose  : 
615 //=======================================================================
616
617 Standard_Boolean Bnd_Box::IsOut (const gp_Pnt& P) const
618 {
619   if        (IsWhole())  return Standard_False;
620   else if   (IsVoid())   return Standard_True;
621   else {
622     Standard_Real X,Y,Z;
623     P.Coord(X,Y,Z);
624     if      (!XminFlag() && (X < (Xmin-Gap))) return Standard_True;
625     else if (!XmaxFlag() && (X > (Xmax+Gap))) return Standard_True;
626     else if (!YminFlag() && (Y < (Ymin-Gap))) return Standard_True;
627     else if (!YmaxFlag() && (Y > (Ymax+Gap))) return Standard_True;
628     else if (!ZminFlag() && (Z < (Zmin-Gap))) return Standard_True;
629     else if (!ZmaxFlag() && (Z > (Zmax+Gap))) return Standard_True;
630     else return Standard_False;
631   }
632 }
633
634
635 //=======================================================================
636 //function : IsOut
637 //purpose  : 
638 //=======================================================================
639
640 Standard_Boolean Bnd_Box::IsOut (const gp_Pln& P) const
641 {
642   if        (IsWhole())  return Standard_False;
643   else if   (IsVoid())   return Standard_True;
644   else {
645     Standard_Real A,B,C,D;
646     P.Coefficients (A, B ,C ,D);
647     Standard_Real d = A * (Xmin-Gap) + B * (Ymin-Gap) + C * (Zmin-Gap) + D;
648 //    Standard_Boolean plus = d > 0;
649     Standard_Integer plus = d > 0;
650     if (plus != ((A*(Xmin-Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
651       return Standard_False;
652     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
653       return Standard_False;
654     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
655       return Standard_False;
656     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmin-Gap) + D) > 0))
657       return Standard_False;
658     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
659       return Standard_False;
660     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
661       return Standard_False;
662     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
663       return Standard_False;
664     else return Standard_True;
665   }
666 }
667
668 //=======================================================================
669 //function : IsOut
670 //purpose  : 
671 //=======================================================================
672
673 Standard_Boolean Bnd_Box::IsOut (const gp_Lin& L) const
674 {
675   if        (IsWhole())  return Standard_False;
676   else if   (IsVoid())   return Standard_True;
677   else {
678     Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax;
679     Standard_Real parmin, parmax, par1, par2;
680     Standard_Boolean xToSet, yToSet;
681     Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
682     Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
683
684     if (Abs(L.Direction().XYZ().X())>0.) {
685       par1=(myXmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
686       par2=(myXmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
687       parmin=Min(par1, par2);
688       parmax=Max(par1, par2);
689       xToSet=Standard_True;
690     }
691     else {
692       if (L.Location().XYZ().X()<myXmin || myXmax<L.Location().XYZ().X()) {
693         return Standard_True;
694       }
695       xmin=L.Location().XYZ().X();
696       xmax=L.Location().XYZ().X();
697       parmin=-Bnd_Precision_Infinite;
698       parmax=Bnd_Precision_Infinite;
699       xToSet=Standard_False;
700     }
701
702     if (Abs(L.Direction().XYZ().Y())>0.) {
703       par1=(myYmin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
704       par2=(myYmax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
705       //=================DET change 06/03/01====================
706       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
707         return Standard_True;
708       //========================================================
709       parmin=Max(parmin, Min(par1,par2));
710       parmax=Min(parmax, Max(par1,par2));
711       yToSet=Standard_True;
712     }
713     else {
714       if (L.Location().XYZ().Y()<myYmin || myYmax<L.Location().XYZ().Y()) {
715         return Standard_True;
716       }
717       ymin=L.Location().XYZ().Y();
718       ymax=L.Location().XYZ().Y();
719       yToSet=Standard_False;
720     }
721
722     if (Abs(L.Direction().XYZ().Z())>0.) {
723       par1=(myZmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
724       par2=(myZmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
725       //=================DET change 06/03/01====================
726       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
727         return Standard_True;
728       //========================================================
729       parmin=Max(parmin, Min(par1,par2));
730       parmax=Min(parmax, Max(par1,par2));
731       par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z();
732       par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z();
733       zmin=Min(par1, par2);
734       zmax=Max(par1, par2);
735     }
736     else {
737       if (L.Location().XYZ().Z()<myZmin || myZmax<L.Location().XYZ().Z())
738         return Standard_True;
739       zmin=L.Location().XYZ().Z();
740       zmax=L.Location().XYZ().Z();
741     }
742     if (zmax<myZmin || myZmax<zmin) return Standard_True;
743
744     if (xToSet) {
745       par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X();
746       par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X();
747       xmin=Min(par1, par2);
748       xmax=Max(par1, par2);
749     }
750     if (xmax<myXmin || myXmax<xmin) return Standard_True;
751
752     if (yToSet) {
753       par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y();
754       par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y();
755       ymin=Min(par1, par2);
756       ymax=Max(par1, par2);
757     }
758     if (ymax<myYmin || myYmax<ymin) return Standard_True;
759   }
760   return Standard_False;
761 }
762
763 //=======================================================================
764 //function : IsOut
765 //purpose  : 
766 //=======================================================================
767
768 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other) const
769
770   //modified by NIZNHY-PKV Fri Jul 08 11:03:43 2011f
771   if (!Flags && !Other.Flags) {
772     Standard_Boolean bRet;
773     Standard_Real delta;
774     //
775     delta = Other.Gap + Gap;
776     bRet=((Xmin - Other.Xmax > delta) ||
777           (Other.Xmin - Xmax > delta) ||
778           (Ymin - Other.Ymax > delta) ||
779           (Other.Ymin - Ymax > delta) ||
780           (Zmin - Other.Zmax > delta) ||
781           (Other.Zmin - Zmax > delta));
782     return bRet;
783   }
784   //modified by NIZNHY-PKV Fri Jul 08 11:03:46 2011t
785   if   (IsVoid())         return Standard_True;
786   if   (Other.IsVoid())   return Standard_True;
787   if   (IsWhole())        return Standard_False;
788   if   (Other.IsWhole())  return Standard_False;
789
790   Standard_Real delta = Other.Gap + Gap;
791
792   if (!XminFlag() && !Other.IsOpenXmax())
793     if (Xmin - Other.Xmax > delta) return Standard_True;
794   if (!XmaxFlag() && !Other.IsOpenXmin())
795     if (Other.Xmin - Xmax > delta) return Standard_True;
796   
797   if (!YminFlag() && !Other.IsOpenYmax())
798     if (Ymin - Other.Ymax > delta) return Standard_True;
799   if (!YmaxFlag() && !Other.IsOpenYmin())
800     if (Other.Ymin - Ymax > delta) return Standard_True;
801   
802   if (!ZminFlag() && !Other.IsOpenZmax())
803     if (Zmin - Other.Zmax > delta) return Standard_True;
804   if (!ZmaxFlag() && !Other.IsOpenZmin())
805     if (Other.Zmin - Zmax > delta) return Standard_True;
806
807   return Standard_False;
808 }
809
810 //=======================================================================
811 //function : IsOut
812 //purpose  : 
813 //=======================================================================
814
815 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other, 
816                                  const gp_Trsf& T) const
817 {
818   return IsOut(Other.Transformed(T));
819 }
820
821 //=======================================================================
822 //function : IsOut
823 //purpose  : 
824 //=======================================================================
825
826 Standard_Boolean Bnd_Box::IsOut (const gp_Trsf& T1,
827                                  const Bnd_Box& Other, 
828                                  const gp_Trsf& T2) const
829 {
830   return Transformed(T1).IsOut(Other.Transformed(T2));
831 }
832
833
834 //=======================================================================
835 //function : IsSegmentOut
836 //purpose  : 
837 //=======================================================================
838
839 static Standard_Boolean IsSegmentOut(Standard_Real x1,Standard_Real y1,
840                                      Standard_Real x2,Standard_Real y2,
841                                      Standard_Real xs1,Standard_Real ys1,
842                                      Standard_Real xs2,Standard_Real ys2)
843 {
844   Standard_Real eps = RealSmall();
845   Standard_Real xsmin = Min (xs1, xs2);
846   Standard_Real xsmax = Max (xs1, xs2);
847   Standard_Real ysmin = Min (ys1, ys2);
848   Standard_Real ysmax = Max (ys1, ys2);
849
850   if (ysmax-ysmin < eps && (y1-ys1 < eps && ys1-y2 < eps) &&
851       ((xsmin-x1 < eps && x1-xsmax < eps) || 
852        (xsmin-x2 < eps && x2-xsmax < eps) || 
853        (x1-xs1 < eps && xs1-x2 < eps)))
854     return Standard_False;
855   if (xsmax-xsmin < eps && (x1-xs1 < eps && xs1-x2 < eps) &&
856       ((ysmin-y1 < eps && y1-ysmax < eps) ||
857        (ysmin-y2 < eps && y2-ysmax < eps) ||
858        (y1-ys1 < eps && ys1-y2 < eps)))
859     return Standard_False;
860
861   if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) ||
862       (ys1 < y1 && ys2 < y1) || (ys1 > y2 && ys2 > y2) )
863     return Standard_True;
864
865   if (Abs(xs2-xs1) > eps)
866   {
867     Standard_Real ya = ( Min(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
868     Standard_Real yb = ( Max(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
869     if ( (ya < y1 && yb < y1) || (ya > y2 && yb > y2) ) return Standard_True;
870   }
871   else if (Abs(ys2-ys1) > eps)
872   {
873     Standard_Real xa = ( Min(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
874     Standard_Real xb = ( Max(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
875     if ( (xa < x1 && xb < x1) || (xa > x2 && xb > x2) ) return Standard_True;
876   }
877   else 
878     return Standard_True;
879
880   return Standard_False;
881 }
882
883 Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const
884 {
885
886   if        (IsWhole())  return Standard_False;
887   else if   (IsVoid())   return Standard_True;
888
889   Standard_Real eps = RealSmall();
890   Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
891   Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
892
893   if(Abs(D.X()) < eps && Abs(D.Y()) < eps)
894     return IsSegmentOut(myXmin, myYmin, myXmax, myYmax, P1.X(), P1.Y(), P2.X(), P2.Y());
895
896   if(Abs(D.X()) < eps && Abs(D.Z()) < eps)
897     return IsSegmentOut(myXmin, myZmin, myXmax, myZmax, P1.X(), P1.Z(), P2.X(), P2.Z());
898
899   if(Abs(D.Y()) < eps && Abs(D.Z()) < eps)
900     return IsSegmentOut(myYmin, myZmin, myYmax, myZmax, P1.Y(), P1.Z(), P2.Y(), P2.Z());
901
902   if(Abs(D.X()) < eps)
903   {
904     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
905                      P1.X(),(myYmin-P1.Y())*D.Z()/D.Y()+P1.Z(), 
906                      P2.X(),(myYmin-P2.Y())*D.Z()/D.Y()+P2.Z()))
907       return Standard_False;
908
909     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
910                      P1.X(),(myYmax-P1.Y())*D.Z()/D.Y()+P1.Z(), 
911                      P2.X(),(myYmax-P2.Y())*D.Z()/D.Y()+P2.Z()))
912       return Standard_False;
913
914     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
915                      P1.X(),(myZmin-P1.Z())*D.Y()/D.Z()+P1.Y(), 
916                      P2.X(),(myZmin-P2.Z())*D.Y()/D.Z()+P2.Y()))
917       return Standard_False;
918
919     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
920                      P1.X(),(myZmax-P1.Z())*D.Y()/D.Z()+P1.Y(), 
921                      P2.X(),(myZmax-P2.Z())*D.Y()/D.Z()+P2.Y()))
922       return Standard_False;
923
924     return Standard_True;
925   }//if(D.X() == 0) 
926
927   if(Abs(D.Y()) < eps)
928   {
929     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
930                      P1.Y(),(myXmin-P1.X())*D.Z()/D.X()+P1.Z(), 
931                      P2.Y(),(myXmin-P2.X())*D.Z()/D.X()+P2.Z()))
932       return Standard_False;
933
934     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
935                      P1.Y(),(myXmax-P1.X())*D.Z()/D.X()+P1.Z(), 
936                      P2.Y(),(myXmax-P2.X())*D.Z()/D.X()+P2.Z()))
937       return Standard_False;
938
939     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
940                      P1.Y(),(myZmin-P1.Z())*D.X()/D.Z()+P1.X(), 
941                      P2.Y(),(myZmin-P2.Z())*D.X()/D.Z()+P2.X()))
942       return Standard_False;
943
944     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
945                      P1.Y(),(myZmax-P1.Z())*D.X()/D.Z()+P1.X(), 
946                      P2.Y(),(myZmax-P2.Z())*D.X()/D.Z()+P2.X()))
947       return Standard_False;
948
949     return Standard_True;
950   }//if(D.Y() == 0) 
951
952   if(Abs(D.Z()) < eps)
953   {
954     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
955                      P1.Z(),(myYmax-P1.Y())*D.X()/D.Y()+P1.X(), 
956                      P2.Z(),(myYmax-P2.Y())*D.X()/D.Y()+P2.X()))
957       return Standard_False;
958
959     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
960                      P1.Z(),(myYmin-P1.Y())*D.X()/D.Y()+P1.X(), 
961                      P2.Z(),(myYmin-P2.Y())*D.X()/D.Y()+P2.X()))
962       return Standard_False;
963
964     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
965                      P1.Z(),(myXmax-P1.X())*D.Y()/D.X()+P1.Y(), 
966                      P2.Z(),(myXmax-P2.X())*D.Y()/D.X()+P2.Y()))
967       return Standard_False;
968
969     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
970                      P1.Z(),(myXmin-P1.X())*D.Y()/D.X()+P1.Y(), 
971                      P2.Z(),(myXmin-P2.X())*D.Y()/D.X()+P2.Y()))
972       return Standard_False;
973
974     return Standard_True;
975   }//if(D.Z() == 0) 
976
977   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
978                    (myYmin - P1.Y())/D.Y()*D.X() + P1.X(),
979                    (myYmin - P1.Y())/D.Y()*D.Z() + P1.Z(),
980                    (myYmin - P2.Y())/D.Y()*D.X() + P2.X(),
981                    (myYmin - P2.Y())/D.Y()*D.Z() + P2.Z()))
982     return Standard_False;
983
984   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
985                    (myYmax - P1.Y())/D.Y()*D.X() + P1.X(),
986                    (myYmax - P1.Y())/D.Y()*D.Z() + P1.Z(),
987                    (myYmax - P2.Y())/D.Y()*D.X() + P2.X(),
988                    (myYmax - P2.Y())/D.Y()*D.Z() + P2.Z()))
989     return Standard_False;
990
991   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
992                    (myZmin - P1.Z())/D.Z()*D.X() + P1.X(),
993                    (myZmin - P1.Z())/D.Z()*D.Y() + P1.Y(),
994                    (myZmin - P2.Z())/D.Z()*D.X() + P2.X(),
995                    (myZmin - P2.Z())/D.Z()*D.Y() + P2.Y()))
996     return Standard_False;
997
998   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
999                    (myZmax - P1.Z())/D.Z()*D.X() + P1.X(),
1000                    (myZmax - P1.Z())/D.Z()*D.Y() + P1.Y(),
1001                    (myZmax - P2.Z())/D.Z()*D.X() + P2.X(),
1002                    (myZmax - P2.Z())/D.Z()*D.Y() + P2.Y()))
1003     return Standard_False;
1004
1005   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
1006                    (myXmin - P1.X())/D.X()*D.Z() + P1.Z(),
1007                    (myXmin - P1.X())/D.X()*D.Y() + P1.Y(),
1008                    (myXmin - P2.X())/D.X()*D.Z() + P2.Z(),
1009                    (myXmin - P2.X())/D.X()*D.Y() + P2.Y()))
1010     return Standard_False;
1011
1012   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
1013                    (myXmax - P1.X())/D.X()*D.Z() + P1.Z(),
1014                    (myXmax - P1.X())/D.X()*D.Y() + P1.Y(),
1015                    (myXmax - P2.X())/D.X()*D.Z() + P2.Z(),
1016                    (myXmax - P2.X())/D.X()*D.Y() + P2.Y()))
1017     return Standard_False;
1018
1019   return Standard_True; 
1020
1021 }
1022
1023 //=======================================================================
1024 //function : Distance
1025 //purpose  : computes the minimum distance between two boxes 
1026 //=======================================================================
1027
1028 static Standard_Real DistMini2Box( const Standard_Real r1min, const  Standard_Real r1max,  const Standard_Real r2min, const  Standard_Real r2max)
1029 {  Standard_Real   r1, r2;
1030
1031    r1 = Square(r1min - r2max);
1032    r2 = Square(r1max - r2min);
1033    return (Min( r1, r2 ));   
1034 }
1035
1036
1037
1038 Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const 
1039 {  Standard_Real   xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1;
1040    Standard_Real   xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2;
1041    Standard_Real   dist_x, dist_y, dist_z, dist_t;
1042
1043    Get( xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1);
1044    Other.Get( xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2);
1045
1046    if ( ((xminB1<= xminB2)&&( xminB2 <= xmaxB1)) || ((xminB2<= xminB1)&&( xminB1 <= xmaxB2)) )
1047       { dist_x=0; }
1048       else { dist_x= DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);}
1049    if ( ((yminB1<= yminB2)&&( yminB2 <= ymaxB1)) || ((yminB2<= yminB1)&&( yminB1 <= ymaxB2)) )
1050       { dist_y=0; }
1051       else { dist_y= DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);}  
1052    if ( ((zminB1<= zminB2)&&( zminB2 <= zmaxB1)) || ((zminB2<= zminB1)&&( zminB1 <= zmaxB2)) )
1053       { dist_z=0; }
1054       else { dist_z= DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);}
1055    dist_t = dist_x+ dist_y+ dist_z;
1056    return( Sqrt ( dist_t));
1057 }
1058
1059 //=======================================================================
1060 //function : Dump
1061 //purpose  : 
1062 //=======================================================================
1063
1064 void Bnd_Box::Dump () const
1065 {
1066   cout << "Box3D : ";
1067   if      (IsVoid())  cout << "Void";
1068   else if (IsWhole()) cout << "Whole";
1069   else {
1070     cout << "\n Xmin : ";
1071     if (IsOpenXmin()) cout << "Infinite";
1072     else              cout << Xmin;
1073     cout << "\n Xmax : ";
1074     if (IsOpenXmax()) cout << "Infinite";
1075     else              cout << Xmax;
1076     cout << "\n Ymin : ";
1077     if (IsOpenYmin()) cout << "Infinite";
1078     else              cout << Ymin;
1079     cout << "\n Ymax : ";
1080     if (IsOpenYmax()) cout << "Infinite";
1081     else              cout << Ymax;
1082     cout << "\n Zmin : ";
1083     if (IsOpenZmin()) cout << "Infinite";
1084     else              cout << Zmin;
1085     cout << "\n Zmax : ";
1086     if (IsOpenZmax()) cout << "Infinite";
1087     else              cout << Zmax;
1088   }
1089   cout << "\n Gap : " << Gap;
1090   cout << "\n";
1091 }