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