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> |
7fd59977 |
35 | |
36 | //======================================================================= |
59495dbe |
37 | //function : BndLib_Box2dCurve |
7fd59977 |
38 | //purpose : |
39 | //======================================================================= |
59495dbe |
40 | class BndLib_Box2dCurve { |
41 | public: |
42 | BndLib_Box2dCurve(); |
43 | |
44 | virtual ~BndLib_Box2dCurve(); |
45 | |
46 | void SetCurve(const Handle(Geom2d_Curve)& aC); |
47 | |
35c0599a |
48 | const Handle(Geom2d_Curve)& Curve() const; |
59495dbe |
49 | |
50 | void SetRange(const Standard_Real aT1, |
51 | const Standard_Real aT2); |
52 | |
53 | void Range(Standard_Real& aT1, |
54 | Standard_Real& aT2) const; |
55 | |
56 | const Bnd_Box2d& Box() const; |
7fd59977 |
57 | |
59495dbe |
58 | void Perform(); |
59 | |
60 | void Clear(); |
61 | |
62 | Standard_Integer ErrorStatus() const; |
63 | // |
64 | //----------------------------- |
65 | protected: |
66 | void CheckData(); |
67 | void GetInfoBase(); |
68 | void PerformLineConic(); |
69 | void PerformBezier(); |
70 | void PerformBSpline(); |
71 | void PerformOther(); |
72 | void D0(const Standard_Real, gp_Pnt2d&); |
73 | // |
74 | void Compute(const Handle(Geom2d_Conic)&, |
75 | const GeomAbs_CurveType, |
76 | const Standard_Real, |
77 | const Standard_Real, |
78 | Bnd_Box2d& aBox2D); |
79 | // |
80 | static |
81 | Standard_Integer Compute(const Handle(Geom2d_Conic)&, |
82 | const GeomAbs_CurveType, |
83 | Standard_Real *); |
84 | static |
85 | Standard_Boolean IsTypeBase(const Handle(Geom2d_Curve)& , |
86 | GeomAbs_CurveType& ); |
87 | static |
88 | Standard_Real AdjustToPeriod(const Standard_Real , |
89 | const Standard_Real ); |
90 | // |
91 | void PerformOnePoint(); |
92 | //----------------------------- |
93 | protected: |
35c0599a |
94 | Handle(Geom2d_Curve) myCurve; |
59495dbe |
95 | Bnd_Box2d myBox; |
96 | Standard_Integer myErrorStatus; |
35c0599a |
97 | Handle(Geom2d_Curve) myCurveBase; |
59495dbe |
98 | Standard_Real myOffsetBase; |
99 | Standard_Boolean myOffsetFlag; |
100 | Standard_Real myT1; |
101 | Standard_Real myT2; |
102 | GeomAbs_CurveType myTypeBase; |
103 | }; |
104 | |
105 | |
106 | //======================================================================= |
107 | //function : |
108 | //purpose : |
109 | //======================================================================= |
110 | BndLib_Box2dCurve::BndLib_Box2dCurve() |
7fd59977 |
111 | { |
59495dbe |
112 | Clear(); |
7fd59977 |
113 | } |
7fd59977 |
114 | //======================================================================= |
59495dbe |
115 | //function : ~ |
7fd59977 |
116 | //purpose : |
117 | //======================================================================= |
59495dbe |
118 | BndLib_Box2dCurve::~BndLib_Box2dCurve() |
119 | { |
120 | } |
121 | //======================================================================= |
122 | //function : Clear |
123 | //purpose : |
124 | //======================================================================= |
125 | void BndLib_Box2dCurve::Clear() |
126 | { |
127 | myBox.SetVoid(); |
128 | // |
129 | myErrorStatus=-1; |
130 | myTypeBase=GeomAbs_OtherCurve; |
131 | myOffsetBase=0.; |
132 | myOffsetFlag=Standard_False; |
133 | } |
134 | //======================================================================= |
135 | //function : SetCurve |
136 | //purpose : |
137 | //======================================================================= |
138 | void BndLib_Box2dCurve::SetCurve(const Handle(Geom2d_Curve)& aC2D) |
139 | { |
140 | myCurve=aC2D; |
141 | } |
142 | //======================================================================= |
143 | //function : Curve |
144 | //purpose : |
145 | //======================================================================= |
146 | const Handle(Geom2d_Curve)& BndLib_Box2dCurve::Curve()const |
147 | { |
148 | return myCurve; |
149 | } |
150 | //======================================================================= |
151 | //function : SetRange |
152 | //purpose : |
153 | //======================================================================= |
154 | void BndLib_Box2dCurve::SetRange(const Standard_Real aT1, |
155 | const Standard_Real aT2) |
156 | { |
157 | myT1=aT1; |
158 | myT2=aT2; |
159 | } |
160 | //======================================================================= |
161 | //function : tRange |
162 | //purpose : |
163 | //======================================================================= |
164 | void BndLib_Box2dCurve::Range(Standard_Real& aT1, |
165 | Standard_Real& aT2) const |
166 | { |
167 | aT1=myT1; |
168 | aT2=myT2; |
169 | } |
170 | //======================================================================= |
171 | //function : ErrorStatus |
172 | //purpose : |
173 | //======================================================================= |
174 | Standard_Integer BndLib_Box2dCurve::ErrorStatus()const |
175 | { |
176 | return myErrorStatus; |
177 | } |
178 | //======================================================================= |
179 | //function : Box |
180 | //purpose : |
181 | //======================================================================= |
182 | const Bnd_Box2d& BndLib_Box2dCurve::Box()const |
183 | { |
184 | return myBox; |
185 | } |
186 | //======================================================================= |
187 | //function : CheckData |
188 | //purpose : |
189 | //======================================================================= |
190 | void BndLib_Box2dCurve::CheckData() |
191 | { |
192 | myErrorStatus=0; |
193 | // |
194 | if(myCurve.IsNull()) { |
195 | myErrorStatus=10; |
196 | return; |
197 | } |
198 | // |
199 | if(myT1>myT2) { |
200 | myErrorStatus=12; // invalid range |
201 | return; |
202 | } |
203 | } |
204 | //======================================================================= |
205 | //function : Perform |
206 | //purpose : |
207 | //======================================================================= |
208 | void BndLib_Box2dCurve::Perform() |
7fd59977 |
209 | { |
59495dbe |
210 | Clear(); |
211 | // |
212 | myErrorStatus=0; |
213 | // |
214 | CheckData(); |
215 | if(myErrorStatus) { |
216 | return; |
217 | } |
218 | // |
219 | if (myT1==myT2) { |
220 | PerformOnePoint(); |
221 | return; |
222 | } |
223 | // |
224 | GetInfoBase(); |
225 | if(myErrorStatus) { |
226 | return; |
227 | } |
228 | // |
229 | if (myTypeBase==GeomAbs_Line || |
230 | myTypeBase==GeomAbs_Circle || |
231 | myTypeBase==GeomAbs_Ellipse || |
232 | myTypeBase==GeomAbs_Parabola || |
233 | myTypeBase==GeomAbs_Hyperbola) { // LineConic |
234 | PerformLineConic(); |
235 | } |
236 | else if (myTypeBase==GeomAbs_BezierCurve) { // Bezier |
237 | PerformBezier(); |
238 | } |
239 | else if (myTypeBase==GeomAbs_BSplineCurve) { //B-Spline |
240 | PerformBSpline(); |
241 | } |
242 | else { |
243 | myErrorStatus=11; // unknown type base |
244 | } |
245 | } |
246 | //======================================================================= |
247 | //function : PerformOnePoint |
248 | //purpose : |
249 | //======================================================================= |
250 | void BndLib_Box2dCurve::PerformOnePoint() |
251 | { |
252 | gp_Pnt2d aP2D; |
253 | // |
254 | myCurve->D0(myT1, aP2D); |
255 | myBox.Add(aP2D); |
256 | } |
257 | //======================================================================= |
258 | //function : PerformBezier |
259 | //purpose : |
260 | //======================================================================= |
261 | void BndLib_Box2dCurve::PerformBezier() |
262 | { |
263 | if (myOffsetFlag) { |
264 | PerformOther(); |
265 | return; |
266 | } |
267 | // |
268 | Standard_Integer i, aNbPoles; |
269 | Standard_Real aT1, aT2, aTb[2]; |
270 | gp_Pnt2d aP2D; |
271 | Handle(Geom2d_Geometry) aG; |
272 | Handle(Geom2d_BezierCurve) aCBz, aCBzSeg; |
273 | // |
274 | myErrorStatus=0; |
275 | Bnd_Box2d& aBox2D=myBox; |
276 | // |
277 | aCBz=Handle(Geom2d_BezierCurve)::DownCast(myCurveBase); |
278 | aT1=aCBz->FirstParameter(); |
279 | aT2=aCBz->LastParameter(); |
280 | // |
281 | aTb[0]=myT1; |
282 | if (aTb[0]<aT1) { |
283 | aTb[0]=aT1; |
284 | } |
285 | // |
286 | aTb[1]=myT2; |
287 | if (aTb[1]>aT2) { |
288 | aTb[1]=aT2; |
289 | } |
290 | // |
291 | if (!(aT1==aTb[0] && aT2==aTb[1])) { |
292 | aG=aCBz->Copy(); |
293 | // |
294 | aCBzSeg=Handle(Geom2d_BezierCurve)::DownCast(aG); |
295 | aCBzSeg->Segment(aTb[0], aTb[1]); |
296 | aCBz=aCBzSeg; |
297 | } |
298 | // |
299 | aNbPoles=aCBz->NbPoles(); |
300 | for (i=1; i<=aNbPoles; ++i) { |
301 | aP2D=aCBz->Pole(i); |
302 | aBox2D.Add(aP2D); |
303 | } |
304 | } |
305 | //======================================================================= |
306 | //function : PerformBSpline |
307 | //purpose : |
308 | //======================================================================= |
309 | void BndLib_Box2dCurve::PerformBSpline() |
310 | { |
311 | if (myOffsetFlag) { |
312 | PerformOther(); |
313 | return; |
314 | } |
315 | // |
316 | Standard_Integer i, aNbPoles; |
317 | Standard_Real aT1, aT2, aTb[2]; |
318 | gp_Pnt2d aP2D; |
319 | Handle(Geom2d_Geometry) aG; |
320 | Handle(Geom2d_BSplineCurve) aCBS, aCBSs; |
321 | // |
322 | myErrorStatus=0; |
323 | Bnd_Box2d& aBox2D=myBox; |
324 | // |
325 | aCBS=Handle(Geom2d_BSplineCurve)::DownCast(myCurveBase); |
326 | aT1=aCBS->FirstParameter(); |
327 | aT2=aCBS->LastParameter(); |
328 | // |
329 | aTb[0]=myT1; |
330 | if (aTb[0]<aT1) { |
331 | aTb[0]=aT1; |
332 | } |
333 | aTb[1]=myT2; |
334 | if (aTb[1]>aT2) { |
335 | aTb[1]=aT2; |
336 | } |
7fd59977 |
337 | |
59495dbe |
338 | if(aTb[1] < aTb[0]) |
339 | { |
340 | aTb[0]=aT1; |
341 | aTb[1]=aT2; |
342 | } |
343 | |
344 | // |
345 | if (!(aT1==aTb[0] && aT2==aTb[1])) { |
346 | aG=aCBS->Copy(); |
347 | // |
348 | aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG); |
349 | aCBSs->Segment(aTb[0], aTb[1]); |
350 | aCBS=aCBSs; |
351 | } |
352 | // |
353 | aNbPoles=aCBS->NbPoles(); |
354 | for (i=1; i<=aNbPoles; ++i) { |
355 | aP2D=aCBS->Pole(i); |
356 | aBox2D.Add(aP2D); |
357 | } |
358 | } |
359 | //======================================================================= |
360 | //function : PerformOther |
361 | //purpose : |
362 | //======================================================================= |
363 | void BndLib_Box2dCurve::PerformOther() |
364 | { |
365 | Standard_Integer j, aNb; |
366 | Standard_Real aT, dT; |
367 | gp_Pnt2d aP2D; |
368 | // |
369 | aNb=33; |
370 | dT=(myT2-myT1)/(aNb-1); |
371 | // |
372 | aT=myT1; |
373 | for (j=0; j<aNb; ++j) { |
374 | aT=j*dT; |
375 | myCurve->D0(aT, aP2D); |
376 | myBox.Add(aP2D); |
377 | } |
378 | myCurve->D0(myT2, aP2D); |
379 | myBox.Add(aP2D); |
380 | } |
381 | //======================================================================= |
382 | //function : D0 |
383 | //purpose : |
384 | //======================================================================= |
385 | void BndLib_Box2dCurve::D0(const Standard_Real aU, |
386 | gp_Pnt2d& aP2D) |
387 | { |
388 | gp_Vec2d aV1; |
389 | // |
390 | myCurveBase->D1(aU, aP2D, aV1); |
391 | // |
392 | if (myOffsetFlag) { |
393 | Standard_Integer aIndex, aMaxDegree; |
394 | Standard_Real aA, aB, aR, aRes; |
395 | // |
396 | aMaxDegree=9; |
397 | aIndex = 2; |
398 | aRes=gp::Resolution(); |
399 | // |
400 | while (aV1.Magnitude() <= aRes && aIndex <= aMaxDegree) { |
401 | aV1=myCurveBase->DN(aU, aIndex); |
402 | ++aIndex; |
7fd59977 |
403 | } |
59495dbe |
404 | // |
405 | aA=aV1.Y(); |
406 | aB=-aV1.X(); |
407 | aR=sqrt(aA*aA+aB*aB); |
408 | if(aR<=aRes) { |
409 | myErrorStatus=13; |
410 | return; |
411 | } |
412 | // |
413 | aR=myOffsetBase/aR; |
414 | aA=aA*aR; |
415 | aB=aB*aR; |
416 | aP2D.SetCoord(aP2D.X()+aA, aP2D.Y()+aB); |
417 | } |
418 | // |
419 | } |
420 | //======================================================================= |
421 | //function : GetInfoBase |
422 | //purpose : |
423 | //======================================================================= |
424 | void BndLib_Box2dCurve::GetInfoBase() |
425 | { |
426 | Standard_Boolean bIsTypeBase; |
427 | Standard_Integer iTrimmed, iOffset; |
428 | GeomAbs_CurveType aTypeB; |
429 | Handle(Geom2d_Curve) aC2DB; |
430 | Handle(Geom2d_TrimmedCurve) aCT2D; |
431 | Handle(Geom2d_OffsetCurve) aCF2D; |
432 | // |
433 | myErrorStatus=0; |
434 | myTypeBase=GeomAbs_OtherCurve; |
435 | myOffsetBase=0; |
436 | // |
437 | aC2DB=myCurve; |
438 | bIsTypeBase=IsTypeBase(aC2DB, aTypeB); |
439 | if (bIsTypeBase) { |
440 | myTypeBase=aTypeB; |
441 | myCurveBase=myCurve; |
442 | return; |
443 | } |
444 | // |
445 | aC2DB=myCurve; |
446 | while(!bIsTypeBase) { |
447 | iTrimmed=0; |
448 | iOffset=0; |
449 | aCT2D=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DB); |
450 | if (!aCT2D.IsNull()) { |
451 | aC2DB=aCT2D->BasisCurve(); |
452 | ++iTrimmed; |
7fd59977 |
453 | } |
59495dbe |
454 | // |
455 | aCF2D=Handle(Geom2d_OffsetCurve)::DownCast(aC2DB); |
456 | if (!aCF2D.IsNull()) { |
457 | Standard_Real aOffset; |
458 | // |
459 | aOffset=aCF2D->Offset(); |
460 | myOffsetBase=myOffsetBase+aOffset; |
461 | myOffsetFlag=Standard_True; |
462 | // |
463 | aC2DB=aCF2D->BasisCurve(); |
464 | ++iOffset; |
7fd59977 |
465 | } |
59495dbe |
466 | // |
467 | if (!(iTrimmed || iOffset)) { |
7fd59977 |
468 | break; |
469 | } |
59495dbe |
470 | // |
471 | bIsTypeBase=IsTypeBase(aC2DB, aTypeB); |
472 | if (bIsTypeBase) { |
473 | myTypeBase=aTypeB; |
474 | myCurveBase=aC2DB; |
475 | return; |
7fd59977 |
476 | } |
59495dbe |
477 | } |
478 | // |
479 | myErrorStatus=11; // unknown type base |
480 | } |
481 | //======================================================================= |
482 | //function : IsTypeBase |
483 | //purpose : |
484 | //======================================================================= |
485 | Standard_Boolean BndLib_Box2dCurve::IsTypeBase |
486 | (const Handle(Geom2d_Curve)& aC2D, |
487 | GeomAbs_CurveType& aTypeB) |
488 | { |
489 | Standard_Boolean bRet; |
490 | Handle(Standard_Type) aType; |
491 | // |
492 | bRet=Standard_True; |
493 | // |
494 | aType=aC2D->DynamicType(); |
495 | if (aType==STANDARD_TYPE(Geom2d_Line)) { |
496 | aTypeB=GeomAbs_Line; |
497 | } |
498 | else if (aType==STANDARD_TYPE(Geom2d_Circle)) { |
499 | aTypeB=GeomAbs_Circle; |
500 | } |
501 | else if (aType==STANDARD_TYPE(Geom2d_Ellipse)) { |
502 | aTypeB=GeomAbs_Ellipse; |
503 | } |
504 | else if (aType==STANDARD_TYPE(Geom2d_Parabola)) { |
505 | aTypeB=GeomAbs_Parabola; |
506 | } |
507 | else if (aType==STANDARD_TYPE(Geom2d_Hyperbola)) { |
508 | aTypeB=GeomAbs_Hyperbola; |
509 | } |
510 | else if (aType==STANDARD_TYPE(Geom2d_BezierCurve)) { |
511 | aTypeB=GeomAbs_BezierCurve; |
512 | } |
513 | else if (aType==STANDARD_TYPE(Geom2d_BSplineCurve)) { |
514 | aTypeB=GeomAbs_BSplineCurve; |
515 | } |
516 | else { |
517 | aTypeB=GeomAbs_OtherCurve; |
518 | bRet=!bRet; |
519 | } |
520 | return bRet; |
521 | } |
522 | //======================================================================= |
523 | //function : PerformLineConic |
524 | //purpose : |
525 | //======================================================================= |
526 | void BndLib_Box2dCurve::PerformLineConic() |
527 | { |
528 | Standard_Integer i, iInf[2]; |
bcf50875 |
529 | Standard_Real aTb[2]; |
59495dbe |
530 | gp_Pnt2d aP2D; |
531 | // |
532 | myErrorStatus=0; |
533 | // |
534 | Bnd_Box2d& aBox2D=myBox; |
535 | // |
59495dbe |
536 | iInf[0]=0; |
537 | iInf[1]=0; |
538 | aTb[0]=myT1; |
539 | aTb[1]=myT2; |
540 | // |
541 | for (i=0; i<2; ++i) { |
542 | if (Precision::IsNegativeInfinite(aTb[i])) { |
543 | D0(aTb[i], aP2D); |
544 | aBox2D.Add(aP2D); |
545 | ++iInf[0]; |
546 | } |
547 | else if (Precision::IsPositiveInfinite(aTb[i])) { |
548 | D0(aTb[i], aP2D); |
549 | aBox2D.Add(aP2D); |
550 | ++iInf[1]; |
551 | } |
552 | else { |
553 | D0(aTb[i], aP2D); |
554 | aBox2D.Add(aP2D); |
555 | } |
556 | } |
557 | // |
558 | if (myTypeBase==GeomAbs_Line) { |
559 | return; |
560 | } |
561 | // |
562 | if (iInf[0] && iInf[1]) { |
563 | return; |
564 | } |
565 | //------------- |
566 | Handle(Geom2d_Conic) aConic2D; |
567 | // |
568 | aConic2D=Handle(Geom2d_Conic)::DownCast(myCurveBase); |
569 | Compute(aConic2D, myTypeBase, aTb[0], aTb[1], aBox2D); |
570 | |
571 | } |
572 | //======================================================================= |
573 | //function : Compute |
574 | //purpose : |
575 | //======================================================================= |
576 | void BndLib_Box2dCurve::Compute(const Handle(Geom2d_Conic)& aConic2D, |
577 | const GeomAbs_CurveType aType, |
578 | const Standard_Real aT1, |
579 | const Standard_Real aT2, |
580 | Bnd_Box2d& aBox2D) |
581 | { |
582 | Standard_Integer i, aNbT; |
99661617 |
583 | Standard_Real pT[10], aT, aTwoPI, dT, aEps; |
59495dbe |
584 | gp_Pnt2d aP2D; |
585 | // |
586 | aNbT=Compute(aConic2D, aType, pT); |
587 | // |
588 | if (aType==GeomAbs_Parabola || aType==GeomAbs_Hyperbola) { |
589 | for (i=0; i<aNbT; ++i) { |
590 | aT=pT[i]; |
591 | if (aT>aT1 && aT<aT2) { |
592 | D0(aT, aP2D); |
593 | aBox2D.Add(aP2D); |
7fd59977 |
594 | } |
59495dbe |
595 | } |
596 | return; |
597 | } |
598 | // |
599 | //aType==GeomAbs_Circle || aType==GeomAbs_Ellipse |
600 | aEps=1.e-14; |
601 | aTwoPI=2.*M_PI; |
602 | dT=aT2-aT1; |
603 | // |
99661617 |
604 | Standard_Real aT1z = AdjustToPeriod (aT1, aTwoPI); |
59495dbe |
605 | if (fabs(aT1z)<aEps) { |
606 | aT1z=0.; |
607 | } |
608 | // |
99661617 |
609 | Standard_Real aT2z = aT1z + dT; |
59495dbe |
610 | if (fabs(aT2z-aTwoPI)<aEps) { |
611 | aT2z=aTwoPI; |
612 | } |
99661617 |
613 | // |
59495dbe |
614 | for (i=0; i<aNbT; ++i) { |
99661617 |
615 | aT = pT[i]; |
616 | // adjust aT to range [aT1z, aT1z + 2*PI]; note that pT[i] and aT1z |
617 | // are adjusted to range [0, 2*PI], but aT2z can be greater than 2*PI |
618 | aT = (aT < aT1z ? aT + aTwoPI : aT); |
619 | if (aT <= aT2z) { |
59495dbe |
620 | D0(aT, aP2D); |
621 | aBox2D.Add(aP2D); |
622 | } |
623 | } |
59495dbe |
624 | } |
99661617 |
625 | |
59495dbe |
626 | //======================================================================= |
627 | //function : Compute |
628 | //purpose : |
629 | //======================================================================= |
630 | Standard_Integer BndLib_Box2dCurve::Compute |
631 | (const Handle(Geom2d_Conic)& aConic2D, |
632 | const GeomAbs_CurveType aType, |
633 | Standard_Real *pT) |
634 | { |
635 | Standard_Integer iRet, i, j; |
636 | Standard_Real aCosBt, aSinBt, aCosGm, aSinGm; |
637 | Standard_Real aLx, aLy; |
638 | // |
639 | iRet=0; |
640 | // |
641 | const gp_Ax22d& aPos=aConic2D->Position(); |
642 | const gp_XY& aXDir=aPos.XDirection().XY(); |
643 | const gp_XY& aYDir=aPos.YDirection().XY(); |
644 | // |
645 | aCosBt=aXDir.X(); |
646 | aSinBt=aXDir.Y(); |
647 | aCosGm=aYDir.X(); |
648 | aSinGm=aYDir.Y(); |
649 | // |
650 | if (aType==GeomAbs_Circle || aType==GeomAbs_Ellipse) { |
651 | Standard_Real aR1 = 0.0, aR2 = 0.0, aTwoPI = M_PI+M_PI; |
652 | Standard_Real aA11 = 0.0, aA12 = 0.0, aA21 = 0.0, aA22 = 0.0; |
653 | Standard_Real aBx = 0.0, aBy = 0.0, aB = 0.0, aCosFi = 0.0, aSinFi = 0.0, aFi = 0.0; |
654 | // |
655 | if(aType==GeomAbs_Ellipse) { |
656 | Handle(Geom2d_Ellipse) aEL2D; |
657 | // |
658 | aEL2D=Handle(Geom2d_Ellipse)::DownCast(aConic2D); |
659 | aR1=aEL2D->MajorRadius(); |
660 | aR2=aEL2D->MinorRadius(); |
661 | } |
662 | else if(aType==GeomAbs_Circle) { |
663 | Handle(Geom2d_Circle) aCR2D; |
664 | // |
665 | aCR2D=Handle(Geom2d_Circle)::DownCast(aConic2D); |
666 | aR1=aCR2D->Radius(); |
667 | aR2=aR1; |
668 | } |
669 | // |
670 | aA11=-aR1*aCosBt; |
671 | aA12= aR2*aCosGm; |
672 | aA21=-aR1*aSinBt; |
673 | aA22= aR2*aSinGm; |
674 | // |
675 | for (i=0; i<2; ++i) { |
676 | aLx=(!i) ? 0. : 1.; |
677 | aLy=(!i) ? 1. : 0.; |
678 | aBx=aLx*aA21-aLy*aA11; |
679 | aBy=aLx*aA22-aLy*aA12; |
680 | aB=sqrt(aBx*aBx+aBy*aBy); |
681 | // |
682 | aCosFi=aBx/aB; |
683 | aSinFi=aBy/aB; |
684 | // |
685 | aFi=acos(aCosFi); |
686 | if (aSinFi<0.) { |
687 | aFi=aTwoPI-aFi; |
7fd59977 |
688 | } |
59495dbe |
689 | // |
690 | j=2*i; |
691 | pT[j]=aTwoPI-aFi; |
692 | pT[j]=AdjustToPeriod(pT[j], aTwoPI); |
693 | // |
694 | pT[j+1]=M_PI-aFi; |
695 | pT[j+1]=AdjustToPeriod(pT[j+1], aTwoPI); |
7fd59977 |
696 | } |
59495dbe |
697 | iRet=4; |
698 | }//if (aType==GeomAbs_Ellipse) { |
699 | // |
700 | else if (aType==GeomAbs_Parabola) { |
701 | Standard_Real aFc, aEps; |
702 | Standard_Real aA1, aA2; |
703 | Handle(Geom2d_Parabola) aPR2D; |
704 | // |
705 | aEps=1.e-12; |
706 | // |
707 | aPR2D=Handle(Geom2d_Parabola)::DownCast(aConic2D); |
708 | aFc=aPR2D->Focal(); |
709 | // |
710 | j=0; |
711 | for (i=0; i<2; i++) { |
712 | aLx=(!i) ? 0. : 1.; |
713 | aLy=(!i) ? 1. : 0.; |
714 | // |
715 | aA2=aLx*aSinBt-aLy*aCosBt; |
716 | if (fabs(aA2)<aEps) { |
717 | continue; |
718 | } |
719 | // |
720 | aA1=aLy*aCosGm-aLx*aSinGm; |
721 | // |
722 | pT[j]=2.*aFc*aA1/aA2; |
723 | ++j; |
724 | } |
725 | iRet=j; |
726 | }// else if (aType==GeomAbs_Parabola) { |
727 | // |
728 | else if (aType==GeomAbs_Hyperbola) { |
729 | Standard_Integer k; |
730 | Standard_Real aR1, aR2; |
731 | Standard_Real aEps, aB1, aB2, aB12, aB22, aZ, aD; |
732 | Handle(Geom2d_Hyperbola) aHP2D; |
733 | // |
734 | aEps=1.e-12; |
735 | // |
736 | aHP2D=Handle(Geom2d_Hyperbola)::DownCast(aConic2D); |
737 | aR1=aHP2D->MajorRadius(); |
738 | aR2=aHP2D->MinorRadius(); |
739 | // |
740 | j=0; |
741 | for (i=0; i<2; i++) { |
742 | aLx=(!i) ? 0. : 1.; |
743 | aLy=(!i) ? 1. : 0.; |
744 | // |
745 | aB1=aR1*(aLx*aSinBt-aLy*aCosBt); |
746 | aB2=aR2*(aLx*aSinGm-aLy*aCosGm); |
747 | // |
748 | if (fabs(aB1)<aEps) { |
749 | continue; |
750 | } |
751 | // |
752 | if (fabs(aB2)<aEps) { |
753 | pT[j]=0.; |
754 | ++j; |
755 | } |
756 | else { |
757 | aB12=aB1*aB1; |
758 | aB22=aB2*aB2; |
759 | if (!(aB12>aB22)) { |
760 | continue; |
761 | } |
762 | // |
763 | aD=sqrt(aB12-aB22); |
764 | //------------- |
765 | for (k=-1; k<2; k+=2) { |
766 | aZ=(aB1+k*aD)/aB2; |
767 | if (fabs(aZ)<1.) { |
768 | pT[j]=-log((1.+aZ)/(1.-aZ)); |
769 | ++j; |
770 | } |
771 | } |
7fd59977 |
772 | } |
7fd59977 |
773 | } |
59495dbe |
774 | iRet=j; |
775 | }// else if (aType==GeomAbs_Hyperbola) { |
776 | // |
777 | return iRet; |
778 | } |
779 | //======================================================================= |
780 | //function : AdjustToPeriod |
781 | //purpose : |
782 | //======================================================================= |
783 | Standard_Real BndLib_Box2dCurve::AdjustToPeriod(const Standard_Real aT, |
784 | const Standard_Real aPeriod) |
785 | { |
786 | Standard_Integer k; |
787 | Standard_Real aTRet; |
788 | // |
789 | aTRet=aT; |
790 | if (aT<0.) { |
791 | k=1+(Standard_Integer)(-aT/aPeriod); |
792 | aTRet=aT+k*aPeriod; |
7fd59977 |
793 | } |
59495dbe |
794 | else if (aT>aPeriod) { |
795 | k=(Standard_Integer)(aT/aPeriod); |
796 | aTRet=aT-k*aPeriod; |
797 | } |
798 | if (aTRet==aPeriod) { |
799 | aTRet=0.; |
800 | } |
801 | return aTRet; |
7fd59977 |
802 | } |
59495dbe |
803 | // |
804 | // myErrorStatus: |
805 | // |
806 | // -1 - object is just initialized |
807 | // 10 - myCurve is Null |
808 | // 12 - invalid range myT1 > myT2l |
809 | // 11 - unknown type of base curve |
810 | // 13 - offset curve can not be computed |
811 | //NMTTest |
7fd59977 |
812 | |
59495dbe |
813 | //======================================================================= |
814 | //function : Add |
815 | //purpose : |
816 | //======================================================================= |
817 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
818 | const Standard_Real aTol, |
819 | Bnd_Box2d& aBox2D) |
820 | { |
821 | BndLib_Add2dCurve::Add(aC, |
822 | aC.FirstParameter(), |
823 | aC.LastParameter (), |
824 | aTol, |
825 | aBox2D); |
826 | } |
827 | //======================================================================= |
828 | //function : Add |
829 | //purpose : |
830 | //======================================================================= |
831 | void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC, |
832 | const Standard_Real aU1, |
833 | const Standard_Real aU2, |
834 | const Standard_Real aTol, |
835 | Bnd_Box2d& aBox2D) |
836 | { |
837 | Adaptor2d_Curve2d *pC=(Adaptor2d_Curve2d *)&aC; |
838 | Geom2dAdaptor_Curve *pA=dynamic_cast<Geom2dAdaptor_Curve*>(pC); |
839 | if (!pA) { |
840 | Standard_Real U, DU; |
841 | Standard_Integer N, j; |
842 | gp_Pnt2d P; |
843 | N = 33; |
844 | U = aU1; |
845 | DU = (aU2-aU1)/(N-1); |
846 | for (j=1; j<N; j++) { |
847 | aC.D0(U,P); |
848 | U+=DU; |
849 | aBox2D.Add(P); |
850 | } |
851 | aC.D0(aU2,P); |
852 | aBox2D.Add(P); |
853 | aBox2D.Enlarge(aTol); |
854 | return; |
855 | } |
856 | // |
857 | const Handle(Geom2d_Curve)& aC2D=pA->Curve(); |
858 | // |
859 | BndLib_Add2dCurve::Add(aC2D, aU1, aU2, aTol, aBox2D); |
860 | } |
861 | //======================================================================= |
862 | //function : Add |
863 | //purpose : |
864 | //======================================================================= |
865 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
866 | const Standard_Real aTol, |
867 | Bnd_Box2d& aBox2D) |
868 | { |
869 | Standard_Real aT1, aT2; |
870 | // |
871 | aT1=aC2D->FirstParameter(); |
872 | aT2=aC2D->LastParameter(); |
873 | // |
874 | BndLib_Add2dCurve::Add(aC2D, aT1, aT2, aTol, aBox2D); |
875 | } |
7fd59977 |
876 | |
59495dbe |
877 | //======================================================================= |
878 | //function : Add |
879 | //purpose : |
880 | //======================================================================= |
881 | void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D, |
882 | const Standard_Real aT1, |
883 | const Standard_Real aT2, |
884 | const Standard_Real aTol, |
885 | Bnd_Box2d& aBox2D) |
886 | { |
887 | BndLib_Box2dCurve aBC; |
888 | // |
889 | aBC.SetCurve(aC2D); |
890 | aBC.SetRange(aT1, aT2); |
891 | // |
892 | aBC.Perform(); |
893 | // |
894 | const Bnd_Box2d& aBoxC=aBC.Box(); |
895 | aBox2D.Add(aBoxC); |
896 | aBox2D.Enlarge(aTol); |
897 | } |