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