0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / ProjLib / ProjLib_ProjectOnPlane.cxx
1 // Created on: 1994-09-05
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-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 // 09-Aug-95 : xab : changed the ProjLib_ProjectOnPlane in the case
18 //                   of the line and the parameteriation is kept
19 #include <ProjLib_ProjectOnPlane.hxx>
20 #include <AppCont_Function.hxx>
21 #include <Approx_FitAndDivide.hxx>
22 #include <AppParCurves_MultiCurve.hxx>
23 #include <Standard_ConstructionError.hxx>
24 #include <Standard_NoSuchObject.hxx>
25 #include <Standard_NotImplemented.hxx>
26 #include <Precision.hxx>
27 #include <BSplCLib.hxx>
28 #include <PLib.hxx>
29 #include <Geom_BSplineCurve.hxx>
30 #include <Geom_BezierCurve.hxx>
31 #include <TColgp_HArray1OfPnt.hxx>
32 #include <TColStd_HArray1OfReal.hxx>
33 #include <TColStd_HArray1OfInteger.hxx>
34 #include <Precision.hxx>
35 #include <ElCLib.hxx>
36 #include <Adaptor3d_Curve.hxx>
37 #include <Adaptor3d_HCurve.hxx>
38 #include <GeomAdaptor_HCurve.hxx>
39 #include <Geom_Line.hxx>
40 #include <GeomConvert.hxx>
41 #include <BSplCLib.hxx>
42 #include <Geom_TrimmedCurve.hxx>
43 #include <Geom_Circle.hxx>
44 #include <Geom_Parabola.hxx>
45 #include <Geom_Hyperbola.hxx>
46 #include <Geom_Ellipse.hxx>
47
48
49
50 //=======================================================================
51 //function : OnPlane_Value
52 //purpose  : Evaluate current point of the projected curve
53 //=======================================================================
54
55 static gp_Pnt OnPlane_Value(const Standard_Real U,
56                             const Handle(Adaptor3d_HCurve)& aCurvePtr,
57                             const gp_Ax3& Pl,
58                             const gp_Dir& D)
59 {
60   //                   PO . Z                /  Z = Pl.Direction()
61   // Proj(u) = P(u) + -------  * D     avec  \  O = Pl.Location()
62   //                   D  . Z
63
64   gp_Pnt Point = aCurvePtr->Value(U);
65   
66   gp_Vec PO(Point,Pl.Location());
67   
68   Standard_Real Alpha = PO * gp_Vec(Pl.Direction());
69   Alpha /= D * Pl.Direction();
70   Point.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
71
72   return Point;
73 }
74
75 //=======================================================================
76 //function : OnPlane_DN
77 //purpose  : Evaluate current point of the projected curve
78 //=======================================================================
79
80 static gp_Vec OnPlane_DN(const Standard_Real U,
81                          const Standard_Integer DerivativeRequest,
82                          const Handle(Adaptor3d_HCurve)& aCurvePtr,
83                          const gp_Ax3& Pl,
84                          const gp_Dir& D)
85 {
86   //                   PO . Z                /  Z = Pl.Direction()
87   // Proj(u) = P(u) + -------  * D     avec  \  O = Pl.Location()
88   //                   D  . Z
89
90   gp_Vec Vector = aCurvePtr->DN(U,DerivativeRequest);
91
92   gp_Dir Z = Pl.Direction();
93   
94   Standard_Real
95   Alpha  = Vector * gp_Vec(Z);
96   Alpha /=  D * Z;
97
98   Vector.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
99   return Vector ;
100 }
101
102 //=======================================================================
103 //function : OnPlane_D1
104 //purpose  : 
105 //=======================================================================
106
107 static Standard_Boolean OnPlane_D1(const Standard_Real U,
108                                          gp_Pnt& P,
109                                          gp_Vec& V,
110                                    const Handle(Adaptor3d_HCurve)& aCurvePtr,
111                                    const gp_Ax3& Pl,
112                                    const gp_Dir& D)
113 {
114   Standard_Real Alpha;
115   gp_Pnt Point;
116   gp_Vec Vector;
117   
118   gp_Dir Z = Pl.Direction();
119
120   aCurvePtr->D1(U, Point, Vector);
121
122   // evaluate the point as in `OnPlane_Value`
123   gp_Vec PO(Point,Pl.Location());
124   Alpha  = PO * gp_Vec(Z);
125   Alpha /= D * Z;
126   P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
127
128   
129   // evaluate the derivative.
130   // 
131   //   d(Proj)  d(P)       1        d(P)
132   //   ------ = ---  - -------- * ( --- . Z ) * D
133   //     dU     dU     ( D . Z)     dU  
134   //
135
136   Alpha  = Vector * gp_Vec(Z);
137   Alpha /=  D * Z;
138
139   V.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
140
141   return Standard_True;
142 }
143 //=======================================================================
144 //function : OnPlane_D2
145 //purpose  : 
146 //=======================================================================
147
148 static Standard_Boolean OnPlane_D2(const Standard_Real U,
149                                          gp_Pnt& P,
150                                          gp_Vec& V1,
151                                          gp_Vec& V2,
152                                    const Handle(Adaptor3d_HCurve) & aCurvePtr,
153                                    const gp_Ax3& Pl,
154                                    const gp_Dir& D)
155 {
156   Standard_Real Alpha;
157   gp_Pnt Point;
158   gp_Vec Vector1,
159   Vector2;
160   
161   gp_Dir Z = Pl.Direction();
162
163   aCurvePtr->D2(U, Point, Vector1, Vector2);
164
165   // evaluate the point as in `OnPlane_Value`
166   gp_Vec PO(Point,Pl.Location());
167   Alpha  = PO * gp_Vec(Z);
168   Alpha /= D * Z;
169   P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
170
171   // evaluate the derivative.
172   // 
173   //   d(Proj)  d(P)       1        d(P)
174   //   ------ = ---  - -------- * ( --- . Z ) * D
175   //     dU     dU     ( D . Z)     dU  
176   //
177
178   Alpha  = Vector1 * gp_Vec(Z);
179   Alpha /=  D * Z;
180
181   V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
182
183   Alpha  = Vector2 * gp_Vec(Z);
184   Alpha /=  D * Z;
185
186   V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
187   return Standard_True;
188 }
189
190 //=======================================================================
191 //function : OnPlane_D3
192 //purpose  : 
193 //=======================================================================
194
195 static Standard_Boolean OnPlane_D3(const Standard_Real U,
196                                          gp_Pnt& P,
197                                          gp_Vec& V1,
198                                          gp_Vec& V2,
199                                          gp_Vec& V3,
200                                    const Handle(Adaptor3d_HCurve)& aCurvePtr,
201                                    const gp_Ax3& Pl,
202                                    const gp_Dir& D)
203 {
204   Standard_Real Alpha;
205   gp_Pnt Point;
206   gp_Vec Vector1,
207   Vector2,
208   Vector3;
209   
210   gp_Dir Z = Pl.Direction();
211
212   aCurvePtr->D3(U, Point, Vector1, Vector2, Vector3);
213
214   // evaluate the point as in `OnPlane_Value`
215   gp_Vec PO(Point,Pl.Location());
216   Alpha  = PO * gp_Vec(Z);
217   Alpha /= D * Z;
218   P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
219   
220   // evaluate the derivative.
221   // 
222   //   d(Proj)  d(P)       1        d(P)
223   //   ------ = ---  - -------- * ( --- . Z ) * D
224   //     dU     dU     ( D . Z)     dU  
225   //
226
227   Alpha  = Vector1 * gp_Vec(Z);
228   Alpha /=  D * Z;
229
230   V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
231
232   Alpha  = Vector2 * gp_Vec(Z);
233   Alpha /=  D * Z;
234
235   V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
236   Alpha  = Vector3 * gp_Vec(Z);
237   Alpha /=  D * Z;
238
239   V3.SetXYZ( Vector3.XYZ() - Alpha * D.XYZ());
240   return Standard_True;
241 }
242
243 //=======================================================================
244 //  class  : ProjLib_OnPlane
245 //purpose  : Use to approximate the projection on a plane
246 //=======================================================================
247
248 class ProjLib_OnPlane : public AppCont_Function
249
250 {
251   Handle(Adaptor3d_HCurve) myCurve;
252   gp_Ax3 myPlane;
253   gp_Dir myDirection;
254
255 public :
256
257   ProjLib_OnPlane(const Handle(Adaptor3d_HCurve)& C, 
258                   const gp_Ax3& Pl, 
259                   const gp_Dir& D) 
260 : myCurve(C),
261   myPlane(Pl),
262   myDirection(D)
263   {
264     myNbPnt = 1;
265     myNbPnt2d = 0;
266   }
267
268   Standard_Real FirstParameter() const
269     {return myCurve->FirstParameter();}
270   
271   Standard_Real LastParameter() const
272     {return myCurve->LastParameter();}
273
274     Standard_Boolean Value(const Standard_Real   theT,
275                            NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
276                            NCollection_Array1<gp_Pnt>&   thePnt) const
277     {
278       thePnt(1) = OnPlane_Value(theT, myCurve, myPlane, myDirection);
279       return Standard_True;
280     }
281   
282   Standard_Boolean D1(const Standard_Real   theT,
283                       NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
284                       NCollection_Array1<gp_Vec>&   theVec) const
285   {
286     gp_Pnt aDummyPnt;
287     return OnPlane_D1(theT, aDummyPnt, theVec(1),myCurve,myPlane,myDirection);
288   }
289 };
290
291
292
293
294 //=====================================================================//
295 //                                                                     //
296 //  D E S C R I P T I O N   O F   T H E   C L A S S  :                 // 
297 //                                                                     //
298 //         P r o j L i b _ A p p r o x P r o j e c t O n P l a n e     //
299 //                                                                     //
300 //=====================================================================//
301
302
303
304 //=======================================================================
305 //function : PerformApprox
306 //purpose  : 
307 //=======================================================================
308
309 static void  PerformApprox (const Handle(Adaptor3d_HCurve)& C,
310                             const gp_Ax3& Pl,
311                             const gp_Dir& D,
312                             Handle(Geom_BSplineCurve) &BSplineCurvePtr) 
313
314 {
315   ProjLib_OnPlane F(C,Pl,D);
316
317   Standard_Integer Deg1, Deg2;
318   Deg1 = 8; Deg2 = 8;
319   
320   Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
321                           Precision::PApproximation(),Standard_True);
322   Standard_Integer i;
323   Standard_Integer NbCurves = Fit.NbMultiCurves();
324   Standard_Integer MaxDeg = 0;
325   
326   // Pour transformer la MultiCurve en BSpline, il faut que toutes 
327   // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
328   Standard_Integer NbPoles  = 1;
329   for (i = 1; i <= NbCurves; i++) {
330     Standard_Integer Deg = Fit.Value(i).Degree();
331     MaxDeg = Max ( MaxDeg, Deg);
332   }
333   NbPoles = MaxDeg * NbCurves + 1;               //Poles sur la BSpline
334
335   TColgp_Array1OfPnt    Poles( 1, NbPoles);
336   
337   TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1);  //pour augmentation du degre
338   
339   TColStd_Array1OfReal Knots( 1, NbCurves + 1);  //Noeuds de la BSpline
340   
341   Standard_Integer Compt = 1;
342   for (i = 1; i <= Fit.NbMultiCurves(); i++) {
343     Fit.Parameters(i, Knots(i), Knots(i+1)); 
344     
345     AppParCurves_MultiCurve MC = Fit.Value( i);   //Charge la Ieme Curve
346     TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
347     MC.Curve(1, LocalPoles);
348     
349     //Augmentation eventuelle du degre
350     Standard_Integer Inc = MaxDeg - MC.Degree();
351     if ( Inc > 0) {
352       BSplCLib::IncreaseDegree(Inc, Poles, BSplCLib::NoWeights(),
353                                TempPoles, BSplCLib::NoWeights());
354       //mise a jour des poles de la PCurve
355       for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
356         Poles.SetValue( Compt, TempPoles( j));
357         Compt++;
358       }
359     }
360     else {
361       //mise a jour des poles de la PCurve
362       for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
363         Poles.SetValue( Compt, LocalPoles( j));
364         Compt++;
365       }
366     } 
367     
368     Compt--;
369   }
370   
371   //mise a jour des fields de ProjLib_Approx
372
373   Standard_Integer 
374   NbKnots = NbCurves + 1;
375
376   TColStd_Array1OfInteger    Mults(1, NbKnots);
377   Mults.SetValue( 1, MaxDeg + 1);
378   for ( i = 2; i <= NbCurves; i++) {
379     Mults.SetValue( i, MaxDeg);
380   }
381   Mults.SetValue( NbKnots, MaxDeg + 1);
382   BSplineCurvePtr = 
383     new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
384 }
385
386
387 //=======================================================================
388 //function : ProjectOnPlane
389 //purpose  : 
390 //=======================================================================
391
392 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
393 myKeepParam(Standard_False),
394 myFirstPar(0.),
395 myLastPar(0.),
396 myTolerance(0.),
397 myType     (GeomAbs_OtherCurve),
398 myIsApprox (Standard_False)
399 {
400 }
401
402 //=======================================================================
403 //function : ProjLib_ProjectOnPlane
404 //purpose  : 
405 //=======================================================================
406
407 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) : 
408 myPlane     (Pl)                ,
409 myDirection (Pl.Direction())    ,
410 myKeepParam(Standard_False),
411 myFirstPar(0.),
412 myLastPar(0.),
413 myTolerance(0.),
414 myType      (GeomAbs_OtherCurve),
415 myIsApprox  (Standard_False)
416 {
417 }
418
419 //=======================================================================
420 //function : ProjLib_ProjectOnPlane
421 //purpose  : 
422 //=======================================================================
423
424 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
425                                                const gp_Dir& D  ) :
426 myPlane     (Pl)                ,
427 myDirection (D)                 ,
428 myKeepParam(Standard_False),
429 myFirstPar(0.),
430 myLastPar(0.),
431 myTolerance(0.),
432 myType      (GeomAbs_OtherCurve),
433 myIsApprox  (Standard_False)
434 {
435 //  if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
436 //    throw Standard_ConstructionError
437 //      ("ProjLib_ProjectOnPlane:  The Direction and the Plane are parallel");
438 //  }
439 }
440
441 //=======================================================================
442 //function : Project
443 //purpose  : Returns the projection of a point <Point> on a plane 
444 //           <ThePlane>  along a direction <TheDir>.
445 //=======================================================================
446
447 static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
448                          const gp_Dir& TheDir,
449                          const gp_Pnt& Point) 
450 {
451   gp_Vec PO(Point,ThePlane.Location());
452
453   Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
454   Alpha /= TheDir * ThePlane.Direction();
455   
456   gp_Pnt P;
457   P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
458
459   return P;
460 }
461
462
463 //=======================================================================
464 //function : Project
465 //purpose  : Returns the projection of a Vector <Vec> on a plane 
466 //           <ThePlane> along a direction <TheDir>.
467 //=======================================================================
468
469 static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
470                          const gp_Dir& TheDir,
471                          const gp_Vec& Vec) 
472 {
473   gp_Vec D = Vec;
474   gp_Vec Z = ThePlane.Direction();
475
476   D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
477
478   return D;
479 }
480
481 //=======================================================================
482 //function : Load
483 //purpose  : 
484 //=======================================================================
485
486 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)&    C,
487                                   const Standard_Real Tolerance,
488                                   const Standard_Boolean KeepParametrization) 
489                                   
490 {
491   myCurve      = C;
492   myType       = GeomAbs_OtherCurve;
493   myIsApprox   = Standard_False;
494   myTolerance  = Tolerance ;
495
496   Handle(Geom_BSplineCurve)  ApproxCurve;
497   Handle(GeomAdaptor_HCurve) aGAHCurve;
498
499   Handle(Geom_Line)      GeomLinePtr;
500   Handle(Geom_Circle)    GeomCirclePtr ;
501   Handle(Geom_Ellipse)   GeomEllipsePtr ;
502   Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
503
504   gp_Lin   aLine; 
505   gp_Elips Elips;
506 //  gp_Hypr  Hypr ;
507
508   Standard_Integer num_knots ;
509   GeomAbs_CurveType Type = C->GetType();
510
511   gp_Ax2 Axis;
512   Standard_Real R1 =0., R2 =0.;
513
514   if ( Type != GeomAbs_Line)  // on garde le parametrage
515     myKeepParam = Standard_True;
516   else                        // on prend le choix utilisateur.
517     myKeepParam = KeepParametrization;
518
519   switch ( Type) {
520   case GeomAbs_Line: 
521     {
522       //     P(u) = O + u * Xc
523       // ==> Q(u) = f(P(u)) 
524       //          = f(O) + u * f(Xc)
525
526       gp_Lin L  = myCurve->Line();
527       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
528
529       if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
530         myType = GeomAbs_BSplineCurve;
531         gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
532         TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
533         TColgp_Array1OfPnt      Poles(1,2); Poles.Init(P);
534         TColStd_Array1OfReal    Knots(1,2); 
535         Knots(1) = myCurve->FirstParameter();
536         Knots(2) = myCurve->LastParameter();
537         Handle(Geom_BSplineCurve) BSP = 
538           new Geom_BSplineCurve(Poles,Knots,Mults,1);
539
540 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
541         GeomAdaptor_Curve aGACurve(BSP);
542         myResult = new GeomAdaptor_HCurve(aGACurve);
543 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
544       }
545       else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
546         myType      = GeomAbs_Line;
547         gp_Pnt P    = ProjectPnt(myPlane,myDirection,L.Location());
548         myFirstPar  = myCurve->FirstParameter();
549         myLastPar   = myCurve->LastParameter();
550         aLine       = gp_Lin(P,gp_Dir(Xc));
551         GeomLinePtr = new Geom_Line(aLine);
552         
553 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
554         GeomAdaptor_Curve aGACurve(GeomLinePtr,
555                                    myCurve->FirstParameter(),
556                                    myCurve->LastParameter() );
557         myResult = new GeomAdaptor_HCurve(aGACurve);
558 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
559       }
560       else {
561         myType     = GeomAbs_Line;
562         gp_Pnt P   = ProjectPnt(myPlane,myDirection,L.Location());
563         aLine      = gp_Lin(P,gp_Dir(Xc));
564         Standard_Real Udeb, Ufin;
565         
566         // eval the first and last parameters of the projected curve
567         Udeb = myCurve->FirstParameter();
568         Ufin = myCurve->LastParameter();
569         gp_Pnt P1  = ProjectPnt(myPlane,myDirection,
570                                 myCurve->Value(Udeb)); 
571         gp_Pnt P2  = ProjectPnt(myPlane,myDirection,
572                                 myCurve->Value(Ufin)); 
573         myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
574         myLastPar  = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
575         GeomLinePtr = new Geom_Line(aLine);
576         if (!myKeepParam) {
577 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
578           GeomAdaptor_Curve aGACurve(GeomLinePtr,
579                                      myFirstPar,
580                                      myLastPar) ;
581           myResult = new GeomAdaptor_HCurve(aGACurve);
582 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
583         }
584         else {
585           myType     = GeomAbs_BSplineCurve;
586           //
587           // make a linear BSpline of degree 1 between the end points of
588           // the projected line 
589           //
590           Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
591             new Geom_TrimmedCurve(GeomLinePtr,
592                                   myFirstPar,
593                                   myLastPar) ;
594           
595           Handle(Geom_BSplineCurve) NewCurvePtr =
596             GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
597           num_knots = NewCurvePtr->NbKnots() ;
598           TColStd_Array1OfReal    BsplineKnots(1,num_knots)  ;
599           NewCurvePtr->Knots(BsplineKnots) ;
600           
601           BSplCLib::Reparametrize(myCurve->FirstParameter(), 
602                                   myCurve->LastParameter(),
603                                   BsplineKnots) ;
604           
605           NewCurvePtr->SetKnots(BsplineKnots) ;
606 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
607           GeomAdaptor_Curve aGACurve(NewCurvePtr);
608           myResult = new GeomAdaptor_HCurve(aGACurve);
609 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
610         }
611       }
612       break;
613     }
614   case GeomAbs_Circle:
615     {
616       // Pour le cercle et l ellipse on a les relations suivantes:
617       // ( Rem : pour le cercle R1 = R2 = R)
618       //     P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
619       // ==> Q(u) = f(P(u)) 
620       //          = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
621       
622       gp_Circ Circ = myCurve->Circle();
623       Axis = Circ.Position();
624       R1 = R2 = Circ.Radius();
625
626     }
627     Standard_FALLTHROUGH
628   case GeomAbs_Ellipse:
629     {
630       if ( Type == GeomAbs_Ellipse) {
631         gp_Elips E = myCurve->Ellipse();
632         Axis = E.Position();
633         R1 = E.MajorRadius();
634         R2 = E.MinorRadius();
635       }
636
637       // Common Code  for CIRCLE & ELLIPSE begin here
638       gp_Dir X  = Axis.XDirection();
639       gp_Dir Y  = Axis.YDirection();
640       gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
641       gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
642       gp_Dir Dx,Dy;
643
644       Standard_Real Tol2 = myTolerance*myTolerance;
645       if (VDx.SquareMagnitude() < Tol2 ||
646           VDy.SquareMagnitude() < Tol2    ) {
647         myIsApprox = Standard_True;
648       }
649
650       if (!myIsApprox && 
651           gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
652         Dx = gp_Dir(VDx);
653         Dy = gp_Dir(VDy);
654         gp_Pnt O    = Axis.Location();
655         gp_Pnt P    = ProjectPnt(myPlane,myDirection,O);
656         gp_Pnt Px   = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
657         gp_Pnt Py   = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
658         Standard_Real Major = P.Distance(Px);
659         Standard_Real Minor = P.Distance(Py);
660         gp_Ax2 Axe( P, Dx^Dy,Dx);
661
662         if ( Abs( Major - Minor) < Precision::Confusion()) {
663           myType = GeomAbs_Circle;
664           gp_Circ Circ(Axe, Major);
665           GeomCirclePtr  = new Geom_Circle(Circ);
666 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
667           GeomAdaptor_Curve aGACurve(GeomCirclePtr);
668           myResult = new GeomAdaptor_HCurve(aGACurve);
669 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
670         }
671         else if ( Major > Minor) {
672           myType = GeomAbs_Ellipse;
673           Elips  = gp_Elips( Axe, Major, Minor);
674           
675           GeomEllipsePtr = new Geom_Ellipse(Elips) ;
676 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
677           GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
678           myResult = new GeomAdaptor_HCurve(aGACurve);
679 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
680         }
681         else {
682           myIsApprox = Standard_True;
683           myType = GeomAbs_BSplineCurve;
684           PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
685 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
686           GeomAdaptor_Curve aGACurve(ApproxCurve);
687           myResult = new GeomAdaptor_HCurve(aGACurve);
688 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
689         }
690       }
691       else {
692         myIsApprox = Standard_True;
693         myType     = GeomAbs_BSplineCurve;
694         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
695 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
696         GeomAdaptor_Curve aGACurve(ApproxCurve);
697         myResult = new GeomAdaptor_HCurve(aGACurve);
698 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
699       }
700     }
701     break;
702   case GeomAbs_Parabola:
703     {
704       //     P(u) = O + (u*u)/(4*f) * Xc + u * Yc
705       // ==> Q(u) = f(P(u)) 
706       //          = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
707
708       gp_Parab Parab  = myCurve->Parabola();
709       gp_Ax2   AxeRef = Parab.Position();
710       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
711       gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
712
713       // fix for case when no one action is done. 28.03.2002
714       Standard_Boolean alocalIsDone = Standard_False;
715
716       if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
717         gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
718         if ( Xc.Magnitude() < Precision::Confusion()) {
719           myType = GeomAbs_Line;
720           aLine  = gp_Lin( P, gp_Dir(Yc));
721           
722           GeomLinePtr    = new Geom_Line(aLine) ;
723 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
724           GeomAdaptor_Curve aGACurve(GeomLinePtr);
725           myResult = new GeomAdaptor_HCurve(aGACurve);
726 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
727           alocalIsDone = Standard_True;
728         }
729         else if ( Xc.IsNormal(Yc,Precision::Angular())) {
730           myType = GeomAbs_Parabola;
731           Standard_Real F = Parab.Focal() / Xc.Magnitude();
732           gp_Parab aParab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
733           Handle(Geom_Parabola) GeomParabolaPtr =
734             new Geom_Parabola(aParab) ;
735 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
736           GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
737           myResult = new GeomAdaptor_HCurve(aGACurve);
738 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
739           alocalIsDone = Standard_True;
740         }
741       }
742       if (!alocalIsDone)/*else*/ {
743         myIsApprox = Standard_True;
744         myType     = GeomAbs_BSplineCurve;
745         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
746 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
747         GeomAdaptor_Curve aGACurve(ApproxCurve);
748         myResult = new GeomAdaptor_HCurve(aGACurve);
749 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
750       }
751     }
752     break;
753   case GeomAbs_Hyperbola:
754     {
755       //     P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
756       // ==> Q(u) = f(P(u)) 
757       //          = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
758
759       gp_Hypr Hypr  = myCurve->Hyperbola();
760       gp_Ax2 AxeRef = Hypr.Position();
761       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
762       gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
763       gp_Pnt P  = ProjectPnt(myPlane,myDirection,AxeRef.Location());
764       Standard_Real aR1 = Hypr.MajorRadius();
765       Standard_Real aR2 = Hypr.MinorRadius();
766       gp_Dir Z = myPlane.Direction();
767
768       if ( Xc.Magnitude() < Precision::Confusion()) {
769         myType   = GeomAbs_Hyperbola;
770         gp_Dir X = gp_Dir(Yc) ^ Z;
771         Hypr   = gp_Hypr(gp_Ax2( P, Z, X), 0., aR2 * Yc.Magnitude());
772         GeomHyperbolaPtr =
773           new Geom_Hyperbola(Hypr) ;
774 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
775         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
776         myResult = new GeomAdaptor_HCurve(aGACurve);
777 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
778       }
779       else if ( Yc.Magnitude() < Precision::Confusion()) {
780         myType = GeomAbs_Hyperbola;
781         Hypr = 
782            gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), aR1 * Xc.Magnitude(), 0.);
783         GeomHyperbolaPtr =
784           new Geom_Hyperbola(Hypr) ;
785 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
786         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
787         myResult = new GeomAdaptor_HCurve(aGACurve);
788 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
789       }
790       else if ( Xc.IsNormal(Yc,Precision::Angular())) {
791         myType = GeomAbs_Hyperbola;
792         Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
793                        aR1 * Xc.Magnitude(), aR2 * Yc.Magnitude() );
794         GeomHyperbolaPtr =
795           new Geom_Hyperbola(Hypr) ;
796 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
797         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
798         myResult = new GeomAdaptor_HCurve(aGACurve);
799 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
800       }
801       else {
802         myIsApprox = Standard_True;
803         myType     = GeomAbs_BSplineCurve;
804         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
805 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
806         GeomAdaptor_Curve aGACurve(ApproxCurve);
807         myResult = new GeomAdaptor_HCurve(aGACurve);
808 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
809       }
810     }
811     break;
812   case GeomAbs_BezierCurve:
813     {
814       Handle(Geom_BezierCurve) BezierCurvePtr =
815         myCurve->Bezier() ;
816       Standard_Integer NbPoles = 
817         BezierCurvePtr->NbPoles() ;
818       
819       Handle(Geom_BezierCurve) ProjCu = 
820         Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
821
822       myIsApprox = Standard_False;
823       myType = Type;
824       for ( Standard_Integer i = 1; i <= NbPoles; i++) {
825         ProjCu->SetPole
826           (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
827       }
828       
829 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
830       GeomAdaptor_Curve aGACurve(ProjCu);
831       myResult = new GeomAdaptor_HCurve(aGACurve);
832 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
833     }
834     break ;
835   case GeomAbs_BSplineCurve:
836     {
837       Handle(Geom_BSplineCurve) BSplineCurvePtr =
838         myCurve->BSpline() ;
839       //
840       //    make a copy of the curve and projects its poles 
841       //
842       Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
843         Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
844       
845       myIsApprox = Standard_False;
846       myType = Type;
847       for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
848         ProjectedBSplinePtr->SetPole
849           (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
850       }
851       
852 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
853       GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
854       myResult = new GeomAdaptor_HCurve(aGACurve);
855 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
856     }
857     break;
858   default:
859     {
860       myIsApprox = Standard_True;
861       myType     = GeomAbs_BSplineCurve;
862       PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
863 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
864       GeomAdaptor_Curve aGACurve(ApproxCurve);
865       myResult = new GeomAdaptor_HCurve(aGACurve);
866 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
867     }
868     break;
869   }
870 }
871
872 //=======================================================================
873 //function : GetPlane
874 //purpose  : 
875 //=======================================================================
876
877 const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const 
878 {
879   return myPlane;
880 }
881
882 //=======================================================================
883 //function : GetDirection
884 //purpose  : 
885 //=======================================================================
886
887 const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const 
888 {
889   return myDirection;
890 }
891
892 //=======================================================================
893 //function : GetCurve
894 //purpose  : 
895 //=======================================================================
896
897 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
898 {
899   return myCurve;
900 }
901
902 //=======================================================================
903 //function : GetResult
904 //purpose  : 
905 //=======================================================================
906
907 const Handle(GeomAdaptor_HCurve)& ProjLib_ProjectOnPlane::GetResult() const
908 {
909   return myResult;
910 }
911
912
913 //=======================================================================
914 //function : FirstParameter
915 //purpose  : 
916 //=======================================================================
917
918 Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const 
919 {
920   if ( myKeepParam || myIsApprox) 
921     return myCurve->FirstParameter();
922   else
923     return myFirstPar;
924 }
925
926
927 //=======================================================================
928 //function : LastParameter
929 //purpose  : 
930 //=======================================================================
931
932 Standard_Real ProjLib_ProjectOnPlane::LastParameter() const 
933 {
934   if ( myKeepParam || myIsApprox) 
935     return myCurve->LastParameter();
936   else
937     return myLastPar;
938 }
939
940
941 //=======================================================================
942 //function : Continuity
943 //purpose  : 
944 //=======================================================================
945
946 GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
947 {
948   return myCurve->Continuity() ;
949 }
950
951
952 //=======================================================================
953 //function : NbIntervals
954 //purpose  : 
955 //=======================================================================
956
957 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S) const
958 {
959   return myCurve->NbIntervals(S) ;
960 }
961
962
963 //=======================================================================
964 //function : Intervals
965 //purpose  : 
966 //=======================================================================
967
968 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T, 
969                                        const GeomAbs_Shape S) const
970 {
971   myCurve->Intervals(T,S) ;
972 }
973
974 //=======================================================================
975 //function : Trim
976 //purpose  : 
977 //=======================================================================
978
979 Handle(Adaptor3d_HCurve)  
980 ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
981                              const Standard_Real Last,
982                              const Standard_Real Tolerance) const 
983 {
984   if (myType != GeomAbs_OtherCurve){
985     return myResult->Trim(First,Last,Tolerance) ;
986   }
987   else {
988     throw Standard_NotImplemented ("ProjLib_ProjectOnPlane::Trim() - curve of unsupported type");
989   }
990 }
991
992   
993 //=======================================================================
994 //function : IsClosed
995 //purpose  : 
996 //=======================================================================
997
998 Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
999 {
1000  return myCurve->IsClosed() ;
1001 }
1002
1003
1004 //=======================================================================
1005 //function : IsPeriodic
1006 //purpose  : 
1007 //=======================================================================
1008
1009 Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
1010 {
1011   if ( myIsApprox)
1012     return Standard_False;
1013   else 
1014     return myCurve->IsPeriodic();
1015 }
1016
1017
1018 //=======================================================================
1019 //function : Period
1020 //purpose  : 
1021 //=======================================================================
1022
1023 Standard_Real ProjLib_ProjectOnPlane::Period() const
1024 {
1025   if ( !IsPeriodic()) {
1026     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane::Period");
1027   }
1028                                 
1029   if ( myIsApprox)
1030     return Standard_False;
1031   else 
1032     return myCurve->Period();
1033 }
1034
1035
1036 //=======================================================================
1037 //function : Value
1038 //purpose  : 
1039 //=======================================================================
1040
1041 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const 
1042 {
1043   if (myType != GeomAbs_OtherCurve) { 
1044     return myResult->Value(U);
1045   }
1046   else {
1047     return OnPlane_Value(U,
1048                          myCurve,
1049                          myPlane,
1050                          myDirection);
1051     
1052   }
1053
1054
1055
1056 //=======================================================================
1057 //function : D0
1058 //purpose  : 
1059 //=======================================================================
1060
1061 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1062 {
1063   if (myType != GeomAbs_OtherCurve) {
1064     myResult->D0(U,P) ;
1065   }
1066   else {
1067     P = OnPlane_Value(U,
1068                       myCurve,
1069                       myPlane,
1070                       myDirection);
1071   }
1072 }
1073
1074
1075 //=======================================================================
1076 //function : D1
1077 //purpose  : 
1078 //=======================================================================
1079
1080 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1081                                       gp_Pnt&    P , 
1082                                       gp_Vec&    V ) const 
1083 {
1084   if (myType != GeomAbs_OtherCurve) {
1085     myResult->D1(U,P,V) ;
1086   }
1087   else {
1088     OnPlane_D1(U,
1089                P,
1090                V,
1091                myCurve,
1092                myPlane,
1093                myDirection);
1094   }
1095 }
1096
1097
1098 //=======================================================================
1099 //function : D2
1100 //purpose  : 
1101 //=======================================================================
1102
1103 void ProjLib_ProjectOnPlane::D2(const Standard_Real U, 
1104                                       gp_Pnt&     P, 
1105                                       gp_Vec&     V1, 
1106                                       gp_Vec&     V2) const 
1107 {
1108   if (myType != GeomAbs_OtherCurve)  {
1109     myResult->D2(U,P,V1,V2) ;
1110   }
1111   else {
1112     OnPlane_D2(U,
1113                P,
1114                V1,
1115                V2,
1116                myCurve,
1117                myPlane,
1118                myDirection);
1119   }
1120 }
1121
1122
1123 //=======================================================================
1124 //function : D3
1125 //purpose  : 
1126 //=======================================================================
1127
1128 void ProjLib_ProjectOnPlane::D3(const Standard_Real U, 
1129                                 gp_Pnt& P, 
1130                                 gp_Vec& V1, 
1131                                 gp_Vec& V2, 
1132                                 gp_Vec& V3) const 
1133 {
1134   if (myType != GeomAbs_OtherCurve)   {
1135     myResult->D3(U,P,V1,V2,V3) ;
1136   }
1137   else   {
1138     OnPlane_D3(U,
1139                P,
1140                V1,
1141                V2,
1142                V3,
1143                myCurve,
1144                myPlane,
1145                myDirection); 
1146   }
1147 }
1148
1149
1150 //=======================================================================
1151 //function : DN
1152 //purpose  : 
1153 //=======================================================================
1154
1155 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U, 
1156                                   const Standard_Integer DerivativeRequest)
1157      const 
1158 {
1159   if (myType != GeomAbs_OtherCurve) {
1160     return myResult->DN(U,DerivativeRequest) ;
1161   }
1162   else {
1163     return OnPlane_DN(U,
1164                       DerivativeRequest,
1165                       myCurve,
1166                       myPlane,
1167                       myDirection); 
1168   }   
1169 }
1170
1171
1172 //=======================================================================
1173 //function : Resolution
1174 //purpose  : 
1175 //=======================================================================
1176
1177 Standard_Real ProjLib_ProjectOnPlane::Resolution
1178 (const Standard_Real Tolerance) const 
1179 {
1180   if (myType != GeomAbs_OtherCurve) {
1181     return myResult->Resolution(Tolerance) ;
1182   }
1183   else {
1184     return 0;
1185   }
1186 }
1187     
1188
1189 //=======================================================================
1190 //function : GetType
1191 //purpose  : 
1192 //=======================================================================
1193
1194 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1195 {
1196   return myType;
1197 }
1198
1199
1200 //=======================================================================
1201 //function : Line
1202 //purpose  : 
1203 //=======================================================================
1204
1205 gp_Lin ProjLib_ProjectOnPlane::Line() const
1206 {
1207   if (myType != GeomAbs_Line)
1208     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Line");
1209
1210   return myResult->Line();
1211 }
1212
1213
1214 //=======================================================================
1215 //function : Circle
1216 //purpose  : 
1217 //=======================================================================
1218
1219 gp_Circ ProjLib_ProjectOnPlane::Circle() const
1220 {
1221   if (myType != GeomAbs_Circle)
1222     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Circle");
1223
1224   return myResult->Circle();
1225 }
1226
1227
1228 //=======================================================================
1229 //function : Ellipse
1230 //purpose  : 
1231 //=======================================================================
1232
1233 gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1234 {
1235   if (myType != GeomAbs_Ellipse)
1236     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Ellipse");
1237
1238   return myResult->Ellipse();
1239 }
1240
1241
1242 //=======================================================================
1243 //function : Hyperbola
1244 //purpose  : 
1245 //=======================================================================
1246
1247 gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1248 {
1249   if (myType != GeomAbs_Hyperbola)
1250     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Hyperbola");
1251
1252   return myResult->Hyperbola() ;
1253 }
1254
1255
1256 //=======================================================================
1257 //function : Parabola
1258 //purpose  : 
1259 //=======================================================================
1260
1261 gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1262 {
1263   if (myType != GeomAbs_Parabola)
1264     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Parabola");
1265   
1266   return myResult->Parabola() ;
1267 }
1268
1269 //=======================================================================
1270 //function : Degree
1271 //purpose  : 
1272 //=======================================================================
1273
1274 Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1275 {
1276   if ((GetType() != GeomAbs_BSplineCurve) &&
1277       (GetType() != GeomAbs_BezierCurve))
1278     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Degree");
1279
1280   if ( myIsApprox)
1281     return myResult->Degree();
1282   else
1283     return myCurve->Degree();
1284 }
1285
1286 //=======================================================================
1287 //function : IsRational
1288 //purpose  : 
1289 //=======================================================================
1290
1291 Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const 
1292 {
1293   if ((GetType() != GeomAbs_BSplineCurve) &&
1294       (GetType() != GeomAbs_BezierCurve))
1295     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:IsRational");
1296   
1297   if ( myIsApprox) 
1298     return myResult->IsRational();
1299   else
1300     return myCurve->IsRational();
1301 }
1302
1303 //=======================================================================
1304 //function : NbPoles
1305 //purpose  : 
1306 //=======================================================================
1307
1308 Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1309 {
1310   if ((GetType() != GeomAbs_BSplineCurve) &&
1311       (GetType() != GeomAbs_BezierCurve))
1312     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:NbPoles");
1313   
1314   if ( myIsApprox)
1315     return myResult->NbPoles();
1316   else
1317     return myCurve->NbPoles();
1318 }
1319
1320 //=======================================================================
1321 //function : NbKnots
1322 //purpose  : 
1323 //=======================================================================
1324
1325 Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const 
1326 {
1327   if ( GetType() != GeomAbs_BSplineCurve) 
1328     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:NbKnots");
1329   
1330   if ( myIsApprox) 
1331     return myResult->NbKnots();
1332   else
1333     return myCurve->NbKnots();
1334 }
1335
1336
1337 //=======================================================================
1338 //function : Bezier
1339 //purpose  : 
1340 //=======================================================================
1341
1342 Handle(Geom_BezierCurve)  ProjLib_ProjectOnPlane::Bezier() const
1343 {
1344   if (myType != GeomAbs_BezierCurve)
1345     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Bezier");
1346
1347   return myResult->Bezier() ;
1348 }
1349
1350 //=======================================================================
1351 //function : Bezier
1352 //purpose  : 
1353 //=======================================================================
1354
1355 Handle(Geom_BSplineCurve)  ProjLib_ProjectOnPlane::BSpline() const
1356 {
1357   if (myType != GeomAbs_BSplineCurve)
1358     throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:BSpline");
1359
1360   return myResult->BSpline() ;
1361 }
1362