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