0027261: Incorrect bounding boxes computed for the b-spline faces
[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>
40
bf12f076 41static
42 Standard_Integer ComputeBox(const gp_Hypr& aHypr,
43 const Standard_Real aT1,
44 const Standard_Real aT2,
45 Bnd_Box& aBox);
46
47
1190746b 48namespace
49{
50 //! Compute method
51 template<class PointType, class BndBoxType>
52 void Compute (const Standard_Real theP1, const Standard_Real theP2,
53 const Standard_Real theRa ,const Standard_Real theRb,
54 const PointType& theXd, const PointType& theYd, const PointType& theO,
55 BndBoxType& theB)
56 {
57 Standard_Real aTeta1;
58 Standard_Real aTeta2;
59 if(theP2 < theP1)
60 {
61 aTeta1 = theP2;
62 aTeta2 = theP1;
63 }
64 else
65 {
66 aTeta1 = theP1;
67 aTeta2 = theP2;
68 }
69
70 Standard_Real aDelta = Abs(aTeta2-aTeta1);
71 if(aDelta > 2. * M_PI)
72 {
73 aTeta1 = 0.;
74 aTeta2 = 2. * M_PI;
75 }
76 else
77 {
78 if(aTeta1 < 0.)
79 {
80 do{ aTeta1 += 2.*M_PI; } while (aTeta1 < 0.);
81 }
82 else if (aTeta1 > 2.*M_PI)
83 {
84 do { aTeta1 -= 2.*M_PI; } while (aTeta1 > 2.*M_PI);
85 }
86 aTeta2 = aTeta1 + aDelta;
87 }
88
89 // One places already both ends
90 Standard_Real aCn1, aSn1 ,aCn2, aSn2;
91 aCn1 = Cos(aTeta1); aSn1 = Sin(aTeta1);
92 aCn2 = Cos(aTeta2); aSn2 = Sin(aTeta2);
93 theB.Add(PointType( theO.Coord() +theRa*aCn1*theXd.Coord() +theRb*aSn1*theYd.Coord()));
94 theB.Add(PointType(theO.Coord() +theRa*aCn2*theXd.Coord() +theRb*aSn2*theYd.Coord()));
95
96 Standard_Real aRam, aRbm;
97 if (aDelta > M_PI/8.)
98 {
99 // Main radiuses to take into account only 8 points (/cos(Pi/8.))
100 aRam = theRa/0.92387953251128674;
101 aRbm = theRb/0.92387953251128674;
102 }
103 else
104 {
105 // Main radiuses to take into account the arrow
106 Standard_Real aTc = cos(aDelta/2);
107 aRam = theRa/aTc;
108 aRbm = theRb/aTc;
109 }
110 theB.Add(PointType(theO.Coord() + aRam*aCn1*theXd.Coord() + aRbm*aSn1*theYd.Coord()));
111 theB.Add(PointType(theO.Coord() + aRam*aCn2*theXd.Coord() + aRbm*aSn2*theYd.Coord()));
112
113// cos or sin M_PI/4.
114#define PI4 0.70710678118654746
115
116// 8 points of the polygon
117#define addPoint0 theB.Add(PointType(theO.Coord() +aRam*theXd.Coord()))
118#define addPoint1 theB.Add(PointType(theO.Coord() +aRam*PI4*theXd.Coord() +aRbm*PI4*theYd.Coord()))
119#define addPoint2 theB.Add(PointType(theO.Coord() +aRbm*theYd.Coord()))
120#define addPoint3 theB.Add(PointType(theO.Coord() -aRam*PI4*theXd.Coord() +aRbm*PI4*theYd.Coord()))
121#define addPoint4 theB.Add(PointType(theO.Coord() -aRam*theXd.Coord() ))
122#define addPoint5 theB.Add(PointType(theO.Coord() -aRam*PI4*theXd.Coord() -aRbm*PI4*theYd.Coord()))
123#define addPoint6 theB.Add(PointType(theO.Coord() -aRbm*theYd.Coord()))
124#define addPoint7 theB.Add(PointType(theO.Coord() +aRam*PI4*theXd.Coord() -aRbm*PI4*theYd.Coord()))
125
126 Standard_Integer aDeb = (Standard_Integer )( aTeta1/(M_PI/4.));
127 Standard_Integer aFin = (Standard_Integer )( aTeta2/(M_PI/4.));
128 aDeb++;
129
130 if (aDeb > aFin) return;
131
132 switch (aDeb)
133 {
134 case 1:
135 {
136 addPoint1;
137 if (aFin <= 1) break;
138 }
139 case 2:
140 {
141 addPoint2;
142 if (aFin <= 2) break;
143 }
144 case 3:
145 {
146 addPoint3;
147 if (aFin <= 3) break;
148 }
149 case 4:
150 {
151 addPoint4;
152 if (aFin <= 4) break;
153 }
154 case 5:
155 {
156 addPoint5;
157 if (aFin <= 5) break;
158 }
159 case 6:
160 {
161 addPoint6;
162 if (aFin <= 6) break;
163 }
164 case 7:
165 {
166 addPoint7;
167 if (aFin <= 7) break;
168 }
169 case 8:
170 {
171 addPoint0;
172 if (aFin <= 8) break;
173 }
174 case 9:
175 {
176 addPoint1;
177 if (aFin <= 9) break;
178 }
179 case 10:
180 {
181 addPoint2;
182 if (aFin <= 10) break;
183 }
184 case 11:
185 {
186 addPoint3;
187 if (aFin <= 11) break;
188 }
189 case 12:
190 {
191 addPoint4;
192 if (aFin <= 12) break;
193 }
194 case 13:
195 {
196 addPoint5;
197 if (aFin <= 13) break;
198 }
199 case 14:
200 {
201 addPoint6;
202 if (aFin <= 14) break;
203 }
204 case 15:
205 {
206 addPoint7;
207 if (aFin <= 15) break;
208 }
209 }
210 }
211} // end namespace
b311480e 212
7fd59977 213static void OpenMin(const gp_Dir& V,Bnd_Box& B) {
214 gp_Dir OX(1.,0.,0.);
215 gp_Dir OY(0.,1.,0.);
216 gp_Dir OZ(0.,0.,1.);
217 if (V.IsParallel(OX,Precision::Angular()))
218 B.OpenXmin();
219 else if (V.IsParallel(OY,Precision::Angular()))
220 B.OpenYmin();
221 else if (V.IsParallel(OZ,Precision::Angular()))
222 B.OpenZmin();
223 else {
224 B.OpenXmin();B.OpenYmin();B.OpenZmin();
225 }
226}
227
228static void OpenMax(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.OpenXmax();
234 else if (V.IsParallel(OY,Precision::Angular()))
235 B.OpenYmax();
236 else if (V.IsParallel(OZ,Precision::Angular()))
237 B.OpenZmax();
238 else {
239 B.OpenXmax();B.OpenYmax();B.OpenZmax();
240 }
241}
242
243static void OpenMinMax(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();B.OpenXmin();
249 }
250 else if (V.IsParallel(OY,Precision::Angular())) {
251 B.OpenYmax();B.OpenYmin();
252 }
253 else if (V.IsParallel(OZ,Precision::Angular())) {
254 B.OpenZmax();B.OpenZmin();
255 }
256 else {
257 B.OpenXmin();B.OpenYmin();B.OpenZmin();
258 B.OpenXmax();B.OpenYmax();B.OpenZmax();
259 }
260}
261
262static void OpenMin(const gp_Dir2d& V,Bnd_Box2d& B) {
263 gp_Dir2d OX(1.,0.);
264 gp_Dir2d OY(0.,1.);
265 if (V.IsParallel(OX,Precision::Angular()))
266 B.OpenXmin();
267 else if (V.IsParallel(OY,Precision::Angular()))
268 B.OpenYmin();
269 else {
270 B.OpenXmin();B.OpenYmin();
271 }
272}
273
274static void OpenMax(const gp_Dir2d& V,Bnd_Box2d& B) {
275 gp_Dir2d OX(1.,0.);
276 gp_Dir2d OY(0.,1.);
277 if (V.IsParallel(OX,Precision::Angular()))
278 B.OpenXmax();
279 else if (V.IsParallel(OY,Precision::Angular()))
280 B.OpenYmax();
281 else {
282 B.OpenXmax();B.OpenYmax();
283 }
284}
285
286static void OpenMinMax(const gp_Dir2d& V,Bnd_Box2d& B) {
287 gp_Dir2d OX(1.,0.);
288 gp_Dir2d OY(0.,1.);
289 if (V.IsParallel(OX,Precision::Angular())) {
290 B.OpenXmax();B.OpenXmin();
291 }
292 else if (V.IsParallel(OY,Precision::Angular())) {
293 B.OpenYmax();B.OpenYmin();
294 }
295 else {
296 B.OpenXmin();B.OpenYmin();
297 B.OpenXmax();B.OpenYmax();
298 }
299}
300
301
302void BndLib::Add( const gp_Lin& L,const Standard_Real P1,
bf12f076 303 const Standard_Real P2,
304 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 305
306 if (Precision::IsNegativeInfinite(P1)) {
307 if (Precision::IsNegativeInfinite(P2)) {
308 Standard_Failure::Raise("BndLib::bad parameter");
309 }
310 else if (Precision::IsPositiveInfinite(P2)) {
311 OpenMinMax(L.Direction(),B);
312 B.Add(ElCLib::Value(0.,L));
313 }
314 else {
315 OpenMin(L.Direction(),B);
316 B.Add(ElCLib::Value(P2,L));
317 }
318 }
319 else if (Precision::IsPositiveInfinite(P1)) {
320 if (Precision::IsNegativeInfinite(P2)) {
321 OpenMinMax(L.Direction(),B);
322 B.Add(ElCLib::Value(0.,L));
323 }
324 else if (Precision::IsPositiveInfinite(P2)) {
325 Standard_Failure::Raise("BndLib::bad parameter");
326 }
327 else {
328 OpenMax(L.Direction(),B);
329 B.Add(ElCLib::Value(P2,L));
330 }
331 }
332 else {
333 B.Add(ElCLib::Value(P1,L));
334 if (Precision::IsNegativeInfinite(P2)) {
335 OpenMin(L.Direction(),B);
336 }
337 else if (Precision::IsPositiveInfinite(P2)){
338 OpenMax(L.Direction(),B);
339 }
340 else {
341 B.Add(ElCLib::Value(P2,L));
342 }
343 }
344 B.Enlarge(Tol);
345}
346
347void BndLib::Add( const gp_Lin2d& L,const Standard_Real P1,
bf12f076 348 const Standard_Real P2,
349 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 350
351 if (Precision::IsNegativeInfinite(P1)) {
352 if (Precision::IsNegativeInfinite(P2)) {
353 Standard_Failure::Raise("BndLib::bad parameter");
354 }
355 else if (Precision::IsPositiveInfinite(P2)) {
356 OpenMinMax(L.Direction(),B);
357 B.Add(ElCLib::Value(0.,L));
358 }
359 else {
360 OpenMin(L.Direction(),B);
361 B.Add(ElCLib::Value(P2,L));
362 }
363 }
364 else if (Precision::IsPositiveInfinite(P1)) {
365 if (Precision::IsNegativeInfinite(P2)) {
366 OpenMinMax(L.Direction(),B);
367 B.Add(ElCLib::Value(0.,L));
368 }
369 else if (Precision::IsPositiveInfinite(P2)) {
370 Standard_Failure::Raise("BndLib::bad parameter");
371 }
372 else {
373 OpenMax(L.Direction(),B);
374 B.Add(ElCLib::Value(P2,L));
375 }
376 }
377 else {
378 B.Add(ElCLib::Value(P1,L));
379 if (Precision::IsNegativeInfinite(P2)) {
380 OpenMin(L.Direction(),B);
381 }
382 else if (Precision::IsPositiveInfinite(P2)){
383 OpenMax(L.Direction(),B);
384 }
385 else {
386 B.Add(ElCLib::Value(P2,L));
387 }
388 }
389 B.Enlarge(Tol);
390}
391
392void BndLib::Add( const gp_Circ& C,const Standard_Real Tol, Bnd_Box& B) {
393
394 Standard_Real R = C.Radius();
395 gp_XYZ O = C.Location().XYZ();
396 gp_XYZ Xd = C.XAxis().Direction().XYZ();
397 gp_XYZ Yd = C.YAxis().Direction().XYZ();
398 B.Add(gp_Pnt(O -R*Xd -R*Yd));
399 B.Add(gp_Pnt(O -R*Xd +R*Yd));
400 B.Add(gp_Pnt(O +R*Xd -R*Yd));
401 B.Add(gp_Pnt(O +R*Xd +R*Yd));
402 B.Enlarge(Tol);
403}
404
405void BndLib::Add( const gp_Circ& C,const Standard_Real P1,
bf12f076 406 const Standard_Real P2,
407 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 408
bf12f076 409 Compute(P1,P2,C.Radius(),C.Radius(),gp_Pnt(C.XAxis().Direction().XYZ()),
410 gp_Pnt(C.YAxis().Direction().XYZ()),C.Location(),B);
7fd59977 411 B.Enlarge(Tol);
412}
413
414void BndLib::Add( const gp_Circ2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
415
416 Standard_Real R = C.Radius();
417 gp_XY O = C.Location().XY();
418 gp_XY Xd = C.XAxis().Direction().XY();
419 gp_XY Yd = C.YAxis().Direction().XY();
420 B.Add(gp_Pnt2d(O -R*Xd -R*Yd));
421 B.Add(gp_Pnt2d(O -R*Xd +R*Yd));
422 B.Add(gp_Pnt2d(O +R*Xd -R*Yd));
423 B.Add(gp_Pnt2d(O +R*Xd +R*Yd));
424 B.Enlarge(Tol);
425}
426
427void BndLib::Add(const gp_Circ2d& C,const Standard_Real P1,
bf12f076 428 const Standard_Real P2,
429 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 430
1190746b 431 Compute(P1,P2,C.Radius(),C.Radius(),gp_Pnt2d(C.XAxis().Direction().XY()),
432 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
7fd59977 433 B.Enlarge(Tol);
434}
435
436void BndLib::Add( const gp_Elips& C,const Standard_Real Tol, Bnd_Box& B) {
437
438 Standard_Real Ra = C.MajorRadius();
439 Standard_Real Rb = C.MinorRadius();
440 gp_XYZ Xd = C.XAxis().Direction().XYZ();
441 gp_XYZ Yd = C.YAxis().Direction().XYZ();
442 gp_XYZ O = C.Location().XYZ();
443 B.Add(gp_Pnt(O +Ra*Xd +Rb*Yd));
444 B.Add(gp_Pnt(O -Ra*Xd +Rb*Yd));
445 B.Add(gp_Pnt(O -Ra*Xd -Rb*Yd));
446 B.Add(gp_Pnt(O +Ra*Xd -Rb*Yd));
447 B.Enlarge(Tol);
448}
449
450void BndLib::Add( const gp_Elips& C,const Standard_Real P1,
bf12f076 451 const Standard_Real P2,
452 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 453
1190746b 454 Compute(P1,P2,C.MajorRadius(),C.MinorRadius(),gp_Pnt(C.XAxis().Direction().XYZ()),
bf12f076 455 gp_Pnt(C.YAxis().Direction().XYZ()),C.Location(),B);
7fd59977 456 B.Enlarge(Tol);
457}
458
459void BndLib::Add( const gp_Elips2d& C,const Standard_Real Tol, Bnd_Box2d& B) {
460
461 Standard_Real Ra= C.MajorRadius();
462 Standard_Real Rb= C.MinorRadius();
463 gp_XY Xd = C.XAxis().Direction().XY();
464 gp_XY Yd = C.YAxis().Direction().XY();
465 gp_XY O = C.Location().XY();
466 B.Add(gp_Pnt2d(O +Ra*Xd +Rb*Yd));
467 B.Add(gp_Pnt2d(O -Ra*Xd +Rb*Yd));
468 B.Add(gp_Pnt2d(O -Ra*Xd -Rb*Yd));
469 B.Add(gp_Pnt2d(O +Ra*Xd -Rb*Yd));
470 B.Enlarge(Tol);
471}
472
473void BndLib::Add( const gp_Elips2d& C,const Standard_Real P1,
bf12f076 474 const Standard_Real P2,
475 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 476
477 Compute(P1,P2,C.MajorRadius(),C.MinorRadius(),
bf12f076 478 gp_Pnt2d(C.XAxis().Direction().XY()),
479 gp_Pnt2d(C.YAxis().Direction().XY()),C.Location(),B);
7fd59977 480 B.Enlarge(Tol);
481}
482
483void BndLib::Add( const gp_Parab& P,const Standard_Real P1,
bf12f076 484 const Standard_Real P2,
485 const Standard_Real Tol, Bnd_Box& B) {
7fd59977 486
487 if (Precision::IsNegativeInfinite(P1)) {
488 if (Precision::IsNegativeInfinite(P2)) {
489 Standard_Failure::Raise("BndLib::bad parameter");
490 }
491 else if (Precision::IsPositiveInfinite(P2)) {
492 B.OpenXmax();B.OpenYmax();B.OpenZmax();
493 }
494 else {
495 B.Add(ElCLib::Value(P2,P));
496 }
497 B.OpenXmin();B.OpenYmin();B.OpenZmin();
498 }
499 else if (Precision::IsPositiveInfinite(P1)) {
500 if (Precision::IsNegativeInfinite(P2)) {
501 B.OpenXmin();B.OpenYmin();B.OpenZmin();
502 }
503 else if (Precision::IsPositiveInfinite(P2)) {
504 Standard_Failure::Raise("BndLib::bad parameter");
505 }
506 else {
507 B.Add(ElCLib::Value(P2,P));
508 }
509 B.OpenXmax();B.OpenYmax();B.OpenZmax();
510 }
511 else {
512 B.Add(ElCLib::Value(P1,P));
513 if (Precision::IsNegativeInfinite(P2)) {
514 B.OpenXmin();B.OpenYmin();B.OpenZmin();
515 }
516 else if (Precision::IsPositiveInfinite(P2)){
517 B.OpenXmax();B.OpenYmax();B.OpenZmax();
518 }
519 else {
520 B.Add(ElCLib::Value(P2,P));
521 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
522 }
523 }
524 B.Enlarge(Tol);
525}
526
527void BndLib::Add( const gp_Parab2d& P,const Standard_Real P1,
bf12f076 528 const Standard_Real P2,
529 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 530
531 if (Precision::IsNegativeInfinite(P1)) {
532 if (Precision::IsNegativeInfinite(P2)) {
533 Standard_Failure::Raise("BndLib::bad parameter");
534 }
535 else if (Precision::IsPositiveInfinite(P2)) {
536 B.OpenXmax();B.OpenYmax();
537 }
538 else {
539 B.Add(ElCLib::Value(P2,P));
540 }
541 B.OpenXmin();B.OpenYmin();
542 }
543 else if (Precision::IsPositiveInfinite(P1)) {
544 if (Precision::IsNegativeInfinite(P2)) {
545 B.OpenXmin();B.OpenYmin();
546 }
547 else if (Precision::IsPositiveInfinite(P2)) {
548 Standard_Failure::Raise("BndLib::bad parameter");
549 }
550 else {
551 B.Add(ElCLib::Value(P2,P));
552 }
553 B.OpenXmax();B.OpenYmax();
554 }
555 else {
556 B.Add(ElCLib::Value(P1,P));
557 if (Precision::IsNegativeInfinite(P2)) {
558 B.OpenXmin();B.OpenYmin();
559 }
560 else if (Precision::IsPositiveInfinite(P2)){
561 B.OpenXmax();B.OpenYmax();
562 }
563 else {
564 B.Add(ElCLib::Value(P2,P));
565 if (P1*P2<0) B.Add(ElCLib::Value(0.,P));
566 }
567 }
568 B.Enlarge(Tol);
569}
570
bf12f076 571//=======================================================================
572//function : Add
573//purpose :
574//=======================================================================
575void BndLib::Add(const gp_Hypr& H,
576 const Standard_Real P1,
577 const Standard_Real P2,
578 const Standard_Real Tol,
579 Bnd_Box& B)
580{
7fd59977 581 if (Precision::IsNegativeInfinite(P1)) {
582 if (Precision::IsNegativeInfinite(P2)) {
583 Standard_Failure::Raise("BndLib::bad parameter");
584 }
585 else if (Precision::IsPositiveInfinite(P2)) {
586 B.OpenXmax();B.OpenYmax();B.OpenZmax();
587 }
588 else {
589 B.Add(ElCLib::Value(P2,H));
590 }
591 B.OpenXmin();B.OpenYmin();B.OpenZmin();
592 }
593 else if (Precision::IsPositiveInfinite(P1)) {
594 if (Precision::IsNegativeInfinite(P2)) {
595 B.OpenXmin();B.OpenYmin();B.OpenZmin();
596 }
597 else if (Precision::IsPositiveInfinite(P2)) {
598 Standard_Failure::Raise("BndLib::bad parameter");
599 }
600 else {
601 B.Add(ElCLib::Value(P2,H));
602 }
603 B.OpenXmax();B.OpenYmax();B.OpenZmax();
604 }
605 else {
606 B.Add(ElCLib::Value(P1,H));
607 if (Precision::IsNegativeInfinite(P2)) {
608 B.OpenXmin();B.OpenYmin();B.OpenZmin();
609 }
610 else if (Precision::IsPositiveInfinite(P2)){
611 B.OpenXmax();B.OpenYmax();B.OpenZmax();
612 }
613 else {
bf12f076 614 ComputeBox(H, P1, P2, B);
7fd59977 615 }
616 }
617 B.Enlarge(Tol);
618}
619
620void BndLib::Add(const gp_Hypr2d& H,const Standard_Real P1,
bf12f076 621 const Standard_Real P2,
622 const Standard_Real Tol, Bnd_Box2d& B) {
7fd59977 623
624 if (Precision::IsNegativeInfinite(P1)) {
625 if (Precision::IsNegativeInfinite(P2)) {
626 Standard_Failure::Raise("BndLib::bad parameter");
627 }
628 else if (Precision::IsPositiveInfinite(P2)) {
629 B.OpenXmax();B.OpenYmax();
630 }
631 else {
632 B.Add(ElCLib::Value(P2,H));
633 }
634 B.OpenXmin();B.OpenYmin();
635 }
636 else if (Precision::IsPositiveInfinite(P1)) {
637 if (Precision::IsNegativeInfinite(P2)) {
638 B.OpenXmin();B.OpenYmin();
639 }
640 else if (Precision::IsPositiveInfinite(P2)) {
641 Standard_Failure::Raise("BndLib::bad parameter");
642 }
643 else {
644 B.Add(ElCLib::Value(P2,H));
645 }
646 B.OpenXmax();B.OpenYmax();
647 }
648 else {
649 B.Add(ElCLib::Value(P1,H));
650 if (Precision::IsNegativeInfinite(P2)) {
651 B.OpenXmin();B.OpenYmin();
652 }
653 else if (Precision::IsPositiveInfinite(P2)){
654 B.OpenXmax();B.OpenYmax();
655 }
656 else {
657 B.Add(ElCLib::Value(P2,H));
658 if (P1*P2<0) B.Add(ElCLib::Value(0.,H));
659 }
660 }
661 B.Enlarge(Tol);
662}
663
664void BndLib::Add( const gp_Cylinder& S,const Standard_Real UMin,
bf12f076 665 const Standard_Real UMax,const Standard_Real VMin,
666 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 667
668 if (Precision::IsNegativeInfinite(VMin)) {
669 if (Precision::IsNegativeInfinite(VMax)) {
670 Standard_Failure::Raise("BndLib::bad parameter");
671 }
672 else if (Precision::IsPositiveInfinite(VMax)) {
673 OpenMinMax(S.Axis().Direction(),B);
674 }
675 else {
676 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 677 gp_Pnt(S.XAxis().Direction().XYZ()),
678 gp_Pnt(S.YAxis().Direction().XYZ()),
679 gp_Pnt(S.Location().XYZ() + VMax*S.Axis().Direction().XYZ()),B);
7fd59977 680 OpenMin(S.Axis().Direction(),B);
681 }
682 }
683 else if (Precision::IsPositiveInfinite(VMin)) {
684 if (Precision::IsNegativeInfinite(VMax)) {
685 OpenMinMax(S.Axis().Direction(),B);
686 }
687 else if (Precision::IsPositiveInfinite(VMax)) {
688 Standard_Failure::Raise("BndLib::bad parameter");
689 }
690 else {
691 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 692 gp_Pnt(S.XAxis().Direction().XYZ()),
693 gp_Pnt(S.YAxis().Direction().XYZ()),
694 gp_Pnt(S.Location().XYZ() + VMax*S.Axis().Direction().XYZ()),B);
7fd59977 695 OpenMax(S.Axis().Direction(),B);
696 }
697
698 }
699 else {
700 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 701 gp_Pnt(S.XAxis().Direction().XYZ()),
702 gp_Pnt(S.YAxis().Direction().XYZ()),
703 gp_Pnt(S.Location().XYZ() + VMin*S.Axis().Direction().XYZ()),B);
7fd59977 704 if (Precision::IsNegativeInfinite(VMax)) {
705 OpenMin(S.Axis().Direction(),B);
706 }
707 else if (Precision::IsPositiveInfinite(VMax)) {
708 OpenMax(S.Axis().Direction(),B);
709 }
710 else {
711 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 712 gp_Pnt(S.XAxis().Direction().XYZ()),
713 gp_Pnt(S.YAxis().Direction().XYZ()),
714 gp_Pnt(S.Location().XYZ() + VMax*S.Axis().Direction().XYZ()),B);
7fd59977 715 }
716 }
717
718 B.Enlarge(Tol);
719
720}
721
722void BndLib::Add( const gp_Cylinder& S,const Standard_Real VMin,
bf12f076 723 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 724
c6541a0c 725 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
7fd59977 726}
727
728void BndLib::Add(const gp_Cone& S,const Standard_Real UMin,
bf12f076 729 const Standard_Real UMax,const Standard_Real VMin,
730 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 731
732 Standard_Real R = S.RefRadius();
733 Standard_Real A = S.SemiAngle();
734 if (Precision::IsNegativeInfinite(VMin)) {
735 if (Precision::IsNegativeInfinite(VMax)) {
736 Standard_Failure::Raise("BndLib::bad parameter");
737 }
738 else if (Precision::IsPositiveInfinite(VMax)) {
739 gp_Dir D(Cos(A)*S.Axis().Direction());
740 OpenMinMax(D,B);
741 }
742 else {
743 Compute(UMin,UMax,R+VMax*Sin(A),R+VMax*Sin(A),
bf12f076 744 gp_Pnt(S.XAxis().Direction().XYZ()),
745 gp_Pnt(S.YAxis().Direction().XYZ()),
746 gp_Pnt(S.Location().XYZ() +
747 VMax*Cos(A)*S.Axis().Direction().XYZ()),B);
7fd59977 748 gp_Dir D(Cos(A)*S.Axis().Direction());
749 OpenMin(D,B);
750 }
751
752 }
753 else if (Precision::IsPositiveInfinite(VMin)) {
754 if (Precision::IsNegativeInfinite(VMax)) {
755 gp_Dir D(Cos(A)*S.Axis().Direction());
756 OpenMinMax(D,B);
757 }
758 else if (Precision::IsPositiveInfinite(VMax)) {
759 Standard_Failure::Raise("BndLib::bad parameter");
760 }
761 else {
762 Compute(UMin,UMax,R+VMax*Sin(A),R+VMax*Sin(A),
bf12f076 763 gp_Pnt(S.XAxis().Direction().XYZ()),
764 gp_Pnt(S.YAxis().Direction().XYZ()),
765 gp_Pnt(S.Location().XYZ() +
766 VMax*Cos(A)*S.Axis().Direction().XYZ()),B);
7fd59977 767 gp_Dir D(Cos(A)*S.Axis().Direction());
768 OpenMax(D,B);
769 }
770
771 }
772 else {
773 Compute(UMin,UMax,R+VMin*Sin(A),R+VMin*Sin(A),
bf12f076 774 gp_Pnt(S.XAxis().Direction().XYZ()),
775 gp_Pnt(S.YAxis().Direction().XYZ()),
776 gp_Pnt(S.Location().XYZ() +
777 VMin*Cos(A)*S.Axis().Direction().XYZ()),B);
7fd59977 778 if (Precision::IsNegativeInfinite(VMax)) {
779 gp_Dir D(Cos(A)*S.Axis().Direction());
780 OpenMin(D,B);
781 }
782 else if (Precision::IsPositiveInfinite(VMax)) {
783 gp_Dir D(Cos(A)*S.Axis().Direction());
784 OpenMax(D,B);
785 }
786 else {
787 Compute(UMin,UMax,R+VMax*Sin(A),R+VMax*Sin(A),
bf12f076 788 gp_Pnt(S.XAxis().Direction().XYZ()),
789 gp_Pnt(S.YAxis().Direction().XYZ()),
790 gp_Pnt(S.Location().XYZ() +
791 VMax*Cos(A)*S.Axis().Direction().XYZ()),B);
7fd59977 792 }
793 }
794
795
796 B.Enlarge(Tol);
797}
798
799void BndLib::Add( const gp_Cone& S,const Standard_Real VMin,
bf12f076 800 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 801
c6541a0c 802 BndLib::Add(S,0.,2.*M_PI,VMin,VMax,Tol,B);
7fd59977 803}
804
805void BndLib::Add(const gp_Sphere& S,const Standard_Real UMin,
bf12f076 806 const Standard_Real UMax,const Standard_Real VMin,
807 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
0d969553 808
7fd59977 809#if 0
810 Standard_Real Fi1;
811 Standard_Real Fi2;
812 if (VMax<VMin) {
813 Fi1 = VMax;
814 Fi2 = VMin;
815 }
816 else {
817 Fi1 = VMin;
818 Fi2 = VMax;
819 }
bf12f076 820
7fd59977 821 if (-Fi1>Precision::Angular()) {
822 if (-Fi2>Precision::Angular()) {
823 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 824 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
825 S.Location(),B);
7fd59977 826 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 827 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
1190746b 828 gp_Pnt(S.Location().XYZ()- S.Radius()*S.Position().Axis().Direction().XYZ()),B);
7fd59977 829 }
830 else {
831 Compute(UMin,UMax,S.Radius(),S.Radius(),
1190746b 832 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
833 gp_Pnt(S.Location().XYZ()+ S.Radius()*S.Position().Axis().Direction().XYZ()),B);
7fd59977 834 Compute(UMin,UMax,S.Radius(),S.Radius(),
1190746b 835 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
836 gp_Pnt(S.Location().XYZ()- S.Radius()*S.Position().Axis().Direction().XYZ()),B);
7fd59977 837 }
838 }
839 else {
840 Compute(UMin,UMax,S.Radius(),S.Radius(),
bf12f076 841 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
842 S.Location(),B);
7fd59977 843 Compute(UMin,UMax,S.Radius(),S.Radius(),
1190746b 844 gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),
845 gp_Pnt(S.Location().XYZ() +S.Radius()*S.Position().Axis().Direction().XYZ()),B);
7fd59977 846 }
847 B.Enlarge(Tol);
848#else
849 Standard_Real u,v,du,dv;
850 Standard_Integer iu,iv;
851 du = (UMax-UMin)/10;
852 dv = (VMax-VMin)/10;
853 Standard_Real COSV[11];
854 Standard_Real SINV[11];
855 for(iv=0,v=VMin;iv<=10;iv++) {
856 COSV[iv]=cos(v);
857 SINV[iv]=sin(v);
858 v+=dv;
859 }
860 for(u=UMin,iu=0; iu<=10 ; iu++) {
861 Standard_Real Radiuscosu=S.Radius()*cos(u);
862 Standard_Real Radiussinu=S.Radius()*sin(u);
863 for(v=VMin,iv=0; iv<=10 ; iv++) {
864 Standard_Real sinv=SINV[iv];
865 Standard_Real cosv=COSV[iv];
866 gp_XYZ M;
867 M.SetLinearForm (cosv*Radiuscosu, S.Position().XDirection().XYZ(),
bf12f076 868 cosv*Radiussinu, S.Position().YDirection().XYZ(),
869 S.Radius()*sinv, S.Position().Direction().XYZ() ,
870 S.Position().Location().XYZ() );
7fd59977 871 //-- static int t=0;
872 //-- cout<<"point p"<<++t<<" "<<M.X()<<" "<<M.Y()<<" "<<M.Z()<<endl;
873 B.Add(gp_Pnt(M));
874 v+=dv;
875 }
876 u+=du;
877 }
878
879 Standard_Real Maxduv = Max(du,dv)*0.5;
880 Standard_Real Fleche = S.Radius() * (1 - cos(Maxduv));
881 B.Enlarge(Fleche);
882 B.Enlarge(10*Tol);
883#endif
884}
885
886void BndLib::Add( const gp_Sphere& S,const Standard_Real Tol, Bnd_Box& B) {
887
888 Standard_Real R = S.Radius();
889 gp_XYZ O = S.Location().XYZ();
890 gp_XYZ Xd = S.XAxis().Direction().XYZ();
891 gp_XYZ Yd = S.YAxis().Direction().XYZ();
892 gp_XYZ Zd = S.Position().Axis().Direction().XYZ();
893 B.Add(gp_Pnt(O -R*Xd -R*Yd+ R*Zd));
894 B.Add(gp_Pnt(O -R*Xd +R*Yd+ R*Zd));
895 B.Add(gp_Pnt(O +R*Xd -R*Yd+ R*Zd));
896 B.Add(gp_Pnt(O +R*Xd +R*Yd+ R*Zd));
897 B.Add(gp_Pnt(O +R*Xd -R*Yd- R*Zd));
898 B.Add(gp_Pnt(O -R*Xd -R*Yd- R*Zd));
899 B.Add(gp_Pnt(O +R*Xd +R*Yd- R*Zd));
900 B.Add(gp_Pnt(O -R*Xd +R*Yd- R*Zd));
901 B.Enlarge(Tol);
902}
903
904void BndLib::Add(const gp_Torus& S,const Standard_Real UMin,
bf12f076 905 const Standard_Real UMax,const Standard_Real VMin,
906 const Standard_Real VMax,const Standard_Real Tol, Bnd_Box& B) {
7fd59977 907
908 Standard_Integer Fi1;
909 Standard_Integer Fi2;
910 if (VMax<VMin) {
c6541a0c
D
911 Fi1 = (Standard_Integer )( VMax/(M_PI/4.));
912 Fi2 = (Standard_Integer )( VMin/(M_PI/4.));
7fd59977 913 }
914 else {
c6541a0c
D
915 Fi1 = (Standard_Integer )( VMin/(M_PI/4.));
916 Fi2 = (Standard_Integer )( VMax/(M_PI/4.));
7fd59977 917 }
918 Fi2++;
919
920 Standard_Real Ra = S.MajorRadius();
921 Standard_Real Ri = S.MinorRadius();
922
923 if (Fi2<Fi1) return;
924
925#define SC 0.71
1190746b 926#define addP0 (Compute(UMin,UMax,Ra+Ri,Ra+Ri,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),S.Location(),B))
927#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))
928#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))
929#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))
930#define addP4 (Compute(UMin,UMax,Ra-Ri,Ra-Ri,gp_Pnt(S.XAxis().Direction().XYZ()),gp_Pnt(S.YAxis().Direction().XYZ()),S.Location(),B))
931#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))
932#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))
933#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 934
935 switch (Fi1) {
936 case 0 :
937 {
938 addP0;
939 if (Fi2 <= 0) break;
940 }
941 case 1 :
942 {
943 addP1;
944 if (Fi2 <= 1) break;
945 }
946 case 2 :
947 {
948 addP2;
949 if (Fi2 <= 2) break;
950 }
951 case 3 :
952 {
953 addP3;
954 if (Fi2 <= 3) break;
955 }
956 case 4 :
957 {
958 addP4;
959 if (Fi2 <= 4) break;
960 }
961 case 5 :
962 {
963 addP5;
964 if (Fi2 <= 5) break;
965 }
966 case 6 :
967 {
968 addP6;
969 if (Fi2 <= 6) break;
970 }
971 case 7 :
972 {
973 addP7;
974 if (Fi2 <= 7) break;
975 }
976 case 8 :
977 default :
978 {
979 addP0;
980 switch (Fi2) {
981 case 15 :
bf12f076 982 addP7;
7fd59977 983 case 14 :
bf12f076 984 addP6;
7fd59977 985 case 13 :
bf12f076 986 addP5;
7fd59977 987 case 12 :
bf12f076 988 addP4;
7fd59977 989 case 11 :
bf12f076 990 addP3;
7fd59977 991 case 10 :
bf12f076 992 addP2;
7fd59977 993 case 9 :
bf12f076 994 addP1;
7fd59977 995 case 8 :
bf12f076 996 break;
7fd59977 997 }
998 }
999 }
1000 B.Enlarge(Tol);
1001}
1002
1003
1004void BndLib::Add( const gp_Torus& S,const Standard_Real Tol, Bnd_Box& B) {
1005
1006 Standard_Real RMa = S.MajorRadius();
1007 Standard_Real Rmi = S.MinorRadius();
1008 gp_XYZ O = S.Location().XYZ();
1009 gp_XYZ Xd = S.XAxis().Direction().XYZ();
1010 gp_XYZ Yd = S.YAxis().Direction().XYZ();
1011 gp_XYZ Zd = S.Axis().Direction().XYZ();
1012 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd -(RMa+Rmi)*Yd+ Rmi*Zd));
1013 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd -(RMa+Rmi)*Yd- Rmi*Zd));
1014 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd -(RMa+Rmi)*Yd+ Rmi*Zd));
1015 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd -(RMa+Rmi)*Yd- Rmi*Zd));
1016 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd +(RMa+Rmi)*Yd+ Rmi*Zd));
1017 B.Add(gp_Pnt(O -(RMa+Rmi)*Xd +(RMa+Rmi)*Yd- Rmi*Zd));
1018 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd +(RMa+Rmi)*Yd+ Rmi*Zd));
1019 B.Add(gp_Pnt(O +(RMa+Rmi)*Xd +(RMa+Rmi)*Yd- Rmi*Zd));
1020 B.Enlarge(Tol);
1021}
bf12f076 1022//=======================================================================
1023//function : ComputeBox
1024//purpose :
1025//=======================================================================
1026Standard_Integer ComputeBox(const gp_Hypr& aHypr,
1027 const Standard_Real aT1,
1028 const Standard_Real aT2,
1029 Bnd_Box& aBox)
1030{
1031 Standard_Integer i, iErr;
1032 Standard_Real aRmaj, aRmin, aA, aB, aABP, aBAM, aT3, aCf, aEps;
1033 gp_Pnt aP1, aP2, aP3, aP0;
1034 //
1035 //
1036 aP1=ElCLib::Value(aT1, aHypr);
1037 aP2=ElCLib::Value(aT2, aHypr);
1038 //
1039 aBox.Add(aP1);
1040 aBox.Add(aP2);
1041 //
1042 if (aT1*aT2<0.) {
1043 aP0=ElCLib::Value(0., aHypr);
1044 aBox.Add(aP0);
1045 }
1046 //
1047 aEps=Epsilon(1.);
1048 iErr=1;
1049 //
1050 const gp_Ax2& aPos=aHypr.Position();
1051 const gp_XYZ& aXDir = aPos.XDirection().XYZ();
1052 const gp_XYZ& aYDir = aPos.YDirection().XYZ();
1053 aRmaj=aHypr.MajorRadius();
1054 aRmin=aHypr.MinorRadius();
1055 //
1056 aT3=0;
1057 for (i=1; i<=3; ++i) {
1058 aA=aRmin*aYDir.Coord(i);
1059 aB=aRmaj*aXDir.Coord(i);
1060 //
1061 aABP=aA+aB;
1062 aBAM=aB-aA;
1063 //
1064 aABP=fabs(aABP);
1065 aBAM=fabs(aBAM);
1066 //
1067 if (aABP<aEps || aBAM<aEps) {
1068 continue;
1069 }
1070 //
1071 aCf=aBAM/aABP;
1072 aT3=log(sqrt(aCf));
1073 //
1074 if (aT3<aT1 || aT3>aT2) {
1075 continue;
1076 }
1077 iErr=0;
1078 break;
1079 }
1080 //
1081 if (iErr) {
1082 return iErr;
1083 }
1084 //
1085 aP3=ElCLib::Value(aT3, aHypr);
1086 aBox.Add(aP3);
1087 //
1088 return iErr;
1089}