1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
15 #include <Adaptor2d_HCurve2d.hxx>
16 #include <Adaptor2d_HOffsetCurve.hxx>
17 #include <Adaptor2d_OffsetCurve.hxx>
18 #include <Geom2d_BezierCurve.hxx>
19 #include <Geom2d_BSplineCurve.hxx>
20 #include <Geom2dEvaluator.hxx>
21 #include <GeomAbs_SurfaceType.hxx>
23 #include <gp_Ax22d.hxx>
24 #include <gp_Circ2d.hxx>
25 #include <gp_Dir2d.hxx>
26 #include <gp_Elips2d.hxx>
27 #include <gp_Hypr2d.hxx>
28 #include <gp_Lin2d.hxx>
29 #include <gp_Parab2d.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <gp_Vec2d.hxx>
32 #include <gp_VectorWithNullMagnitude.hxx>
33 #include <Precision.hxx>
34 #include <Standard_DomainError.hxx>
35 #include <Standard_NoSuchObject.hxx>
36 #include <Standard_NotImplemented.hxx>
37 #include <Standard_TypeMismatch.hxx>
39 //=======================================================================
40 //function : Adaptor2d_OffsetCurve
42 //=======================================================================
43 Adaptor2d_OffsetCurve::Adaptor2d_OffsetCurve()
50 //=======================================================================
51 //function : Adaptor2d_OffsetCurve
53 //=======================================================================
55 Adaptor2d_OffsetCurve::Adaptor2d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& theCurve)
63 //=======================================================================
64 //function : Adaptor2d_OffsetCurve
66 //=======================================================================
68 Adaptor2d_OffsetCurve::Adaptor2d_OffsetCurve
69 (const Handle(Adaptor2d_HCurve2d)& theCurve, const Standard_Real theOffset)
72 myFirst (theCurve->FirstParameter()),
73 myLast (theCurve->LastParameter())
77 //=======================================================================
78 //function : Adaptor2d_OffsetCurve
80 //=======================================================================
82 Adaptor2d_OffsetCurve::Adaptor2d_OffsetCurve(
83 const Handle(Adaptor2d_HCurve2d)& theCurve,
84 const Standard_Real theOffset,
85 const Standard_Real theWFirst,
86 const Standard_Real theWLast )
94 //=======================================================================
97 //=======================================================================
99 void Adaptor2d_OffsetCurve::Load(const Handle(Adaptor2d_HCurve2d)& C )
105 //=======================================================================
108 //=======================================================================
110 void Adaptor2d_OffsetCurve::Load( const Standard_Real Offset)
113 myFirst = myCurve->FirstParameter();
114 myLast = myCurve->LastParameter();
117 //=======================================================================
120 //=======================================================================
122 void Adaptor2d_OffsetCurve::Load(const Standard_Real Offset,
123 const Standard_Real WFirst,
124 const Standard_Real WLast)
131 //=======================================================================
132 //function : Continuity
134 //=======================================================================
136 GeomAbs_Shape Adaptor2d_OffsetCurve::Continuity() const
138 switch (myCurve->Continuity()) {
139 case GeomAbs_CN: return GeomAbs_CN;
140 case GeomAbs_C3: return GeomAbs_C2;
141 case GeomAbs_C2: return GeomAbs_G2;
142 case GeomAbs_G2: return GeomAbs_C1;
143 case GeomAbs_C1: return GeomAbs_G1;
144 case GeomAbs_G1: return GeomAbs_C0;
147 throw Standard_TypeMismatch("Adaptor2d_OffsetCurve::IntervalContinuity");
155 //=======================================================================
156 //function : NbIntervals
158 //=======================================================================
160 Standard_Integer Adaptor2d_OffsetCurve::NbIntervals(const GeomAbs_Shape S) const
163 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
165 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
167 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
169 if(nbInter == 1) return nbInter;
171 TColStd_Array1OfReal T(1,nbInter+1);
173 myCurve->Intervals(T,Sh);
175 Standard_Integer first = 1;
176 while (T(first) <= myFirst) first++;
177 Standard_Integer last = nbInter+1;
178 while (T(last) >= myLast) last--;
179 return (last - first + 2);
182 //=======================================================================
183 //function : Intervals
185 //=======================================================================
187 void Adaptor2d_OffsetCurve::Intervals(TColStd_Array1OfReal& TI,
188 const GeomAbs_Shape S) const
191 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
193 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
195 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
199 TI(TI.Lower()) = myFirst ;
200 TI(TI.Lower() + 1) = myLast ;
204 TColStd_Array1OfReal T(1,nbInter+1);
205 myCurve->Intervals(T,Sh);
207 Standard_Integer first = 1;
208 while (T(first) <= myFirst) first++;
209 Standard_Integer last = nbInter+1;
210 while (T(last) >= myLast) last--;
212 Standard_Integer i = TI.Lower(), j;
213 for (j = first-1; j <= last+1; j++) {
218 TI(TI.Lower()) = myFirst ;
219 TI(TI.Lower() + last-first + 2) = myLast ;
224 //=======================================================================
227 //=======================================================================
229 Handle(Adaptor2d_HCurve2d) Adaptor2d_OffsetCurve::Trim
230 (const Standard_Real First,
231 const Standard_Real Last,
232 const Standard_Real) const
234 Handle(Adaptor2d_HOffsetCurve) HO = new Adaptor2d_HOffsetCurve(*this);
235 HO->ChangeCurve2d().Load(myOffset,First,Last);
240 //=======================================================================
241 //function : IsClosed
243 //=======================================================================
245 Standard_Boolean Adaptor2d_OffsetCurve::IsClosed() const
247 if ( myOffset == 0.) {
248 return myCurve->IsClosed();
251 if (myCurve->Continuity() == GeomAbs_C0)
252 return Standard_False;
254 if ( myCurve->IsClosed()) {
258 (myCurve->FirstParameter(),P,Dummy[0]);
260 (myCurve->LastParameter(),P,Dummy[1]);
261 if (Dummy[0].IsParallel(Dummy[1],Precision::Angular()) &&
262 !(Dummy[0].IsOpposite(Dummy[1],Precision::Angular())))
263 return Standard_True;
265 return Standard_False;
268 return Standard_False;
273 //=======================================================================
274 //function : IsPeriodic
276 //=======================================================================
278 Standard_Boolean Adaptor2d_OffsetCurve::IsPeriodic() const
280 return myCurve->IsPeriodic();
283 //=======================================================================
286 //=======================================================================
288 Standard_Real Adaptor2d_OffsetCurve::Period() const
290 return myCurve->Period();
293 //=======================================================================
296 //=======================================================================
298 gp_Pnt2d Adaptor2d_OffsetCurve::Value(const Standard_Real U) const
300 if ( myOffset != 0.) {
303 myCurve->D1(U, aP, aV);
304 Geom2dEvaluator::CalculateD0(aP, aV, myOffset);
308 return myCurve->Value(U);
312 //=======================================================================
315 //=======================================================================
317 void Adaptor2d_OffsetCurve::D0(const Standard_Real U, gp_Pnt2d& P) const
322 //=======================================================================
325 //=======================================================================
327 void Adaptor2d_OffsetCurve::D1
328 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V) const
330 if (myOffset != 0.) {
332 myCurve->D2(U, P, V, aV2);
333 Geom2dEvaluator::CalculateD1( P, V, aV2, myOffset);
336 myCurve->D1(U, P, V);
340 //=======================================================================
343 //=======================================================================
345 void Adaptor2d_OffsetCurve::D2
346 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
348 if (myOffset != 0.) {
350 myCurve->D3(U, P, V1, V2, aV3);
351 Geom2dEvaluator::CalculateD2(P, V1, V2, aV3, Standard_False, myOffset);
354 myCurve->D2(U, P, V1, V2);
358 //=======================================================================
361 //=======================================================================
363 void Adaptor2d_OffsetCurve::D3
364 (const Standard_Real U,
365 gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2, gp_Vec2d& V3) const
367 if (myOffset != 0.) {
368 gp_Vec2d aV4 = myCurve->DN(U, 4);
369 myCurve->D3(U, P, V1, V2, V3);
370 Geom2dEvaluator::CalculateD3(P, V1, V2, V3, aV4, Standard_False, myOffset);
373 myCurve->D3(U, P, V1, V2, V3);
377 //=======================================================================
380 //=======================================================================
382 gp_Vec2d Adaptor2d_OffsetCurve::DN
383 (const Standard_Real , const Standard_Integer ) const
385 throw Standard_NotImplemented("Adaptor2d_OffsetCurve::DN");
389 //=======================================================================
390 //function : Resolution
392 //=======================================================================
394 Standard_Real Adaptor2d_OffsetCurve::Resolution(const Standard_Real R3d) const
396 return Precision::PConfusion(R3d);
400 //=======================================================================
403 //=======================================================================
405 GeomAbs_CurveType Adaptor2d_OffsetCurve::GetType() const {
407 if ( myOffset == 0.) {
408 return myCurve->GetType();
411 switch (myCurve->GetType()) {
417 return GeomAbs_Circle;
420 return GeomAbs_OffsetCurve;
426 //=======================================================================
429 //=======================================================================
431 gp_Lin2d Adaptor2d_OffsetCurve::Line() const
433 if ( GetType() == GeomAbs_Line) {
437 return gp_Lin2d(P,V);
440 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::Line");
445 //=======================================================================
448 //=======================================================================
450 gp_Circ2d Adaptor2d_OffsetCurve::Circle() const
452 if ( GetType() == GeomAbs_Circle) {
453 if (myOffset == 0.) {
454 return myCurve->Circle();
457 gp_Circ2d C1( myCurve->Circle());
458 Standard_Real radius = C1.Radius();
459 gp_Ax22d axes( C1.Axis());
460 gp_Dir2d Xd = axes.XDirection();
461 gp_Dir2d Yd = axes.YDirection();
462 Standard_Real Crossed = Xd.X()*Yd.Y()-Xd.Y()*Yd.X();
463 Standard_Real Signe = ( Crossed > 0.) ? 1. : -1.;
465 radius += Signe*myOffset;
467 return gp_Circ2d( axes,radius);
469 else if ( radius < 0.) {
471 axes.SetXDirection( (axes.XDirection()).Reversed());
472 return gp_Circ2d( axes,radius);
474 else { // Cercle de rayon Nul
475 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::Circle");
480 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::Circle");
484 //=======================================================================
487 //=======================================================================
489 gp_Elips2d Adaptor2d_OffsetCurve::Ellipse() const
491 if (myCurve->GetType() == GeomAbs_Ellipse && myOffset == 0.) {
492 return myCurve->Ellipse();
495 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve:Ellipse");
499 //=======================================================================
500 //function : Hyperbola
502 //=======================================================================
504 gp_Hypr2d Adaptor2d_OffsetCurve::Hyperbola() const
506 if (myCurve->GetType()==GeomAbs_Hyperbola && myOffset==0.) {
507 return myCurve->Hyperbola();
510 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve:Hyperbola");
514 //=======================================================================
515 //function : Parabola
517 //=======================================================================
519 gp_Parab2d Adaptor2d_OffsetCurve::Parabola() const
521 if (myCurve->GetType() == GeomAbs_Parabola && myOffset == 0.) {
522 return myCurve->Parabola();
525 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve:Parabola");
528 //=======================================================================
531 //=======================================================================
533 Standard_Integer Adaptor2d_OffsetCurve::Degree() const
535 GeomAbs_CurveType type = myCurve->GetType();
536 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
538 return myCurve->Degree();
541 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::Degree");
544 //=======================================================================
545 //function : IsRational
547 //=======================================================================
549 Standard_Boolean Adaptor2d_OffsetCurve::IsRational() const
551 if ( myOffset == 0.) {
552 return myCurve->IsRational();
554 return Standard_False;
556 //=======================================================================
559 //=======================================================================
561 Standard_Integer Adaptor2d_OffsetCurve::NbPoles() const
563 GeomAbs_CurveType type = myCurve->GetType();
564 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
566 return myCurve->NbPoles();
569 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::NbPoles");
573 //=======================================================================
576 //=======================================================================
578 Standard_Integer Adaptor2d_OffsetCurve::NbKnots() const
580 if( myOffset == 0.) {
581 return myCurve->NbKnots();
584 throw Standard_NoSuchObject("Adaptor2d_OffsetCurve::NbKnots");
588 //=======================================================================
591 //=======================================================================
593 Handle(Geom2d_BezierCurve) Adaptor2d_OffsetCurve::Bezier() const
595 Standard_NoSuchObject_Raise_if (myOffset != 0.0e0 || GetType() != GeomAbs_BezierCurve,
596 "Adaptor2d_OffsetCurve::Bezier() - wrong curve type");
597 return myCurve->Bezier();
601 //=======================================================================
604 //=======================================================================
606 Handle(Geom2d_BSplineCurve) Adaptor2d_OffsetCurve::BSpline() const
608 Standard_NoSuchObject_Raise_if (myOffset != 0.0e0 || GetType() != GeomAbs_BSplineCurve,
609 "Adaptor2d_OffsetCurve::BSpline() - wrong curve type");
610 return myCurve->BSpline();
613 static Standard_Integer nbPoints(const Handle(Adaptor2d_HCurve2d)& theCurve)
616 Standard_Integer nbs = 20;
618 if (theCurve->GetType() == GeomAbs_BezierCurve)
620 nbs = Max(nbs, 3 + theCurve->NbPoles());
622 else if (theCurve->GetType() == GeomAbs_BSplineCurve) {
623 nbs = Max(nbs, theCurve->NbKnots() * theCurve->Degree());
631 //=======================================================================
632 //function : NbSamples
634 //=======================================================================
636 Standard_Integer Adaptor2d_OffsetCurve::NbSamples() const
638 return nbPoints(myCurve);