b311480e |
1 | // Copyright (c) 1996-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. |
7fd59977 |
14 | |
7fd59977 |
15 | |
42cf5bc1 |
16 | #include <Adaptor2d_Curve2d.hxx> |
17 | #include <Bnd_Box2d.hxx> |
18 | #include <BndLib_Add2dCurve.hxx> |
19 | #include <Geom2d_BezierCurve.hxx> |
20 | #include <Geom2d_BSplineCurve.hxx> |
59495dbe |
21 | #include <Geom2d_Circle.hxx> |
42cf5bc1 |
22 | #include <Geom2d_Conic.hxx> |
23 | #include <Geom2d_Curve.hxx> |
59495dbe |
24 | #include <Geom2d_Ellipse.hxx> |
42cf5bc1 |
25 | #include <Geom2d_Geometry.hxx> |
59495dbe |
26 | #include <Geom2d_Hyperbola.hxx> |
59495dbe |
27 | #include <Geom2d_Line.hxx> |
42cf5bc1 |
28 | #include <Geom2d_OffsetCurve.hxx> |
29 | #include <Geom2d_Parabola.hxx> |
30 | #include <Geom2d_TrimmedCurve.hxx> |
59495dbe |
31 | #include <Geom2dAdaptor_Curve.hxx> |
42cf5bc1 |
32 | #include <gp.hxx> |
33 | #include <Precision.hxx> |
34 | #include <Standard_Type.hxx> |
3ba87fdb |
35 | #include <math_MultipleVarFunction.hxx> |
36 | #include <math_Function.hxx> |
37 | #include <math_BrentMinimum.hxx> |
38 | #include <math_PSO.hxx> |
7fd59977 |
39 | |
40 | //======================================================================= |
59495dbe |
41 | //function : BndLib_Box2dCurve |
7fd59977 |
42 | //purpose : |
43 | //======================================================================= |
59495dbe |
44 | class BndLib_Box2dCurve { |
45 | public: |
46 | BndLib_Box2dCurve(); |
47 | |
48 | virtual ~BndLib_Box2dCurve(); |
49 | |
50 | void SetCurve(const Handle(Geom2d_Curve)& aC); |
51 | |
35c0599a |
52 | const Handle(Geom2d_Curve)& Curve() const; |
59495dbe |
53 | |
54 | void SetRange(const Standard_Real aT1, |
55 | const Standard_Real aT2); |
56 | |
57 | void Range(Standard_Real& aT1, |
58 | Standard_Real& aT2) const; |
59 | |
60 | const Bnd_Box2d& Box() const; |
7fd59977 |
61 | |
59495dbe |
62 | void Perform(); |
63 | |
3ba87fdb |
64 | void PerformOptimal(const Standard_Real Tol); |
65 | |
59495dbe |
66 | void Clear(); |
67 | |
68 | Standard_Integer ErrorStatus() const; |
69 | // |
70 | //----------------------------- |
71 | protected: |
72 | void CheckData(); |
73 | void GetInfoBase(); |
74 | void PerformLineConic(); |
75 | void PerformBezier(); |
76 | void PerformBSpline(); |
77 | void PerformOther(); |
78 | void D0(const Standard_Real, gp_Pnt2d&); |
79 | // |
80 | void Compute(const Handle(Geom2d_Conic)&, |
81 | const GeomAbs_CurveType, |
82 | const Standard_Real, |
83 | const Standard_Real, |
84 | Bnd_Box2d& aBox2D); |
85 | // |
86 | static |
87 | Standard_Integer Compute(const Handle(Geom2d_Conic)&, |
88 | const GeomAbs_CurveType, |
89 | Standard_Real *); |
90 | static |
91 | Standard_Boolean IsTypeBase(const Handle(Geom2d_Curve)& , |
92 | GeomAbs_CurveType& ); |
93 | static |
94 | Standard_Real AdjustToPeriod(const Standard_Real , |
95 | const Standard_Real ); |
96 | // |
97 | void PerformOnePoint(); |
3ba87fdb |
98 | // |
99 | void PerformGenCurv(const Standard_Real Tol = Precision::PConfusion()); |
100 | // |
101 | Standard_Integer NbSamples(); |
102 | // |
103 | Standard_Real AdjustExtr(const Standard_Real UMin, |
104 | const Standard_Real UMax, |
105 | const Standard_Real Extr0, |
106 | const Standard_Integer CoordIndx, |
107 | const Standard_Real Tol, |
108 | const Standard_Boolean IsMin); |
59495dbe |
109 | //----------------------------- |
110 | protected: |
35c0599a |
111 | Handle(Geom2d_Curve) myCurve; |
59495dbe |
112 | Bnd_Box2d myBox; |
113 | Standard_Integer myErrorStatus; |
35c0599a |
114 | Handle(Geom2d_Curve) myCurveBase; |
59495dbe |
115 | Standard_Real myOffsetBase; |
116 | Standard_Boolean myOffsetFlag; |
117 | Standard_Real myT1; |
118 | Standard_Real myT2; |
119 | GeomAbs_CurveType myTypeBase; |
120 | }; |
3ba87fdb |
121 | // |
122 | class Curv2dMaxMinCoordMVar : public math_MultipleVarFunction |
123 | { |
124 | public: |
125 | Curv2dMaxMinCoordMVar(const Handle(Geom2d_Curve)& theCurve, |
126 | const Standard_Real UMin, |
127 | const Standard_Real UMax, |
128 | const Standard_Integer CoordIndx, |
129 | const Standard_Real Sign) |
130 | : myCurve(theCurve), |
131 | myUMin(UMin), |
132 | myUMax(UMax), |
133 | myCoordIndx(CoordIndx), |
134 | mySign(Sign) |
135 | { |
136 | } |
137 | |
138 | Standard_Boolean Value (const math_Vector& X, |
139 | Standard_Real& F) |
140 | { |
141 | if (!CheckInputData(X(1))) |
142 | { |
143 | return Standard_False; |
144 | } |
145 | gp_Pnt2d aP = myCurve->Value(X(1)); |
146 | |
147 | F = mySign * aP.Coord(myCoordIndx); |
148 | |
149 | return Standard_True; |
150 | } |
151 | |
152 | |
153 | |
154 | Standard_Integer NbVariables() const |
155 | { |
156 | return 1; |
157 | } |
158 | |
159 | private: |
160 | Curv2dMaxMinCoordMVar & operator = (const Curv2dMaxMinCoordMVar & theOther); |
161 | |
162 | Standard_Boolean CheckInputData(Standard_Real theParam) |
163 | { |
164 | if (theParam < myUMin || |
165 | theParam > myUMax) |
166 | return Standard_False; |
167 | return Standard_True; |
168 | } |
169 | |
170 | const Handle(Geom2d_Curve)& myCurve; |
171 | Standard_Real myUMin; |
172 | Standard_Real myUMax; |
173 | Standard_Integer myCoordIndx; |
174 | Standard_Real mySign; |
175 | }; |
176 | // |
177 | class Curv2dMaxMinCoord : public math_Function |
178 | { |
179 | public: |
180 | Curv2dMaxMinCoord(const Handle(Geom2d_Curve)& theCurve, |
181 | const Standard_Real UMin, |
182 | const Standard_Real UMax, |
183 | const Standard_Integer CoordIndx, |
184 | const Standard_Real Sign) |
185 | : myCurve(theCurve), |
186 | myUMin(UMin), |
187 | myUMax(UMax), |
188 | myCoordIndx(CoordIndx), |
189 | mySign(Sign) |
190 | { |
191 | } |
192 | |
193 | Standard_Boolean Value (const Standard_Real X, |
194 | Standard_Real& F) |
195 | { |
196 | if (!CheckInputData(X)) |
197 | { |
198 | return Standard_False; |
199 | } |
200 | gp_Pnt2d aP = myCurve->Value(X); |
201 | |
202 | F = mySign * aP.Coord(myCoordIndx); |
203 | |
204 | return Standard_True; |
205 | } |
59495dbe |
206 | |
3ba87fdb |
207 | private: |
208 | Curv2dMaxMinCoord & operator = (const Curv2dMaxMinCoord & theOther); |
209 | |
210 | Standard_Boolean CheckInputData(Standard_Real theParam) |
211 | { |
212 | if (theParam < myUMin || |
213 | theParam > myUMax) |
214 | return Standard_False; |
215 | return Standard_True; |
216 | } |
217 | |
218 | const Handle(Geom2d_Curve)& myCurve; |
219 | Standard_Real myUMin; |
220 | Standard_Real myUMax; |
221 | Standard_Integer myCoordIndx; |
222 | Standard_Real mySign; |
223 | }; |
59495dbe |
224 | |
225 | //======================================================================= |
226 | //function : |
227 | //purpose : |
228 | //======================================================================= |
229 | BndLib_Box2dCurve::BndLib_Box2dCurve() |
7fd59977 |
230 | { |
59495dbe |
231 | Clear(); |
7fd59977 |
232 | } |
7fd59977 |
233 | //======================================================================= |
59495dbe |
234 | //function : ~ |
7fd59977 |
235 | //purpose : |
236 | //======================================================================= |
59495dbe |
237 | BndLib_Box2dCurve::~BndLib_Box2dCurve() |
238 | { |
239 | } |
240 | //======================================================================= |
241 | //function : Clear |
242 | //purpose : |
243 | //======================================================================= |
244 | void BndLib_Box2dCurve::Clear() |
245 | { |
246 | myBox.SetVoid(); |
247 | // |
248 | myErrorStatus=-1; |
249 | myTypeBase=GeomAbs_OtherCurve; |
250 | myOffsetBase=0.; |
251 | myOffsetFlag=Standard_False; |
252 | } |
253 | //======================================================================= |
254 | //function : SetCurve |
255 | //purpose : |
256 | //======================================================================= |
257 | void BndLib_Box2dCurve::SetCurve(const Handle(Geom2d_Curve)& aC2D) |
258 | { |
259 | myCurve=aC2D; |
260 | } |
261 | //======================================================================= |
262 | //function : Curve |
263 | //purpose : |
264 | //======================================================================= |
265 | const Handle(Geom2d_Curve)& BndLib_Box2dCurve::Curve()const |
266 | { |
267 | return myCurve; |
268 | } |
269 | //======================================================================= |
270 | //function : SetRange |
271 | //purpose : |
272 | //======================================================================= |
273 | void BndLib_Box2dCurve::SetRange(const Standard_Real aT1, |
274 | const Standard_Real aT2) |
275 | { |
276 | myT1=aT1; |
277 | myT2=aT2; |
278 | } |
279 | //======================================================================= |
280 | //function : tRange |
281 | //purpose : |
282 | //======================================================================= |
283 | void BndLib_Box2dCurve::Range(Standard_Real& aT1, |
284 | Standard_Real& aT2) const |
285 | { |
286 | aT1=myT1; |
287 | aT2=myT2; |
288 | } |
289 | //======================================================================= |
290 | //function : ErrorStatus |
291 | //purpose : |
292 | //======================================================================= |
293 | Standard_Integer BndLib_Box2dCurve::ErrorStatus()const |
294 | { |
295 | return myErrorStatus; |
296 | } |
297 | //======================================================================= |
298 | //function : Box |
299 | //purpose : |
300 | //======================================================================= |
301 | const Bnd_Box2d& BndLib_Box2dCurve::Box()const |
302 | { |
303 | return myBox; |
304 | } |
305 | //======================================================================= |
306 | //function : CheckData |
307 | //purpose : |
308 | //======================================================================= |
309 | void BndLib_Box2dCurve::CheckData() |
310 | { |
311 | myErrorStatus=0; |
312 | // |
313 | if(myCurve.IsNull()) { |
314 | myErrorStatus=10; |
315 | return; |
316 | } |
317 | // |
318 | if(myT1>myT2) { |
319 | myErrorStatus=12; // invalid range |
320 | return; |
321 | } |
322 | } |
323 | //======================================================================= |
324 | //function : Perform |
325 | //purpose : |
326 | //======================================================================= |
327 | void BndLib_Box2dCurve::Perform() |
7fd59977 |
328 | { |
59495dbe |
329 | Clear(); |
330 | // |
331 | myErrorStatus=0; |
332 | // |
333 | CheckData(); |
334 | if(myErrorStatus) { |
335 | return; |
336 | } |
337 | // |
338 | if (myT1==myT2) { |
339 | PerformOnePoint(); |
340 | return; |
341 | } |
342 | // |
343 | GetInfoBase(); |
344 | if(myErrorStatus) { |
345 | return; |
346 | } |
347 | // |
348 | if (myTypeBase==GeomAbs_Line || |
349 | myTypeBase==GeomAbs_Circle || |
350 | myTypeBase==GeomAbs_Ellipse || |
351 | myTypeBase==GeomAbs_Parabola || |
352 | myTypeBase==GeomAbs_Hyperbola) { // LineConic |
353 | PerformLineConic(); |
354 | } |
355 | else if (myTypeBase==GeomAbs_BezierCurve) { // Bezier |
356 | PerformBezier(); |
357 | } |
358 | else if (myTypeBase==GeomAbs_BSplineCurve) { //B-Spline |
359 | PerformBSpline(); |
360 | } |
361 | else { |
362 | myErrorStatus=11; // unknown type base |
363 | } |
364 | } |
365 | //======================================================================= |
3ba87fdb |
366 | //function : PerformOptimal |
367 | //purpose : |
368 | //======================================================================= |
369 | void BndLib_Box2dCurve::PerformOptimal(const Standard_Real Tol) |
370 | { |
371 | Clear(); |
372 | myErrorStatus=0; |
373 | CheckData(); |
374 | |
375 | if(myErrorStatus) { |
376 | return; |
377 | } |
378 | |
379 | if (myT1==myT2) { |
380 | PerformOnePoint(); |
381 | return; |
382 | } |
383 | |
384 | GetInfoBase(); |
385 | if(myErrorStatus) { |
386 | return; |
387 | } |
388 | |
389 | if (myTypeBase==GeomAbs_Line || |
390 | myTypeBase==GeomAbs_Circle || |
391 | myTypeBase==GeomAbs_Ellipse || |
392 | myTypeBase==GeomAbs_Parabola || |
393 | myTypeBase==GeomAbs_Hyperbola) { // LineConic |
394 | PerformLineConic(); |
395 | } |
396 | else { |
397 | PerformGenCurv(Tol); |
398 | } |
399 | } |
400 | //======================================================================= |
59495dbe |
401 | //function : PerformOnePoint |
402 | //purpose : |
403 | //======================================================================= |
404 | void BndLib_Box2dCurve::PerformOnePoint() |
405 | { |
406 | gp_Pnt2d aP2D; |
407 | // |
408 | myCurve->D0(myT1, aP2D); |
409 | myBox.Add(aP2D); |
410 | } |
411 | //======================================================================= |
412 | //function : PerformBezier |
413 | //purpose : |
414 | //======================================================================= |
415 | void BndLib_Box2dCurve::PerformBezier() |
416 | { |
417 | if (myOffsetFlag) { |
418 | PerformOther(); |
419 | return; |
420 | } |
421 | // |
422 | Standard_Integer i, aNbPoles; |
423 | Standard_Real aT1, aT2, aTb[2]; |
424 | gp_Pnt2d aP2D; |
425 | Handle(Geom2d_Geometry) aG; |
426 | Handle(Geom2d_BezierCurve) aCBz, aCBzSeg; |
427 | // |
428 | myErrorStatus=0; |
429 | Bnd_Box2d& aBox2D=myBox; |
430 | // |
431 | aCBz=Handle(Geom2d_BezierCurve)::DownCast(myCurveBase); |
432 | aT1=aCBz->FirstParameter(); |
433 | aT2=aCBz->LastParameter(); |
434 | // |
435 | aTb[0]=myT1; |
436 | if (aTb[0]<aT1) { |
437 | aTb[0]=aT1; |
438 | } |
439 | // |
440 | aTb[1]=myT2; |
441 | if (aTb[1]>aT2) { |
442 | aTb[1]=aT2; |
443 | } |
444 | // |
445 | if (!(aT1==aTb[0] && aT2==aTb[1])) { |
446 | aG=aCBz->Copy(); |
447 | // |
448 | aCBzSeg=Handle(Geom2d_BezierCurve)::DownCast(aG); |
449 | aCBzSeg->Segment(aTb[0], aTb[1]); |
450 | aCBz=aCBzSeg; |
451 | } |
452 | // |
453 | aNbPoles=aCBz->NbPoles(); |
454 | for (i=1; i<=aNbPoles; ++i) { |
455 | aP2D=aCBz->Pole(i); |
456 | aBox2D.Add(aP2D); |
457 | } |
458 | } |
459 | //======================================================================= |
460 | //function : PerformBSpline |
461 | //purpose : |
462 | //======================================================================= |
463 | void BndLib_Box2dCurve::PerformBSpline() |
464 | { |
465 | if (myOffsetFlag) { |
466 | PerformOther(); |
467 | return; |
468 | } |
469 | // |
470 | Standard_Integer i, aNbPoles; |
471 | Standard_Real aT1, aT2, aTb[2]; |
472 | gp_Pnt2d aP2D; |
473 | Handle(Geom2d_Geometry) aG; |
474 | Handle(Geom2d_BSplineCurve) aCBS, aCBSs; |
475 | // |
476 | myErrorStatus=0; |
477 | Bnd_Box2d& aBox2D=myBox; |
478 | // |
479 | aCBS=Handle(Geom2d_BSplineCurve)::DownCast(myCurveBase); |
480 | aT1=aCBS->FirstParameter(); |
481 | aT2=aCBS->LastParameter(); |
482 | // |
483 | aTb[0]=myT1; |
484 | if (aTb[0]<aT1) { |
485 | aTb[0]=aT1; |
486 | } |
487 | aTb[1]=myT2; |
488 | if (aTb[1]>aT2) { |
489 | aTb[1]=aT2; |
490 | } |
7fd59977 |
491 | |
59495dbe |
492 | if(aTb[1] < aTb[0]) |
493 | { |
494 | aTb[0]=aT1; |
495 | aTb[1]=aT2; |
496 | } |
497 | |
498 | // |
81093856 |
499 | const Standard_Real eps = Precision::PConfusion(); |
500 | if (fabs(aT1-aTb[0]) > eps || fabs(aT2-aTb[1]) > eps) { |
59495dbe |
501 | aG=aCBS->Copy(); |
502 | // |
503 | aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG); |
504 | aCBSs->Segment(aTb[0], aTb[1]); |
505 | aCBS=aCBSs; |
506 | } |
507 | // |
508 | aNbPoles=aCBS->NbPoles(); |
509 | for (i=1; i<=aNbPoles; ++i) { |
510 | aP2D=aCBS->Pole(i); |
511 | aBox2D.Add(aP2D); |
512 | } |
513 | } |
514 | //======================================================================= |
515 | //function : PerformOther |
516 | //purpose : |
517 | //======================================================================= |
518 | void BndLib_Box2dCurve::PerformOther() |
519 | { |
520 | Standard_Integer j, aNb; |
521 | Standard_Real aT, dT; |
522 | gp_Pnt2d aP2D; |
523 | // |
524 | aNb=33; |
525 | dT=(myT2-myT1)/(aNb-1); |
526 | // |
59495dbe |
527 | for (j=0; j<aNb; ++j) { |
ece3f950 |
528 | aT=myT1+j*dT; |
59495dbe |
529 | myCurve->D0(aT, aP2D); |
530 | myBox.Add(aP2D); |
531 | } |
532 | myCurve->D0(myT2, aP2D); |
533 | myBox.Add(aP2D); |
534 | } |
535 | //======================================================================= |
3ba87fdb |
536 | //function : NbSamples |
537 | //purpose : |
538 | //======================================================================= |
539 | Standard_Integer BndLib_Box2dCurve::NbSamples() |
540 | { |
541 | Standard_Integer N; |
542 | switch (myTypeBase) { |
543 | case GeomAbs_BezierCurve: |
544 | { |
545 | Handle(Geom2d_BezierCurve) aCBz=Handle(Geom2d_BezierCurve)::DownCast(myCurveBase); |
546 | N = aCBz->NbPoles(); |
547 | //By default parametric range of Bezier curv is [0, 1] |
548 | Standard_Real du = myT2 - myT1; |
549 | if(du < .9) |
550 | { |
551 | N = RealToInt(du*N) + 1; |
552 | N = Max(N, 5); |
553 | } |
554 | break; |
555 | } |
556 | case GeomAbs_BSplineCurve: |
557 | { |
558 | Handle(Geom2d_BSplineCurve) aCBS=Handle(Geom2d_BSplineCurve)::DownCast(myCurveBase); |
559 | N = (aCBS->Degree() + 1)*(aCBS->NbKnots() -1); |
560 | Standard_Real umin = aCBS->FirstParameter(), |
561 | umax = aCBS->LastParameter(); |
562 | Standard_Real du = (myT2 - myT1) / (umax - umin); |
563 | if(du < .9) |
564 | { |
565 | N = RealToInt(du*N) + 1; |
566 | N = Max(N, 5); |
567 | } |
568 | break; |
569 | } |
570 | default: |
571 | N = 17; |
572 | } |
573 | return Min (23,N); |
574 | } |
575 | //======================================================================= |
576 | //function : AdjustExtr |
577 | //purpose : |
578 | //======================================================================= |
579 | Standard_Real BndLib_Box2dCurve::AdjustExtr(const Standard_Real UMin, |
580 | const Standard_Real UMax, |
581 | const Standard_Real Extr0, |
582 | const Standard_Integer CoordIndx, |
583 | const Standard_Real Tol, |
584 | const Standard_Boolean IsMin) |
585 | { |
586 | Standard_Real aSign = IsMin ? 1.:-1.; |
587 | Standard_Real extr = aSign * Extr0; |
588 | // |
589 | Standard_Real Du = (myCurve->LastParameter() - myCurve->FirstParameter()); |
590 | // |
591 | Geom2dAdaptor_Curve aGAC(myCurve); |
592 | Standard_Real UTol = Max(aGAC.Resolution(Tol), Precision::PConfusion()); |
593 | Standard_Real reltol = UTol / Max(Abs(UMin), Abs(UMax)); |
594 | if(UMax - UMin < 0.01 * Du) |
595 | { |
596 | //It is suggested that function has one extremum on small interval |
597 | math_BrentMinimum anOptLoc(reltol, 100, UTol); |
598 | Curv2dMaxMinCoord aFunc(myCurve, UMin, UMax, CoordIndx, aSign); |
599 | anOptLoc.Perform(aFunc, UMin, (UMin+UMax)/2., UMax); |
600 | if(anOptLoc.IsDone()) |
601 | { |
602 | extr = anOptLoc.Minimum(); |
603 | return aSign * extr; |
604 | } |
605 | } |
606 | // |
607 | Standard_Integer aNbParticles = Max(8, RealToInt(32 * (UMax - UMin) / Du)); |
608 | Standard_Real maxstep = (UMax - UMin) / (aNbParticles + 1); |
609 | math_Vector aT(1,1); |
610 | math_Vector aLowBorder(1,1); |
611 | math_Vector aUppBorder(1,1); |
612 | math_Vector aSteps(1,1); |
613 | aLowBorder(1) = UMin; |
614 | aUppBorder(1) = UMax; |
615 | aSteps(1) = Min(0.1 * Du, maxstep); |
616 | |
617 | Curv2dMaxMinCoordMVar aFunc(myCurve, UMin, UMax, CoordIndx, aSign); |
618 | math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps, aNbParticles); |
619 | aFinder.Perform(aSteps, extr, aT); |
620 | // |
621 | math_BrentMinimum anOptLoc(reltol, 100, UTol); |
622 | Curv2dMaxMinCoord aFunc1(myCurve, UMin, UMax, CoordIndx, aSign); |
623 | anOptLoc.Perform(aFunc1, Max(aT(1) - aSteps(1), UMin), aT(1), Min(aT(1) + aSteps(1), UMax)); |
624 | |
625 | if(anOptLoc.IsDone()) |
626 | { |
627 | extr = anOptLoc.Minimum(); |
628 | return aSign * extr; |
629 | } |
630 | |
631 | return aSign * extr; |
632 | } |
633 | |
634 | //======================================================================= |
635 | //function : PerformGenCurv |
636 | //purpose : |
637 | //======================================================================= |
638 | void BndLib_Box2dCurve::PerformGenCurv(const Standard_Real Tol) |
639 | { |
640 | // |
641 | Standard_Integer Nu = NbSamples(); |
642 | // |
643 | Standard_Real CoordMin[2] = {RealLast(), RealLast()}; |
644 | Standard_Real CoordMax[2] = {-RealLast(), -RealLast()}; |
645 | Standard_Real DeflMax[2] = {-RealLast(), -RealLast()}; |
646 | // |
647 | gp_Pnt2d P; |
648 | Standard_Integer i, k; |
649 | Standard_Real du = (myT2 - myT1)/(Nu-1), du2 = du / 2.; |
650 | NCollection_Array1<gp_XY> aPnts(1, Nu); |
651 | Standard_Real u; |
652 | for (i = 1, u = myT1; i <= Nu; i++, u += du) |
653 | { |
654 | D0(u,P); |
655 | aPnts(i) = P.XY(); |
656 | // |
657 | for(k = 0; k < 2; ++k) |
658 | { |
659 | if(CoordMin[k] > P.Coord(k+1)) |
660 | { |
661 | CoordMin[k] = P.Coord(k+1); |
662 | } |
663 | if(CoordMax[k] < P.Coord(k+1)) |
664 | { |
665 | CoordMax[k] = P.Coord(k+1); |
666 | } |
667 | } |
668 | // |
669 | if(i > 1) |
670 | { |
671 | gp_XY aPm = 0.5 * (aPnts(i-1) + aPnts(i)); |
672 | D0(u - du2, P); |
673 | gp_XY aD = (P.XY() - aPm); |
674 | for(k = 0; k < 2; ++k) |
675 | { |
676 | if(CoordMin[k] > P.Coord(k+1)) |
677 | { |
678 | CoordMin[k] = P.Coord(k+1); |
679 | } |
680 | if(CoordMax[k] < P.Coord(k+1)) |
681 | { |
682 | CoordMax[k] = P.Coord(k+1); |
683 | } |
684 | Standard_Real d = Abs(aD.Coord(k+1)); |
685 | if(DeflMax[k] < d) |
686 | { |
687 | DeflMax[k] = d; |
688 | } |
689 | } |
690 | } |
691 | } |
692 | // |
693 | //Adjusting minmax |
694 | for(k = 0; k < 2; ++k) |
695 | { |
696 | Standard_Real d = DeflMax[k]; |
697 | if(d <= Tol) |
698 | { |
699 | continue; |
700 | } |
701 | Standard_Real CMin = CoordMin[k]; |
702 | Standard_Real CMax = CoordMax[k]; |
703 | for(i = 1; i <= Nu; ++i) |
704 | { |
705 | if(aPnts(i).Coord(k+1) - CMin < d) |
706 | { |
707 | Standard_Real tmin, tmax; |
708 | tmin = myT1 + Max(0, i-2) * du; |
709 | tmax = myT1 + Min(Nu-1, i) * du; |
710 | Standard_Real cmin = AdjustExtr(tmin, tmax, |
711 | CMin, k + 1, Tol, Standard_True); |
712 | if(cmin < CMin) |
713 | { |
714 | CMin = cmin; |
715 | } |
716 | } |
717 | else if(CMax - aPnts(i).Coord(k+1) < d) |
718 | { |
719 | Standard_Real tmin, tmax; |
720 | tmin = myT1 + Max(0, i-2) * du; |
721 | tmax = myT1 + Min(Nu-1, i) * du; |
722 | Standard_Real cmax = AdjustExtr(tmin, tmax, |
723 | CMax, k + 1, Tol, Standard_False); |
724 | if(cmax > CMax) |
725 | { |
726 | CMax = cmax; |
727 | } |
728 | } |
729 | } |
730 | CoordMin[k] = CMin; |
731 | CoordMax[k] = CMax; |
732 | } |
733 | |
734 | myBox.Add(gp_Pnt2d(CoordMin[0], CoordMin[1])); |
735 | myBox.Add(gp_Pnt2d(CoordMax[0], CoordMax[1])); |
736 | myBox.Enlarge(Tol); |
737 | } |
738 | //======================================================================= |
59495dbe |
739 | //function : D0 |
740 | //purpose : |
741 | //======================================================================= |
742 | void BndLib_Box2dCurve::D0(const Standard_Real aU, |
743 | gp_Pnt2d& aP2D) |
744 | { |
745 | gp_Vec2d aV1; |
746 | // |
747 | myCurveBase->D1(aU, aP2D, aV1); |
748 | // |
749 | if (myOffsetFlag) { |
750 | Standard_Integer aIndex, aMaxDegree; |
751 | Standard_Real aA, aB, aR, aRes; |
752 | // |
753 | aMaxDegree=9; |
754 | aIndex = 2; |
755 | aRes=gp::Resolution(); |
756 | // |
757 | while (aV1.Magnitude() <= aRes && aIndex <= aMaxDegree) { |
758 | aV1=myCurveBase->DN(aU, aIndex); |
759 | ++aIndex; |
7fd59977 |
760 | } |
59495dbe |
761 | // |
762 | aA=aV1.Y(); |
763 | aB=-aV1.X(); |
764 | aR=sqrt(aA*aA+aB*aB); |
765 | if(aR<=aRes) { |
766 | myErrorStatus=13; |
767 | return; |
768 | } |
769 | // |
770 | aR=myOffsetBase/aR; |
771 | aA=aA*aR; |
772 | aB=aB*aR; |
773 | aP2D.SetCoord(aP2D.X()+aA, aP2D.Y()+aB); |
774 | } |
775 | // |
776 | } |
777 | //======================================================================= |
778 | //function : GetInfoBase |
779 | //purpose : |
780 | //======================================================================= |
781 | void BndLib_Box2dCurve::GetInfoBase() |
782 | { |
783 | Standard_Boolean bIsTypeBase; |
784 | Standard_Integer iTrimmed, iOffset; |
785 | GeomAbs_CurveType aTypeB; |
786 | Handle(Geom2d_Curve) aC2DB; |
787 | Handle(Geom2d_TrimmedCurve) aCT2D; |
788 | Handle(Geom2d_OffsetCurve) aCF2D; |
789 | // |
790 | myErrorStatus=0; |
791 | myTypeBase=GeomAbs_OtherCurve; |
792 | myOffsetBase=0; |
793 | // |
794 | aC2DB=myCurve; |
795 | bIsTypeBase=IsTypeBase(aC2DB, aTypeB); |
796 | if (bIsTypeBase) { |
797 | myTypeBase=aTypeB; |
798 | myCurveBase=myCurve; |
799 | return; |
800 | } |
801 | // |
59495dbe |
802 | while(!bIsTypeBase) { |
803 | iTrimmed=0; |
804 | iOffset=0; |
805 | aCT2D=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DB); |
806 | if (!aCT2D.IsNull()) { |
807 | aC2DB=aCT2D->BasisCurve(); |
808 | ++iTrimmed; |
7fd59977 |
809 | } |
59495dbe |
810 | // |
811 | aCF2D=Handle(Geom2d_OffsetCurve)::DownCast(aC2DB); |
812 | if (!aCF2D.IsNull()) { |
813 | Standard_Real aOffset; |
814 | // |
815 | aOffset=aCF2D->Offset(); |
816 | myOffsetBase=myOffsetBase+aOffset; |
817 | myOffsetFlag=Standard_True; |
818 | // |
819 | aC2DB=aCF2D->BasisCurve(); |
820 | ++iOffset; |
7fd59977 |
821 | } |
59495dbe |
822 | // |
823 | if (!(iTrimmed || iOffset)) { |
7fd59977 |
824 | break; |
825 | } |
59495dbe |
826 | // |
827 | bIsTypeBase=IsTypeBase(aC2DB, aTypeB); |
828 | if (bIsTypeBase) { |
829 | myTypeBase=aTypeB; |
830 | myCurveBase=aC2DB; |
831 | return; |
7fd59977 |
832 | } |
59495dbe |
833 | } |
834 | // |
835 | myErrorStatus=11; // unknown type base |
836 | } |
837 | //======================================================================= |
838 | //function : IsTypeBase |
839 | //purpose : |
840 | //======================================================================= |
841 | Standard_Boolean BndLib_Box2dCurve::IsTypeBase |
842 | (const Handle(Geom2d_Curve)& aC2D, |
843 | GeomAbs_CurveType& aTypeB) |
844 | { |
845 | Standard_Boolean bRet; |
846 | Handle(Standard_Type) aType; |
847 | // |
848 | bRet=Standard_True; |
849 | // |
850 | aType=aC2D->DynamicType(); |
851 | if (aType==STANDARD_TYPE(Geom2d_Line)) { |
852 | aTypeB=GeomAbs_Line; |
853 | } |
854 | else if (aType==STANDARD_TYPE(Geom2d_Circle)) { |
855 | aTypeB=GeomAbs_Circle; |
856 | } |
857 | else if (aType==STANDARD_TYPE(Geom2d_Ellipse)) { |
858 | aTypeB=GeomAbs_Ellipse; |
859 | } |
860 | else if (aType==STANDARD_TYPE(Geom2d_Parabola)) { |
861 | aTypeB=GeomAbs_Parabola; |
862 | } |
863 | else if (aType==STANDARD_TYPE(Geom2d_Hyperbola)) { |
864 | aTypeB=GeomAbs_Hyperbola; |
865 | } |
866 | else if (aType==STANDARD_TYPE(Geom2d_BezierCurve)) { |
867 | aTypeB=GeomAbs_BezierCurve; |
868 | } |
869 | else if (aType==STANDARD_TYPE(Geom2d_BSplineCurve)) { |
870 | aTypeB=GeomAbs_BSplineCurve; |
871 | } |
872 | else { |
873 | aTypeB=GeomAbs_OtherCurve; |
874 | bRet=!bRet; |
875 | } |
876 | return bRet; |
877 | } |
878 | //======================================================================= |
879 | //function : PerformLineConic |
880 | //purpose : |
881 | //======================================================================= |
882 | void BndLib_Box2dCurve::PerformLineConic() |
883 | { |
884 | Standard_Integer i, iInf[2]; |
bcf50875 |
885 | Standard_Real aTb[2]; |
59495dbe |
886 | gp_Pnt2d aP2D; |
887 | // |
888 | myErrorStatus=0; |
889 | // |
890 | Bnd_Box2d& aBox2D=myBox; |
891 | // |
59495dbe |
892 | iInf[0]=0; |
893 | iInf[1]=0; |
894 | aTb[0]=myT1; |
895 | aTb[1]=myT2; |
896 | // |
897 | for (i=0; i<2; ++i) { |
898 | if (Precision::IsNegativeInfinite(aTb[i])) { |
899 | D0(aTb[i], aP2D); |
900 | aBox2D.Add(aP2D); |
901 | ++iInf[0]; |
902 | } |
903 | else if (Precision::IsPositiveInfinite(aTb[i])) { |
904 | D0(aTb[i], aP2D); |
905 | aBox2D.Add(aP2D); |
906 | ++iInf[1]; |
907 | } |
908 | else { |
909 | D0(aTb[i], aP2D); |
910 | aBox2D.Add(aP2D); |
911 | } |
912 | } |
913 | // |
914 | if (myTypeBase==GeomAbs_Line) { |
915 | return; |
916 | } |
917 | // |
918 | if (iInf[0] && iInf[1]) { |
919 | return; |
920 | } |
921 | //------------- |
922 | Handle(Geom2d_Conic) aConic2D; |
923 | // |
924 | aConic2D=Handle(Geom2d_Conic)::DownCast(myCurveBase); |
925 | Compute(aConic2D, myTypeBase, aTb[0], aTb[1], aBox2D); |
926 | |
927 | } |
928 | //======================================================================= |
929 | //function : Compute |
930 | //purpose : |
931 | //======================================================================= |
932 | void BndLib_Box2dCurve::Compute(const Handle(Geom2d_Conic)& aConic2D, |
933 | const GeomAbs_CurveType aType, |
934 | const Standard_Real aT1, |
935 | const Standard_Real aT2, |
936 | Bnd_Box2d& aBox2D) |
937 | { |
938 | Standard_Integer i, aNbT; |
99661617 |
939 | Standard_Real pT[10], aT, aTwoPI, dT, aEps; |
59495dbe |
940 | gp_Pnt2d aP2D; |
941 | // |
942 | aNbT=Compute(aConic2D, aType, pT); |
943 | // |
944 | if (aType==GeomAbs_Parabola || aType==GeomAbs_Hyperbola) { |
945 | for (i=0; i<aNbT; ++i) { |
946 | aT=pT[i]; |
947 | if (aT>aT1 && aT<aT2) { |
948 | D0(aT, aP2D); |
949 | aBox2D.Add(aP2D); |
7fd59977 |
950 | } |
59495dbe |
951 | } |
952 | return; |
953 | } |
954 | // |
955 | //aType==GeomAbs_Circle || aType==GeomAbs_Ellipse |
956 | aEps=1.e-14; |
957 | aTwoPI=2.*M_PI; |
958 | dT=aT2-aT1; |
959 | // |
99661617 |
960 | Standard_Real aT1z = AdjustToPeriod (aT1, aTwoPI); |
59495dbe |
961 | if (fabs(aT1z)<aEps) { |
962 | aT1z=0.; |
963 | } |
964 | // |
99661617 |
965 | Standard_Real aT2z = aT1z + dT; |
59495dbe |
966 | if (fabs(aT2z-aTwoPI)<aEps) { |
967 | aT2z=aTwoPI; |
968 | } |
99661617 |
969 | // |
59495dbe |
970 | for (i=0; i<aNbT; ++i) { |
99661617 |
971 | aT = pT[i]; |
972 | // adjust aT to range [aT1z, aT1z + 2*PI]; note that pT[i] and aT1z |
973 | // are adjusted to range [0, 2*PI], but aT2z can be greater than 2*PI |
974 | aT = (aT < aT1z ? aT + aTwoPI : aT); |
975 | if (aT <= aT2z) { |
59495dbe |
976 | D0(aT, aP2D); |
977 | aBox2D.Add(aP2D); |
978 | } |
979 | } |
59495dbe |
980 | } |
99661617 |
981 | |
59495dbe |
982 | //======================================================================= |
983 | //function : Compute |
984 | //purpose : |
985 | //======================================================================= |
986 | Standard_Integer BndLib_Box2dCurve::Compute |
987 | (const Handle(Geom2d_Conic)& aConic2D, |
988 | const GeomAbs_CurveType aType, |
989 | Standard_Real *pT) |
990 | { |
991 | Standard_Integer iRet, i, j; |
992 | Standard_Real aCosBt, aSinBt, aCosGm, aSinGm; |
993 | Standard_Real aLx, aLy; |
994 | // |
995 | iRet=0; |
996 | // |
997 | const gp_Ax22d& aPos=aConic2D->Position(); |
998 | const gp_XY& aXDir=aPos.XDirection().XY(); |
999 | const gp_XY& aYDir=aPos.YDirection().XY(); |
1000 | // |
1001 | aCosBt=aXDir.X(); |
1002 | aSinBt=aXDir.Y(); |
1003 | aCosGm=aYDir.X(); |
1004 | aSinGm=aYDir.Y(); |
1005 | // |
1006 | if (aType==GeomAbs_Circle || aType==GeomAbs_Ellipse) { |
1007 | Standard_Real aR1 = 0.0, aR2 = 0.0, aTwoPI = M_PI+M_PI; |
1008 | Standard_Real aA11 = 0.0, aA12 = 0.0, aA21 = 0.0, aA22 = 0.0; |
1009 | Standard_Real aBx = 0.0, aBy = 0.0, aB = 0.0, aCosFi = 0.0, aSinFi = 0.0, aFi = 0.0; |
1010 | // |
1011 | if(aType==GeomAbs_Ellipse) { |
1012 | Handle(Geom2d_Ellipse) aEL2D; |
1013 | // |
1014 | aEL2D=Handle(Geom2d_Ellipse)::DownCast(aConic2D); |
1015 | aR1=aEL2D->MajorRadius(); |
1016 | aR2=aEL2D->MinorRadius(); |
1017 | } |
1018 | else if(aType==GeomAbs_Circle) { |
1019 | Handle(Geom2d_Circle) aCR2D; |
1020 | // |
1021 | aCR2D=Handle(Geom2d_Circle)::DownCast(aConic2D); |
1022 | aR1=aCR2D->Radius(); |
1023 | aR2=aR1; |
1024 | } |
1025 | // |
1026 | aA11=-aR1*aCosBt; |
1027 | aA12= aR2*aCosGm; |
1028 | aA21=-aR1*aSinBt; |
1029 | aA22= aR2*aSinGm; |
1030 | // |
1031 | for (i=0; i<2; ++i) { |
1032 | aLx=(!i) ? 0. : 1.; |
1033 | aLy=(!i) ? 1. : 0.; |
1034 | aBx=aLx*aA21-aLy*aA11; |
1035 | aBy=aLx*aA22-aLy*aA12; |
1036 | aB=sqrt(aBx*aBx+aBy*aBy); |
1037 | // |
1038 | aCosFi=aBx/aB; |
1039 | aSinFi=aBy/aB; |
1040 | // |
1041 | aFi=acos(aCosFi); |
1042 | if (aSinFi<0.) { |
1043 | aFi=aTwoPI-aFi; |
7fd59977 |
1044 | } |
59495dbe |
1045 | // |
1046 | j=2*i; |
1047 | pT[j]=aTwoPI-aFi; |
1048 | pT[j]=AdjustToPeriod(pT[j], aTwoPI); |
1049 | // |
1050 | pT[j+1]=M_PI-aFi; |
1051 | pT[j+1]=AdjustToPeriod(pT[j+1], aTwoPI); |
7fd59977 |
1052 | } |
59495dbe |
1053 | iRet=4; |
1054 | }//if (aType==GeomAbs_Ellipse) { |
1055 | // |
1056 | else if (aType==GeomAbs_Parabola) { |
1057 | Standard_Real aFc, aEps; |
1058 | Standard_Real aA1, aA2; |
1059 | Handle(Geom2d_Parabola) aPR2D; |
1060 | // |
1061 | aEps=1.e-12; |
1062 | // |
1063 | aPR2D=Handle(Geom2d_Parabola)::DownCast(aConic2D); |
1064 | aFc=aPR2D->Focal(); |
1065 | // |
1066 | j=0; |
1067 | for (i=0; i<2; i++) { |
1068 | aLx=(!i) ? 0. : 1.; |
1069 | aLy=(!i) ? 1. : 0.; |
1070 | // |
1071 | aA2=aLx*aSinBt-aLy*aCosBt; |
1072 | if (fabs(aA2)<aEps) { |
1073 | continue; |
1074 | } |
1075 | // |
1076 | aA1=aLy*aCosGm-aLx*aSinGm; |
1077 | // |
1078 | pT[j]=2.*aFc*aA1/aA2; |
1079 | ++j; |
1080 | } |
1081 | iRet=j; |
1082 | }// else if (aType==GeomAbs_Parabola) { |
1083 | // |
1084 | else if (aType==GeomAbs_Hyperbola) { |
1085 | Standard_Integer k; |
1086 | Standard_Real aR1, aR2; |
1087 | Standard_Real aEps, aB1, aB2, aB12, aB22, aZ, aD; |
1088 | Handle(Geom2d_Hyperbola) aHP2D; |
1089 | // |
1090 | aEps=1.e-12; |
1091 | // |
1092 | aHP2D=Handle(Geom2d_Hyperbola)::DownCast(aConic2D); |
1093 | aR1=aHP2D->MajorRadius(); |
1094 | aR2=aHP2D->MinorRadius(); |
1095 | // |
1096 | j=0; |
1097 | for (i=0; i<2; i++) { |
1098 | aLx=(!i) ? 0. : 1.; |
1099 | aLy=(!i) ? 1. : 0.; |
1100 | // |
1101 | aB1=aR1*(aLx*aSinBt-aLy*aCosBt); |
1102 | aB2=aR2*(aLx*aSinGm-aLy*aCosGm); |
1103 | // |
1104 | if (fabs(aB1)<aEps) { |
1105 | continue; |
1106 | } |
1107 | // |
1108 | if (fabs(aB2)<aEps) { |
1109 | pT[j]=0.; |
1110 | ++j; |
1111 | } |
1112 | else { |
1113 | aB12=aB1*aB1; |
1114 | aB22=aB2*aB2; |
1115 | if (!(aB12>aB22)) { |
1116 | continue; |
1117 | } |
1118 | // |
1119 | aD=sqrt(aB12-aB22); |
1120 | //------------- |
1121 | for (k=-1; k<2; k+=2) { |
1122 | aZ=(aB1+k*aD)/aB2; |
1123 | if (fabs(aZ)<1.) { |
1124 | pT[j]=-log((1.+aZ)/(1.-aZ)); |
1125 | ++j; |
1126 | } |
1127 | } |
7fd59977 |
1128 | } |
7fd59977 |
1129 | } |
59495dbe |
1130 | iRet=j; |
1131 | }// else if (aType==GeomAbs_Hyperbola) { |
1132 | // |
1133 | return iRet; |
1134 | } |
1135 | //======================================================================= |
1136 | //function : AdjustToPeriod |
1137 | //purpose : |
1138 | //======================================================================= |
1139 | Standard_Real BndLib_Box2dCurve::AdjustToPeriod(const Standard_Real aT, |
1140 | const Standard_Real aPeriod) |
1141 | { |
1142 | Standard_Integer k; |
1143 | Standard_Real aTRet; |
1144 | // |
1145 | aTRet=aT; |
1146 | if (aT<0.) { |
1147 | k=1+(Standard_Integer)(-aT/aPeriod); |
1148 | aTRet=aT+k*aPeriod; |
7fd59977 |
1149 | } |
59495dbe |
1150 | else if (aT>aPeriod) { |
1151 | k=(Standard_Integer)(aT/aPeriod); |
1152 | aTRet=aT-k*aPeriod; |
1153 | } |
1154 | if (aTRet==aPeriod) { |
1155 | aTRet=0.; |
1156 | } |
1157 | return aTRet; |
7fd59977 |
1158 | } |
59495dbe |
1159 | // |
1160 | // myErrorStatus: |
1161 | // |
1162 | // -1 - object is just initialized |
1163 | // 10 - myCurve is Null |
1164 | // 12 - invalid range myT1 > myT2l |
1165 | // 11 - unknown type of base curve |
1166 | // 13 - offset curve can not be computed |
1167 | //NMTTest |
7fd59977 |
1168 | |
59495dbe |
1169 | //======================================================================= |
1170 | //function : Add |
1171 | //purpose : |
1172 | //======================================================================= |
1173 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
1174 | const Standard_Real aTol, |
1175 | Bnd_Box2d& aBox2D) |
1176 | { |
1177 | BndLib_Add2dCurve::Add(aC, |
1178 | aC.FirstParameter(), |
1179 | aC.LastParameter (), |
1180 | aTol, |
1181 | aBox2D); |
1182 | } |
1183 | //======================================================================= |
1184 | //function : Add |
1185 | //purpose : |
1186 | //======================================================================= |
1187 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
1188 | const Standard_Real aU1, |
1189 | const Standard_Real aU2, |
1190 | const Standard_Real aTol, |
1191 | Bnd_Box2d& aBox2D) |
1192 | { |
1193 | Adaptor2d_Curve2d *pC=(Adaptor2d_Curve2d *)&aC; |
1194 | Geom2dAdaptor_Curve *pA=dynamic_cast<Geom2dAdaptor_Curve*>(pC); |
1195 | if (!pA) { |
1196 | Standard_Real U, DU; |
1197 | Standard_Integer N, j; |
1198 | gp_Pnt2d P; |
1199 | N = 33; |
1200 | U = aU1; |
1201 | DU = (aU2-aU1)/(N-1); |
1202 | for (j=1; j<N; j++) { |
1203 | aC.D0(U,P); |
1204 | U+=DU; |
1205 | aBox2D.Add(P); |
1206 | } |
1207 | aC.D0(aU2,P); |
1208 | aBox2D.Add(P); |
1209 | aBox2D.Enlarge(aTol); |
1210 | return; |
1211 | } |
1212 | // |
1213 | const Handle(Geom2d_Curve)& aC2D=pA->Curve(); |
1214 | // |
1215 | BndLib_Add2dCurve::Add(aC2D, aU1, aU2, aTol, aBox2D); |
1216 | } |
1217 | //======================================================================= |
1218 | //function : Add |
1219 | //purpose : |
1220 | //======================================================================= |
1221 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
1222 | const Standard_Real aTol, |
1223 | Bnd_Box2d& aBox2D) |
1224 | { |
1225 | Standard_Real aT1, aT2; |
1226 | // |
1227 | aT1=aC2D->FirstParameter(); |
1228 | aT2=aC2D->LastParameter(); |
1229 | // |
1230 | BndLib_Add2dCurve::Add(aC2D, aT1, aT2, aTol, aBox2D); |
1231 | } |
7fd59977 |
1232 | |
59495dbe |
1233 | //======================================================================= |
1234 | //function : Add |
1235 | //purpose : |
1236 | //======================================================================= |
1237 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
1238 | const Standard_Real aT1, |
1239 | const Standard_Real aT2, |
1240 | const Standard_Real aTol, |
1241 | Bnd_Box2d& aBox2D) |
1242 | { |
1243 | BndLib_Box2dCurve aBC; |
1244 | // |
1245 | aBC.SetCurve(aC2D); |
1246 | aBC.SetRange(aT1, aT2); |
1247 | // |
1248 | aBC.Perform(); |
1249 | // |
1250 | const Bnd_Box2d& aBoxC=aBC.Box(); |
1251 | aBox2D.Add(aBoxC); |
1252 | aBox2D.Enlarge(aTol); |
1253 | } |
3ba87fdb |
1254 | //======================================================================= |
1255 | //function : AddOptimal |
1256 | //purpose : |
1257 | //======================================================================= |
1258 | void BndLib_Add2dCurve::AddOptimal(const Handle(Geom2d_Curve)& aC2D, |
1259 | const Standard_Real aT1, |
1260 | const Standard_Real aT2, |
1261 | const Standard_Real aTol, |
1262 | Bnd_Box2d& aBox2D) |
1263 | { |
1264 | BndLib_Box2dCurve aBC; |
1265 | // |
1266 | aBC.SetCurve(aC2D); |
1267 | aBC.SetRange(aT1, aT2); |
1268 | // |
1269 | aBC.PerformOptimal(aTol); |
1270 | // |
1271 | const Bnd_Box2d& aBoxC=aBC.Box(); |
1272 | aBox2D.Add(aBoxC); |
1273 | aBox2D.Enlarge(aTol); |
1274 | } |