ea39cec9bee40523452eb0d5c1000a64b64218c7
[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   //modified by NIZNHY-PKV Fri Jul 08 11:03:43 2011f
753   if (!Flags && !Other.Flags) {
754     Standard_Boolean bRet;
755     Standard_Real delta;
756     //
757     delta = Other.Gap + Gap;
758     bRet=((Xmin - Other.Xmax > delta) ||
759           (Other.Xmin - Xmax > delta) ||
760           (Ymin - Other.Ymax > delta) ||
761           (Other.Ymin - Ymax > delta) ||
762           (Zmin - Other.Zmax > delta) ||
763           (Other.Zmin - Zmax > delta));
764     return bRet;
765   }
766   //modified by NIZNHY-PKV Fri Jul 08 11:03:46 2011t
767   if   (IsVoid())         return Standard_True;
768   if   (Other.IsVoid())   return Standard_True;
769   if   (IsWhole())        return Standard_False;
770   if   (Other.IsWhole())  return Standard_False;
771
772   Standard_Real delta = Other.Gap + Gap;
773
774   if (!XminFlag() && !Other.IsOpenXmax())
775     if (Xmin - Other.Xmax > delta) return Standard_True;
776   if (!XmaxFlag() && !Other.IsOpenXmin())
777     if (Other.Xmin - Xmax > delta) return Standard_True;
778   
779   if (!YminFlag() && !Other.IsOpenYmax())
780     if (Ymin - Other.Ymax > delta) return Standard_True;
781   if (!YmaxFlag() && !Other.IsOpenYmin())
782     if (Other.Ymin - Ymax > delta) return Standard_True;
783   
784   if (!ZminFlag() && !Other.IsOpenZmax())
785     if (Zmin - Other.Zmax > delta) return Standard_True;
786   if (!ZmaxFlag() && !Other.IsOpenZmin())
787     if (Other.Zmin - Zmax > delta) return Standard_True;
788
789   return Standard_False;
790 }
791
792 //=======================================================================
793 //function : IsOut
794 //purpose  : 
795 //=======================================================================
796
797 Standard_Boolean Bnd_Box::IsOut (const Bnd_Box& Other, 
798                                  const gp_Trsf& T) const
799 {
800   return IsOut(Other.Transformed(T));
801 }
802
803 //=======================================================================
804 //function : IsOut
805 //purpose  : 
806 //=======================================================================
807
808 Standard_Boolean Bnd_Box::IsOut (const gp_Trsf& T1,
809                                  const Bnd_Box& Other, 
810                                  const gp_Trsf& T2) const
811 {
812   return Transformed(T1).IsOut(Other.Transformed(T2));
813 }
814
815
816 //=======================================================================
817 //function : IsOut
818 //purpose  : 
819 //=======================================================================
820
821 static Standard_Boolean IsSegmentOut(Standard_Real x1,Standard_Real y1,
822                                      Standard_Real x2,Standard_Real y2,
823                                      Standard_Real xs1,Standard_Real ys1,
824                                      Standard_Real xs2,Standard_Real ys2)
825 {
826   Standard_Real eps = RealSmall();
827   Standard_Real xsmin = Min (xs1, xs2);
828   Standard_Real xsmax = Max (xs1, xs2);
829   Standard_Real ysmin = Min (ys1, ys2);
830   Standard_Real ysmax = Max (ys1, ys2);
831
832   if (ysmax-ysmin < eps && (y1-ys1 < eps && ys1-y2 < eps) &&
833       (xsmin-x1 < eps && x1-xsmax < eps || xsmin-x2 < eps && x2-xsmax < eps ||
834        x1-xs1 < eps && xs1-x2 < eps))
835     return Standard_False;
836   if (xsmax-xsmin < eps && (x1-xs1 < eps && xs1-x2 < eps) &&
837       (ysmin-y1 < eps && y1-ysmax < eps || ysmin-y2 < eps && y2-ysmax < eps ||
838        y1-ys1 < eps && ys1-y2 < eps))
839     return Standard_False;
840
841   if ((xs1 < x1 && xs2 < x1) || (xs1 > x2 && xs2 > x2) ||
842       (ys1 < y1 && ys2 < y1) || (ys1 > y2 && ys2 > y2) )
843     return Standard_True;
844
845   if (Abs(xs2-xs1) > eps)
846   {
847     Standard_Real ya = ( Min(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
848     Standard_Real yb = ( Max(x1, x2) - xs1 ) * ( ys2 - ys1 ) / ( xs2 - xs1 ) + ys1;
849     if ( (ya < y1 && yb < y1) || (ya > y2 && yb > y2) ) return Standard_True;
850   }
851   else if (Abs(ys2-ys1) > eps)
852   {
853     Standard_Real xa = ( Min(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
854     Standard_Real xb = ( Max(y1, y2) - ys1 ) * ( xs2 - xs1 ) / ( ys2 - ys1 ) + xs1;
855     if ( (xa < x1 && xb < x1) || (xa > x2 && xb > x2) ) return Standard_True;
856   }
857   else 
858     return Standard_True;
859
860   return Standard_False;
861 }
862
863 Standard_Boolean Bnd_Box::IsOut(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Dir& D) const
864 {
865
866   if        (IsWhole())  return Standard_False;
867   else if   (IsVoid())   return Standard_True;
868
869   Standard_Real eps = RealSmall();
870   Standard_Real myXmin, myYmin, myZmin, myXmax, myYmax, myZmax;
871   Get (myXmin, myYmin, myZmin, myXmax, myYmax, myZmax);
872
873   if(Abs(D.X()) < eps && Abs(D.Y()) < eps)
874     return IsSegmentOut(myXmin, myYmin, myXmax, myYmax, P1.X(), P1.Y(), P2.X(), P2.Y());
875
876   if(Abs(D.X()) < eps && Abs(D.Z()) < eps)
877     return IsSegmentOut(myXmin, myZmin, myXmax, myZmax, P1.X(), P1.Z(), P2.X(), P2.Z());
878
879   if(Abs(D.Y()) < eps && Abs(D.Z()) < eps)
880     return IsSegmentOut(myYmin, myZmin, myYmax, myZmax, P1.Y(), P1.Z(), P2.Y(), P2.Z());
881
882   if(Abs(D.X()) < eps)
883   {
884     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
885                      P1.X(),(myYmin-P1.Y())*D.Z()/D.Y()+P1.Z(), 
886                      P2.X(),(myYmin-P2.Y())*D.Z()/D.Y()+P2.Z()))
887       return Standard_False;
888
889     if(!IsSegmentOut(myXmin, myZmin, myXmax, myZmax,
890                      P1.X(),(myYmax-P1.Y())*D.Z()/D.Y()+P1.Z(), 
891                      P2.X(),(myYmax-P2.Y())*D.Z()/D.Y()+P2.Z()))
892       return Standard_False;
893
894     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
895                      P1.X(),(myZmin-P1.Z())*D.Y()/D.Z()+P1.Y(), 
896                      P2.X(),(myZmin-P2.Z())*D.Y()/D.Z()+P2.Y()))
897       return Standard_False;
898
899     if(!IsSegmentOut(myXmin, myYmin, myXmax, myYmax,
900                      P1.X(),(myZmax-P1.Z())*D.Y()/D.Z()+P1.Y(), 
901                      P2.X(),(myZmax-P2.Z())*D.Y()/D.Z()+P2.Y()))
902       return Standard_False;
903
904     return Standard_True;
905   }//if(D.X() == 0) 
906
907   if(Abs(D.Y()) < eps)
908   {
909     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
910                      P1.Y(),(myXmin-P1.X())*D.Z()/D.X()+P1.Z(), 
911                      P2.Y(),(myXmin-P2.X())*D.Z()/D.X()+P2.Z()))
912       return Standard_False;
913
914     if(!IsSegmentOut(myYmin, myZmin, myYmax, myZmax,
915                      P1.Y(),(myXmax-P1.X())*D.Z()/D.X()+P1.Z(), 
916                      P2.Y(),(myXmax-P2.X())*D.Z()/D.X()+P2.Z()))
917       return Standard_False;
918
919     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
920                      P1.Y(),(myZmin-P1.Z())*D.X()/D.Z()+P1.X(), 
921                      P2.Y(),(myZmin-P2.Z())*D.X()/D.Z()+P2.X()))
922       return Standard_False;
923
924     if(!IsSegmentOut(myYmin, myXmin, myYmax, myXmax,
925                      P1.Y(),(myZmax-P1.Z())*D.X()/D.Z()+P1.X(), 
926                      P2.Y(),(myZmax-P2.Z())*D.X()/D.Z()+P2.X()))
927       return Standard_False;
928
929     return Standard_True;
930   }//if(D.Y() == 0) 
931
932   if(Abs(D.Z()) < eps)
933   {
934     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
935                      P1.Z(),(myYmax-P1.Y())*D.X()/D.Y()+P1.X(), 
936                      P2.Z(),(myYmax-P2.Y())*D.X()/D.Y()+P2.X()))
937       return Standard_False;
938
939     if(!IsSegmentOut(myZmin, myXmin, myZmax, myXmax,
940                      P1.Z(),(myYmin-P1.Y())*D.X()/D.Y()+P1.X(), 
941                      P2.Z(),(myYmin-P2.Y())*D.X()/D.Y()+P2.X()))
942       return Standard_False;
943
944     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
945                      P1.Z(),(myXmax-P1.X())*D.Y()/D.X()+P1.Y(), 
946                      P2.Z(),(myXmax-P2.X())*D.Y()/D.X()+P2.Y()))
947       return Standard_False;
948
949     if(!IsSegmentOut(myZmin, myYmin, myZmax, myYmax,
950                      P1.Z(),(myXmin-P1.X())*D.Y()/D.X()+P1.Y(), 
951                      P2.Z(),(myXmin-P2.X())*D.Y()/D.X()+P2.Y()))
952       return Standard_False;
953
954     return Standard_True;
955   }//if(D.Z() == 0) 
956
957   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
958                    (myYmin - P1.Y())/D.Y()*D.X() + P1.X(),
959                    (myYmin - P1.Y())/D.Y()*D.Z() + P1.Z(),
960                    (myYmin - P2.Y())/D.Y()*D.X() + P2.X(),
961                    (myYmin - P2.Y())/D.Y()*D.Z() + P2.Z()))
962     return Standard_False;
963
964   if(!IsSegmentOut(myXmin,myZmin,myXmax,myZmax,
965                    (myYmax - P1.Y())/D.Y()*D.X() + P1.X(),
966                    (myYmax - P1.Y())/D.Y()*D.Z() + P1.Z(),
967                    (myYmax - P2.Y())/D.Y()*D.X() + P2.X(),
968                    (myYmax - P2.Y())/D.Y()*D.Z() + P2.Z()))
969     return Standard_False;
970
971   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
972                    (myZmin - P1.Z())/D.Z()*D.X() + P1.X(),
973                    (myZmin - P1.Z())/D.Z()*D.Y() + P1.Y(),
974                    (myZmin - P2.Z())/D.Z()*D.X() + P2.X(),
975                    (myZmin - P2.Z())/D.Z()*D.Y() + P2.Y()))
976     return Standard_False;
977
978   if(!IsSegmentOut(myXmin,myYmin,myXmax,myYmax,
979                    (myZmax - P1.Z())/D.Z()*D.X() + P1.X(),
980                    (myZmax - P1.Z())/D.Z()*D.Y() + P1.Y(),
981                    (myZmax - P2.Z())/D.Z()*D.X() + P2.X(),
982                    (myZmax - P2.Z())/D.Z()*D.Y() + P2.Y()))
983     return Standard_False;
984
985   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
986                    (myXmin - P1.X())/D.X()*D.Z() + P1.Z(),
987                    (myXmin - P1.X())/D.X()*D.Y() + P1.Y(),
988                    (myXmin - P2.X())/D.X()*D.Z() + P2.Z(),
989                    (myXmin - P2.X())/D.X()*D.Y() + P2.Y()))
990     return Standard_False;
991
992   if(!IsSegmentOut(myZmin,myYmin,myZmax,myYmax,
993                    (myXmax - P1.X())/D.X()*D.Z() + P1.Z(),
994                    (myXmax - P1.X())/D.X()*D.Y() + P1.Y(),
995                    (myXmax - P2.X())/D.X()*D.Z() + P2.Z(),
996                    (myXmax - P2.X())/D.X()*D.Y() + P2.Y()))
997     return Standard_False;
998
999   return Standard_True; 
1000
1001 }
1002
1003 //=======================================================================
1004 //function : Distance
1005 //purpose  : computes the minimum distance between two boxes 
1006 //=======================================================================
1007
1008 static Standard_Real DistMini2Box( const Standard_Real r1min, const  Standard_Real r1max,  const Standard_Real r2min, const  Standard_Real r2max)
1009 {  Standard_Real   r1, r2;
1010
1011    r1 = Square(r1min - r2max);
1012    r2 = Square(r1max - r2min);
1013    return (Min( r1, r2 ));   
1014 }
1015
1016
1017
1018 Standard_Real Bnd_Box::Distance(const Bnd_Box& Other) const 
1019 {  Standard_Real   xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1;
1020    Standard_Real   xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2;
1021    Standard_Real   dist_x, dist_y, dist_z, dist_t;
1022
1023    Get( xminB1, yminB1, zminB1, xmaxB1, ymaxB1, zmaxB1);
1024    Other.Get( xminB2, yminB2, zminB2, xmaxB2, ymaxB2, zmaxB2);
1025
1026    if ( ((xminB1<= xminB2)&&( xminB2 <= xmaxB1)) || ((xminB2<= xminB1)&&( xminB1 <= xmaxB2)) )
1027       { dist_x=0; }
1028       else { dist_x= DistMini2Box(xminB1, xmaxB1, xminB2, xmaxB2);}
1029    if ( ((yminB1<= yminB2)&&( yminB2 <= ymaxB1)) || ((yminB2<= yminB1)&&( yminB1 <= ymaxB2)) )
1030       { dist_y=0; }
1031       else { dist_y= DistMini2Box(yminB1, ymaxB1, yminB2, ymaxB2);}  
1032    if ( ((zminB1<= zminB2)&&( zminB2 <= zmaxB1)) || ((zminB2<= zminB1)&&( zminB1 <= zmaxB2)) )
1033       { dist_z=0; }
1034       else { dist_z= DistMini2Box(zminB1, zmaxB1, zminB2, zmaxB2);}
1035    dist_t = dist_x+ dist_y+ dist_z;
1036    return( Sqrt ( dist_t));
1037 }
1038
1039 //=======================================================================
1040 //function : Dump
1041 //purpose  : 
1042 //=======================================================================
1043
1044 void Bnd_Box::Dump () const
1045 {
1046   cout << "Box3D : ";
1047   if      (IsVoid())  cout << "Void";
1048   else if (IsWhole()) cout << "Whole";
1049   else {
1050     cout << "\n Xmin : ";
1051     if (IsOpenXmin()) cout << "Infinite";
1052     else              cout << Xmin;
1053     cout << "\n Xmax : ";
1054     if (IsOpenXmax()) cout << "Infinite";
1055     else              cout << Xmax;
1056     cout << "\n Ymin : ";
1057     if (IsOpenYmin()) cout << "Infinite";
1058     else              cout << Ymin;
1059     cout << "\n Ymax : ";
1060     if (IsOpenYmax()) cout << "Infinite";
1061     else              cout << Ymax;
1062     cout << "\n Zmin : ";
1063     if (IsOpenZmin()) cout << "Infinite";
1064     else              cout << Zmin;
1065     cout << "\n Zmax : ";
1066     if (IsOpenZmax()) cout << "Infinite";
1067     else              cout << Zmax;
1068   }
1069   cout << "\n Gap : " << Gap;
1070   cout << "\n";
1071 }