6bdb10e4c3fad1a7c4ead40e05d4500381c6983b
[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   if (Abs(DX) > gp::Resolution()) {
581     if (DX > 0) OpenXmax();
582     else        OpenXmin();
583   }
584   if (Abs(DY) > gp::Resolution()) {
585     if (DY > 0) OpenYmax();
586     else        OpenYmin();
587   }
588   if (Abs(DZ) > gp::Resolution()) {
589     if (DZ > 0) OpenZmax();
590     else        OpenZmin();
591   }
592 }
593
594 //=======================================================================
595 //function : IsOut
596 //purpose  : 
597 //=======================================================================
598
599 Standard_Boolean Bnd_Box::IsOut (const gp_Pnt& P) const
600 {
601   if        (IsWhole())  return Standard_False;
602   else if   (IsVoid())   return Standard_True;
603   else {
604     Standard_Real X,Y,Z;
605     P.Coord(X,Y,Z);
606     if      (!XminFlag() && (X < (Xmin-Gap))) return Standard_True;
607     else if (!XmaxFlag() && (X > (Xmax+Gap))) return Standard_True;
608     else if (!YminFlag() && (Y < (Ymin-Gap))) return Standard_True;
609     else if (!YmaxFlag() && (Y > (Ymax+Gap))) return Standard_True;
610     else if (!ZminFlag() && (Z < (Zmin-Gap))) return Standard_True;
611     else if (!ZmaxFlag() && (Z > (Zmax+Gap))) return Standard_True;
612     else return Standard_False;
613   }
614 }
615
616
617 //=======================================================================
618 //function : IsOut
619 //purpose  : 
620 //=======================================================================
621
622 Standard_Boolean Bnd_Box::IsOut (const gp_Pln& P) const
623 {
624   if        (IsWhole())  return Standard_False;
625   else if   (IsVoid())   return Standard_True;
626   else {
627     Standard_Real A,B,C,D;
628     P.Coefficients (A, B ,C ,D);
629     Standard_Real d = A * (Xmin-Gap) + B * (Ymin-Gap) + C * (Zmin-Gap) + D;
630 //    Standard_Boolean plus = d > 0;
631     Standard_Integer plus = d > 0;
632     if (plus != ((A*(Xmin-Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
633       return Standard_False;
634     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
635       return Standard_False;
636     if (plus != ((A*(Xmin-Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
637       return Standard_False;
638     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmin-Gap) + D) > 0))
639       return Standard_False;
640     if (plus != ((A*(Xmax+Gap) + B*(Ymin-Gap) + C*(Zmax+Gap) + D) > 0))
641       return Standard_False;
642     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmin-Gap) + D) > 0))
643       return Standard_False;
644     if (plus != ((A*(Xmax+Gap) + B*(Ymax+Gap) + C*(Zmax+Gap) + D) > 0))
645       return Standard_False;
646     else return Standard_True;
647   }
648 }
649
650 //=======================================================================
651 //function : IsOut
652 //purpose  : 
653 //=======================================================================
654
655 Standard_Boolean Bnd_Box::IsOut (const gp_Lin& L) const
656 {
657   if        (IsWhole())  return Standard_False;
658   else if   (IsVoid())   return Standard_True;
659   else {
660     Standard_Real xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax;
661     Standard_Real parmin, parmax, par1, par2;
662     Standard_Boolean xToSet, yToSet;
663     Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
664     Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
665
666     if (Abs(L.Direction().XYZ().X())>0.) {
667       par1=(myXmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
668       par2=(myXmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
669       parmin=Min(par1, par2);
670       parmax=Max(par1, par2);
671       xToSet=Standard_True;
672     }
673     else {
674       if (L.Location().XYZ().X()<myXmin || myXmax<L.Location().XYZ().X()) {
675         return Standard_True;
676       }
677       xmin=L.Location().XYZ().X();
678       xmax=L.Location().XYZ().X();
679       parmin=-Bnd_Precision_Infinite;
680       parmax=Bnd_Precision_Infinite;
681       xToSet=Standard_False;
682     }
683
684     if (Abs(L.Direction().XYZ().Y())>0.) {
685       par1=(myYmin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
686       par2=(myYmax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
687       //=================DET change 06/03/01====================
688       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
689         return Standard_True;
690       //========================================================
691       parmin=Max(parmin, Min(par1,par2));
692       parmax=Min(parmax, Max(par1,par2));
693       yToSet=Standard_True;
694     }
695     else {
696       if (L.Location().XYZ().Y()<myYmin || myYmax<L.Location().XYZ().Y()) {
697         return Standard_True;
698       }
699       ymin=L.Location().XYZ().Y();
700       ymax=L.Location().XYZ().Y();
701       yToSet=Standard_False;
702     }
703
704     if (Abs(L.Direction().XYZ().Z())>0.) {
705       par1=(myZmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
706       par2=(myZmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
707       //=================DET change 06/03/01====================
708       if(parmax < Min(par1,par2) || parmin > Max(par1,par2))
709         return Standard_True;
710       //========================================================
711       parmin=Max(parmin, Min(par1,par2));
712       parmax=Min(parmax, Max(par1,par2));
713       par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z();
714       par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z();
715       zmin=Min(par1, par2);
716       zmax=Max(par1, par2);
717     }
718     else {
719       if (L.Location().XYZ().Z()<myZmin || myZmax<L.Location().XYZ().Z())
720         return Standard_True;
721       zmin=L.Location().XYZ().Z();
722       zmax=L.Location().XYZ().Z();
723     }
724     if (zmax<myZmin || myZmax<zmin) return Standard_True;
725
726     if (xToSet) {
727       par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X();
728       par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X();
729       xmin=Min(par1, par2);
730       xmax=Max(par1, par2);
731     }
732     if (xmax<myXmin || myXmax<xmin) return Standard_True;
733
734     if (yToSet) {
735       par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y();
736       par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y();
737       ymin=Min(par1, par2);
738       ymax=Max(par1, par2);
739     }
740     if (ymax<myYmin || myYmax<ymin) return Standard_True;
741   }
742   return Standard_False;
743 }
744
745 //=======================================================================
746 //function : IsOut
747 //purpose  : 
748 //=======================================================================
749
750 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other) const
751 {
752   if   (IsVoid())         return Standard_True;
753   if   (Other.IsVoid())   return Standard_True;
754   if   (IsWhole())        return Standard_False;
755   if   (Other.IsWhole())  return Standard_False;
756
757   Standard_Real delta = Other.Gap + Gap;
758
759   if (!XminFlag() && !Other.IsOpenXmax())
760     if (Xmin - Other.Xmax > delta) return Standard_True;
761   if (!XmaxFlag() && !Other.IsOpenXmin())
762     if (Other.Xmin - Xmax > delta) return Standard_True;
763   
764   if (!YminFlag() && !Other.IsOpenYmax())
765     if (Ymin - Other.Ymax > delta) return Standard_True;
766   if (!YmaxFlag() && !Other.IsOpenYmin())
767     if (Other.Ymin - Ymax > delta) return Standard_True;
768   
769   if (!ZminFlag() && !Other.IsOpenZmax())
770     if (Zmin - Other.Zmax > delta) return Standard_True;
771   if (!ZmaxFlag() && !Other.IsOpenZmin())
772     if (Other.Zmin - Zmax > delta) return Standard_True;
773
774   return Standard_False;
775 }
776
777 //=======================================================================
778 //function : IsOut
779 //purpose  : 
780 //=======================================================================
781
782 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other, 
783                                  const gp_Trsf& T) const
784 {
785   return IsOut(Other.Transformed(T));
786 }
787
788 //=======================================================================
789 //function : IsOut
790 //purpose  : 
791 //=======================================================================
792
793 Standard_Boolean Bnd_Box::IsOut (const gp_Trsf& T1,
794                                  const Bnd_Box& Other, 
795                                  const gp_Trsf& T2) const
796 {
797   return Transformed(T1).IsOut(Other.Transformed(T2));
798 }
799
800
801 //=======================================================================
802 //function : IsOut
803 //purpose  : 
804 //=======================================================================
805
806 static Standard_Boolean IsSegmentOut(Standard_Real x1,Standard_Real y1,
807                                      Standard_Real x2,Standard_Real y2,
808                                      Standard_Real xs1,Standard_Real ys1,
809                                      Standard_Real xs2,Standard_Real ys2)
810 {
811   Standard_Real eps = RealSmall();
812   Standard_Real xsmin = Min (xs1, xs2);
813   Standard_Real xsmax = Max (xs1, xs2);
814   Standard_Real ysmin = Min (ys1, ys2);
815   Standard_Real ysmax = Max (ys1, ys2);
816
817   if (ysmax-ysmin < eps && (y1-ys1 < eps && ys1-y2 < eps) &&
818       (xsmin-x1 < eps && x1-xsmax < eps || xsmin-x2 < eps && x2-xsmax < eps ||
819        x1-xs1 < eps && xs1-x2 < eps))
820     return Standard_False;
821   if (xsmax-xsmin < eps && (x1-xs1 < eps && xs1-x2 < eps) &&
822       (ysmin-y1 < eps && y1-ysmax < eps || ysmin-y2 < eps && y2-ysmax < eps ||
823        y1-ys1 < eps && ys1-y2 < eps))
824     return Standard_False;
825
826   if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) ||
827       (ys1 < y1 && ys2 < y1) || (ys1 > y2 && ys2 > y2) )
828     return Standard_True;
829
830   if (Abs(xs2-xs1) > eps)
831   {
832     Standard_Real ya = ( Min(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
833     Standard_Real yb = ( Max(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
834     if ( (ya < y1 && yb < y1) || (ya > y2 && yb > y2) ) return Standard_True;
835   }
836   else if (Abs(ys2-ys1) > eps)
837   {
838     Standard_Real xa = ( Min(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
839     Standard_Real xb = ( Max(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
840     if ( (xa < x1 && xb < x1) || (xa > x2 && xb > x2) ) return Standard_True;
841   }
842   else 
843     return Standard_True;
844
845   return Standard_False;
846 }
847
848 Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const
849 {
850
851   if        (IsWhole())  return Standard_False;
852   else if   (IsVoid())   return Standard_True;
853
854   Standard_Real eps = RealSmall();
855   Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
856   Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
857
858   if(Abs(D.X()) < eps && Abs(D.Y()) < eps)
859     return IsSegmentOut(myXmin, myYmin, myXmax, myYmax, P1.X(), P1.Y(), P2.X(), P2.Y());
860
861   if(Abs(D.X()) < eps && Abs(D.Z()) < eps)
862     return IsSegmentOut(myXmin, myZmin, myXmax, myZmax, P1.X(), P1.Z(), P2.X(), P2.Z());
863
864   if(Abs(D.Y()) < eps && Abs(D.Z()) < eps)
865     return IsSegmentOut(myYmin, myZmin, myYmax, myZmax, P1.Y(), P1.Z(), P2.Y(), P2.Z());
866
867   if(Abs(D.X()) < eps)
868   {
869     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
870                      P1.X(),(myYmin-P1.Y())*D.Z()/D.Y()+P1.Z(), 
871                      P2.X(),(myYmin-P2.Y())*D.Z()/D.Y()+P2.Z()))
872       return Standard_False;
873
874     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
875                      P1.X(),(myYmax-P1.Y())*D.Z()/D.Y()+P1.Z(), 
876                      P2.X(),(myYmax-P2.Y())*D.Z()/D.Y()+P2.Z()))
877       return Standard_False;
878
879     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
880                      P1.X(),(myZmin-P1.Z())*D.Y()/D.Z()+P1.Y(), 
881                      P2.X(),(myZmin-P2.Z())*D.Y()/D.Z()+P2.Y()))
882       return Standard_False;
883
884     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
885                      P1.X(),(myZmax-P1.Z())*D.Y()/D.Z()+P1.Y(), 
886                      P2.X(),(myZmax-P2.Z())*D.Y()/D.Z()+P2.Y()))
887       return Standard_False;
888
889     return Standard_True;
890   }//if(D.X() == 0) 
891
892   if(Abs(D.Y()) < eps)
893   {
894     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
895                      P1.Y(),(myXmin-P1.X())*D.Z()/D.X()+P1.Z(), 
896                      P2.Y(),(myXmin-P2.X())*D.Z()/D.X()+P2.Z()))
897       return Standard_False;
898
899     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
900                      P1.Y(),(myXmax-P1.X())*D.Z()/D.X()+P1.Z(), 
901                      P2.Y(),(myXmax-P2.X())*D.Z()/D.X()+P2.Z()))
902       return Standard_False;
903
904     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
905                      P1.Y(),(myZmin-P1.Z())*D.X()/D.Z()+P1.X(), 
906                      P2.Y(),(myZmin-P2.Z())*D.X()/D.Z()+P2.X()))
907       return Standard_False;
908
909     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
910                      P1.Y(),(myZmax-P1.Z())*D.X()/D.Z()+P1.X(), 
911                      P2.Y(),(myZmax-P2.Z())*D.X()/D.Z()+P2.X()))
912       return Standard_False;
913
914     return Standard_True;
915   }//if(D.Y() == 0) 
916
917   if(Abs(D.Z()) < eps)
918   {
919     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
920                      P1.Z(),(myYmax-P1.Y())*D.X()/D.Y()+P1.X(), 
921                      P2.Z(),(myYmax-P2.Y())*D.X()/D.Y()+P2.X()))
922       return Standard_False;
923
924     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
925                      P1.Z(),(myYmin-P1.Y())*D.X()/D.Y()+P1.X(), 
926                      P2.Z(),(myYmin-P2.Y())*D.X()/D.Y()+P2.X()))
927       return Standard_False;
928
929     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
930                      P1.Z(),(myXmax-P1.X())*D.Y()/D.X()+P1.Y(), 
931                      P2.Z(),(myXmax-P2.X())*D.Y()/D.X()+P2.Y()))
932       return Standard_False;
933
934     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
935                      P1.Z(),(myXmin-P1.X())*D.Y()/D.X()+P1.Y(), 
936                      P2.Z(),(myXmin-P2.X())*D.Y()/D.X()+P2.Y()))
937       return Standard_False;
938
939     return Standard_True;
940   }//if(D.Z() == 0) 
941
942   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
943                    (myYmin - P1.Y())/D.Y()*D.X() + P1.X(),
944                    (myYmin - P1.Y())/D.Y()*D.Z() + P1.Z(),
945                    (myYmin - P2.Y())/D.Y()*D.X() + P2.X(),
946                    (myYmin - P2.Y())/D.Y()*D.Z() + P2.Z()))
947     return Standard_False;
948
949   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
950                    (myYmax - P1.Y())/D.Y()*D.X() + P1.X(),
951                    (myYmax - P1.Y())/D.Y()*D.Z() + P1.Z(),
952                    (myYmax - P2.Y())/D.Y()*D.X() + P2.X(),
953                    (myYmax - P2.Y())/D.Y()*D.Z() + P2.Z()))
954     return Standard_False;
955
956   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
957                    (myZmin - P1.Z())/D.Z()*D.X() + P1.X(),
958                    (myZmin - P1.Z())/D.Z()*D.Y() + P1.Y(),
959                    (myZmin - P2.Z())/D.Z()*D.X() + P2.X(),
960                    (myZmin - P2.Z())/D.Z()*D.Y() + P2.Y()))
961     return Standard_False;
962
963   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
964                    (myZmax - P1.Z())/D.Z()*D.X() + P1.X(),
965                    (myZmax - P1.Z())/D.Z()*D.Y() + P1.Y(),
966                    (myZmax - P2.Z())/D.Z()*D.X() + P2.X(),
967                    (myZmax - P2.Z())/D.Z()*D.Y() + P2.Y()))
968     return Standard_False;
969
970   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
971                    (myXmin - P1.X())/D.X()*D.Z() + P1.Z(),
972                    (myXmin - P1.X())/D.X()*D.Y() + P1.Y(),
973                    (myXmin - P2.X())/D.X()*D.Z() + P2.Z(),
974                    (myXmin - P2.X())/D.X()*D.Y() + P2.Y()))
975     return Standard_False;
976
977   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
978                    (myXmax - P1.X())/D.X()*D.Z() + P1.Z(),
979                    (myXmax - P1.X())/D.X()*D.Y() + P1.Y(),
980                    (myXmax - P2.X())/D.X()*D.Z() + P2.Z(),
981                    (myXmax - P2.X())/D.X()*D.Y() + P2.Y()))
982     return Standard_False;
983
984   return Standard_True; 
985
986 }
987
988 //=======================================================================
989 //function : Distance
990 //purpose  : computes the minimum distance between two boxes 
991 //=======================================================================
992
993 static Standard_Real DistMini2Box( const Standard_Real r1min, const  Standard_Real r1max,  const Standard_Real r2min, const  Standard_Real r2max)
994 {  Standard_Real   r1, r2;
995
996    r1 = Square(r1min - r2max);
997    r2 = Square(r1max - r2min);
998    return (Min( r1, r2 ));   
999 }
1000
1001
1002
1003 Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const 
1004 {  Standard_Real   xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1;
1005    Standard_Real   xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2;
1006    Standard_Real   dist_x, dist_y, dist_z, dist_t;
1007
1008    Get( xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1);
1009    Other.Get( xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2);
1010
1011    if ( ((xminB1<= xminB2)&&( xminB2 <= xmaxB1)) || ((xminB2<= xminB1)&&( xminB1 <= xmaxB2)) )
1012       { dist_x=0; }
1013       else { dist_x= DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);}
1014    if ( ((yminB1<= yminB2)&&( yminB2 <= ymaxB1)) || ((yminB2<= yminB1)&&( yminB1 <= ymaxB2)) )
1015       { dist_y=0; }
1016       else { dist_y= DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);}  
1017    if ( ((zminB1<= zminB2)&&( zminB2 <= zmaxB1)) || ((zminB2<= zminB1)&&( zminB1 <= zmaxB2)) )
1018       { dist_z=0; }
1019       else { dist_z= DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);}
1020    dist_t = dist_x+ dist_y+ dist_z;
1021    return( Sqrt ( dist_t));
1022 }
1023
1024 //=======================================================================
1025 //function : Dump
1026 //purpose  : 
1027 //=======================================================================
1028
1029 void Bnd_Box::Dump () const
1030 {
1031   cout << "Box3D : ";
1032   if      (IsVoid())  cout << "Void";
1033   else if (IsWhole()) cout << "Whole";
1034   else {
1035     cout << "\n Xmin : ";
1036     if (IsOpenXmin()) cout << "Infinite";
1037     else              cout << Xmin;
1038     cout << "\n Xmax : ";
1039     if (IsOpenXmax()) cout << "Infinite";
1040     else              cout << Xmax;
1041     cout << "\n Ymin : ";
1042     if (IsOpenYmin()) cout << "Infinite";
1043     else              cout << Ymin;
1044     cout << "\n Ymax : ";
1045     if (IsOpenYmax()) cout << "Infinite";
1046     else              cout << Ymax;
1047     cout << "\n Zmin : ";
1048     if (IsOpenZmin()) cout << "Infinite";
1049     else              cout << Zmin;
1050     cout << "\n Zmax : ";
1051     if (IsOpenZmax()) cout << "Infinite";
1052     else              cout << Zmax;
1053   }
1054   cout << "\n Gap : " << Gap;
1055   cout << "\n";
1056 }