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