069b9f1c475f0e4a2c5be99d9225b928997d0653
[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 myType     (GeomAbs_OtherCurve),
383 myIsApprox (Standard_False)
384 {
385 }
386
387 //=======================================================================
388 //function : ProjLib_ProjectOnPlane
389 //purpose  : 
390 //=======================================================================
391
392 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) : 
393 myPlane     (Pl)                ,
394 myDirection (Pl.Direction())    ,
395 myType      (GeomAbs_OtherCurve),
396 myIsApprox  (Standard_False)
397 {
398 }
399
400 //=======================================================================
401 //function : ProjLib_ProjectOnPlane
402 //purpose  : 
403 //=======================================================================
404
405 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
406                                                const gp_Dir& D  ) :
407 myPlane     (Pl)                ,
408 myDirection (D)                 ,
409 myType      (GeomAbs_OtherCurve),
410 myIsApprox  (Standard_False)
411 {
412 //  if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
413 //    Standard_ConstructionError::Raise
414 //      ("ProjLib_ProjectOnPlane:  The Direction and the Plane are parallel");
415 //  }
416 }
417
418 //=======================================================================
419 //function : Project
420 //purpose  : Returns the projection of a point <Point> on a plane 
421 //           <ThePlane>  along a direction <TheDir>.
422 //=======================================================================
423
424 static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
425                          const gp_Dir& TheDir,
426                          const gp_Pnt& Point) 
427 {
428   gp_Vec PO(Point,ThePlane.Location());
429
430   Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
431   Alpha /= TheDir * ThePlane.Direction();
432   
433   gp_Pnt P;
434   P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
435
436   return P;
437 }
438
439
440 //=======================================================================
441 //function : Project
442 //purpose  : Returns the projection of a Vector <Vec> on a plane 
443 //           <ThePlane> along a direction <TheDir>.
444 //=======================================================================
445
446 static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
447                          const gp_Dir& TheDir,
448                          const gp_Vec& Vec) 
449 {
450   gp_Vec D = Vec;
451   gp_Vec Z = ThePlane.Direction();
452
453   D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
454
455   return D;
456 }
457
458 //=======================================================================
459 //function : Load
460 //purpose  : 
461 //=======================================================================
462
463 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)&    C,
464                                   const Standard_Real Tolerance,
465                                   const Standard_Boolean KeepParametrization) 
466                                   
467 {
468   myCurve      = C;
469   myType       = GeomAbs_OtherCurve;
470   myIsApprox   = Standard_False;
471   myTolerance  = Tolerance ;
472
473   Handle(Geom_BSplineCurve)  ApproxCurve;
474   Handle(GeomAdaptor_HCurve) aGAHCurve;
475
476   Handle(Geom_Line)      GeomLinePtr;
477   Handle(Geom_Circle)    GeomCirclePtr ;
478   Handle(Geom_Ellipse)   GeomEllipsePtr ;
479   Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
480
481   gp_Lin   aLine; 
482   gp_Elips Elips;
483 //  gp_Hypr  Hypr ;
484
485   Standard_Integer num_knots ;
486   GeomAbs_CurveType Type = C->GetType();
487
488   gp_Ax2 Axis;
489   Standard_Real R1 =0., R2 =0.;
490
491   if ( Type != GeomAbs_Line)  // on garde le parametrage
492     myKeepParam = Standard_True;
493   else                        // on prend le choix utilisateur.
494     myKeepParam = KeepParametrization;
495
496   switch ( Type) {
497   case GeomAbs_Line: 
498     {
499       //     P(u) = O + u * Xc
500       // ==> Q(u) = f(P(u)) 
501       //          = f(O) + u * f(Xc)
502
503       gp_Lin L  = myCurve->Line();
504       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
505
506       if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
507         myType = GeomAbs_BSplineCurve;
508         gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
509         TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
510         TColgp_Array1OfPnt      Poles(1,2); Poles.Init(P);
511         TColStd_Array1OfReal    Knots(1,2); 
512         Knots(1) = myCurve->FirstParameter();
513         Knots(2) = myCurve->LastParameter();
514         Handle(Geom_BSplineCurve) BSP = 
515           new Geom_BSplineCurve(Poles,Knots,Mults,1);
516
517 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
518         GeomAdaptor_Curve aGACurve(BSP);
519         myResult = new GeomAdaptor_HCurve(aGACurve);
520 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
521       }
522       else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
523         myType      = GeomAbs_Line;
524         gp_Pnt P    = ProjectPnt(myPlane,myDirection,L.Location());
525         myFirstPar  = myCurve->FirstParameter();
526         myLastPar   = myCurve->LastParameter();
527         aLine       = gp_Lin(P,gp_Dir(Xc));
528         GeomLinePtr = new Geom_Line(aLine);
529         
530 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
531         GeomAdaptor_Curve aGACurve(GeomLinePtr,
532                                    myCurve->FirstParameter(),
533                                    myCurve->LastParameter() );
534         myResult = new GeomAdaptor_HCurve(aGACurve);
535 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
536       }
537       else {
538         myType     = GeomAbs_Line;
539         gp_Pnt P   = ProjectPnt(myPlane,myDirection,L.Location());
540         aLine      = gp_Lin(P,gp_Dir(Xc));
541         Standard_Real Udeb, Ufin;
542         
543         // eval the first and last parameters of the projected curve
544         Udeb = myCurve->FirstParameter();
545         Ufin = myCurve->LastParameter();
546         gp_Pnt P1  = ProjectPnt(myPlane,myDirection,
547                                 myCurve->Value(Udeb)); 
548         gp_Pnt P2  = ProjectPnt(myPlane,myDirection,
549                                 myCurve->Value(Ufin)); 
550         myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
551         myLastPar  = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
552         GeomLinePtr = new Geom_Line(aLine);
553         if (!myKeepParam) {
554 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
555           GeomAdaptor_Curve aGACurve(GeomLinePtr,
556                                      myFirstPar,
557                                      myLastPar) ;
558           myResult = new GeomAdaptor_HCurve(aGACurve);
559 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
560         }
561         else {
562           myType     = GeomAbs_BSplineCurve;
563           //
564           // make a linear BSpline of degree 1 between the end points of
565           // the projected line 
566           //
567           Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
568             new Geom_TrimmedCurve(GeomLinePtr,
569                                   myFirstPar,
570                                   myLastPar) ;
571           
572           Handle(Geom_BSplineCurve) NewCurvePtr =
573             GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
574           num_knots = NewCurvePtr->NbKnots() ;
575           TColStd_Array1OfReal    BsplineKnots(1,num_knots)  ;
576           NewCurvePtr->Knots(BsplineKnots) ;
577           
578           BSplCLib::Reparametrize(myCurve->FirstParameter(), 
579                                   myCurve->LastParameter(),
580                                   BsplineKnots) ;
581           
582           NewCurvePtr->SetKnots(BsplineKnots) ;
583 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
584           GeomAdaptor_Curve aGACurve(NewCurvePtr);
585           myResult = new GeomAdaptor_HCurve(aGACurve);
586 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
587         }
588       }
589       break;
590     }
591   case GeomAbs_Circle:
592     {
593       // Pour le cercle et l ellipse on a les relations suivantes:
594       // ( Rem : pour le cercle R1 = R2 = R)
595       //     P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
596       // ==> Q(u) = f(P(u)) 
597       //          = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
598       
599       gp_Circ Circ = myCurve->Circle();
600       Axis = Circ.Position();
601       R1 = R2 = Circ.Radius();
602
603     }
604   case GeomAbs_Ellipse:
605     {
606       if ( Type == GeomAbs_Ellipse) {
607         gp_Elips E = myCurve->Ellipse();
608         Axis = E.Position();
609         R1 = E.MajorRadius();
610         R2 = E.MinorRadius();
611       }
612
613       // Common Code  for CIRCLE & ELLIPSE begin here
614       gp_Dir X  = Axis.XDirection();
615       gp_Dir Y  = Axis.YDirection();
616       gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
617       gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
618       gp_Dir Dx,Dy;
619
620       Standard_Real Tol2 = myTolerance*myTolerance;
621       if (VDx.SquareMagnitude() < Tol2 ||
622           VDy.SquareMagnitude() < Tol2    ) {
623         myIsApprox = Standard_True;
624       }
625
626       if (!myIsApprox && 
627           gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
628         Dx = gp_Dir(VDx);
629         Dy = gp_Dir(VDy);
630         gp_Pnt O    = Axis.Location();
631         gp_Pnt P    = ProjectPnt(myPlane,myDirection,O);
632         gp_Pnt Px   = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
633         gp_Pnt Py   = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
634         Standard_Real Major = P.Distance(Px);
635         Standard_Real Minor = P.Distance(Py);
636         gp_Ax2 Axe( P, Dx^Dy,Dx);
637
638         if ( Abs( Major - Minor) < Precision::Confusion()) {
639           myType = GeomAbs_Circle;
640           gp_Circ Circ(Axe, Major);
641           GeomCirclePtr  = new Geom_Circle(Circ);
642 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
643           GeomAdaptor_Curve aGACurve(GeomCirclePtr);
644           myResult = new GeomAdaptor_HCurve(aGACurve);
645 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
646         }
647         else if ( Major > Minor) {
648           myType = GeomAbs_Ellipse;
649           Elips  = gp_Elips( Axe, Major, Minor);
650           
651           GeomEllipsePtr = new Geom_Ellipse(Elips) ;
652 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
653           GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
654           myResult = new GeomAdaptor_HCurve(aGACurve);
655 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
656         }
657         else {
658           myIsApprox = Standard_True;
659           myType = GeomAbs_BSplineCurve;
660           PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
661 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
662           GeomAdaptor_Curve aGACurve(ApproxCurve);
663           myResult = new GeomAdaptor_HCurve(aGACurve);
664 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
665         }
666       }
667       else {
668         myIsApprox = Standard_True;
669         myType     = GeomAbs_BSplineCurve;
670         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
671 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
672         GeomAdaptor_Curve aGACurve(ApproxCurve);
673         myResult = new GeomAdaptor_HCurve(aGACurve);
674 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
675       }
676     }
677     break;
678   case GeomAbs_Parabola:
679     {
680       //     P(u) = O + (u*u)/(4*f) * Xc + u * Yc
681       // ==> Q(u) = f(P(u)) 
682       //          = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
683
684       gp_Parab Parab  = myCurve->Parabola();
685       gp_Ax2   AxeRef = Parab.Position();
686       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
687       gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
688
689       // fix for case when no one action is done. 28.03.2002
690       Standard_Boolean alocalIsDone = Standard_False;
691
692       if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
693         gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
694         if ( Xc.Magnitude() < Precision::Confusion()) {
695           myType = GeomAbs_Line;
696           aLine  = gp_Lin( P, gp_Dir(Yc));
697           
698           GeomLinePtr    = new Geom_Line(aLine) ;
699 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
700           GeomAdaptor_Curve aGACurve(GeomLinePtr);
701           myResult = new GeomAdaptor_HCurve(aGACurve);
702 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
703           alocalIsDone = Standard_True;
704         }
705         else if ( Xc.IsNormal(Yc,Precision::Angular())) {
706           myType = GeomAbs_Parabola;
707           Standard_Real F = Parab.Focal() / Xc.Magnitude();
708           gp_Parab Parab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
709           Handle(Geom_Parabola) GeomParabolaPtr =
710             new Geom_Parabola(Parab) ;
711 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
712           GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
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       }
718       if (!alocalIsDone)/*else*/ {
719         myIsApprox = Standard_True;
720         myType     = GeomAbs_BSplineCurve;
721         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
722 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
723         GeomAdaptor_Curve aGACurve(ApproxCurve);
724         myResult = new GeomAdaptor_HCurve(aGACurve);
725 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
726       }
727     }
728     break;
729   case GeomAbs_Hyperbola:
730     {
731       //     P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
732       // ==> Q(u) = f(P(u)) 
733       //          = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
734
735       gp_Hypr Hypr  = myCurve->Hyperbola();
736       gp_Ax2 AxeRef = Hypr.Position();
737       gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
738       gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
739       gp_Pnt P  = ProjectPnt(myPlane,myDirection,AxeRef.Location());
740       Standard_Real R1 = Hypr.MajorRadius();
741       Standard_Real R2 = Hypr.MinorRadius();
742       gp_Dir Z = myPlane.Direction();
743
744       if ( Xc.Magnitude() < Precision::Confusion()) {
745         myType   = GeomAbs_Hyperbola;
746         gp_Dir X = gp_Dir(Yc) ^ Z;
747         Hypr   = gp_Hypr(gp_Ax2( P, Z, X), 0., R2 * Yc.Magnitude());
748         GeomHyperbolaPtr =
749           new Geom_Hyperbola(Hypr) ;
750 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
751         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
752         myResult = new GeomAdaptor_HCurve(aGACurve);
753 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
754       }
755       else if ( Yc.Magnitude() < Precision::Confusion()) {
756         myType = GeomAbs_Hyperbola;
757         Hypr = 
758            gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
759         GeomHyperbolaPtr =
760           new Geom_Hyperbola(Hypr) ;
761 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
762         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
763         myResult = new GeomAdaptor_HCurve(aGACurve);
764 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
765       }
766       else if ( Xc.IsNormal(Yc,Precision::Angular())) {
767         myType = GeomAbs_Hyperbola;
768         Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
769                        R1 * Xc.Magnitude(), R2 * Yc.Magnitude() );
770         GeomHyperbolaPtr =
771           new Geom_Hyperbola(Hypr) ;
772 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
773         GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
774         myResult = new GeomAdaptor_HCurve(aGACurve);
775 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
776       }
777       else {
778         myIsApprox = Standard_True;
779         myType     = GeomAbs_BSplineCurve;
780         PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
781 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
782         GeomAdaptor_Curve aGACurve(ApproxCurve);
783         myResult = new GeomAdaptor_HCurve(aGACurve);
784 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
785       }
786     }
787     break;
788   case GeomAbs_BezierCurve:
789     {
790       Handle(Geom_BezierCurve) BezierCurvePtr =
791         myCurve->Bezier() ;
792       Standard_Integer NbPoles = 
793         BezierCurvePtr->NbPoles() ;
794       
795       Handle(Geom_BezierCurve) ProjCu = 
796         Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
797
798       myIsApprox = Standard_False;
799       myType = Type;
800       for ( Standard_Integer i = 1; i <= NbPoles; i++) {
801         ProjCu->SetPole
802           (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
803       }
804       
805 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
806       GeomAdaptor_Curve aGACurve(ProjCu);
807       myResult = new GeomAdaptor_HCurve(aGACurve);
808 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
809     }
810     break ;
811   case GeomAbs_BSplineCurve:
812     {
813       Handle(Geom_BSplineCurve) BSplineCurvePtr =
814         myCurve->BSpline() ;
815       //
816       //    make a copy of the curve and projects its poles 
817       //
818       Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
819         Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
820       
821       myIsApprox = Standard_False;
822       myType = Type;
823       for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
824         ProjectedBSplinePtr->SetPole
825           (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
826       }
827       
828 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
829       GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
830       myResult = new GeomAdaptor_HCurve(aGACurve);
831 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
832     }
833     break;
834   default:
835     {
836       myIsApprox = Standard_True;
837       myType     = GeomAbs_BSplineCurve;
838       PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
839 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
840       GeomAdaptor_Curve aGACurve(ApproxCurve);
841       myResult = new GeomAdaptor_HCurve(aGACurve);
842 //  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
843     }
844     break;
845   }
846 }
847
848 //=======================================================================
849 //function : GetPlane
850 //purpose  : 
851 //=======================================================================
852
853 const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const 
854 {
855   return myPlane;
856 }
857
858 //=======================================================================
859 //function : GetDirection
860 //purpose  : 
861 //=======================================================================
862
863 const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const 
864 {
865   return myDirection;
866 }
867
868 //=======================================================================
869 //function : GetCurve
870 //purpose  : 
871 //=======================================================================
872
873 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
874 {
875   return myCurve;
876 }
877
878
879 //=======================================================================
880 //function : FirstParameter
881 //purpose  : 
882 //=======================================================================
883
884 Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const 
885 {
886   if ( myKeepParam || myIsApprox) 
887     return myCurve->FirstParameter();
888   else
889     return myFirstPar;
890 }
891
892
893 //=======================================================================
894 //function : LastParameter
895 //purpose  : 
896 //=======================================================================
897
898 Standard_Real ProjLib_ProjectOnPlane::LastParameter() const 
899 {
900   if ( myKeepParam || myIsApprox) 
901     return myCurve->LastParameter();
902   else
903     return myLastPar;
904 }
905
906
907 //=======================================================================
908 //function : Continuity
909 //purpose  : 
910 //=======================================================================
911
912 GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
913 {
914   return myCurve->Continuity() ;
915 }
916
917
918 //=======================================================================
919 //function : NbIntervals
920 //purpose  : 
921 //=======================================================================
922
923 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S) 
924 {
925   return myCurve->NbIntervals(S) ;
926 }
927
928
929 //=======================================================================
930 //function : Intervals
931 //purpose  : 
932 //=======================================================================
933
934 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T, 
935                                        const GeomAbs_Shape S) 
936 {
937   myCurve->Intervals(T,S) ;
938 }
939
940 //=======================================================================
941 //function : Trim
942 //purpose  : 
943 //=======================================================================
944
945 Handle(Adaptor3d_HCurve)  
946 ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
947                              const Standard_Real Last,
948                              const Standard_Real Tolerance) const 
949 {
950   if (myType != GeomAbs_OtherCurve){
951     return myResult->Trim(First,Last,Tolerance) ;
952   }
953   else {
954     Standard_NotImplemented::Raise("");
955   }
956
957   // portage WNT
958   Handle(Adaptor3d_HCurve) dummy;
959   return dummy;
960 }
961
962   
963 //=======================================================================
964 //function : IsClosed
965 //purpose  : 
966 //=======================================================================
967
968 Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
969 {
970  return myCurve->IsClosed() ;
971 }
972
973
974 //=======================================================================
975 //function : IsPeriodic
976 //purpose  : 
977 //=======================================================================
978
979 Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
980 {
981   if ( myIsApprox)
982     return Standard_False;
983   else 
984     return myCurve->IsPeriodic();
985 }
986
987
988 //=======================================================================
989 //function : Period
990 //purpose  : 
991 //=======================================================================
992
993 Standard_Real ProjLib_ProjectOnPlane::Period() const
994 {
995   if ( !IsPeriodic()) {
996     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
997   }
998                                 
999   if ( myIsApprox)
1000     return Standard_False;
1001   else 
1002     return myCurve->Period();
1003 }
1004
1005
1006 //=======================================================================
1007 //function : Value
1008 //purpose  : 
1009 //=======================================================================
1010
1011 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const 
1012 {
1013   if (myType != GeomAbs_OtherCurve) { 
1014     return myResult->Value(U);
1015   }
1016   else {
1017     return OnPlane_Value(U,
1018                          myCurve,
1019                          myPlane,
1020                          myDirection);
1021     
1022   }
1023
1024
1025
1026 //=======================================================================
1027 //function : D0
1028 //purpose  : 
1029 //=======================================================================
1030
1031 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1032 {
1033   if (myType != GeomAbs_OtherCurve) {
1034     myResult->D0(U,P) ;
1035   }
1036   else {
1037     P = OnPlane_Value(U,
1038                       myCurve,
1039                       myPlane,
1040                       myDirection);
1041   }
1042 }
1043
1044
1045 //=======================================================================
1046 //function : D1
1047 //purpose  : 
1048 //=======================================================================
1049
1050 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1051                                       gp_Pnt&    P , 
1052                                       gp_Vec&    V ) const 
1053 {
1054   if (myType != GeomAbs_OtherCurve) {
1055     myResult->D1(U,P,V) ;
1056   }
1057   else {
1058     OnPlane_D1(U,
1059                P,
1060                V,
1061                myCurve,
1062                myPlane,
1063                myDirection);
1064   }
1065 }
1066
1067
1068 //=======================================================================
1069 //function : D2
1070 //purpose  : 
1071 //=======================================================================
1072
1073 void ProjLib_ProjectOnPlane::D2(const Standard_Real U, 
1074                                       gp_Pnt&     P, 
1075                                       gp_Vec&     V1, 
1076                                       gp_Vec&     V2) const 
1077 {
1078   if (myType != GeomAbs_OtherCurve)  {
1079     myResult->D2(U,P,V1,V2) ;
1080   }
1081   else {
1082     OnPlane_D2(U,
1083                P,
1084                V1,
1085                V2,
1086                myCurve,
1087                myPlane,
1088                myDirection);
1089   }
1090 }
1091
1092
1093 //=======================================================================
1094 //function : D3
1095 //purpose  : 
1096 //=======================================================================
1097
1098 void ProjLib_ProjectOnPlane::D3(const Standard_Real U, 
1099                                 gp_Pnt& P, 
1100                                 gp_Vec& V1, 
1101                                 gp_Vec& V2, 
1102                                 gp_Vec& V3) const 
1103 {
1104   if (myType != GeomAbs_OtherCurve)   {
1105     myResult->D3(U,P,V1,V2,V3) ;
1106   }
1107   else   {
1108     OnPlane_D3(U,
1109                P,
1110                V1,
1111                V2,
1112                V3,
1113                myCurve,
1114                myPlane,
1115                myDirection); 
1116   }
1117 }
1118
1119
1120 //=======================================================================
1121 //function : DN
1122 //purpose  : 
1123 //=======================================================================
1124
1125 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U, 
1126                                   const Standard_Integer DerivativeRequest)
1127      const 
1128 {
1129   if (myType != GeomAbs_OtherCurve) {
1130     return myResult->DN(U,DerivativeRequest) ;
1131   }
1132   else {
1133     return OnPlane_DN(U,
1134                       DerivativeRequest,
1135                       myCurve,
1136                       myPlane,
1137                       myDirection); 
1138   }   
1139 }
1140
1141
1142 //=======================================================================
1143 //function : Resolution
1144 //purpose  : 
1145 //=======================================================================
1146
1147 Standard_Real ProjLib_ProjectOnPlane::Resolution
1148 (const Standard_Real Tolerance) const 
1149 {
1150   if (myType != GeomAbs_OtherCurve) {
1151     return myResult->Resolution(Tolerance) ;
1152   }
1153   else {
1154     return 0;
1155   }
1156 }
1157     
1158
1159 //=======================================================================
1160 //function : GetType
1161 //purpose  : 
1162 //=======================================================================
1163
1164 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1165 {
1166   return myType;
1167 }
1168
1169
1170 //=======================================================================
1171 //function : Line
1172 //purpose  : 
1173 //=======================================================================
1174
1175 gp_Lin ProjLib_ProjectOnPlane::Line() const
1176 {
1177   if (myType != GeomAbs_Line)
1178     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");
1179
1180   return myResult->Line();
1181 }
1182
1183
1184 //=======================================================================
1185 //function : Circle
1186 //purpose  : 
1187 //=======================================================================
1188
1189 gp_Circ ProjLib_ProjectOnPlane::Circle() const
1190 {
1191   if (myType != GeomAbs_Circle)
1192     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");
1193
1194   return myResult->Circle();
1195 }
1196
1197
1198 //=======================================================================
1199 //function : Ellipse
1200 //purpose  : 
1201 //=======================================================================
1202
1203 gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1204 {
1205   if (myType != GeomAbs_Ellipse)
1206     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");
1207
1208   return myResult->Ellipse();
1209 }
1210
1211
1212 //=======================================================================
1213 //function : Hyperbola
1214 //purpose  : 
1215 //=======================================================================
1216
1217 gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1218 {
1219   if (myType != GeomAbs_Hyperbola)
1220     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");
1221
1222   return myResult->Hyperbola() ;
1223 }
1224
1225
1226 //=======================================================================
1227 //function : Parabola
1228 //purpose  : 
1229 //=======================================================================
1230
1231 gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1232 {
1233   if (myType != GeomAbs_Parabola)
1234     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
1235   
1236   return myResult->Parabola() ;
1237 }
1238
1239 //=======================================================================
1240 //function : Degree
1241 //purpose  : 
1242 //=======================================================================
1243
1244 Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1245 {
1246   if ((GetType() != GeomAbs_BSplineCurve) &&
1247       (GetType() != GeomAbs_BezierCurve))
1248     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");
1249
1250   if ( myIsApprox)
1251     return myResult->Degree();
1252   else
1253     return myCurve->Degree();
1254 }
1255
1256 //=======================================================================
1257 //function : IsRational
1258 //purpose  : 
1259 //=======================================================================
1260
1261 Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const 
1262 {
1263   if ((GetType() != GeomAbs_BSplineCurve) &&
1264       (GetType() != GeomAbs_BezierCurve))
1265     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
1266   
1267   if ( myIsApprox) 
1268     return myResult->IsRational();
1269   else
1270     return myCurve->IsRational();
1271 }
1272
1273 //=======================================================================
1274 //function : NbPoles
1275 //purpose  : 
1276 //=======================================================================
1277
1278 Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1279 {
1280   if ((GetType() != GeomAbs_BSplineCurve) &&
1281       (GetType() != GeomAbs_BezierCurve))
1282     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
1283   
1284   if ( myIsApprox)
1285     return myResult->NbPoles();
1286   else
1287     return myCurve->NbPoles();
1288 }
1289
1290 //=======================================================================
1291 //function : NbKnots
1292 //purpose  : 
1293 //=======================================================================
1294
1295 Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const 
1296 {
1297   if ( GetType() != GeomAbs_BSplineCurve) 
1298     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
1299   
1300   if ( myIsApprox) 
1301     return myResult->NbKnots();
1302   else
1303     return myCurve->NbKnots();
1304 }
1305
1306
1307 //=======================================================================
1308 //function : Bezier
1309 //purpose  : 
1310 //=======================================================================
1311
1312 Handle(Geom_BezierCurve)  ProjLib_ProjectOnPlane::Bezier() const
1313 {
1314   if (myType != GeomAbs_BezierCurve)
1315     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");
1316
1317   return myResult->Bezier() ;
1318 }
1319
1320 //=======================================================================
1321 //function : Bezier
1322 //purpose  : 
1323 //=======================================================================
1324
1325 Handle(Geom_BSplineCurve)  ProjLib_ProjectOnPlane::BSpline() const
1326 {
1327   if (myType != GeomAbs_BSplineCurve)
1328     Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");
1329
1330   return myResult->BSpline() ;
1331 }
1332