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 | // |
499 | if (!(aT1==aTb[0] && aT2==aTb[1])) { |
500 | aG=aCBS->Copy(); |
501 | // |
502 | aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG); |
503 | aCBSs->Segment(aTb[0], aTb[1]); |
504 | aCBS=aCBSs; |
505 | } |
506 | // |
507 | aNbPoles=aCBS->NbPoles(); |
508 | for (i=1; i<=aNbPoles; ++i) { |
509 | aP2D=aCBS->Pole(i); |
510 | aBox2D.Add(aP2D); |
511 | } |
512 | } |
513 | //======================================================================= |
514 | //function : PerformOther |
515 | //purpose : |
516 | //======================================================================= |
517 | void BndLib_Box2dCurve::PerformOther() |
518 | { |
519 | Standard_Integer j, aNb; |
520 | Standard_Real aT, dT; |
521 | gp_Pnt2d aP2D; |
522 | // |
523 | aNb=33; |
524 | dT=(myT2-myT1)/(aNb-1); |
525 | // |
526 | aT=myT1; |
527 | for (j=0; j<aNb; ++j) { |
528 | aT=j*dT; |
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 | // |
802 | aC2DB=myCurve; |
803 | while(!bIsTypeBase) { |
804 | iTrimmed=0; |
805 | iOffset=0; |
806 | aCT2D=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DB); |
807 | if (!aCT2D.IsNull()) { |
808 | aC2DB=aCT2D->BasisCurve(); |
809 | ++iTrimmed; |
7fd59977 |
810 | } |
59495dbe |
811 | // |
812 | aCF2D=Handle(Geom2d_OffsetCurve)::DownCast(aC2DB); |
813 | if (!aCF2D.IsNull()) { |
814 | Standard_Real aOffset; |
815 | // |
816 | aOffset=aCF2D->Offset(); |
817 | myOffsetBase=myOffsetBase+aOffset; |
818 | myOffsetFlag=Standard_True; |
819 | // |
820 | aC2DB=aCF2D->BasisCurve(); |
821 | ++iOffset; |
7fd59977 |
822 | } |
59495dbe |
823 | // |
824 | if (!(iTrimmed || iOffset)) { |
7fd59977 |
825 | break; |
826 | } |
59495dbe |
827 | // |
828 | bIsTypeBase=IsTypeBase(aC2DB, aTypeB); |
829 | if (bIsTypeBase) { |
830 | myTypeBase=aTypeB; |
831 | myCurveBase=aC2DB; |
832 | return; |
7fd59977 |
833 | } |
59495dbe |
834 | } |
835 | // |
836 | myErrorStatus=11; // unknown type base |
837 | } |
838 | //======================================================================= |
839 | //function : IsTypeBase |
840 | //purpose : |
841 | //======================================================================= |
842 | Standard_Boolean BndLib_Box2dCurve::IsTypeBase |
843 | (const Handle(Geom2d_Curve)& aC2D, |
844 | GeomAbs_CurveType& aTypeB) |
845 | { |
846 | Standard_Boolean bRet; |
847 | Handle(Standard_Type) aType; |
848 | // |
849 | bRet=Standard_True; |
850 | // |
851 | aType=aC2D->DynamicType(); |
852 | if (aType==STANDARD_TYPE(Geom2d_Line)) { |
853 | aTypeB=GeomAbs_Line; |
854 | } |
855 | else if (aType==STANDARD_TYPE(Geom2d_Circle)) { |
856 | aTypeB=GeomAbs_Circle; |
857 | } |
858 | else if (aType==STANDARD_TYPE(Geom2d_Ellipse)) { |
859 | aTypeB=GeomAbs_Ellipse; |
860 | } |
861 | else if (aType==STANDARD_TYPE(Geom2d_Parabola)) { |
862 | aTypeB=GeomAbs_Parabola; |
863 | } |
864 | else if (aType==STANDARD_TYPE(Geom2d_Hyperbola)) { |
865 | aTypeB=GeomAbs_Hyperbola; |
866 | } |
867 | else if (aType==STANDARD_TYPE(Geom2d_BezierCurve)) { |
868 | aTypeB=GeomAbs_BezierCurve; |
869 | } |
870 | else if (aType==STANDARD_TYPE(Geom2d_BSplineCurve)) { |
871 | aTypeB=GeomAbs_BSplineCurve; |
872 | } |
873 | else { |
874 | aTypeB=GeomAbs_OtherCurve; |
875 | bRet=!bRet; |
876 | } |
877 | return bRet; |
878 | } |
879 | //======================================================================= |
880 | //function : PerformLineConic |
881 | //purpose : |
882 | //======================================================================= |
883 | void BndLib_Box2dCurve::PerformLineConic() |
884 | { |
885 | Standard_Integer i, iInf[2]; |
bcf50875 |
886 | Standard_Real aTb[2]; |
59495dbe |
887 | gp_Pnt2d aP2D; |
888 | // |
889 | myErrorStatus=0; |
890 | // |
891 | Bnd_Box2d& aBox2D=myBox; |
892 | // |
59495dbe |
893 | iInf[0]=0; |
894 | iInf[1]=0; |
895 | aTb[0]=myT1; |
896 | aTb[1]=myT2; |
897 | // |
898 | for (i=0; i<2; ++i) { |
899 | if (Precision::IsNegativeInfinite(aTb[i])) { |
900 | D0(aTb[i], aP2D); |
901 | aBox2D.Add(aP2D); |
902 | ++iInf[0]; |
903 | } |
904 | else if (Precision::IsPositiveInfinite(aTb[i])) { |
905 | D0(aTb[i], aP2D); |
906 | aBox2D.Add(aP2D); |
907 | ++iInf[1]; |
908 | } |
909 | else { |
910 | D0(aTb[i], aP2D); |
911 | aBox2D.Add(aP2D); |
912 | } |
913 | } |
914 | // |
915 | if (myTypeBase==GeomAbs_Line) { |
916 | return; |
917 | } |
918 | // |
919 | if (iInf[0] && iInf[1]) { |
920 | return; |
921 | } |
922 | //------------- |
923 | Handle(Geom2d_Conic) aConic2D; |
924 | // |
925 | aConic2D=Handle(Geom2d_Conic)::DownCast(myCurveBase); |
926 | Compute(aConic2D, myTypeBase, aTb[0], aTb[1], aBox2D); |
927 | |
928 | } |
929 | //======================================================================= |
930 | //function : Compute |
931 | //purpose : |
932 | //======================================================================= |
933 | void BndLib_Box2dCurve::Compute(const Handle(Geom2d_Conic)& aConic2D, |
934 | const GeomAbs_CurveType aType, |
935 | const Standard_Real aT1, |
936 | const Standard_Real aT2, |
937 | Bnd_Box2d& aBox2D) |
938 | { |
939 | Standard_Integer i, aNbT; |
99661617 |
940 | Standard_Real pT[10], aT, aTwoPI, dT, aEps; |
59495dbe |
941 | gp_Pnt2d aP2D; |
942 | // |
943 | aNbT=Compute(aConic2D, aType, pT); |
944 | // |
945 | if (aType==GeomAbs_Parabola || aType==GeomAbs_Hyperbola) { |
946 | for (i=0; i<aNbT; ++i) { |
947 | aT=pT[i]; |
948 | if (aT>aT1 && aT<aT2) { |
949 | D0(aT, aP2D); |
950 | aBox2D.Add(aP2D); |
7fd59977 |
951 | } |
59495dbe |
952 | } |
953 | return; |
954 | } |
955 | // |
956 | //aType==GeomAbs_Circle || aType==GeomAbs_Ellipse |
957 | aEps=1.e-14; |
958 | aTwoPI=2.*M_PI; |
959 | dT=aT2-aT1; |
960 | // |
99661617 |
961 | Standard_Real aT1z = AdjustToPeriod (aT1, aTwoPI); |
59495dbe |
962 | if (fabs(aT1z)<aEps) { |
963 | aT1z=0.; |
964 | } |
965 | // |
99661617 |
966 | Standard_Real aT2z = aT1z + dT; |
59495dbe |
967 | if (fabs(aT2z-aTwoPI)<aEps) { |
968 | aT2z=aTwoPI; |
969 | } |
99661617 |
970 | // |
59495dbe |
971 | for (i=0; i<aNbT; ++i) { |
99661617 |
972 | aT = pT[i]; |
973 | // adjust aT to range [aT1z, aT1z + 2*PI]; note that pT[i] and aT1z |
974 | // are adjusted to range [0, 2*PI], but aT2z can be greater than 2*PI |
975 | aT = (aT < aT1z ? aT + aTwoPI : aT); |
976 | if (aT <= aT2z) { |
59495dbe |
977 | D0(aT, aP2D); |
978 | aBox2D.Add(aP2D); |
979 | } |
980 | } |
59495dbe |
981 | } |
99661617 |
982 | |
59495dbe |
983 | //======================================================================= |
984 | //function : Compute |
985 | //purpose : |
986 | //======================================================================= |
987 | Standard_Integer BndLib_Box2dCurve::Compute |
988 | (const Handle(Geom2d_Conic)& aConic2D, |
989 | const GeomAbs_CurveType aType, |
990 | Standard_Real *pT) |
991 | { |
992 | Standard_Integer iRet, i, j; |
993 | Standard_Real aCosBt, aSinBt, aCosGm, aSinGm; |
994 | Standard_Real aLx, aLy; |
995 | // |
996 | iRet=0; |
997 | // |
998 | const gp_Ax22d& aPos=aConic2D->Position(); |
999 | const gp_XY& aXDir=aPos.XDirection().XY(); |
1000 | const gp_XY& aYDir=aPos.YDirection().XY(); |
1001 | // |
1002 | aCosBt=aXDir.X(); |
1003 | aSinBt=aXDir.Y(); |
1004 | aCosGm=aYDir.X(); |
1005 | aSinGm=aYDir.Y(); |
1006 | // |
1007 | if (aType==GeomAbs_Circle || aType==GeomAbs_Ellipse) { |
1008 | Standard_Real aR1 = 0.0, aR2 = 0.0, aTwoPI = M_PI+M_PI; |
1009 | Standard_Real aA11 = 0.0, aA12 = 0.0, aA21 = 0.0, aA22 = 0.0; |
1010 | Standard_Real aBx = 0.0, aBy = 0.0, aB = 0.0, aCosFi = 0.0, aSinFi = 0.0, aFi = 0.0; |
1011 | // |
1012 | if(aType==GeomAbs_Ellipse) { |
1013 | Handle(Geom2d_Ellipse) aEL2D; |
1014 | // |
1015 | aEL2D=Handle(Geom2d_Ellipse)::DownCast(aConic2D); |
1016 | aR1=aEL2D->MajorRadius(); |
1017 | aR2=aEL2D->MinorRadius(); |
1018 | } |
1019 | else if(aType==GeomAbs_Circle) { |
1020 | Handle(Geom2d_Circle) aCR2D; |
1021 | // |
1022 | aCR2D=Handle(Geom2d_Circle)::DownCast(aConic2D); |
1023 | aR1=aCR2D->Radius(); |
1024 | aR2=aR1; |
1025 | } |
1026 | // |
1027 | aA11=-aR1*aCosBt; |
1028 | aA12= aR2*aCosGm; |
1029 | aA21=-aR1*aSinBt; |
1030 | aA22= aR2*aSinGm; |
1031 | // |
1032 | for (i=0; i<2; ++i) { |
1033 | aLx=(!i) ? 0. : 1.; |
1034 | aLy=(!i) ? 1. : 0.; |
1035 | aBx=aLx*aA21-aLy*aA11; |
1036 | aBy=aLx*aA22-aLy*aA12; |
1037 | aB=sqrt(aBx*aBx+aBy*aBy); |
1038 | // |
1039 | aCosFi=aBx/aB; |
1040 | aSinFi=aBy/aB; |
1041 | // |
1042 | aFi=acos(aCosFi); |
1043 | if (aSinFi<0.) { |
1044 | aFi=aTwoPI-aFi; |
7fd59977 |
1045 | } |
59495dbe |
1046 | // |
1047 | j=2*i; |
1048 | pT[j]=aTwoPI-aFi; |
1049 | pT[j]=AdjustToPeriod(pT[j], aTwoPI); |
1050 | // |
1051 | pT[j+1]=M_PI-aFi; |
1052 | pT[j+1]=AdjustToPeriod(pT[j+1], aTwoPI); |
7fd59977 |
1053 | } |
59495dbe |
1054 | iRet=4; |
1055 | }//if (aType==GeomAbs_Ellipse) { |
1056 | // |
1057 | else if (aType==GeomAbs_Parabola) { |
1058 | Standard_Real aFc, aEps; |
1059 | Standard_Real aA1, aA2; |
1060 | Handle(Geom2d_Parabola) aPR2D; |
1061 | // |
1062 | aEps=1.e-12; |
1063 | // |
1064 | aPR2D=Handle(Geom2d_Parabola)::DownCast(aConic2D); |
1065 | aFc=aPR2D->Focal(); |
1066 | // |
1067 | j=0; |
1068 | for (i=0; i<2; i++) { |
1069 | aLx=(!i) ? 0. : 1.; |
1070 | aLy=(!i) ? 1. : 0.; |
1071 | // |
1072 | aA2=aLx*aSinBt-aLy*aCosBt; |
1073 | if (fabs(aA2)<aEps) { |
1074 | continue; |
1075 | } |
1076 | // |
1077 | aA1=aLy*aCosGm-aLx*aSinGm; |
1078 | // |
1079 | pT[j]=2.*aFc*aA1/aA2; |
1080 | ++j; |
1081 | } |
1082 | iRet=j; |
1083 | }// else if (aType==GeomAbs_Parabola) { |
1084 | // |
1085 | else if (aType==GeomAbs_Hyperbola) { |
1086 | Standard_Integer k; |
1087 | Standard_Real aR1, aR2; |
1088 | Standard_Real aEps, aB1, aB2, aB12, aB22, aZ, aD; |
1089 | Handle(Geom2d_Hyperbola) aHP2D; |
1090 | // |
1091 | aEps=1.e-12; |
1092 | // |
1093 | aHP2D=Handle(Geom2d_Hyperbola)::DownCast(aConic2D); |
1094 | aR1=aHP2D->MajorRadius(); |
1095 | aR2=aHP2D->MinorRadius(); |
1096 | // |
1097 | j=0; |
1098 | for (i=0; i<2; i++) { |
1099 | aLx=(!i) ? 0. : 1.; |
1100 | aLy=(!i) ? 1. : 0.; |
1101 | // |
1102 | aB1=aR1*(aLx*aSinBt-aLy*aCosBt); |
1103 | aB2=aR2*(aLx*aSinGm-aLy*aCosGm); |
1104 | // |
1105 | if (fabs(aB1)<aEps) { |
1106 | continue; |
1107 | } |
1108 | // |
1109 | if (fabs(aB2)<aEps) { |
1110 | pT[j]=0.; |
1111 | ++j; |
1112 | } |
1113 | else { |
1114 | aB12=aB1*aB1; |
1115 | aB22=aB2*aB2; |
1116 | if (!(aB12>aB22)) { |
1117 | continue; |
1118 | } |
1119 | // |
1120 | aD=sqrt(aB12-aB22); |
1121 | //------------- |
1122 | for (k=-1; k<2; k+=2) { |
1123 | aZ=(aB1+k*aD)/aB2; |
1124 | if (fabs(aZ)<1.) { |
1125 | pT[j]=-log((1.+aZ)/(1.-aZ)); |
1126 | ++j; |
1127 | } |
1128 | } |
7fd59977 |
1129 | } |
7fd59977 |
1130 | } |
59495dbe |
1131 | iRet=j; |
1132 | }// else if (aType==GeomAbs_Hyperbola) { |
1133 | // |
1134 | return iRet; |
1135 | } |
1136 | //======================================================================= |
1137 | //function : AdjustToPeriod |
1138 | //purpose : |
1139 | //======================================================================= |
1140 | Standard_Real BndLib_Box2dCurve::AdjustToPeriod(const Standard_Real aT, |
1141 | const Standard_Real aPeriod) |
1142 | { |
1143 | Standard_Integer k; |
1144 | Standard_Real aTRet; |
1145 | // |
1146 | aTRet=aT; |
1147 | if (aT<0.) { |
1148 | k=1+(Standard_Integer)(-aT/aPeriod); |
1149 | aTRet=aT+k*aPeriod; |
7fd59977 |
1150 | } |
59495dbe |
1151 | else if (aT>aPeriod) { |
1152 | k=(Standard_Integer)(aT/aPeriod); |
1153 | aTRet=aT-k*aPeriod; |
1154 | } |
1155 | if (aTRet==aPeriod) { |
1156 | aTRet=0.; |
1157 | } |
1158 | return aTRet; |
7fd59977 |
1159 | } |
59495dbe |
1160 | // |
1161 | // myErrorStatus: |
1162 | // |
1163 | // -1 - object is just initialized |
1164 | // 10 - myCurve is Null |
1165 | // 12 - invalid range myT1 > myT2l |
1166 | // 11 - unknown type of base curve |
1167 | // 13 - offset curve can not be computed |
1168 | //NMTTest |
7fd59977 |
1169 | |
59495dbe |
1170 | //======================================================================= |
1171 | //function : Add |
1172 | //purpose : |
1173 | //======================================================================= |
1174 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
1175 | const Standard_Real aTol, |
1176 | Bnd_Box2d& aBox2D) |
1177 | { |
1178 | BndLib_Add2dCurve::Add(aC, |
1179 | aC.FirstParameter(), |
1180 | aC.LastParameter (), |
1181 | aTol, |
1182 | aBox2D); |
1183 | } |
1184 | //======================================================================= |
1185 | //function : Add |
1186 | //purpose : |
1187 | //======================================================================= |
1188 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
1189 | const Standard_Real aU1, |
1190 | const Standard_Real aU2, |
1191 | const Standard_Real aTol, |
1192 | Bnd_Box2d& aBox2D) |
1193 | { |
1194 | Adaptor2d_Curve2d *pC=(Adaptor2d_Curve2d *)&aC; |
1195 | Geom2dAdaptor_Curve *pA=dynamic_cast<Geom2dAdaptor_Curve*>(pC); |
1196 | if (!pA) { |
1197 | Standard_Real U, DU; |
1198 | Standard_Integer N, j; |
1199 | gp_Pnt2d P; |
1200 | N = 33; |
1201 | U = aU1; |
1202 | DU = (aU2-aU1)/(N-1); |
1203 | for (j=1; j<N; j++) { |
1204 | aC.D0(U,P); |
1205 | U+=DU; |
1206 | aBox2D.Add(P); |
1207 | } |
1208 | aC.D0(aU2,P); |
1209 | aBox2D.Add(P); |
1210 | aBox2D.Enlarge(aTol); |
1211 | return; |
1212 | } |
1213 | // |
1214 | const Handle(Geom2d_Curve)& aC2D=pA->Curve(); |
1215 | // |
1216 | BndLib_Add2dCurve::Add(aC2D, aU1, aU2, aTol, aBox2D); |
1217 | } |
1218 | //======================================================================= |
1219 | //function : Add |
1220 | //purpose : |
1221 | //======================================================================= |
1222 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
1223 | const Standard_Real aTol, |
1224 | Bnd_Box2d& aBox2D) |
1225 | { |
1226 | Standard_Real aT1, aT2; |
1227 | // |
1228 | aT1=aC2D->FirstParameter(); |
1229 | aT2=aC2D->LastParameter(); |
1230 | // |
1231 | BndLib_Add2dCurve::Add(aC2D, aT1, aT2, aTol, aBox2D); |
1232 | } |
7fd59977 |
1233 | |
59495dbe |
1234 | //======================================================================= |
1235 | //function : Add |
1236 | //purpose : |
1237 | //======================================================================= |
1238 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
1239 | const Standard_Real aT1, |
1240 | const Standard_Real aT2, |
1241 | const Standard_Real aTol, |
1242 | Bnd_Box2d& aBox2D) |
1243 | { |
1244 | BndLib_Box2dCurve aBC; |
1245 | // |
1246 | aBC.SetCurve(aC2D); |
1247 | aBC.SetRange(aT1, aT2); |
1248 | // |
1249 | aBC.Perform(); |
1250 | // |
1251 | const Bnd_Box2d& aBoxC=aBC.Box(); |
1252 | aBox2D.Add(aBoxC); |
1253 | aBox2D.Enlarge(aTol); |
1254 | } |
3ba87fdb |
1255 | //======================================================================= |
1256 | //function : AddOptimal |
1257 | //purpose : |
1258 | //======================================================================= |
1259 | void BndLib_Add2dCurve::AddOptimal(const Handle(Geom2d_Curve)& aC2D, |
1260 | const Standard_Real aT1, |
1261 | const Standard_Real aT2, |
1262 | const Standard_Real aTol, |
1263 | Bnd_Box2d& aBox2D) |
1264 | { |
1265 | BndLib_Box2dCurve aBC; |
1266 | // |
1267 | aBC.SetCurve(aC2D); |
1268 | aBC.SetRange(aT1, aT2); |
1269 | // |
1270 | aBC.PerformOptimal(aTol); |
1271 | // |
1272 | const Bnd_Box2d& aBoxC=aBC.Box(); |
1273 | aBox2D.Add(aBoxC); |
1274 | aBox2D.Enlarge(aTol); |
1275 | } |