0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / BndLib / BndLib.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15
42cf5bc1 16#include <Bnd_Box.hxx>
17#include <Bnd_Box2d.hxx>
18#include <BndLib.hxx>
7fd59977 19#include <ElCLib.hxx>
42cf5bc1 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>
28#include <gp_Lin.hxx>
29#include <gp_Lin2d.hxx>
30#include <gp_Parab.hxx>
31#include <gp_Parab2d.hxx>
7fd59977 32#include <gp_Pnt.hxx>
33#include <gp_Pnt2d.hxx>
42cf5bc1 34#include <gp_Sphere.hxx>
35#include <gp_Torus.hxx>
36#include <gp_XY.hxx>
37#include <gp_XYZ.hxx>
7fd59977 38#include <Precision.hxx>
39#include <Standard_Failure.hxx>
3ba87fdb 40#include <ElSLib.hxx>
7fd59977 41
bf12f076 42static
43 Standard_Integer ComputeBox(const gp_Hypr& aHypr,
44 const Standard_Real aT1,
45 const Standard_Real aT2,
46 Bnd_Box& aBox);
47
48
1190746b 49namespace
50{
51 //! Compute method
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,
56 BndBoxType& theB)
57 {
58 Standard_Real aTeta1;
59 Standard_Real aTeta2;
60 if(theP2 < theP1)
61 {
62 aTeta1 = theP2;
63 aTeta2 = theP1;
64 }
65 else
66 {
67 aTeta1 = theP1;
68 aTeta2 = theP2;
69 }
70
71 Standard_Real aDelta = Abs(aTeta2-aTeta1);
72 if(aDelta > 2. * M_PI)
73 {
74 aTeta1 = 0.;
75 aTeta2 = 2. * M_PI;
76 }
77 else
78 {
79 if(aTeta1 < 0.)
80 {
81 do{ aTeta1 += 2.*M_PI; } while (aTeta1 < 0.);
82 }
83 else if (aTeta1 > 2.*M_PI)
84 {
85 do { aTeta1 -= 2.*M_PI; } while (aTeta1 > 2.*M_PI);
86 }
87 aTeta2 = aTeta1 + aDelta;
88 }
89
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()));
96
97 Standard_Real aRam, aRbm;
98 if (aDelta > M_PI/8.)
99 {
100 // Main radiuses to take into account only 8 points (/cos(Pi/8.))
101 aRam = theRa/0.92387953251128674;
102 aRbm = theRb/0.92387953251128674;
103 }
104 else
105 {
106 // Main radiuses to take into account the arrow
107 Standard_Real aTc = cos(aDelta/2);
108 aRam = theRa/aTc;
109 aRbm = theRb/aTc;
110 }
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()));
113
114// cos or sin M_PI/4.
115#define PI4 0.70710678118654746
116
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()))
126
127 Standard_Integer aDeb = (Standard_Integer )( aTeta1/(M_PI/4.));
128 Standard_Integer aFin = (Standard_Integer )( aTeta2/(M_PI/4.));
129 aDeb++;
130
131 if (aDeb > aFin) return;
132
133 switch (aDeb)
134 {
135 case 1:
136 {
137 addPoint1;
138 if (aFin <= 1) break;
139 }
140 case 2:
141 {
142 addPoint2;
143 if (aFin <= 2) break;
144 }
145 case 3:
146 {
147 addPoint3;
148 if (aFin <= 3) break;
149 }
150 case 4:
151 {
152 addPoint4;
153 if (aFin <= 4) break;
154 }
155 case 5:
156 {
157 addPoint5;
158 if (aFin <= 5) break;
159 }
160 case 6:
161 {
162 addPoint6;
163 if (aFin <= 6) break;
164 }
165 case 7:
166 {
167 addPoint7;
168 if (aFin <= 7) break;
169 }
170 case 8:
171 {
172 addPoint0;
173 if (aFin <= 8) break;
174 }
175 case 9:
176 {
177 addPoint1;
178 if (aFin <= 9) break;
179 }
180 case 10:
181 {
182 addPoint2;
183 if (aFin <= 10) break;
184 }
185 case 11:
186 {
187 addPoint3;
188 if (aFin <= 11) break;
189 }
190 case 12:
191 {
192 addPoint4;
193 if (aFin <= 12) break;
194 }
195 case 13:
196 {
197 addPoint5;
198 if (aFin <= 13) break;
199 }
200 case 14:
201 {
202 addPoint6;
203 if (aFin <= 14) break;
204 }
205 case 15:
206 {
207 addPoint7;
208 if (aFin <= 15) break;
209 }
210 }
211 }
212} // end namespace
b311480e 213
7fd59977 214static void OpenMin(const gp_Dir& V,Bnd_Box& B) {
215 gp_Dir OX(1.,0.,0.);
216 gp_Dir OY(0.,1.,0.);
217 gp_Dir OZ(0.,0.,1.);
218 if (V.IsParallel(OX,Precision::Angular()))
219 B.OpenXmin();
220 else if (V.IsParallel(OY,Precision::Angular()))
221 B.OpenYmin();
222 else if (V.IsParallel(OZ,Precision::Angular()))
223 B.OpenZmin();
224 else {
225 B.OpenXmin();B.OpenYmin();B.OpenZmin();
226 }
227}
228
229static void OpenMax(const gp_Dir& V,Bnd_Box& B) {
230 gp_Dir OX(1.,0.,0.);
231 gp_Dir OY(0.,1.,0.);
232 gp_Dir OZ(0.,0.,1.);
233 if (V.IsParallel(OX,Precision::Angular()))
234 B.OpenXmax();
235 else if (V.IsParallel(OY,Precision::Angular()))
236 B.OpenYmax();
237 else if (V.IsParallel(OZ,Precision::Angular()))
238 B.OpenZmax();
239 else {
240 B.OpenXmax();B.OpenYmax();B.OpenZmax();
241 }
242}
243
244static void OpenMinMax(const gp_Dir& V,Bnd_Box& B) {
245 gp_Dir OX(1.,0.,0.);
246 gp_Dir OY(0.,1.,0.);
247 gp_Dir OZ(0.,0.,1.);
248 if (V.IsParallel(OX,Precision::Angular())) {
249 B.OpenXmax();B.OpenXmin();
250 }
251 else if (V.IsParallel(OY,Precision::Angular())) {
252 B.OpenYmax();B.OpenYmin();
253 }
254 else if (V.IsParallel(OZ,Precision::Angular())) {
255 B.OpenZmax();B.OpenZmin();
256 }
257 else {
258 B.OpenXmin();B.OpenYmin();B.OpenZmin();
259 B.OpenXmax();B.OpenYmax();B.OpenZmax();
260 }
261}
262
263static void OpenMin(const gp_Dir2d& V,Bnd_Box2d& B) {
264 gp_Dir2d OX(1.,0.);
265 gp_Dir2d OY(0.,1.);
266 if (V.IsParallel(OX,Precision::Angular()))
267 B.OpenXmin();
268 else if (V.IsParallel(OY,Precision::Angular()))
269 B.OpenYmin();
270 else {
271 B.OpenXmin();B.OpenYmin();
272 }
273}
274
275static void OpenMax(const gp_Dir2d& V,Bnd_Box2d& B) {
276 gp_Dir2d OX(1.,0.);
277 gp_Dir2d OY(0.,1.);
278 if (V.IsParallel(OX,Precision::Angular()))
279 B.OpenXmax();
280 else if (V.IsParallel(OY,Precision::Angular()))
281 B.OpenYmax();
282 else {
283 B.OpenXmax();B.OpenYmax();
284 }
285}
286
287static void OpenMinMax(const gp_Dir2d& V,Bnd_Box2d& B) {
288 gp_Dir2d OX(1.,0.);
289 gp_Dir2d OY(0.,1.);
290 if (V.IsParallel(OX,Precision::Angular())) {
291 B.OpenXmax();B.OpenXmin();
292 }
293 else if (V.IsParallel(OY,Precision::Angular())) {
294 B.OpenYmax();B.OpenYmin();
295 }
296 else {
297 B.OpenXmin();B.OpenYmin();
298 B.OpenXmax();B.OpenYmax();
299 }
300}
301
302
303void BndLib::Add( const gp_Lin& L,const Standard_Real P1,
bf12f076 304 const Standard_Real P2,
305 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 306
307 if (Precision::IsNegativeInfinite(P1)) {
308 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 309 throw Standard_Failure("BndLib::bad parameter");
7fd59977 310 }
311 else if (Precision::IsPositiveInfinite(P2)) {
312 OpenMinMax(L.Direction(),B);
313 B.Add(ElCLib::Value(0.,L));
314 }
315 else {
316 OpenMin(L.Direction(),B);
317 B.Add(ElCLib::Value(P2,L));
318 }
319 }
320 else if (Precision::IsPositiveInfinite(P1)) {
321 if (Precision::IsNegativeInfinite(P2)) {
322 OpenMinMax(L.Direction(),B);
323 B.Add(ElCLib::Value(0.,L));
324 }
325 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 326 throw Standard_Failure("BndLib::bad parameter");
7fd59977 327 }
328 else {
329 OpenMax(L.Direction(),B);
330 B.Add(ElCLib::Value(P2,L));
331 }
332 }
333 else {
334 B.Add(ElCLib::Value(P1,L));
335 if (Precision::IsNegativeInfinite(P2)) {
336 OpenMin(L.Direction(),B);
337 }
338 else if (Precision::IsPositiveInfinite(P2)){
339 OpenMax(L.Direction(),B);
340 }
341 else {
342 B.Add(ElCLib::Value(P2,L));
343 }
344 }
345 B.Enlarge(Tol);
346}
347
348void BndLib::Add( const gp_Lin2d& L,const Standard_Real P1,
bf12f076 349 const Standard_Real P2,
350 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 351
352 if (Precision::IsNegativeInfinite(P1)) {
353 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 354 throw Standard_Failure("BndLib::bad parameter");
7fd59977 355 }
356 else if (Precision::IsPositiveInfinite(P2)) {
357 OpenMinMax(L.Direction(),B);
358 B.Add(ElCLib::Value(0.,L));
359 }
360 else {
361 OpenMin(L.Direction(),B);
362 B.Add(ElCLib::Value(P2,L));
363 }
364 }
365 else if (Precision::IsPositiveInfinite(P1)) {
366 if (Precision::IsNegativeInfinite(P2)) {
367 OpenMinMax(L.Direction(),B);
368 B.Add(ElCLib::Value(0.,L));
369 }
370 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 371 throw Standard_Failure("BndLib::bad parameter");
7fd59977 372 }
373 else {
374 OpenMax(L.Direction(),B);
375 B.Add(ElCLib::Value(P2,L));
376 }
377 }
378 else {
379 B.Add(ElCLib::Value(P1,L));
380 if (Precision::IsNegativeInfinite(P2)) {
381 OpenMin(L.Direction(),B);
382 }
383 else if (Precision::IsPositiveInfinite(P2)){
384 OpenMax(L.Direction(),B);
385 }
386 else {
387 B.Add(ElCLib::Value(P2,L));
388 }
389 }
390 B.Enlarge(Tol);
391}
392
3ba87fdb 393void BndLib::Add( const gp_Circ& C, const Standard_Real Tol, Bnd_Box& B)
394{
395 Standard_Real U1 = 0., U2 = 2.*M_PI;
396 Add(C, U1, U2, Tol, B);
397}
398
399void BndLib::Add(const gp_Circ& C,
400 const Standard_Real U1,
401 const Standard_Real U2,
402 const Standard_Real Tol,
403 Bnd_Box& B)
404{
405 Standard_Real period = 2.*M_PI - Epsilon(2.*M_PI);
7fd59977 406
3ba87fdb 407 Standard_Real utrim1 = U1, utrim2 = U2;
408 if(U2 - U1 > period)
409 {
410 utrim1 = 0.;
411 utrim2 = 2.*M_PI;
412 }
413 else
414 {
415 Standard_Real tol = Epsilon(1.);
416 ElCLib::AdjustPeriodic(0., 2.*M_PI,
417 tol,
418 utrim1, utrim2);
419 }
7fd59977 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();
3ba87fdb 424 const gp_Ax2& pos = C.Position();
425 //
426 Standard_Real tt;
427 Standard_Real xmin, xmax, txmin, txmax;
428 if(Abs(Xd.X()) > gp::Resolution())
429 {
430 txmin = ATan(Yd.X() / Xd.X());
431 txmin = ElCLib::InPeriod(txmin, 0., 2.*M_PI);
432 }
433 else
434 {
435 txmin = M_PI/ 2.;
436 }
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();
440 if(xmin > xmax)
441 {
442 tt = xmin;
443 xmin = xmax;
444 xmax = tt;
445 tt = txmin;
446 txmin = txmax;
447 txmax = tt;
448 }
449 //
450 Standard_Real ymin, ymax, tymin, tymax;
451 if(Abs(Xd.Y()) > gp::Resolution())
452 {
453 tymin = ATan(Yd.Y() / Xd.Y());
454 tymin = ElCLib::InPeriod(tymin, 0., 2.*M_PI);
455 }
456 else
457 {
458 tymin = M_PI/ 2.;
459 }
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();
463 if(ymin > ymax)
464 {
465 tt = ymin;
466 ymin = ymax;
467 ymax = tt;
468 tt = tymin;
469 tymin = tymax;
470 tymax = tt;
471 }
472 //
473 Standard_Real zmin, zmax, tzmin, tzmax;
474 if(Abs(Xd.Z()) > gp::Resolution())
475 {
476 tzmin = ATan(Yd.Z() / Xd.Z());
477 tzmin = ElCLib::InPeriod(tzmin, 0., 2.*M_PI);
478 }
479 else
480 {
481 tzmin = M_PI/ 2.;
482 }
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();
486 if(zmin > zmax)
487 {
488 tt = zmin;
489 zmin = zmax;
490 zmax = tt;
491 tt = tzmin;
492 tzmin = tzmax;
493 tzmax = tt;
494 }
495 //
496 if(utrim2 - utrim1 >= period)
497 {
498 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
499 }
500 else
501 {
502 gp_Pnt P = ElCLib::CircleValue(utrim1, pos, R);
503 B.Add(P);
504 P = ElCLib::CircleValue(utrim2, pos, R);
505 B.Add(P);
506 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
507 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
508 Standard_Real gap = B.GetGap();
509 Xmin += gap;
510 Ymin += gap;
511 Zmin += gap;
512 Xmax -= gap;
513 Ymax -= gap;
514 Zmax -= gap;
515 //
516 txmin = ElCLib::InPeriod(txmin, utrim1, utrim1 + 2. * M_PI);
517 if(txmin >= utrim1 && txmin <= utrim2)
518 {
519 Xmin = Min(xmin, Xmin);
520 }
521 txmax = ElCLib::InPeriod(txmax, utrim1, utrim1 + 2. * M_PI);
522 if(txmax >= utrim1 && txmax <= utrim2)
523 {
524 Xmax = Max(xmax, Xmax);
525 }
526 //
527 tymin = ElCLib::InPeriod(tymin, utrim1, utrim1 + 2. * M_PI);
528 if(tymin >= utrim1 && tymin <= utrim2)
529 {
530 Ymin = Min(ymin, Ymin);
531 }
532 tymax = ElCLib::InPeriod(tymax, utrim1, utrim1 + 2. * M_PI);
533 if(tymax >= utrim1 && tymax <= utrim2)
534 {
535 Ymax = Max(ymax, Ymax);
536 }
537 //
538 tzmin = ElCLib::InPeriod(tzmin, utrim1, utrim1 + 2. * M_PI);
539 if(tzmin >= utrim1 && tzmin <= utrim2)
540 {
541 Zmin = Min(zmin, Zmin);
542 }
543 tzmax = ElCLib::InPeriod(tzmax, utrim1, utrim1 + 2. * M_PI);
544 if(tzmax >= utrim1 && tzmax <= utrim2)
545 {
546 Zmax = Max(zmax, Zmax);
547 }
548 //
549 B.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
550 }
551 //
7fd59977 552 B.Enlarge(Tol);
553}
554
555void BndLib::Add( const gp_Circ2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
556
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));
565 B.Enlarge(Tol);
566}
567
568void BndLib::Add(const gp_Circ2d& C,const Standard_Real P1,
bf12f076 569 const Standard_Real P2,
570 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 571
1190746b 572 Compute(P1,P2,C.Radius(),C.Radius(),gp_Pnt2d(C.XAxis().Direction().XY()),
573 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
7fd59977 574 B.Enlarge(Tol);
575}
576
3ba87fdb 577void BndLib::Add(const gp_Elips& C, const Standard_Real Tol, Bnd_Box& B)
578{
579 Standard_Real U1 = 0., U2 = 2.*M_PI;
580 Add(C, U1, U2, Tol, B);
7fd59977 581}
582
3ba87fdb 583void BndLib::Add(const gp_Elips& C,
584 const Standard_Real U1,
585 const Standard_Real U2,
586 const Standard_Real Tol,
587 Bnd_Box& B)
588{
589 Standard_Real period = 2.*M_PI - Epsilon(2.*M_PI);
7fd59977 590
3ba87fdb 591 Standard_Real utrim1 = U1, utrim2 = U2;
592 if(U2 - U1 > period)
593 {
594 utrim1 = 0.;
595 utrim2 = 2.*M_PI;
596 }
597 else
598 {
599 Standard_Real tol = Epsilon(1.);
600 ElCLib::AdjustPeriodic(0., 2.*M_PI,
601 tol,
602 utrim1, utrim2);
603 }
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();
610 //
611 Standard_Real tt;
612 Standard_Real xmin, xmax, txmin, txmax;
613 if(Abs(Xd.X()) > gp::Resolution())
614 {
615 txmin = ATan((MinR*Yd.X()) / (MajR*Xd.X()));
616 txmin = ElCLib::InPeriod(txmin, 0., 2.*M_PI);
617 }
618 else
619 {
620 txmin = M_PI/ 2.;
621 }
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();
625 if(xmin > xmax)
626 {
627 tt = xmin;
628 xmin = xmax;
629 xmax = tt;
630 tt = txmin;
631 txmin = txmax;
632 txmax = tt;
633 }
634 //
635 Standard_Real ymin, ymax, tymin, tymax;
636 if(Abs(Xd.Y()) > gp::Resolution())
637 {
638 tymin = ATan((MinR*Yd.Y()) / (MajR*Xd.Y()));
639 tymin = ElCLib::InPeriod(tymin, 0., 2.*M_PI);
640 }
641 else
642 {
643 tymin = M_PI/ 2.;
644 }
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();
648 if(ymin > ymax)
649 {
650 tt = ymin;
651 ymin = ymax;
652 ymax = tt;
653 tt = tymin;
654 tymin = tymax;
655 tymax = tt;
656 }
657 //
658 Standard_Real zmin, zmax, tzmin, tzmax;
659 if(Abs(Xd.Z()) > gp::Resolution())
660 {
661 tzmin = ATan((MinR*Yd.Z()) / (MajR*Xd.Z()));
662 tzmin = ElCLib::InPeriod(tzmin, 0., 2.*M_PI);
663 }
664 else
665 {
666 tzmin = M_PI/ 2.;
667 }
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();
671 if(zmin > zmax)
672 {
673 tt = zmin;
674 zmin = zmax;
675 zmax = tt;
676 tt = tzmin;
677 tzmin = tzmax;
678 tzmax = tt;
679 }
680 //
681 if(utrim2 - utrim1 >= period)
682 {
683 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
684 }
685 else
686 {
687 gp_Pnt P = ElCLib::EllipseValue(utrim1, pos, MajR, MinR);
688 B.Add(P);
689 P = ElCLib::EllipseValue(utrim2, pos, MajR, MinR);
690 B.Add(P);
691 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
692 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
693 Standard_Real gap = B.GetGap();
694 Xmin += gap;
695 Ymin += gap;
696 Zmin += gap;
697 Xmax -= gap;
698 Ymax -= gap;
699 Zmax -= gap;
700 //
701 txmin = ElCLib::InPeriod(txmin, utrim1, utrim1 + 2. * M_PI);
702 if(txmin >= utrim1 && txmin <= utrim2)
703 {
704 Xmin = Min(xmin, Xmin);
705 }
706 txmax = ElCLib::InPeriod(txmax, utrim1, utrim1 + 2. * M_PI);
707 if(txmax >= utrim1 && txmax <= utrim2)
708 {
709 Xmax = Max(xmax, Xmax);
710 }
711 //
712 tymin = ElCLib::InPeriod(tymin, utrim1, utrim1 + 2. * M_PI);
713 if(tymin >= utrim1 && tymin <= utrim2)
714 {
715 Ymin = Min(ymin, Ymin);
716 }
717 tymax = ElCLib::InPeriod(tymax, utrim1, utrim1 + 2. * M_PI);
718 if(tymax >= utrim1 && tymax <= utrim2)
719 {
720 Ymax = Max(ymax, Ymax);
721 }
722 //
723 tzmin = ElCLib::InPeriod(tzmin, utrim1, utrim1 + 2. * M_PI);
724 if(tzmin >= utrim1 && tzmin <= utrim2)
725 {
726 Zmin = Min(zmin, Zmin);
727 }
728 tzmax = ElCLib::InPeriod(tzmax, utrim1, utrim1 + 2. * M_PI);
729 if(tzmax >= utrim1 && tzmax <= utrim2)
730 {
731 Zmax = Max(zmax, Zmax);
732 }
733 //
734 B.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
735 }
736 //
7fd59977 737 B.Enlarge(Tol);
738}
739
740void BndLib::Add( const gp_Elips2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
741
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));
751 B.Enlarge(Tol);
752}
753
754void BndLib::Add( const gp_Elips2d& C,const Standard_Real P1,
bf12f076 755 const Standard_Real P2,
756 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 757
758 Compute(P1,P2,C.MajorRadius(),C.MinorRadius(),
bf12f076 759 gp_Pnt2d(C.XAxis().Direction().XY()),
760 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
7fd59977 761 B.Enlarge(Tol);
762}
763
764void BndLib::Add( const gp_Parab& P,const Standard_Real P1,
bf12f076 765 const Standard_Real P2,
766 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 767
768 if (Precision::IsNegativeInfinite(P1)) {
769 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 770 throw Standard_Failure("BndLib::bad parameter");
7fd59977 771 }
772 else if (Precision::IsPositiveInfinite(P2)) {
773 B.OpenXmax();B.OpenYmax();B.OpenZmax();
774 }
775 else {
776 B.Add(ElCLib::Value(P2,P));
777 }
778 B.OpenXmin();B.OpenYmin();B.OpenZmin();
779 }
780 else if (Precision::IsPositiveInfinite(P1)) {
781 if (Precision::IsNegativeInfinite(P2)) {
782 B.OpenXmin();B.OpenYmin();B.OpenZmin();
783 }
784 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 785 throw Standard_Failure("BndLib::bad parameter");
7fd59977 786 }
787 else {
788 B.Add(ElCLib::Value(P2,P));
789 }
790 B.OpenXmax();B.OpenYmax();B.OpenZmax();
791 }
792 else {
793 B.Add(ElCLib::Value(P1,P));
794 if (Precision::IsNegativeInfinite(P2)) {
795 B.OpenXmin();B.OpenYmin();B.OpenZmin();
796 }
797 else if (Precision::IsPositiveInfinite(P2)){
798 B.OpenXmax();B.OpenYmax();B.OpenZmax();
799 }
800 else {
801 B.Add(ElCLib::Value(P2,P));
802 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
803 }
804 }
805 B.Enlarge(Tol);
806}
807
808void BndLib::Add( const gp_Parab2d& P,const Standard_Real P1,
bf12f076 809 const Standard_Real P2,
810 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 811
812 if (Precision::IsNegativeInfinite(P1)) {
813 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 814 throw Standard_Failure("BndLib::bad parameter");
7fd59977 815 }
816 else if (Precision::IsPositiveInfinite(P2)) {
817 B.OpenXmax();B.OpenYmax();
818 }
819 else {
820 B.Add(ElCLib::Value(P2,P));
821 }
822 B.OpenXmin();B.OpenYmin();
823 }
824 else if (Precision::IsPositiveInfinite(P1)) {
825 if (Precision::IsNegativeInfinite(P2)) {
826 B.OpenXmin();B.OpenYmin();
827 }
828 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 829 throw Standard_Failure("BndLib::bad parameter");
7fd59977 830 }
831 else {
832 B.Add(ElCLib::Value(P2,P));
833 }
834 B.OpenXmax();B.OpenYmax();
835 }
836 else {
837 B.Add(ElCLib::Value(P1,P));
838 if (Precision::IsNegativeInfinite(P2)) {
839 B.OpenXmin();B.OpenYmin();
840 }
841 else if (Precision::IsPositiveInfinite(P2)){
842 B.OpenXmax();B.OpenYmax();
843 }
844 else {
845 B.Add(ElCLib::Value(P2,P));
846 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
847 }
848 }
849 B.Enlarge(Tol);
850}
851
bf12f076 852//=======================================================================
853//function : Add
854//purpose :
855//=======================================================================
856void BndLib::Add(const gp_Hypr& H,
857 const Standard_Real P1,
858 const Standard_Real P2,
859 const Standard_Real Tol,
860 Bnd_Box& B)
861{
7fd59977 862 if (Precision::IsNegativeInfinite(P1)) {
863 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 864 throw Standard_Failure("BndLib::bad parameter");
7fd59977 865 }
866 else if (Precision::IsPositiveInfinite(P2)) {
867 B.OpenXmax();B.OpenYmax();B.OpenZmax();
868 }
869 else {
870 B.Add(ElCLib::Value(P2,H));
871 }
872 B.OpenXmin();B.OpenYmin();B.OpenZmin();
873 }
874 else if (Precision::IsPositiveInfinite(P1)) {
875 if (Precision::IsNegativeInfinite(P2)) {
876 B.OpenXmin();B.OpenYmin();B.OpenZmin();
877 }
878 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 879 throw Standard_Failure("BndLib::bad parameter");
7fd59977 880 }
881 else {
882 B.Add(ElCLib::Value(P2,H));
883 }
884 B.OpenXmax();B.OpenYmax();B.OpenZmax();
885 }
886 else {
887 B.Add(ElCLib::Value(P1,H));
888 if (Precision::IsNegativeInfinite(P2)) {
889 B.OpenXmin();B.OpenYmin();B.OpenZmin();
890 }
891 else if (Precision::IsPositiveInfinite(P2)){
892 B.OpenXmax();B.OpenYmax();B.OpenZmax();
893 }
894 else {
bf12f076 895 ComputeBox(H, P1, P2, B);
7fd59977 896 }
897 }
898 B.Enlarge(Tol);
899}
900
901void BndLib::Add(const gp_Hypr2d& H,const Standard_Real P1,
bf12f076 902 const Standard_Real P2,
903 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 904
905 if (Precision::IsNegativeInfinite(P1)) {
906 if (Precision::IsNegativeInfinite(P2)) {
9775fa61 907 throw Standard_Failure("BndLib::bad parameter");
7fd59977 908 }
909 else if (Precision::IsPositiveInfinite(P2)) {
910 B.OpenXmax();B.OpenYmax();
911 }
912 else {
913 B.Add(ElCLib::Value(P2,H));
914 }
915 B.OpenXmin();B.OpenYmin();
916 }
917 else if (Precision::IsPositiveInfinite(P1)) {
918 if (Precision::IsNegativeInfinite(P2)) {
919 B.OpenXmin();B.OpenYmin();
920 }
921 else if (Precision::IsPositiveInfinite(P2)) {
9775fa61 922 throw Standard_Failure("BndLib::bad parameter");
7fd59977 923 }
924 else {
925 B.Add(ElCLib::Value(P2,H));
926 }
927 B.OpenXmax();B.OpenYmax();
928 }
929 else {
930 B.Add(ElCLib::Value(P1,H));
931 if (Precision::IsNegativeInfinite(P2)) {
932 B.OpenXmin();B.OpenYmin();
933 }
934 else if (Precision::IsPositiveInfinite(P2)){
935 B.OpenXmax();B.OpenYmax();
936 }
937 else {
938 B.Add(ElCLib::Value(P2,H));
939 if (P1*P2<0) B.Add(ElCLib::Value(0.,H));
940 }
941 }
942 B.Enlarge(Tol);
943}
944
3ba87fdb 945static void ComputeCyl(const gp_Cylinder& Cyl,
946 const Standard_Real UMin, const Standard_Real UMax,
947 const Standard_Real VMin, const Standard_Real VMax,
948 Bnd_Box& B)
949{
950 gp_Circ aC = ElSLib::CylinderVIso(Cyl.Position(), Cyl.Radius(), VMin);
951 BndLib::Add(aC, UMin, UMax, 0., B);
952 //
953 gp_Vec aT = (VMax - VMin) * Cyl.Axis().Direction();
954 aC.Translate(aT);
955 BndLib::Add(aC, UMin, UMax, 0., B);
956}
957
7fd59977 958void BndLib::Add( const gp_Cylinder& S,const Standard_Real UMin,
bf12f076 959 const Standard_Real UMax,const Standard_Real VMin,
3ba87fdb 960 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B)
961{
962 if (Precision::IsNegativeInfinite(VMin))
963 {
964 if (Precision::IsNegativeInfinite(VMax))
965 {
9775fa61 966 throw Standard_Failure("BndLib::bad parameter");
7fd59977 967 }
3ba87fdb 968 else if (Precision::IsPositiveInfinite(VMax))
969 {
970 OpenMinMax(S.Axis().Direction(),B);
7fd59977 971 }
3ba87fdb 972 else
973 {
974 ComputeCyl(S, UMin, UMax, 0., VMax,B);
7fd59977 975 OpenMin(S.Axis().Direction(),B);
976 }
977 }
3ba87fdb 978 else if (Precision::IsPositiveInfinite(VMin))
979 {
980 if (Precision::IsNegativeInfinite(VMax))
981 {
7fd59977 982 OpenMinMax(S.Axis().Direction(),B);
983 }
3ba87fdb 984 else if (Precision::IsPositiveInfinite(VMax))
985 {
9775fa61 986 throw Standard_Failure("BndLib::bad parameter");
7fd59977 987 }
3ba87fdb 988 else
989 {
990 ComputeCyl(S, UMin, UMax, 0., VMax, B);
7fd59977 991 OpenMax(S.Axis().Direction(),B);
992 }
7fd59977 993 }
3ba87fdb 994 else
995 {
996 if (Precision::IsNegativeInfinite(VMax))
997 {
998 ComputeCyl(S, UMin, UMax, VMin, 0., B);
7fd59977 999 OpenMin(S.Axis().Direction(),B);
1000 }
3ba87fdb 1001 else if (Precision::IsPositiveInfinite(VMax))
1002 {
1003 ComputeCyl(S, UMin, UMax, VMin, 0., B);
7fd59977 1004 OpenMax(S.Axis().Direction(),B);
1005 }
3ba87fdb 1006 else
1007 {
1008 ComputeCyl(S, UMin, UMax, VMin, VMax, B);
7fd59977 1009 }
1010 }
1011
1012 B.Enlarge(Tol);
1013
1014}
1015
1016void BndLib::Add( const gp_Cylinder& S,const Standard_Real VMin,
bf12f076 1017 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 1018
c6541a0c 1019 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
7fd59977 1020}
1021
3ba87fdb 1022static void ComputeCone (const gp_Cone& Cone,
1023 const Standard_Real UMin, const Standard_Real UMax,
1024 const Standard_Real VMin, const Standard_Real VMax,
1025 Bnd_Box& B)
1026{
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())
1032 {
1033 BndLib::Add(aC, UMin, UMax, 0., B);
1034 }
1035 else
1036 {
1037 B.Add(aC.Location());
1038 }
1039 //
1040 aC = ElSLib::ConeVIso(aPos, R, sang, VMax);
1041 if(aC.Radius() > Precision::Confusion())
1042 {
1043 BndLib::Add(aC, UMin, UMax, 0., B);
1044 }
1045 else
1046 {
1047 B.Add(aC.Location());
1048 }
1049}
1050
7fd59977 1051void BndLib::Add(const gp_Cone& S,const Standard_Real UMin,
bf12f076 1052 const Standard_Real UMax,const Standard_Real VMin,
1053 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 1054
7fd59977 1055 Standard_Real A = S.SemiAngle();
3ba87fdb 1056 if (Precision::IsNegativeInfinite(VMin))
1057 {
1058 if (Precision::IsNegativeInfinite(VMax))
1059 {
9775fa61 1060 throw Standard_Failure("BndLib::bad parameter");
7fd59977 1061 }
3ba87fdb 1062 else if (Precision::IsPositiveInfinite(VMax))
1063 {
7fd59977 1064 gp_Dir D(Cos(A)*S.Axis().Direction());
1065 OpenMinMax(D,B);
1066 }
3ba87fdb 1067 else
1068 {
1069 ComputeCone(S, UMin, UMax, 0., VMax, B);
7fd59977 1070 gp_Dir D(Cos(A)*S.Axis().Direction());
1071 OpenMin(D,B);
1072 }
1073
1074 }
3ba87fdb 1075 else if (Precision::IsPositiveInfinite(VMin))
1076 {
1077 if (Precision::IsNegativeInfinite(VMax))
1078 {
7fd59977 1079 gp_Dir D(Cos(A)*S.Axis().Direction());
1080 OpenMinMax(D,B);
1081 }
3ba87fdb 1082 else if (Precision::IsPositiveInfinite(VMax))
1083 {
9775fa61 1084 throw Standard_Failure("BndLib::bad parameter");
7fd59977 1085 }
3ba87fdb 1086 else
1087 {
1088 ComputeCone(S, UMin, UMax, 0., VMax, B);
7fd59977 1089 gp_Dir D(Cos(A)*S.Axis().Direction());
1090 OpenMax(D,B);
1091 }
7fd59977 1092 }
3ba87fdb 1093 else
1094 {
1095 if (Precision::IsNegativeInfinite(VMax))
1096 {
1097 ComputeCone(S, UMin, UMax, VMin, 0., B);
7fd59977 1098 gp_Dir D(Cos(A)*S.Axis().Direction());
1099 OpenMin(D,B);
1100 }
3ba87fdb 1101 else if (Precision::IsPositiveInfinite(VMax))
1102 {
1103 ComputeCone(S, UMin, UMax, VMin, 0., B);
7fd59977 1104 gp_Dir D(Cos(A)*S.Axis().Direction());
1105 OpenMax(D,B);
1106 }
3ba87fdb 1107 else
1108 {
1109 ComputeCone(S, UMin, UMax, VMin, VMax, B);
7fd59977 1110 }
1111 }
1112
7fd59977 1113 B.Enlarge(Tol);
1114}
1115
1116void BndLib::Add( const gp_Cone& S,const Standard_Real VMin,
bf12f076 1117 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 1118
c6541a0c 1119 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
7fd59977 1120}
1121
3ba87fdb 1122static void ComputeSphere (const gp_Sphere& Sphere,
1123 const Standard_Real UMin, const Standard_Real UMax,
1124 const Standard_Real VMin, const Standard_Real VMax,
1125 Bnd_Box& B)
1126{
1127 gp_Pnt P = Sphere.Location();
1128 Standard_Real R = Sphere.Radius();
1129 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
1130 xmin = P.X() - R;
1131 xmax = P.X() + R;
1132 ymin = P.Y() - R;
1133 ymax = P.Y() + R;
1134 zmin = P.Z() - R;
1135 zmax = P.Z() + R;
1136
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)
1140 {
1141 // a whole sphere
1142 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
1143 }
1144 else
1145 {
1146 Standard_Real u, v;
1147 Standard_Real umax = UMin + 2. * M_PI;
1148 const gp_Ax3& Pos = Sphere.Position();
1149 gp_Pnt PExt = P;
1150 PExt.SetX(xmin);
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)
1154 {
1155 B.Add(PExt);
1156 }
1157 //
1158 PExt.SetX(xmax);
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)
1162 {
1163 B.Add(PExt);
1164 }
1165 PExt.SetX(P.X());
1166 //
1167 PExt.SetY(ymin);
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)
1171 {
1172 B.Add(PExt);
1173 }
1174 //
1175 PExt.SetY(ymax);
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)
1179 {
1180 B.Add(PExt);
1181 }
1182 PExt.SetY(P.Y());
1183 //
1184 PExt.SetZ(zmin);
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)
1188 {
1189 B.Add(PExt);
1190 }
1191 //
1192 PExt.SetZ(zmax);
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)
1196 {
1197 B.Add(PExt);
1198 }
1199 //
1200 // Add boundaries of patch
1201 // UMin, UMax
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);
1206 // VMin, VMax
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);
1211 }
1212}
1213
7fd59977 1214void BndLib::Add(const gp_Sphere& S,const Standard_Real UMin,
bf12f076 1215 const Standard_Real UMax,const Standard_Real VMin,
3ba87fdb 1216 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B)
1217{
1218 ComputeSphere(S, UMin, UMax, VMin, VMax, B);
1219 B.Enlarge(Tol);
7fd59977 1220}
1221
3ba87fdb 1222void BndLib::Add( const gp_Sphere& S,const Standard_Real Tol, Bnd_Box& B)
1223{
1224 gp_Pnt P = S.Location();
7fd59977 1225 Standard_Real R = S.Radius();
3ba87fdb 1226 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
1227 xmin = P.X() - R;
1228 xmax = P.X() + R;
1229 ymin = P.Y() - R;
1230 ymax = P.Y() + R;
1231 zmin = P.Z() - R;
1232 zmax = P.Z() + R;
1233 B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
7fd59977 1234 B.Enlarge(Tol);
1235}
1236
1237void BndLib::Add(const gp_Torus& S,const Standard_Real UMin,
bf12f076 1238 const Standard_Real UMax,const Standard_Real VMin,
1239 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 1240
1241 Standard_Integer Fi1;
1242 Standard_Integer Fi2;
1243 if (VMax<VMin) {
c6541a0c
D
1244 Fi1 = (Standard_Integer )( VMax/(M_PI/4.));
1245 Fi2 = (Standard_Integer )( VMin/(M_PI/4.));
7fd59977 1246 }
1247 else {
c6541a0c
D
1248 Fi1 = (Standard_Integer )( VMin/(M_PI/4.));
1249 Fi2 = (Standard_Integer )( VMax/(M_PI/4.));
7fd59977 1250 }
1251 Fi2++;
1252
1253 Standard_Real Ra = S.MajorRadius();
1254 Standard_Real Ri = S.MinorRadius();
1255
1256 if (Fi2<Fi1) return;
1257
1258#define SC 0.71
1190746b 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))
7fd59977 1267
1268 switch (Fi1) {
1269 case 0 :
1270 {
1271 addP0;
1272 if (Fi2 <= 0) break;
1273 }
1274 case 1 :
1275 {
1276 addP1;
1277 if (Fi2 <= 1) break;
1278 }
1279 case 2 :
1280 {
1281 addP2;
1282 if (Fi2 <= 2) break;
1283 }
1284 case 3 :
1285 {
1286 addP3;
1287 if (Fi2 <= 3) break;
1288 }
1289 case 4 :
1290 {
1291 addP4;
1292 if (Fi2 <= 4) break;
1293 }
1294 case 5 :
1295 {
1296 addP5;
1297 if (Fi2 <= 5) break;
1298 }
1299 case 6 :
1300 {
1301 addP6;
1302 if (Fi2 <= 6) break;
1303 }
1304 case 7 :
1305 {
1306 addP7;
1307 if (Fi2 <= 7) break;
1308 }
1309 case 8 :
1310 default :
1311 {
1312 addP0;
1313 switch (Fi2) {
1314 case 15 :
bf12f076 1315 addP7;
7fd59977 1316 case 14 :
bf12f076 1317 addP6;
7fd59977 1318 case 13 :
bf12f076 1319 addP5;
7fd59977 1320 case 12 :
bf12f076 1321 addP4;
7fd59977 1322 case 11 :
bf12f076 1323 addP3;
7fd59977 1324 case 10 :
bf12f076 1325 addP2;
7fd59977 1326 case 9 :
bf12f076 1327 addP1;
7fd59977 1328 case 8 :
bf12f076 1329 break;
7fd59977 1330 }
1331 }
1332 }
1333 B.Enlarge(Tol);
1334}
1335
1336
1337void BndLib::Add( const gp_Torus& S,const Standard_Real Tol, Bnd_Box& B) {
1338
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));
1353 B.Enlarge(Tol);
1354}
bf12f076 1355//=======================================================================
1356//function : ComputeBox
1357//purpose :
1358//=======================================================================
1359Standard_Integer ComputeBox(const gp_Hypr& aHypr,
1360 const Standard_Real aT1,
1361 const Standard_Real aT2,
1362 Bnd_Box& aBox)
1363{
1364 Standard_Integer i, iErr;
1365 Standard_Real aRmaj, aRmin, aA, aB, aABP, aBAM, aT3, aCf, aEps;
1366 gp_Pnt aP1, aP2, aP3, aP0;
1367 //
1368 //
1369 aP1=ElCLib::Value(aT1, aHypr);
1370 aP2=ElCLib::Value(aT2, aHypr);
1371 //
1372 aBox.Add(aP1);
1373 aBox.Add(aP2);
1374 //
1375 if (aT1*aT2<0.) {
1376 aP0=ElCLib::Value(0., aHypr);
1377 aBox.Add(aP0);
1378 }
1379 //
1380 aEps=Epsilon(1.);
1381 iErr=1;
1382 //
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();
1388 //
1389 aT3=0;
1390 for (i=1; i<=3; ++i) {
1391 aA=aRmin*aYDir.Coord(i);
1392 aB=aRmaj*aXDir.Coord(i);
1393 //
1394 aABP=aA+aB;
1395 aBAM=aB-aA;
1396 //
1397 aABP=fabs(aABP);
1398 aBAM=fabs(aBAM);
1399 //
1400 if (aABP<aEps || aBAM<aEps) {
1401 continue;
1402 }
1403 //
1404 aCf=aBAM/aABP;
1405 aT3=log(sqrt(aCf));
1406 //
1407 if (aT3<aT1 || aT3>aT2) {
1408 continue;
1409 }
1410 iErr=0;
1411 break;
1412 }
1413 //
1414 if (iErr) {
1415 return iErr;
1416 }
1417 //
1418 aP3=ElCLib::Value(aT3, aHypr);
1419 aBox.Add(aP3);
1420 //
1421 return iErr;
1422}