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