0026647: BRepTools::UVBounds() computes zero range by V
[occt.git] / src / BndLib / BndLib_Add2dCurve.cxx
CommitLineData
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 40class 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//=======================================================================
110BndLib_Box2dCurve::BndLib_Box2dCurve()
7fd59977 111{
59495dbe 112 Clear();
7fd59977 113}
7fd59977 114//=======================================================================
59495dbe 115//function : ~
7fd59977 116//purpose :
117//=======================================================================
59495dbe 118BndLib_Box2dCurve::~BndLib_Box2dCurve()
119{
120}
121//=======================================================================
122//function : Clear
123//purpose :
124//=======================================================================
125void 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//=======================================================================
138void BndLib_Box2dCurve::SetCurve(const Handle(Geom2d_Curve)& aC2D)
139{
140 myCurve=aC2D;
141}
142//=======================================================================
143//function : Curve
144//purpose :
145//=======================================================================
146const Handle(Geom2d_Curve)& BndLib_Box2dCurve::Curve()const
147{
148 return myCurve;
149}
150//=======================================================================
151//function : SetRange
152//purpose :
153//=======================================================================
154void 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//=======================================================================
164void 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//=======================================================================
174Standard_Integer BndLib_Box2dCurve::ErrorStatus()const
175{
176 return myErrorStatus;
177}
178//=======================================================================
179//function : Box
180//purpose :
181//=======================================================================
182const Bnd_Box2d& BndLib_Box2dCurve::Box()const
183{
184 return myBox;
185}
186//=======================================================================
187//function : CheckData
188//purpose :
189//=======================================================================
190void 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//=======================================================================
208void 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//=======================================================================
250void 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//=======================================================================
261void 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//=======================================================================
309void 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//=======================================================================
363void 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//=======================================================================
385void 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//=======================================================================
424void 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//=======================================================================
485Standard_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//=======================================================================
526void 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//=======================================================================
576void 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//=======================================================================
630Standard_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//=======================================================================
783Standard_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//=======================================================================
817void 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//=======================================================================
831void 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//=======================================================================
865void 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//=======================================================================
881void 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}