1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Bnd_Box.hxx>
17 #include <Bnd_Box2d.hxx>
20 #include <gp_Circ.hxx>
21 #include <gp_Circ2d.hxx>
22 #include <gp_Cone.hxx>
23 #include <gp_Cylinder.hxx>
24 #include <gp_Elips.hxx>
25 #include <gp_Elips2d.hxx>
26 #include <gp_Hypr.hxx>
27 #include <gp_Hypr2d.hxx>
29 #include <gp_Lin2d.hxx>
30 #include <gp_Parab.hxx>
31 #include <gp_Parab2d.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <gp_Sphere.hxx>
35 #include <gp_Torus.hxx>
38 #include <Precision.hxx>
39 #include <Standard_Failure.hxx>
43 Standard_Integer ComputeBox(const gp_Hypr& aHypr,
44 const Standard_Real aT1,
45 const Standard_Real aT2,
52 template<class PointType, class BndBoxType>
53 void Compute (const Standard_Real theP1, const Standard_Real theP2,
54 const Standard_Real theRa ,const Standard_Real theRb,
55 const PointType& theXd, const PointType& theYd, const PointType& theO,
71 Standard_Real aDelta = Abs(aTeta2-aTeta1);
72 if(aDelta > 2. * M_PI)
81 do{ aTeta1 += 2.*M_PI; } while (aTeta1 < 0.);
83 else if (aTeta1 > 2.*M_PI)
85 do { aTeta1 -= 2.*M_PI; } while (aTeta1 > 2.*M_PI);
87 aTeta2 = aTeta1 + aDelta;
90 // One places already both ends
91 Standard_Real aCn1, aSn1 ,aCn2, aSn2;
92 aCn1 = Cos(aTeta1); aSn1 = Sin(aTeta1);
93 aCn2 = Cos(aTeta2); aSn2 = Sin(aTeta2);
94 theB.Add(PointType( theO.Coord() +theRa*aCn1*theXd.Coord() +theRb*aSn1*theYd.Coord()));
95 theB.Add(PointType(theO.Coord() +theRa*aCn2*theXd.Coord() +theRb*aSn2*theYd.Coord()));
97 Standard_Real aRam, aRbm;
100 // Main radiuses to take into account only 8 points (/cos(Pi/8.))
101 aRam = theRa/0.92387953251128674;
102 aRbm = theRb/0.92387953251128674;
106 // Main radiuses to take into account the arrow
107 Standard_Real aTc = cos(aDelta/2);
111 theB.Add(PointType(theO.Coord() + aRam*aCn1*theXd.Coord() + aRbm*aSn1*theYd.Coord()));
112 theB.Add(PointType(theO.Coord() + aRam*aCn2*theXd.Coord() + aRbm*aSn2*theYd.Coord()));
114 // cos or sin M_PI/4.
115 #define PI4 0.70710678118654746
117 // 8 points of the polygon
118 #define addPoint0 theB.Add(PointType(theO.Coord() +aRam*theXd.Coord()))
119 #define addPoint1 theB.Add(PointType(theO.Coord() +aRam*PI4*theXd.Coord() +aRbm*PI4*theYd.Coord()))
120 #define addPoint2 theB.Add(PointType(theO.Coord() +aRbm*theYd.Coord()))
121 #define addPoint3 theB.Add(PointType(theO.Coord() -aRam*PI4*theXd.Coord() +aRbm*PI4*theYd.Coord()))
122 #define addPoint4 theB.Add(PointType(theO.Coord() -aRam*theXd.Coord() ))
123 #define addPoint5 theB.Add(PointType(theO.Coord() -aRam*PI4*theXd.Coord() -aRbm*PI4*theYd.Coord()))
124 #define addPoint6 theB.Add(PointType(theO.Coord() -aRbm*theYd.Coord()))
125 #define addPoint7 theB.Add(PointType(theO.Coord() +aRam*PI4*theXd.Coord() -aRbm*PI4*theYd.Coord()))
127 Standard_Integer aDeb = (Standard_Integer )( aTeta1/(M_PI/4.));
128 Standard_Integer aFin = (Standard_Integer )( aTeta2/(M_PI/4.));
131 if (aDeb > aFin) return;
138 if (aFin <= 1) break;
143 if (aFin <= 2) break;
148 if (aFin <= 3) break;
153 if (aFin <= 4) break;
158 if (aFin <= 5) break;
163 if (aFin <= 6) break;
168 if (aFin <= 7) break;
173 if (aFin <= 8) break;
178 if (aFin <= 9) break;
183 if (aFin <= 10) break;
188 if (aFin <= 11) break;
193 if (aFin <= 12) break;
198 if (aFin <= 13) break;
203 if (aFin <= 14) break;
208 if (aFin <= 15) break;
214 static void OpenMin(const gp_Dir& V,Bnd_Box& B) {
218 if (V.IsParallel(OX,Precision::Angular()))
220 else if (V.IsParallel(OY,Precision::Angular()))
222 else if (V.IsParallel(OZ,Precision::Angular()))
225 B.OpenXmin();B.OpenYmin();B.OpenZmin();
229 static void OpenMax(const gp_Dir& V,Bnd_Box& B) {
233 if (V.IsParallel(OX,Precision::Angular()))
235 else if (V.IsParallel(OY,Precision::Angular()))
237 else if (V.IsParallel(OZ,Precision::Angular()))
240 B.OpenXmax();B.OpenYmax();B.OpenZmax();
244 static void OpenMinMax(const gp_Dir& V,Bnd_Box& B) {
248 if (V.IsParallel(OX,Precision::Angular())) {
249 B.OpenXmax();B.OpenXmin();
251 else if (V.IsParallel(OY,Precision::Angular())) {
252 B.OpenYmax();B.OpenYmin();
254 else if (V.IsParallel(OZ,Precision::Angular())) {
255 B.OpenZmax();B.OpenZmin();
258 B.OpenXmin();B.OpenYmin();B.OpenZmin();
259 B.OpenXmax();B.OpenYmax();B.OpenZmax();
263 static void OpenMin(const gp_Dir2d& V,Bnd_Box2d& B) {
266 if (V.IsParallel(OX,Precision::Angular()))
268 else if (V.IsParallel(OY,Precision::Angular()))
271 B.OpenXmin();B.OpenYmin();
275 static void OpenMax(const gp_Dir2d& V,Bnd_Box2d& B) {
278 if (V.IsParallel(OX,Precision::Angular()))
280 else if (V.IsParallel(OY,Precision::Angular()))
283 B.OpenXmax();B.OpenYmax();
287 static void OpenMinMax(const gp_Dir2d& V,Bnd_Box2d& B) {
290 if (V.IsParallel(OX,Precision::Angular())) {
291 B.OpenXmax();B.OpenXmin();
293 else if (V.IsParallel(OY,Precision::Angular())) {
294 B.OpenYmax();B.OpenYmin();
297 B.OpenXmin();B.OpenYmin();
298 B.OpenXmax();B.OpenYmax();
303 void BndLib::Add( const gp_Lin& L,const Standard_Real P1,
304 const Standard_Real P2,
305 const Standard_Real Tol, Bnd_Box& B) {
307 if (Precision::IsNegativeInfinite(P1)) {
308 if (Precision::IsNegativeInfinite(P2)) {
309 Standard_Failure::Raise("BndLib::bad parameter");
311 else if (Precision::IsPositiveInfinite(P2)) {
312 OpenMinMax(L.Direction(),B);
313 B.Add(ElCLib::Value(0.,L));
316 OpenMin(L.Direction(),B);
317 B.Add(ElCLib::Value(P2,L));
320 else if (Precision::IsPositiveInfinite(P1)) {
321 if (Precision::IsNegativeInfinite(P2)) {
322 OpenMinMax(L.Direction(),B);
323 B.Add(ElCLib::Value(0.,L));
325 else if (Precision::IsPositiveInfinite(P2)) {
326 Standard_Failure::Raise("BndLib::bad parameter");
329 OpenMax(L.Direction(),B);
330 B.Add(ElCLib::Value(P2,L));
334 B.Add(ElCLib::Value(P1,L));
335 if (Precision::IsNegativeInfinite(P2)) {
336 OpenMin(L.Direction(),B);
338 else if (Precision::IsPositiveInfinite(P2)){
339 OpenMax(L.Direction(),B);
342 B.Add(ElCLib::Value(P2,L));
348 void BndLib::Add( const gp_Lin2d& L,const Standard_Real P1,
349 const Standard_Real P2,
350 const Standard_Real Tol, Bnd_Box2d& B) {
352 if (Precision::IsNegativeInfinite(P1)) {
353 if (Precision::IsNegativeInfinite(P2)) {
354 Standard_Failure::Raise("BndLib::bad parameter");
356 else if (Precision::IsPositiveInfinite(P2)) {
357 OpenMinMax(L.Direction(),B);
358 B.Add(ElCLib::Value(0.,L));
361 OpenMin(L.Direction(),B);
362 B.Add(ElCLib::Value(P2,L));
365 else if (Precision::IsPositiveInfinite(P1)) {
366 if (Precision::IsNegativeInfinite(P2)) {
367 OpenMinMax(L.Direction(),B);
368 B.Add(ElCLib::Value(0.,L));
370 else if (Precision::IsPositiveInfinite(P2)) {
371 Standard_Failure::Raise("BndLib::bad parameter");
374 OpenMax(L.Direction(),B);
375 B.Add(ElCLib::Value(P2,L));
379 B.Add(ElCLib::Value(P1,L));
380 if (Precision::IsNegativeInfinite(P2)) {
381 OpenMin(L.Direction(),B);
383 else if (Precision::IsPositiveInfinite(P2)){
384 OpenMax(L.Direction(),B);
387 B.Add(ElCLib::Value(P2,L));
393 void BndLib::Add( const gp_Circ& C, const Standard_Real Tol, Bnd_Box& B)
395 Standard_Real U1 = 0., U2 = 2.*M_PI;
396 Add(C, U1, U2, Tol, B);
399 void BndLib::Add(const gp_Circ& C,
400 const Standard_Real U1,
401 const Standard_Real U2,
402 const Standard_Real Tol,
405 Standard_Real period = 2.*M_PI - Epsilon(2.*M_PI);
407 Standard_Real utrim1 = U1, utrim2 = U2;
415 Standard_Real tol = Epsilon(1.);
416 ElCLib::AdjustPeriodic(0., 2.*M_PI,
420 Standard_Real R = C.Radius();
421 gp_XYZ O = C.Location().XYZ();
422 gp_XYZ Xd = C.XAxis().Direction().XYZ();
423 gp_XYZ Yd = C.YAxis().Direction().XYZ();
424 const gp_Ax2& pos = C.Position();
427 Standard_Real xmin, xmax, txmin, txmax;
428 if(Abs(Xd.X()) > gp::Resolution())
430 txmin = ATan(Yd.X() / Xd.X());
431 txmin = ElCLib::InPeriod(txmin, 0., 2.*M_PI);
437 txmax = txmin <= M_PI? txmin + M_PI : txmin - M_PI;
438 xmin = R * Cos(txmin) * Xd.X() + R * Sin(txmin) * Yd.X() + O.X();
439 xmax = R * Cos(txmax) * Xd.X() + R * Sin(txmax) * Yd.X() + O.X();
450 Standard_Real ymin, ymax, tymin, tymax;
451 if(Abs(Xd.Y()) > gp::Resolution())
453 tymin = ATan(Yd.Y() / Xd.Y());
454 tymin = ElCLib::InPeriod(tymin, 0., 2.*M_PI);
460 tymax = tymin <= M_PI? tymin + M_PI : tymin - M_PI;
461 ymin = R * Cos(tymin) * Xd.Y() + R * Sin(tymin) * Yd.Y() + O.Y();
462 ymax = R * Cos(tymax) * Xd.Y() + R * Sin(tymax) * Yd.Y() + O.Y();
473 Standard_Real zmin, zmax, tzmin, tzmax;
474 if(Abs(Xd.Z()) > gp::Resolution())
476 tzmin = ATan(Yd.Z() / Xd.Z());
477 tzmin = ElCLib::InPeriod(tzmin, 0., 2.*M_PI);
483 tzmax = tzmin <= M_PI? tzmin + M_PI : tzmin - M_PI;
484 zmin = R * Cos(tzmin) * Xd.Z() + R * Sin(tzmin) * Yd.Z() + O.Z();
485 zmax = R * Cos(tzmax) * Xd.Z() + R * Sin(tzmax) * Yd.Z() + O.Z();
496 if(utrim2 - utrim1 >= period)
498 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
502 gp_Pnt P = ElCLib::CircleValue(utrim1, pos, R);
504 P = ElCLib::CircleValue(utrim2, pos, R);
506 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
507 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
508 Standard_Real gap = B.GetGap();
516 txmin = ElCLib::InPeriod(txmin, utrim1, utrim1 + 2. * M_PI);
517 if(txmin >= utrim1 && txmin <= utrim2)
519 Xmin = Min(xmin, Xmin);
521 txmax = ElCLib::InPeriod(txmax, utrim1, utrim1 + 2. * M_PI);
522 if(txmax >= utrim1 && txmax <= utrim2)
524 Xmax = Max(xmax, Xmax);
527 tymin = ElCLib::InPeriod(tymin, utrim1, utrim1 + 2. * M_PI);
528 if(tymin >= utrim1 && tymin <= utrim2)
530 Ymin = Min(ymin, Ymin);
532 tymax = ElCLib::InPeriod(tymax, utrim1, utrim1 + 2. * M_PI);
533 if(tymax >= utrim1 && tymax <= utrim2)
535 Ymax = Max(ymax, Ymax);
538 tzmin = ElCLib::InPeriod(tzmin, utrim1, utrim1 + 2. * M_PI);
539 if(tzmin >= utrim1 && tzmin <= utrim2)
541 Zmin = Min(zmin, Zmin);
543 tzmax = ElCLib::InPeriod(tzmax, utrim1, utrim1 + 2. * M_PI);
544 if(tzmax >= utrim1 && tzmax <= utrim2)
546 Zmax = Max(zmax, Zmax);
549 B.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
555 void BndLib::Add( const gp_Circ2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
557 Standard_Real R = C.Radius();
558 gp_XY O = C.Location().XY();
559 gp_XY Xd = C.XAxis().Direction().XY();
560 gp_XY Yd = C.YAxis().Direction().XY();
561 B.Add(gp_Pnt2d(O -R*Xd -R*Yd));
562 B.Add(gp_Pnt2d(O -R*Xd +R*Yd));
563 B.Add(gp_Pnt2d(O +R*Xd -R*Yd));
564 B.Add(gp_Pnt2d(O +R*Xd +R*Yd));
568 void BndLib::Add(const gp_Circ2d& C,const Standard_Real P1,
569 const Standard_Real P2,
570 const Standard_Real Tol, Bnd_Box2d& B) {
572 Compute(P1,P2,C.Radius(),C.Radius(),gp_Pnt2d(C.XAxis().Direction().XY()),
573 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
577 void BndLib::Add(const gp_Elips& C, const Standard_Real Tol, Bnd_Box& B)
579 Standard_Real U1 = 0., U2 = 2.*M_PI;
580 Add(C, U1, U2, Tol, B);
583 void BndLib::Add(const gp_Elips& C,
584 const Standard_Real U1,
585 const Standard_Real U2,
586 const Standard_Real Tol,
589 Standard_Real period = 2.*M_PI - Epsilon(2.*M_PI);
591 Standard_Real utrim1 = U1, utrim2 = U2;
599 Standard_Real tol = Epsilon(1.);
600 ElCLib::AdjustPeriodic(0., 2.*M_PI,
604 Standard_Real MajR = C.MajorRadius();
605 Standard_Real MinR = C.MinorRadius();
606 gp_XYZ O = C.Location().XYZ();
607 gp_XYZ Xd = C.XAxis().Direction().XYZ();
608 gp_XYZ Yd = C.YAxis().Direction().XYZ();
609 const gp_Ax2& pos = C.Position();
612 Standard_Real xmin, xmax, txmin, txmax;
613 if(Abs(Xd.X()) > gp::Resolution())
615 txmin = ATan((MinR*Yd.X()) / (MajR*Xd.X()));
616 txmin = ElCLib::InPeriod(txmin, 0., 2.*M_PI);
622 txmax = txmin <= M_PI? txmin + M_PI : txmin - M_PI;
623 xmin = MajR * Cos(txmin) * Xd.X() + MinR * Sin(txmin) * Yd.X() + O.X();
624 xmax = MajR * Cos(txmax) * Xd.X() + MinR * Sin(txmax) * Yd.X() + O.X();
635 Standard_Real ymin, ymax, tymin, tymax;
636 if(Abs(Xd.Y()) > gp::Resolution())
638 tymin = ATan((MinR*Yd.Y()) / (MajR*Xd.Y()));
639 tymin = ElCLib::InPeriod(tymin, 0., 2.*M_PI);
645 tymax = tymin <= M_PI? tymin + M_PI : tymin - M_PI;
646 ymin = MajR * Cos(tymin) * Xd.Y() + MinR * Sin(tymin) * Yd.Y() + O.Y();
647 ymax = MajR * Cos(tymax) * Xd.Y() + MinR * Sin(tymax) * Yd.Y() + O.Y();
658 Standard_Real zmin, zmax, tzmin, tzmax;
659 if(Abs(Xd.Z()) > gp::Resolution())
661 tzmin = ATan((MinR*Yd.Z()) / (MajR*Xd.Z()));
662 tzmin = ElCLib::InPeriod(tzmin, 0., 2.*M_PI);
668 tzmax = tzmin <= M_PI? tzmin + M_PI : tzmin - M_PI;
669 zmin = MajR * Cos(tzmin) * Xd.Z() + MinR * Sin(tzmin) * Yd.Z() + O.Z();
670 zmax = MajR * Cos(tzmax) * Xd.Z() + MinR * Sin(tzmax) * Yd.Z() + O.Z();
681 if(utrim2 - utrim1 >= period)
683 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
687 gp_Pnt P = ElCLib::EllipseValue(utrim1, pos, MajR, MinR);
689 P = ElCLib::EllipseValue(utrim2, pos, MajR, MinR);
691 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
692 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
693 Standard_Real gap = B.GetGap();
701 txmin = ElCLib::InPeriod(txmin, utrim1, utrim1 + 2. * M_PI);
702 if(txmin >= utrim1 && txmin <= utrim2)
704 Xmin = Min(xmin, Xmin);
706 txmax = ElCLib::InPeriod(txmax, utrim1, utrim1 + 2. * M_PI);
707 if(txmax >= utrim1 && txmax <= utrim2)
709 Xmax = Max(xmax, Xmax);
712 tymin = ElCLib::InPeriod(tymin, utrim1, utrim1 + 2. * M_PI);
713 if(tymin >= utrim1 && tymin <= utrim2)
715 Ymin = Min(ymin, Ymin);
717 tymax = ElCLib::InPeriod(tymax, utrim1, utrim1 + 2. * M_PI);
718 if(tymax >= utrim1 && tymax <= utrim2)
720 Ymax = Max(ymax, Ymax);
723 tzmin = ElCLib::InPeriod(tzmin, utrim1, utrim1 + 2. * M_PI);
724 if(tzmin >= utrim1 && tzmin <= utrim2)
726 Zmin = Min(zmin, Zmin);
728 tzmax = ElCLib::InPeriod(tzmax, utrim1, utrim1 + 2. * M_PI);
729 if(tzmax >= utrim1 && tzmax <= utrim2)
731 Zmax = Max(zmax, Zmax);
734 B.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
740 void BndLib::Add( const gp_Elips2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
742 Standard_Real Ra= C.MajorRadius();
743 Standard_Real Rb= C.MinorRadius();
744 gp_XY Xd = C.XAxis().Direction().XY();
745 gp_XY Yd = C.YAxis().Direction().XY();
746 gp_XY O = C.Location().XY();
747 B.Add(gp_Pnt2d(O +Ra*Xd +Rb*Yd));
748 B.Add(gp_Pnt2d(O -Ra*Xd +Rb*Yd));
749 B.Add(gp_Pnt2d(O -Ra*Xd -Rb*Yd));
750 B.Add(gp_Pnt2d(O +Ra*Xd -Rb*Yd));
754 void BndLib::Add( const gp_Elips2d& C,const Standard_Real P1,
755 const Standard_Real P2,
756 const Standard_Real Tol, Bnd_Box2d& B) {
758 Compute(P1,P2,C.MajorRadius(),C.MinorRadius(),
759 gp_Pnt2d(C.XAxis().Direction().XY()),
760 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
764 void BndLib::Add( const gp_Parab& P,const Standard_Real P1,
765 const Standard_Real P2,
766 const Standard_Real Tol, Bnd_Box& B) {
768 if (Precision::IsNegativeInfinite(P1)) {
769 if (Precision::IsNegativeInfinite(P2)) {
770 Standard_Failure::Raise("BndLib::bad parameter");
772 else if (Precision::IsPositiveInfinite(P2)) {
773 B.OpenXmax();B.OpenYmax();B.OpenZmax();
776 B.Add(ElCLib::Value(P2,P));
778 B.OpenXmin();B.OpenYmin();B.OpenZmin();
780 else if (Precision::IsPositiveInfinite(P1)) {
781 if (Precision::IsNegativeInfinite(P2)) {
782 B.OpenXmin();B.OpenYmin();B.OpenZmin();
784 else if (Precision::IsPositiveInfinite(P2)) {
785 Standard_Failure::Raise("BndLib::bad parameter");
788 B.Add(ElCLib::Value(P2,P));
790 B.OpenXmax();B.OpenYmax();B.OpenZmax();
793 B.Add(ElCLib::Value(P1,P));
794 if (Precision::IsNegativeInfinite(P2)) {
795 B.OpenXmin();B.OpenYmin();B.OpenZmin();
797 else if (Precision::IsPositiveInfinite(P2)){
798 B.OpenXmax();B.OpenYmax();B.OpenZmax();
801 B.Add(ElCLib::Value(P2,P));
802 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
808 void BndLib::Add( const gp_Parab2d& P,const Standard_Real P1,
809 const Standard_Real P2,
810 const Standard_Real Tol, Bnd_Box2d& B) {
812 if (Precision::IsNegativeInfinite(P1)) {
813 if (Precision::IsNegativeInfinite(P2)) {
814 Standard_Failure::Raise("BndLib::bad parameter");
816 else if (Precision::IsPositiveInfinite(P2)) {
817 B.OpenXmax();B.OpenYmax();
820 B.Add(ElCLib::Value(P2,P));
822 B.OpenXmin();B.OpenYmin();
824 else if (Precision::IsPositiveInfinite(P1)) {
825 if (Precision::IsNegativeInfinite(P2)) {
826 B.OpenXmin();B.OpenYmin();
828 else if (Precision::IsPositiveInfinite(P2)) {
829 Standard_Failure::Raise("BndLib::bad parameter");
832 B.Add(ElCLib::Value(P2,P));
834 B.OpenXmax();B.OpenYmax();
837 B.Add(ElCLib::Value(P1,P));
838 if (Precision::IsNegativeInfinite(P2)) {
839 B.OpenXmin();B.OpenYmin();
841 else if (Precision::IsPositiveInfinite(P2)){
842 B.OpenXmax();B.OpenYmax();
845 B.Add(ElCLib::Value(P2,P));
846 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
852 //=======================================================================
855 //=======================================================================
856 void BndLib::Add(const gp_Hypr& H,
857 const Standard_Real P1,
858 const Standard_Real P2,
859 const Standard_Real Tol,
862 if (Precision::IsNegativeInfinite(P1)) {
863 if (Precision::IsNegativeInfinite(P2)) {
864 Standard_Failure::Raise("BndLib::bad parameter");
866 else if (Precision::IsPositiveInfinite(P2)) {
867 B.OpenXmax();B.OpenYmax();B.OpenZmax();
870 B.Add(ElCLib::Value(P2,H));
872 B.OpenXmin();B.OpenYmin();B.OpenZmin();
874 else if (Precision::IsPositiveInfinite(P1)) {
875 if (Precision::IsNegativeInfinite(P2)) {
876 B.OpenXmin();B.OpenYmin();B.OpenZmin();
878 else if (Precision::IsPositiveInfinite(P2)) {
879 Standard_Failure::Raise("BndLib::bad parameter");
882 B.Add(ElCLib::Value(P2,H));
884 B.OpenXmax();B.OpenYmax();B.OpenZmax();
887 B.Add(ElCLib::Value(P1,H));
888 if (Precision::IsNegativeInfinite(P2)) {
889 B.OpenXmin();B.OpenYmin();B.OpenZmin();
891 else if (Precision::IsPositiveInfinite(P2)){
892 B.OpenXmax();B.OpenYmax();B.OpenZmax();
895 ComputeBox(H, P1, P2, B);
901 void BndLib::Add(const gp_Hypr2d& H,const Standard_Real P1,
902 const Standard_Real P2,
903 const Standard_Real Tol, Bnd_Box2d& B) {
905 if (Precision::IsNegativeInfinite(P1)) {
906 if (Precision::IsNegativeInfinite(P2)) {
907 Standard_Failure::Raise("BndLib::bad parameter");
909 else if (Precision::IsPositiveInfinite(P2)) {
910 B.OpenXmax();B.OpenYmax();
913 B.Add(ElCLib::Value(P2,H));
915 B.OpenXmin();B.OpenYmin();
917 else if (Precision::IsPositiveInfinite(P1)) {
918 if (Precision::IsNegativeInfinite(P2)) {
919 B.OpenXmin();B.OpenYmin();
921 else if (Precision::IsPositiveInfinite(P2)) {
922 Standard_Failure::Raise("BndLib::bad parameter");
925 B.Add(ElCLib::Value(P2,H));
927 B.OpenXmax();B.OpenYmax();
930 B.Add(ElCLib::Value(P1,H));
931 if (Precision::IsNegativeInfinite(P2)) {
932 B.OpenXmin();B.OpenYmin();
934 else if (Precision::IsPositiveInfinite(P2)){
935 B.OpenXmax();B.OpenYmax();
938 B.Add(ElCLib::Value(P2,H));
939 if (P1*P2<0) B.Add(ElCLib::Value(0.,H));
945 static void ComputeCyl(const gp_Cylinder& Cyl,
946 const Standard_Real UMin, const Standard_Real UMax,
947 const Standard_Real VMin, const Standard_Real VMax,
950 gp_Circ aC = ElSLib::CylinderVIso(Cyl.Position(), Cyl.Radius(), VMin);
951 BndLib::Add(aC, UMin, UMax, 0., B);
953 gp_Vec aT = (VMax - VMin) * Cyl.Axis().Direction();
955 BndLib::Add(aC, UMin, UMax, 0., B);
958 void BndLib::Add( const gp_Cylinder& S,const Standard_Real UMin,
959 const Standard_Real UMax,const Standard_Real VMin,
960 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B)
962 if (Precision::IsNegativeInfinite(VMin))
964 if (Precision::IsNegativeInfinite(VMax))
966 Standard_Failure::Raise("BndLib::bad parameter");
968 else if (Precision::IsPositiveInfinite(VMax))
970 OpenMinMax(S.Axis().Direction(),B);
974 ComputeCyl(S, UMin, UMax, 0., VMax,B);
975 OpenMin(S.Axis().Direction(),B);
978 else if (Precision::IsPositiveInfinite(VMin))
980 if (Precision::IsNegativeInfinite(VMax))
982 OpenMinMax(S.Axis().Direction(),B);
984 else if (Precision::IsPositiveInfinite(VMax))
986 Standard_Failure::Raise("BndLib::bad parameter");
990 ComputeCyl(S, UMin, UMax, 0., VMax, B);
991 OpenMax(S.Axis().Direction(),B);
996 if (Precision::IsNegativeInfinite(VMax))
998 ComputeCyl(S, UMin, UMax, VMin, 0., B);
999 OpenMin(S.Axis().Direction(),B);
1001 else if (Precision::IsPositiveInfinite(VMax))
1003 ComputeCyl(S, UMin, UMax, VMin, 0., B);
1004 OpenMax(S.Axis().Direction(),B);
1008 ComputeCyl(S, UMin, UMax, VMin, VMax, B);
1016 void BndLib::Add( const gp_Cylinder& S,const Standard_Real VMin,
1017 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
1019 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
1022 static void ComputeCone (const gp_Cone& Cone,
1023 const Standard_Real UMin, const Standard_Real UMax,
1024 const Standard_Real VMin, const Standard_Real VMax,
1027 const gp_Ax3& aPos = Cone.Position();
1028 Standard_Real R = Cone.RefRadius();
1029 Standard_Real sang = Cone.SemiAngle();
1030 gp_Circ aC = ElSLib::ConeVIso(aPos, R, sang, VMin);
1031 if(aC.Radius() > Precision::Confusion())
1033 BndLib::Add(aC, UMin, UMax, 0., B);
1037 B.Add(aC.Location());
1040 aC = ElSLib::ConeVIso(aPos, R, sang, VMax);
1041 if(aC.Radius() > Precision::Confusion())
1043 BndLib::Add(aC, UMin, UMax, 0., B);
1047 B.Add(aC.Location());
1051 void BndLib::Add(const gp_Cone& S,const Standard_Real UMin,
1052 const Standard_Real UMax,const Standard_Real VMin,
1053 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
1055 Standard_Real A = S.SemiAngle();
1056 if (Precision::IsNegativeInfinite(VMin))
1058 if (Precision::IsNegativeInfinite(VMax))
1060 Standard_Failure::Raise("BndLib::bad parameter");
1062 else if (Precision::IsPositiveInfinite(VMax))
1064 gp_Dir D(Cos(A)*S.Axis().Direction());
1069 ComputeCone(S, UMin, UMax, 0., VMax, B);
1070 gp_Dir D(Cos(A)*S.Axis().Direction());
1075 else if (Precision::IsPositiveInfinite(VMin))
1077 if (Precision::IsNegativeInfinite(VMax))
1079 gp_Dir D(Cos(A)*S.Axis().Direction());
1082 else if (Precision::IsPositiveInfinite(VMax))
1084 Standard_Failure::Raise("BndLib::bad parameter");
1088 ComputeCone(S, UMin, UMax, 0., VMax, B);
1089 gp_Dir D(Cos(A)*S.Axis().Direction());
1095 if (Precision::IsNegativeInfinite(VMax))
1097 ComputeCone(S, UMin, UMax, VMin, 0., B);
1098 gp_Dir D(Cos(A)*S.Axis().Direction());
1101 else if (Precision::IsPositiveInfinite(VMax))
1103 ComputeCone(S, UMin, UMax, VMin, 0., B);
1104 gp_Dir D(Cos(A)*S.Axis().Direction());
1109 ComputeCone(S, UMin, UMax, VMin, VMax, B);
1116 void BndLib::Add( const gp_Cone& S,const Standard_Real VMin,
1117 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
1119 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
1122 static void ComputeSphere (const gp_Sphere& Sphere,
1123 const Standard_Real UMin, const Standard_Real UMax,
1124 const Standard_Real VMin, const Standard_Real VMax,
1127 gp_Pnt P = Sphere.Location();
1128 Standard_Real R = Sphere.Radius();
1129 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
1137 Standard_Real uper = 2. * M_PI - Precision::PConfusion();
1138 Standard_Real vper = M_PI - Precision::PConfusion();
1139 if (UMax - UMin >= uper && VMax - VMin >= vper)
1142 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
1147 Standard_Real umax = UMin + 2. * M_PI;
1148 const gp_Ax3& Pos = Sphere.Position();
1151 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1152 u = ElCLib::InPeriod(u, UMin, umax);
1153 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1159 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1160 u = ElCLib::InPeriod(u, UMin, umax);
1161 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1168 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1169 u = ElCLib::InPeriod(u, UMin, umax);
1170 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1176 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1177 u = ElCLib::InPeriod(u, UMin, umax);
1178 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1185 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1186 u = ElCLib::InPeriod(u, UMin, umax);
1187 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1193 ElSLib::SphereParameters(Pos, R, PExt, u, v);
1194 u = ElCLib::InPeriod(u, UMin, umax);
1195 if(u >= UMin && u <= UMax && v >= VMin && v <= VMax)
1200 // Add boundaries of patch
1202 gp_Circ aC = ElSLib::SphereUIso(Pos, R, UMin);
1203 BndLib::Add(aC, VMin, VMax, 0., B);
1204 aC = ElSLib::SphereUIso(Pos, R, UMax);
1205 BndLib::Add(aC, VMin, VMax, 0., B);
1207 aC = ElSLib::SphereVIso(Pos, R, VMin);
1208 BndLib::Add(aC, UMin, UMax, 0., B);
1209 aC = ElSLib::SphereVIso(Pos, R, VMax);
1210 BndLib::Add(aC, UMin, UMax, 0., B);
1214 void BndLib::Add(const gp_Sphere& S,const Standard_Real UMin,
1215 const Standard_Real UMax,const Standard_Real VMin,
1216 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B)
1218 ComputeSphere(S, UMin, UMax, VMin, VMax, B);
1222 void BndLib::Add( const gp_Sphere& S,const Standard_Real Tol, Bnd_Box& B)
1224 gp_Pnt P = S.Location();
1225 Standard_Real R = S.Radius();
1226 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
1233 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
1237 void BndLib::Add(const gp_Torus& S,const Standard_Real UMin,
1238 const Standard_Real UMax,const Standard_Real VMin,
1239 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
1241 Standard_Integer Fi1;
1242 Standard_Integer Fi2;
1244 Fi1 = (Standard_Integer )( VMax/(M_PI/4.));
1245 Fi2 = (Standard_Integer )( VMin/(M_PI/4.));
1248 Fi1 = (Standard_Integer )( VMin/(M_PI/4.));
1249 Fi2 = (Standard_Integer )( VMax/(M_PI/4.));
1253 Standard_Real Ra = S.MajorRadius();
1254 Standard_Real Ri = S.MinorRadius();
1256 if (Fi2<Fi1) return;
1259 #define addP0 (Compute(UMin,UMax,Ra+Ri,Ra+Ri,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),S.Location(),B))
1260 #define addP1 (Compute(UMin,UMax,Ra+Ri*SC,Ra+Ri*SC,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()+(Ri*SC)*S.Axis().Direction().XYZ()),B))
1261 #define addP2 (Compute(UMin,UMax,Ra,Ra,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()+Ri*S.Axis().Direction().XYZ()),B))
1262 #define addP3 (Compute(UMin,UMax,Ra-Ri*SC,Ra-Ri*SC,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()+(Ri*SC)*S.Axis().Direction().XYZ()),B))
1263 #define addP4 (Compute(UMin,UMax,Ra-Ri,Ra-Ri,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),S.Location(),B))
1264 #define addP5 (Compute(UMin,UMax,Ra-Ri*SC,Ra-Ri*SC,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()-(Ri*SC)*S.Axis().Direction().XYZ()),B))
1265 #define addP6 (Compute(UMin,UMax,Ra,Ra,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()-Ri*S.Axis().Direction().XYZ()),B))
1266 #define addP7 (Compute(UMin,UMax,Ra+Ri*SC,Ra+Ri*SC,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),gp_Pnt(S.Location().XYZ()-(Ri*SC)*S.Axis().Direction().XYZ()),B))
1272 if (Fi2 <= 0) break;
1277 if (Fi2 <= 1) break;
1282 if (Fi2 <= 2) break;
1287 if (Fi2 <= 3) break;
1292 if (Fi2 <= 4) break;
1297 if (Fi2 <= 5) break;
1302 if (Fi2 <= 6) break;
1307 if (Fi2 <= 7) break;
1337 void BndLib::Add( const gp_Torus& S,const Standard_Real Tol, Bnd_Box& B) {
1339 Standard_Real RMa = S.MajorRadius();
1340 Standard_Real Rmi = S.MinorRadius();
1341 gp_XYZ O = S.Location().XYZ();
1342 gp_XYZ Xd = S.XAxis().Direction().XYZ();
1343 gp_XYZ Yd = S.YAxis().Direction().XYZ();
1344 gp_XYZ Zd = S.Axis().Direction().XYZ();
1345 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd -(RMa+Rmi)*Yd+ Rmi*Zd));
1346 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd -(RMa+Rmi)*Yd- Rmi*Zd));
1347 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd -(RMa+Rmi)*Yd+ Rmi*Zd));
1348 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd -(RMa+Rmi)*Yd- Rmi*Zd));
1349 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd +(RMa+Rmi)*Yd+ Rmi*Zd));
1350 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd +(RMa+Rmi)*Yd- Rmi*Zd));
1351 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd +(RMa+Rmi)*Yd+ Rmi*Zd));
1352 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd +(RMa+Rmi)*Yd- Rmi*Zd));
1355 //=======================================================================
1356 //function : ComputeBox
1358 //=======================================================================
1359 Standard_Integer ComputeBox(const gp_Hypr& aHypr,
1360 const Standard_Real aT1,
1361 const Standard_Real aT2,
1364 Standard_Integer i, iErr;
1365 Standard_Real aRmaj, aRmin, aA, aB, aABP, aBAM, aT3, aCf, aEps;
1366 gp_Pnt aP1, aP2, aP3, aP0;
1369 aP1=ElCLib::Value(aT1, aHypr);
1370 aP2=ElCLib::Value(aT2, aHypr);
1376 aP0=ElCLib::Value(0., aHypr);
1383 const gp_Ax2& aPos=aHypr.Position();
1384 const gp_XYZ& aXDir = aPos.XDirection().XYZ();
1385 const gp_XYZ& aYDir = aPos.YDirection().XYZ();
1386 aRmaj=aHypr.MajorRadius();
1387 aRmin=aHypr.MinorRadius();
1390 for (i=1; i<=3; ++i) {
1391 aA=aRmin*aYDir.Coord(i);
1392 aB=aRmaj*aXDir.Coord(i);
1400 if (aABP<aEps || aBAM<aEps) {
1407 if (aT3<aT1 || aT3>aT2) {
1418 aP3=ElCLib::Value(aT3, aHypr);