Commit | Line | Data |
---|---|---|
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 | 42 | static |
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 | 49 | namespace |
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 | 214 | static 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 | ||
229 | static 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 | ||
244 | static 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 | ||
263 | static 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 | ||
275 | static 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 | ||
287 | static 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 | ||
303 | void 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 | ||
348 | void 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 | 393 | void 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 | ||
399 | void 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 | ||
555 | void 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 | ||
568 | void 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 | 577 | void 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 | 583 | void 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 | ||
740 | void 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 | ||
754 | void 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 | ||
764 | void 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 | ||
808 | void 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 | //======================================================================= | |
856 | void 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 | ||
901 | void 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 | 945 | static void ComputeCyl(const gp_Cylinder& Cyl, |
946 | const Standard_Real UMin, const Standard_Real UMax, | |
947 | const Standard_Real VMin, const Standard_Real VMax, | |
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 | 958 | void 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 | ||
1016 | void 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 | 1022 | static void ComputeCone (const gp_Cone& Cone, |
1023 | const Standard_Real UMin, const Standard_Real UMax, | |
1024 | const Standard_Real VMin, const Standard_Real VMax, | |
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 | 1051 | void 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 | ||
1116 | void 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 | 1122 | static void ComputeSphere (const gp_Sphere& Sphere, |
1123 | const Standard_Real UMin, const Standard_Real UMax, | |
1124 | const Standard_Real VMin, const Standard_Real VMax, | |
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 | 1214 | void 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 | 1222 | void 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 | ||
1237 | void 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 | ||
1337 | void 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 | //======================================================================= | |
1359 | Standard_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 | } |