0025621: CAST analysis - Avoid constructors not supplying an initial value for all...
[occt.git] / src / Geom2dAdaptor / Geom2dAdaptor_Curve.cxx
1 // Created on: 1993-06-04
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902)
18 // 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals) (PRO9248)
19 // 20/10/97 : JPI -> traitement des offset curves
20
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
23
24 #include <Geom2dAdaptor_Curve.ixx>
25 #include <Geom2d_OffsetCurve.hxx>
26 #include <Geom2dAdaptor_HCurve.hxx>
27 #include <Adaptor2d_HCurve2d.hxx>
28 #include <BSplCLib.hxx>
29 #include <GeomAbs_Shape.hxx>
30 #include <TColgp_Array1OfPnt2d.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <TColStd_HArray1OfInteger.hxx>
34 #include <Precision.hxx>
35 #include <gp.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2d_Circle.hxx>
38 #include <Geom2d_Line.hxx>
39 #include <Geom2d_TrimmedCurve.hxx>
40 #include <Geom2d_BezierCurve.hxx>
41 #include <Geom2d_BSplineCurve.hxx>
42 #include <Geom2d_Ellipse.hxx>
43 #include <Geom2d_Parabola.hxx>
44 #include <Geom2d_Hyperbola.hxx>
45 //#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
46
47 #include <Standard_OutOfRange.hxx>
48 #include <Standard_NoSuchObject.hxx>
49 #include <Standard_NullObject.hxx>
50 #include <Standard_NotImplemented.hxx>
51
52 #define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve))
53 #define PosTol Precision::PConfusion()/2
54
55 //=======================================================================
56 //function : LocalContinuity
57 //purpose  : Computes the Continuity of a BSplineCurve 
58 //           between the parameters U1 and U2
59 //           The continuity is C(d-m) 
60 //             with   d = degree, 
61 //                    m = max multiplicity of the Knots between U1 and U2
62 //=======================================================================
63
64 GeomAbs_Shape Geom2dAdaptor_Curve::LocalContinuity(const Standard_Real U1, 
65                                                    const Standard_Real U2) 
66      const {
67
68        Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," ");
69        Standard_Integer Nb = myBspl->NbKnots();
70        Standard_Integer Index1 = 0;
71        Standard_Integer Index2 = 0;
72        Standard_Real newFirst, newLast;
73        TColStd_Array1OfReal    TK(1,Nb);
74        TColStd_Array1OfInteger TM(1,Nb);
75        myBspl->Knots(TK);
76        myBspl->Multiplicities(TM);
77        BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U1,myBspl->IsPeriodic(),
78                                  1,Nb,Index1,newFirst);
79        BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U2,myBspl->IsPeriodic(),
80                                  1,Nb,Index2,newLast);
81        if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) { 
82          if (Index1 < Nb)Index1++;
83        }
84        if ( Abs(newLast-TK(Index2))<Precision::PConfusion())
85          Index2--;
86        Standard_Integer MultMax;
87        // attention aux courbes peridiques.
88        if ( (myBspl->IsPeriodic()) && (Index1 == Nb) )
89          Index1 = 1;
90
91        if ( Index2 - Index1 <= 0) {
92          MultMax = 100;  // CN entre 2 Noeuds consecutifs
93        }
94        else {
95          MultMax = TM(Index1+1);
96          for(Standard_Integer i = Index1+1;i<=Index2;i++) {
97            if ( TM(i)>MultMax) MultMax=TM(i);
98          }
99          MultMax = myBspl->Degree() - MultMax;
100        }
101        if ( MultMax <= 0) {
102          return GeomAbs_C0;
103        }
104        else if ( MultMax == 1) {
105          return GeomAbs_C1;
106        } 
107        else if ( MultMax == 2) {
108          return GeomAbs_C2;
109        }
110        else if ( MultMax == 3) {
111          return GeomAbs_C3;
112        }
113        else { 
114          return GeomAbs_CN;
115        }
116      }
117
118
119 //=======================================================================
120 //function : Geom2dAdaptor_Curve
121 //purpose  : 
122 //=======================================================================
123
124 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve()
125 : myTypeCurve(GeomAbs_OtherCurve),
126   myFirst    (0.0),
127   myLast     (0.0)
128 {
129 }
130
131 //=======================================================================
132 //function : Geom2dAdaptor_Curve
133 //purpose  : 
134 //=======================================================================
135
136 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv)
137 : myTypeCurve(GeomAbs_OtherCurve),
138   myFirst    (0.0),
139   myLast     (0.0)
140 {
141   Load(theCrv);
142 }
143
144 //=======================================================================
145 //function : Geom2dAdaptor_Curve
146 //purpose  : 
147 //=======================================================================
148
149 Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv,
150                                          const Standard_Real theUFirst,
151                                          const Standard_Real theULast)
152 : myTypeCurve(GeomAbs_OtherCurve),
153   myFirst    (theUFirst),
154   myLast     (theULast)
155 {
156   Load(theCrv, theUFirst, theULast);
157 }
158
159
160 //=======================================================================
161 //function : Load
162 //purpose  : 
163 //=======================================================================
164
165 void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
166                                                  const Standard_Real UFirst,
167                                                  const Standard_Real ULast) 
168 {
169   myFirst = UFirst;
170   myLast  = ULast;
171
172   if ( myCurve != C) {
173     myCurve = C;
174
175     Handle(Standard_Type) TheType = C->DynamicType();
176     if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
177       Load((*((Handle(Geom2d_TrimmedCurve)*)&C))->BasisCurve(),
178            UFirst,ULast);
179     }
180     else if ( TheType ==  STANDARD_TYPE(Geom2d_Circle)) {
181       myTypeCurve = GeomAbs_Circle;
182     }
183     else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
184       myTypeCurve = GeomAbs_Line;
185     }
186     else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
187       myTypeCurve = GeomAbs_Ellipse;
188     }
189     else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
190       myTypeCurve = GeomAbs_Parabola;
191     }
192     else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
193       myTypeCurve = GeomAbs_Hyperbola;
194     }
195     else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
196       myTypeCurve = GeomAbs_BezierCurve;
197     }
198     else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
199       myTypeCurve = GeomAbs_BSplineCurve;
200     }
201     else {
202       myTypeCurve = GeomAbs_OtherCurve;
203     }
204   }
205 }
206
207 //    --
208 //    --     Global methods - Apply to the whole curve.
209 //    --     
210
211 //=======================================================================
212 //function : Continuity
213 //purpose  : 
214 //=======================================================================
215
216 GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const 
217 {
218   if (myTypeCurve == GeomAbs_BSplineCurve) {
219     return LocalContinuity(myFirst, myLast);
220   }
221   else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
222     GeomAbs_Shape S = 
223       (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); 
224     switch(S){
225     case GeomAbs_CN: return GeomAbs_CN;
226     case GeomAbs_C3: return GeomAbs_C2;
227     case GeomAbs_C2: return GeomAbs_C1;
228     case GeomAbs_C1: return GeomAbs_C0;  
229     case GeomAbs_G1: return GeomAbs_G1;
230     case GeomAbs_G2: return GeomAbs_G2;
231
232     default:
233       Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity");
234     }
235   }
236
237   else if (myTypeCurve == GeomAbs_OtherCurve) {
238     Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity");
239   }
240   else {
241     return GeomAbs_CN;
242   }
243
244   // portage WNT
245   return GeomAbs_CN;
246 }
247
248 //=======================================================================
249 //function : NbIntervals
250 //purpose  : 
251 //=======================================================================
252
253 Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
254 {
255   Standard_Integer myNbIntervals = 1;
256   Standard_Integer NbSplit;
257   if (myTypeCurve == GeomAbs_BSplineCurve) {
258     Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
259     Standard_Integer LastIndex  = myBspl->LastUKnotIndex();
260     TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
261     if ( S > Continuity()) {
262       Standard_Integer Cont;
263       switch ( S) {
264       case GeomAbs_G1:
265       case GeomAbs_G2:
266         Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
267         break;
268       case GeomAbs_C0:
269         myNbIntervals = 1;
270         break;
271       case GeomAbs_C1:
272       case GeomAbs_C2:
273       case GeomAbs_C3: 
274       case GeomAbs_CN: 
275         {
276           if      ( S == GeomAbs_C1) Cont = 1;
277           else if ( S == GeomAbs_C2) Cont = 2;
278           else if ( S == GeomAbs_C3) Cont = 3;
279           else                       Cont = myBspl->Degree();
280           Standard_Integer Degree = myBspl->Degree();
281           Standard_Integer NbKnots = myBspl->NbKnots();
282           TColStd_Array1OfInteger Mults (1, NbKnots);
283           myBspl->Multiplicities (Mults);
284           NbSplit = 1;
285           Standard_Integer Index   = FirstIndex;
286           Inter (NbSplit) = Index;
287           Index++;
288           NbSplit++;
289           while (Index < LastIndex) 
290             {
291               if (Degree - Mults (Index) < Cont) 
292                 {
293                   Inter (NbSplit) = Index;
294                   NbSplit++;
295                 }
296               Index++;
297             }
298           Inter (NbSplit) = Index;
299
300           Standard_Integer NbInt = NbSplit-1;
301           
302           Standard_Integer Nb = myBspl->NbKnots();
303           Standard_Integer Index1 = 0;
304           Standard_Integer Index2 = 0;
305           Standard_Real newFirst, newLast;
306           TColStd_Array1OfReal    TK(1,Nb);
307           TColStd_Array1OfInteger TM(1,Nb);
308           myBspl->Knots(TK);
309           myBspl->Multiplicities(TM);
310           BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
311                                     myBspl->IsPeriodic(),
312                                     1,Nb,Index1,newFirst);
313           BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
314                                     myBspl->IsPeriodic(),
315                                     1,Nb,Index2,newLast);
316
317           // On decale eventuellement les indices  
318           // On utilise une "petite" tolerance, la resolution ne doit 
319           // servir que pour les tres longue courbes....(PRO9248)
320           Standard_Real Eps = Min(Resolution(Precision::Confusion()),
321                                   Precision::PConfusion()); 
322           if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
323           if ( newLast-TK(Index2)> Eps) Index2++;
324           
325           myNbIntervals = 1;
326           for ( Standard_Integer i=1; i<=NbInt; i++)
327             if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
328         }
329         break;
330       }
331     }
332   }
333   else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
334     GeomAbs_Shape BaseS=GeomAbs_C0;
335     switch(S){
336     case GeomAbs_G1:
337     case GeomAbs_G2:
338       Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
339       break;
340     case GeomAbs_C0: BaseS = GeomAbs_C1; break;
341     case GeomAbs_C1: BaseS = GeomAbs_C2; break;
342     case GeomAbs_C2: BaseS = GeomAbs_C3; break;
343     default: BaseS = GeomAbs_CN;
344     }
345     Geom2dAdaptor_Curve C
346       ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
347     myNbIntervals = C.NbIntervals(BaseS);
348   }
349
350   return myNbIntervals;
351 }
352
353 //=======================================================================
354 //function : Intervals
355 //purpose  : 
356 //=======================================================================
357
358 void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
359                                     const GeomAbs_Shape S   ) const 
360 {
361   Standard_Integer myNbIntervals = 1;
362   Standard_Integer NbSplit;
363   if (myTypeCurve == GeomAbs_BSplineCurve) {
364     Standard_Integer FirstIndex = myBspl->FirstUKnotIndex();
365     Standard_Integer LastIndex  = myBspl->LastUKnotIndex();
366     TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
367     if ( S > Continuity()) {
368       Standard_Integer Cont;
369       switch ( S) {
370       case GeomAbs_G1:
371       case GeomAbs_G2:
372         Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals");
373         break;
374       case GeomAbs_C0:
375         myNbIntervals = 1;
376         break;
377       case GeomAbs_C1:
378       case GeomAbs_C2:
379       case GeomAbs_C3: 
380       case GeomAbs_CN: 
381         {
382           if      ( S == GeomAbs_C1) Cont = 1;
383           else if ( S == GeomAbs_C2) Cont = 2;
384           else if ( S == GeomAbs_C3) Cont = 3;
385           else                       Cont = myBspl->Degree();
386           Standard_Integer Degree = myBspl->Degree();
387           Standard_Integer NbKnots = myBspl->NbKnots();
388           TColStd_Array1OfInteger Mults (1, NbKnots);
389           myBspl->Multiplicities (Mults);
390           NbSplit = 1;
391           Standard_Integer Index   = FirstIndex;
392           Inter (NbSplit) = Index;
393           Index++;
394           NbSplit++;
395           while (Index < LastIndex) 
396             {
397               if (Degree - Mults (Index) < Cont) 
398                 {
399                   Inter (NbSplit) = Index;
400                   NbSplit++;
401                 }
402               Index++;
403             }
404           Inter (NbSplit) = Index;
405           Standard_Integer NbInt = NbSplit-1;
406           
407           Standard_Integer Nb = myBspl->NbKnots();
408           Standard_Integer Index1 = 0;
409           Standard_Integer Index2 = 0;
410           Standard_Real newFirst, newLast;
411           TColStd_Array1OfReal    TK(1,Nb);
412           TColStd_Array1OfInteger TM(1,Nb);
413           myBspl->Knots(TK);
414           myBspl->Multiplicities(TM);
415           BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst,
416                                     myBspl->IsPeriodic(),
417                                     1,Nb,Index1,newFirst);
418           BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast,
419                                     myBspl->IsPeriodic(),
420                                     1,Nb,Index2,newLast);
421
422
423           // On decale eventuellement les indices  
424           // On utilise une "petite" tolerance, la resolution ne doit 
425           // servir que pour les tres longue courbes....(PRO9248)
426           Standard_Real Eps = Min(Resolution(Precision::Confusion()),
427                                   Precision::PConfusion()); 
428           if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
429           if ( newLast-TK(Index2)> Eps) Index2++;
430           
431           Inter( 1) = Index1;
432           myNbIntervals = 1;
433           for ( Standard_Integer i=1; i<=NbInt; i++) {
434             if (Inter(i) > Index1 && Inter(i)<Index2 ) {
435               myNbIntervals++;
436               Inter(myNbIntervals) = Inter(i);
437             }
438           }
439           Inter(myNbIntervals+1) = Index2;
440           
441           Standard_Integer ii = T.Lower() - 1;
442           for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
443             T(ii + I) = TK(Inter(I));
444           }
445         }
446         break;
447       }
448     }
449   }
450   else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
451     GeomAbs_Shape BaseS=GeomAbs_C0;
452     switch(S){
453     case GeomAbs_G1:
454     case GeomAbs_G2:
455       Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals");
456       break;
457     case GeomAbs_C0: BaseS = GeomAbs_C1; break;
458     case GeomAbs_C1: BaseS = GeomAbs_C2; break;
459     case GeomAbs_C2: BaseS = GeomAbs_C3; break;
460     default: BaseS = GeomAbs_CN;
461     }
462     Geom2dAdaptor_Curve C
463       ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
464     myNbIntervals = C.NbIntervals(BaseS);
465     C.Intervals(T, BaseS);
466   }
467
468   T( T.Lower() ) = myFirst;
469   T( T.Lower() + myNbIntervals ) = myLast;
470 }
471
472 //=======================================================================
473 //function : Trim
474 //purpose  : 
475 //=======================================================================
476
477 Handle(Adaptor2d_HCurve2d) Geom2dAdaptor_Curve::Trim
478 (const Standard_Real First,
479  const Standard_Real Last,
480 // const Standard_Real Tol) const 
481  const Standard_Real ) const 
482 {
483   Handle(Geom2dAdaptor_HCurve) HE = new Geom2dAdaptor_HCurve(myCurve,First,Last);
484   return HE;
485 }
486
487
488 //=======================================================================
489 //function : IsClosed
490 //purpose  : 
491 //=======================================================================
492
493 Standard_Boolean Geom2dAdaptor_Curve::IsClosed() const 
494 {
495   if (!Precision::IsPositiveInfinite(myLast) &&
496       !Precision::IsNegativeInfinite(myFirst)) {
497     gp_Pnt2d Pd = Value(myFirst);
498     gp_Pnt2d Pf = Value(myLast);
499     return ( Pd.Distance(Pf) <= Precision::Confusion());
500   }
501   else
502     return Standard_False;
503 }
504
505 //=======================================================================
506 //function : IsPeriodic
507 //purpose  : 
508 //=======================================================================
509
510 Standard_Boolean Geom2dAdaptor_Curve::IsPeriodic() const 
511 {
512   if (myCurve->IsPeriodic())
513     return IsClosed();
514   else
515     return Standard_False;
516 }
517
518 //=======================================================================
519 //function : Period
520 //purpose  : 
521 //=======================================================================
522
523 Standard_Real Geom2dAdaptor_Curve::Period() const 
524 {
525   return myCurve->LastParameter() - myCurve->FirstParameter();
526 }
527
528 //=======================================================================
529 //function : Value
530 //purpose  : 
531 //=======================================================================
532
533 gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const 
534 {
535   if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
536       (U==myFirst || U==myLast) ) {
537     Standard_Integer Ideb = 0, Ifin = 0;
538     if (U==myFirst) {
539       myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
540       if (Ideb<1) Ideb=1;
541       if (Ideb>=Ifin) Ifin = Ideb+1;
542     }
543     if (U==myLast) {
544       myBspl->LocateU(myLast,  PosTol, Ideb, Ifin);
545       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
546       if (Ideb>=Ifin) Ideb = Ifin-1;
547     }
548     return myBspl->LocalValue(U, Ideb, Ifin);
549   }
550   else {
551     return myCurve->Value( U);
552   }
553 }
554
555 //=======================================================================
556 //function : D0
557 //purpose  : 
558 //=======================================================================
559
560 void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
561 {
562   if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
563       (U==myFirst || U==myLast) ) {
564     Standard_Integer Ideb = 0, Ifin = 0;
565     if (U==myFirst) {
566       myBspl->LocateU(myFirst,  PosTol, Ideb, Ifin);
567       if (Ideb<1) Ideb=1;
568       if (Ideb>=Ifin) Ifin = Ideb+1;
569     }
570     if (U==myLast) {
571       myBspl->LocateU(myLast,  PosTol, Ideb, Ifin);
572       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
573       if (Ideb>=Ifin) Ideb = Ifin-1;
574     }
575     myBspl->LocalD0( U, Ideb, Ifin, P);
576   }
577   else {
578     myCurve->D0(U, P);
579   } 
580 }
581
582 //=======================================================================
583 //function : D1
584 //purpose  : 
585 //=======================================================================
586
587 void Geom2dAdaptor_Curve::D1(const Standard_Real U,
588                              gp_Pnt2d& P, gp_Vec2d& V) const 
589 {
590   if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
591       (U==myFirst || U==myLast) ) {
592     Standard_Integer Ideb = 0, Ifin = 0;
593     if (U==myFirst) {
594       myBspl->LocateU(myFirst,  PosTol, Ideb, Ifin);
595       if (Ideb<1) Ideb=1;
596       if (Ideb>=Ifin) Ifin = Ideb+1;
597     }
598     if (U==myLast) {
599       myBspl->LocateU(myLast,  PosTol, Ideb, Ifin);
600       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
601       if (Ideb>=Ifin) Ideb = Ifin-1;
602     }
603     myBspl->LocalD1( U, Ideb, Ifin, P, V); 
604   } 
605   else {
606     myCurve->D1( U, P, V);
607   }
608 }
609
610 //=======================================================================
611 //function : D2
612 //purpose  : 
613 //=======================================================================
614
615 void Geom2dAdaptor_Curve::D2(const Standard_Real U, 
616                              gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const 
617 {
618   if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
619       (U==myFirst || U==myLast) ) {
620     Standard_Integer Ideb = 0, Ifin = 0;
621     if (U==myFirst) {
622       myBspl->LocateU(myFirst,  PosTol, Ideb, Ifin);
623       if (Ideb<1) Ideb=1;
624       if (Ideb>=Ifin) Ifin = Ideb+1;
625     }
626     if (U==myLast) {
627       myBspl->LocateU(myLast,  PosTol, Ideb, Ifin);
628       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
629       if (Ideb>=Ifin) Ideb = Ifin-1;
630     }
631     myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
632   }
633   else {
634     myCurve->D2( U, P, V1, V2);
635   }
636 }
637
638 //=======================================================================
639 //function : D3
640 //purpose  : 
641 //=======================================================================
642
643 void Geom2dAdaptor_Curve::D3(const Standard_Real U, 
644                              gp_Pnt2d& P,  gp_Vec2d& V1, 
645                              gp_Vec2d& V2, gp_Vec2d& V3) const 
646 {
647   if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
648       (U==myFirst || U==myLast) ) {
649     Standard_Integer Ideb = 0, Ifin = 0;
650     if (U==myFirst) {
651       myBspl->LocateU(myFirst,  PosTol, Ideb, Ifin);
652       if (Ideb<1) Ideb=1;
653       if (Ideb>=Ifin) Ifin = Ideb+1;
654     }
655     if (U==myLast) {
656       myBspl->LocateU(myLast,  PosTol, Ideb, Ifin);
657       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
658       if (Ideb>=Ifin) Ideb = Ifin-1;
659     }
660     myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);  
661   }
662   else {
663     myCurve->D3( U, P, V1, V2, V3);
664   }
665 }
666
667 //=======================================================================
668 //function : DN
669 //purpose  : 
670 //=======================================================================
671
672 gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, 
673                                  const Standard_Integer N) const 
674 {
675   if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
676       (U==myFirst || U==myLast) ) {
677     Standard_Integer Ideb = 0, Ifin = 0;
678     if (U==myFirst) {
679       myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
680       if (Ideb<1) Ideb=1;
681       if (Ideb>=Ifin) Ifin = Ideb+1;
682     }
683     if (U==myLast) {
684       myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
685       if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
686       if (Ideb>=Ifin) Ideb = Ifin-1;
687     } 
688     return myBspl->LocalDN( U, Ideb, Ifin, N);
689   }  
690   else {
691     return myCurve->DN( U, N);
692   }
693 }
694
695 //=======================================================================
696 //function : Resolution
697 //purpose  : 
698 //=======================================================================
699
700 Standard_Real Geom2dAdaptor_Curve::Resolution(const Standard_Real Ruv) const {
701   switch ( myTypeCurve) {
702   case GeomAbs_Line :
703     return Ruv;
704   case GeomAbs_Circle: {
705     Standard_Real R = (*((Handle(Geom2d_Circle)*)&myCurve))->Circ2d().Radius();
706     if ( R > Ruv/2.)
707       return 2*ASin(Ruv/(2*R));
708     else
709       return 2*M_PI;
710   }
711   case GeomAbs_Ellipse: {
712     return Ruv / (*((Handle(Geom2d_Ellipse)*)&myCurve))->MajorRadius();
713   }
714   case GeomAbs_BezierCurve: {
715     Standard_Real res;
716     (*((Handle(Geom2d_BezierCurve)*)&myCurve))->Resolution(Ruv,res);
717     return res;
718   }
719   case GeomAbs_BSplineCurve: {
720     Standard_Real res;
721     (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->Resolution(Ruv,res);
722     return res;
723   }
724   default:
725     return Precision::Parametric(Ruv);
726   }  
727 }
728
729
730 //    --
731 //    --     The following methods must  be called when GetType returned
732 //    --     the corresponding type.
733 //    --     
734
735 //=======================================================================
736 //function : Line
737 //purpose  : 
738 //=======================================================================
739
740 gp_Lin2d Geom2dAdaptor_Curve::Line() const 
741 {
742   Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, "");
743   return (*((Handle(Geom2d_Line)*)&myCurve))->Lin2d();
744 }
745
746 //=======================================================================
747 //function : Circle
748 //purpose  : 
749 //=======================================================================
750
751 gp_Circ2d  Geom2dAdaptor_Curve::Circle() const 
752 {
753   Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, "");
754   return (*((Handle(Geom2d_Circle)*)&myCurve))->Circ2d();
755 }
756
757 //=======================================================================
758 //function : Ellipse
759 //purpose  : 
760 //=======================================================================
761
762 gp_Elips2d Geom2dAdaptor_Curve::Ellipse() const 
763 {
764   Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, "");
765   return (*((Handle(Geom2d_Ellipse)*)&myCurve))->Elips2d();
766 }
767
768 //=======================================================================
769 //function : Hyperbola
770 //purpose  : 
771 //=======================================================================
772
773 gp_Hypr2d Geom2dAdaptor_Curve::Hyperbola() const 
774 {
775   Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, "");
776   return (*((Handle(Geom2d_Hyperbola)*)&myCurve))->Hypr2d();
777 }
778
779 //=======================================================================
780 //function : Parabola
781 //purpose  : 
782 //=======================================================================
783
784 gp_Parab2d Geom2dAdaptor_Curve::Parabola() const 
785 {
786   Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, "");
787   return (*((Handle(Geom2d_Parabola)*)&myCurve))->Parab2d();
788 }
789
790 //=======================================================================
791 //function : Degree
792 //purpose  : 
793 //=======================================================================
794
795 Standard_Integer Geom2dAdaptor_Curve::Degree() const
796 {
797   if (myTypeCurve == GeomAbs_BezierCurve)
798     return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->Degree();
799   else if (myTypeCurve == GeomAbs_BSplineCurve)
800     return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->Degree();
801   else
802     Standard_NoSuchObject::Raise();
803   // portage WNT 
804   return 0;
805 }
806
807 //=======================================================================
808 //function : IsRational
809 //purpose  : 
810 //=======================================================================
811
812 Standard_Boolean Geom2dAdaptor_Curve::IsRational() const {
813   switch( myTypeCurve) {
814   case GeomAbs_BSplineCurve:
815     return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->IsRational();
816   case GeomAbs_BezierCurve:
817     return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->IsRational();
818   default:
819     return Standard_False;
820   }
821 }
822
823 //=======================================================================
824 //function : NbPoles
825 //purpose  : 
826 //=======================================================================
827
828 Standard_Integer Geom2dAdaptor_Curve::NbPoles() const
829 {
830   if (myTypeCurve == GeomAbs_BezierCurve)
831     return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->NbPoles();
832   else if (myTypeCurve == GeomAbs_BSplineCurve)
833     return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->NbPoles();
834   else
835     Standard_NoSuchObject::Raise();
836   // portage WNT 
837   return 0;
838 }
839
840 //=======================================================================
841 //function : NbKnots
842 //purpose  : 
843 //=======================================================================
844
845 Standard_Integer Geom2dAdaptor_Curve::NbKnots() const {
846   if ( myTypeCurve != GeomAbs_BSplineCurve)
847     Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::NbKnots");
848   return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->NbKnots();
849
850 }
851
852 //=======================================================================
853 //function : Bezier
854 //purpose  : 
855 //=======================================================================
856
857 Handle(Geom2d_BezierCurve) Geom2dAdaptor_Curve::Bezier() const 
858 {
859   return *((Handle(Geom2d_BezierCurve)*)&myCurve);
860 }
861
862 //=======================================================================
863 //function : BSpline
864 //purpose  : 
865 //=======================================================================
866
867 Handle(Geom2d_BSplineCurve) Geom2dAdaptor_Curve::BSpline() const 
868 {
869   return *((Handle(Geom2d_BSplineCurve)*)&myCurve);
870 }
871
872 static Standard_Integer nbPoints(const Handle(Geom2d_Curve)& theCurve) 
873 {
874  
875   Standard_Integer nbs = 10;
876   
877   if(theCurve->IsKind(STANDARD_TYPE( Geom2d_Line)) )
878     nbs = 2;
879   else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BezierCurve))) 
880   {
881     nbs = 3 + (*((Handle(Geom2d_BezierCurve)*)&theCurve))->NbPoles();
882   }
883   else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BSplineCurve))) { 
884     nbs =  (*((Handle(Geom2d_BSplineCurve)*)&theCurve))->NbKnots();
885     nbs*= (*((Handle(Geom2d_BSplineCurve)*)&theCurve))->Degree();
886     if(nbs < 2.0) nbs=2;
887   }
888   else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
889   {
890     Handle(Geom2d_Curve) aCurve = (*((Handle(Geom2d_OffsetCurve)*)&theCurve))->BasisCurve();
891     return Max(nbs, nbPoints(aCurve));
892   }
893
894   else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
895   {
896     Handle(Geom2d_Curve) aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&theCurve))->BasisCurve();
897     return Max(nbs, nbPoints(aCurve));
898   }
899   if(nbs>300)
900     nbs = 300;
901   return nbs;
902   
903 }
904
905 Standard_Integer Geom2dAdaptor_Curve::NbSamples() const
906 {
907   return  nbPoints(myCurve);
908 }