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