1 // Created on: 1993-08-25
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272
18 
19 #include <GeomAbs_SurfaceType.hxx>
20 #include <Standard_NoSuchObject.hxx>
21 #include <Standard_NotImplemented.hxx>
22 #include <ProjLib_ProjectedCurve.hxx>
23 #include <ProjLib_CompProjectedCurve.hxx>
24 #include <ProjLib_HCompProjectedCurve.hxx>
25 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
26 #include <ProjLib_ComputeApprox.hxx>
27 #include <ProjLib_Projector.hxx>
28 #include <Adaptor3d_Curve.hxx>
29 #include <Adaptor3d_Surface.hxx>
30 #include <Approx_CurveOnSurface.hxx>
31 #include <ProjLib_Plane.hxx>
32 #include <ProjLib_Cylinder.hxx>
33 #include <ProjLib_Cone.hxx>
34 #include <ProjLib_Sphere.hxx>
35 #include <ProjLib_Torus.hxx>
36 #include <Precision.hxx>
37 #include <Geom2d_BSplineCurve.hxx>
38 #include <Geom2d_BezierCurve.hxx>
39 #include <gp_Vec2d.hxx>
40 #include <StdFail_NotDone.hxx>
41 #include <gp_XY.hxx>
42 #include <TColgp_HArray1OfPnt2d.hxx>
43 #include <TColStd_HArray1OfReal.hxx>
44 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
45 #include <Geom2dConvert.hxx>
46 #include <TColStd_Array1OfReal.hxx>
47 #include <TColStd_Array1OfInteger.hxx>
48 #include <TColgp_Array1OfPnt2d.hxx>
49 #include <TColgp_HArray1OfVec2d.hxx>
50 #include <TColStd_HArray1OfBoolean.hxx>
51 #include <BSplCLib.hxx>
52 #include <GeomAbs_IsoType.hxx>
53 #include <Geom2d_Line.hxx>
54 #include <Geom2d_TrimmedCurve.hxx>
55 #include <ElCLib.hxx>
56 #include <GeomLib.hxx>
57 #include <Extrema_ExtPC.hxx>
58 #include <NCollection_DataMap.hxx>
59 #include <ElSLib.hxx>
60 #include <ElCLib.hxx>
61 
IMPLEMENT_STANDARD_RTTIEXT(ProjLib_ProjectedCurve,Adaptor2d_Curve2d)62 IMPLEMENT_STANDARD_RTTIEXT(ProjLib_ProjectedCurve, Adaptor2d_Curve2d)
63 
64 //=======================================================================
65 //function : ComputeTolU
66 //purpose  :
67 //=======================================================================
68 
69 static Standard_Real ComputeTolU(const Handle(Adaptor3d_Surface)& theSurf,
70                                  const Standard_Real theTolerance)
71 {
72   Standard_Real aTolU = theSurf->UResolution(theTolerance);
73   if (theSurf->IsUPeriodic())
74   {
75     aTolU = Min(aTolU, 0.01*theSurf->UPeriod());
76   }
77 
78   return aTolU;
79 }
80 
81 //=======================================================================
82 //function : ComputeTolV
83 //purpose  :
84 //=======================================================================
85 
ComputeTolV(const Handle (Adaptor3d_Surface)& theSurf,const Standard_Real theTolerance)86 static Standard_Real ComputeTolV(const Handle(Adaptor3d_Surface)& theSurf,
87                                  const Standard_Real theTolerance)
88 {
89   Standard_Real aTolV = theSurf->VResolution(theTolerance);
90   if (theSurf->IsVPeriodic())
91   {
92     aTolV = Min(aTolV, 0.01*theSurf->VPeriod());
93   }
94 
95   return aTolV;
96 }
97 
98 //=======================================================================
99 //function : IsoIsDeg
100 //purpose  :
101 //=======================================================================
102 
IsoIsDeg(const Adaptor3d_Surface & S,const Standard_Real Param,const GeomAbs_IsoType IT,const Standard_Real TolMin,const Standard_Real TolMax)103 static Standard_Boolean IsoIsDeg  (const Adaptor3d_Surface& S,
104 				   const Standard_Real      Param,
105 				   const GeomAbs_IsoType    IT,
106 				   const Standard_Real      TolMin,
107 				   const Standard_Real      TolMax)
108 {
109     Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
110     Standard_Boolean Along = Standard_True;
111     U1 = S.FirstUParameter();
112     U2 = S.LastUParameter();
113     V1 = S.FirstVParameter();
114     V2 = S.LastVParameter();
115     gp_Vec D1U,D1V;
116     gp_Pnt P;
117     Standard_Real Step,D1NormMax;
118     if (IT == GeomAbs_IsoV)
119     {
120       Step = (U2 - U1)/10;
121       D1NormMax=0.;
122       for (T=U1;T<=U2;T=T+Step)
123       {
124         S.D1(T,Param,P,D1U,D1V);
125         D1NormMax=Max(D1NormMax,D1U.Magnitude());
126       }
127 
128       if (D1NormMax >TolMax || D1NormMax < TolMin )
129            Along = Standard_False;
130     }
131     else
132     {
133       Step = (V2 - V1)/10;
134       D1NormMax=0.;
135       for (T=V1;T<=V2;T=T+Step)
136       {
137 	S.D1(Param,T,P,D1U,D1V);
138         D1NormMax=Max(D1NormMax,D1V.Magnitude());
139       }
140 
141       if (D1NormMax >TolMax || D1NormMax < TolMin )
142            Along = Standard_False;
143 
144 
145     }
146     return Along;
147 }
148 
149 //=======================================================================
150 //function : TrimC3d
151 //purpose  :
152 //=======================================================================
153 
TrimC3d(Handle (Adaptor3d_Curve)& myCurve,Standard_Boolean * IsTrimmed,const Standard_Real dt,const gp_Pnt & Pole,Standard_Integer * SingularCase,const Standard_Integer NumberOfSingularCase,const Standard_Real TolConf)154 static void TrimC3d(Handle(Adaptor3d_Curve)& myCurve,
155                     Standard_Boolean* IsTrimmed,
156                     const Standard_Real dt,
157                     const gp_Pnt& Pole,
158                     Standard_Integer* SingularCase,
159                     const Standard_Integer NumberOfSingularCase,
160                     const Standard_Real TolConf)
161 {
162   Standard_Real f = myCurve->FirstParameter();
163   Standard_Real l = myCurve->LastParameter();
164 
165   gp_Pnt P = myCurve->Value(f);
166 
167   if(P.Distance(Pole) <= TolConf) {
168     IsTrimmed[0] = Standard_True;
169     f = f+dt;
170     myCurve = myCurve->Trim(f, l, Precision::Confusion());
171     SingularCase[0] = NumberOfSingularCase;
172   }
173 
174   P = myCurve->Value(l);
175   if(P.Distance(Pole) <= TolConf) {
176     IsTrimmed[1] = Standard_True;
177     l = l-dt;
178     myCurve = myCurve->Trim(f, l, Precision::Confusion());
179     SingularCase[1] = NumberOfSingularCase;
180   }
181 }
182 
183 //=======================================================================
184 //function : ExtendC2d
185 //purpose  :
186 //=======================================================================
187 
ExtendC2d(Handle (Geom2d_BSplineCurve)& aRes,const Standard_Real,const Standard_Real,const Standard_Real u1,const Standard_Real u2,const Standard_Real v1,const Standard_Real v2,const Standard_Integer FirstOrLast,const Standard_Integer NumberOfSingularCase)188 static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
189                        const Standard_Real /*t*/,
190                        const Standard_Real /*dt*/,
191                        const Standard_Real u1,
192                        const Standard_Real u2,
193                        const Standard_Real v1,
194                        const Standard_Real v2,
195                        const Standard_Integer FirstOrLast,
196                        const Standard_Integer NumberOfSingularCase)
197 {
198   Standard_Real theParam = (FirstOrLast == 0)? aRes->FirstParameter()
199     : aRes->LastParameter();
200 
201   gp_Pnt2d                              aPBnd;
202   gp_Vec2d                              aVBnd;
203   gp_Dir2d                              aDBnd;
204   Handle(Geom2d_TrimmedCurve)           aSegment;
205   Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aRes, Convert_RationalC1);
206   Standard_Real                         aTol = Precision::Confusion();
207 
208   aRes->D1(theParam, aPBnd, aVBnd);
209   aDBnd.SetXY(aVBnd.XY());
210   gp_Lin2d aLin(aPBnd, aDBnd); //line in direction of derivative
211 
212   gp_Pnt2d thePole;
213   gp_Dir2d theBoundDir;
214   switch (NumberOfSingularCase)
215   {
216   case 1:
217     {
218       thePole.SetCoord(u1, v1);
219       theBoundDir.SetCoord(0., 1.);
220       break;
221     }
222   case 2:
223     {
224       thePole.SetCoord(u2, v1);
225       theBoundDir.SetCoord(0., 1.);
226       break;
227     }
228   case 3:
229     {
230       thePole.SetCoord(u1, v1);
231       theBoundDir.SetCoord(1., 0.);
232       break;
233     }
234   case 4:
235     {
236       thePole.SetCoord(u1, v2);
237       theBoundDir.SetCoord(1., 0.);
238       break;
239     }
240   }
241   gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
242   Standard_Real ParOnLin = 0.;
243   if (theBoundDir.IsParallel(aDBnd, 100.*Precision::Angular()))
244   {
245     ParOnLin = ElCLib::Parameter(aLin, thePole);
246   }
247   else
248   {
249     Standard_Real U1x = BoundLin.Direction().X();
250     Standard_Real U1y = BoundLin.Direction().Y();
251     Standard_Real U2x = aLin.Direction().X();
252     Standard_Real U2y = aLin.Direction().Y();
253     Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X();
254     Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y();
255 
256     Standard_Real D = U1y*U2x - U1x*U2y;
257 
258     ParOnLin = (Uo21y * U1x - Uo21x * U1y) / D; //parameter of intersection point
259   }
260 
261   Handle(Geom2d_Line) aSegLine = new Geom2d_Line(aLin);
262   aSegment = (FirstOrLast == 0)?
263     new Geom2d_TrimmedCurve(aSegLine, ParOnLin, 0.) :
264     new Geom2d_TrimmedCurve(aSegLine, 0., ParOnLin);
265 
266   Standard_Boolean anAfter = FirstOrLast != 0;
267   aCompCurve.Add(aSegment, aTol, anAfter);
268   aRes = aCompCurve.BSplineCurve();
269 }
270 
271 //=======================================================================
272 //function : Project
273 //purpose  :
274 //=======================================================================
275 
Project(ProjLib_Projector & P,Handle (Adaptor3d_Curve)& C)276 static void Project(ProjLib_Projector& P, Handle(Adaptor3d_Curve)& C)
277 {
278   GeomAbs_CurveType CType = C->GetType();
279   switch (CType) {
280     case GeomAbs_Line:
281       P.Project(C->Line());
282       break;
283     case GeomAbs_Circle:
284       P.Project(C->Circle());
285       break;
286     case GeomAbs_Ellipse:
287       P.Project(C->Ellipse());
288       break;
289     case GeomAbs_Hyperbola:
290       P.Project(C->Hyperbola());
291       break;
292     case GeomAbs_Parabola:
293       P.Project(C->Parabola());
294       break;
295     case GeomAbs_BSplineCurve:
296     case GeomAbs_BezierCurve:
297     case GeomAbs_OffsetCurve:
298     case GeomAbs_OtherCurve:    // try the approximation
299       break;
300     default:
301       throw Standard_NoSuchObject(" ");
302   }
303 }
304 
305 //=======================================================================
306 //function : ProjLib_ProjectedCurve
307 //purpose  :
308 //=======================================================================
309 
ProjLib_ProjectedCurve()310 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() :
311   myTolerance(Precision::Confusion()),
312   myDegMin(-1), myDegMax(-1),
313   myMaxSegments(-1),
314   myMaxDist(-1.),
315   myBndPnt(AppParCurves_TangencyPoint)
316 {
317 }
318 
319 
320 //=======================================================================
321 //function : ProjLib_ProjectedCurve
322 //purpose  :
323 //=======================================================================
324 
ProjLib_ProjectedCurve(const Handle (Adaptor3d_Surface)& S)325 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
326 (const Handle(Adaptor3d_Surface)& S) :
327   myTolerance(Precision::Confusion()),
328   myDegMin(-1), myDegMax(-1),
329   myMaxSegments(-1),
330   myMaxDist(-1.),
331   myBndPnt(AppParCurves_TangencyPoint)
332 {
333   Load(S);
334 }
335 
336 
337 //=======================================================================
338 //function : ProjLib_ProjectedCurve
339 //purpose  :
340 //=======================================================================
341 
ProjLib_ProjectedCurve(const Handle (Adaptor3d_Surface)& S,const Handle (Adaptor3d_Curve)& C)342 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
343 (const Handle(Adaptor3d_Surface)& S,
344  const Handle(Adaptor3d_Curve)& C) :
345   myTolerance(Precision::Confusion()),
346   myDegMin(-1), myDegMax(-1),
347   myMaxSegments(-1),
348   myMaxDist(-1.),
349   myBndPnt(AppParCurves_TangencyPoint)
350 {
351   Load(S);
352   Perform(C);
353 }
354 
355 
356 //=======================================================================
357 //function : ProjLib_ProjectedCurve
358 //purpose  :
359 //=======================================================================
360 
ProjLib_ProjectedCurve(const Handle (Adaptor3d_Surface)& S,const Handle (Adaptor3d_Curve)& C,const Standard_Real Tol)361 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
362 (const Handle(Adaptor3d_Surface)& S,
363  const Handle(Adaptor3d_Curve)&   C,
364  const Standard_Real             Tol) :
365   myTolerance(Max(Tol, Precision::Confusion())),
366   myDegMin(-1), myDegMax(-1),
367   myMaxSegments(-1),
368   myMaxDist(-1.),
369   myBndPnt(AppParCurves_TangencyPoint)
370 {
371   Load(S);
372   Perform(C);
373 }
374 
375 //=======================================================================
376 //function : ShallowCopy
377 //purpose  :
378 //=======================================================================
379 
Handle(Adaptor2d_Curve2d)380 Handle(Adaptor2d_Curve2d) ProjLib_ProjectedCurve::ShallowCopy() const
381 {
382   Handle(ProjLib_ProjectedCurve) aCopy = new ProjLib_ProjectedCurve();
383 
384   aCopy->myTolerance   = myTolerance;
385   if (!mySurface.IsNull())
386   {
387     aCopy->mySurface = mySurface->ShallowCopy();
388   }
389   if (!myCurve.IsNull())
390   {
391     aCopy->myCurve = myCurve->ShallowCopy();
392   }
393   aCopy->myResult      = myResult;
394   aCopy->myDegMin      = myDegMin;
395   aCopy->myDegMax      = myDegMax;
396   aCopy->myMaxSegments = myMaxSegments;
397   aCopy->myMaxDist     = myMaxDist;
398   aCopy->myBndPnt      = myBndPnt;
399 
400   return aCopy;
401 }
402 
403 //=======================================================================
404 //function : Load
405 //purpose  :
406 //=======================================================================
407 
Load(const Handle (Adaptor3d_Surface)& S)408 void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_Surface)& S)
409 {
410   mySurface = S ;
411 }
412 
413 //=======================================================================
414 //function : Load
415 //purpose  :
416 //=======================================================================
417 
Load(const Standard_Real theTol)418 void ProjLib_ProjectedCurve::Load(const Standard_Real theTol)
419 {
420   myTolerance = theTol;
421 }
422 
423 //=======================================================================
424 //function : Perform
425 //purpose  :
426 //=======================================================================
427 
Perform(const Handle (Adaptor3d_Curve)& C)428 void ProjLib_ProjectedCurve::Perform(const Handle(Adaptor3d_Curve)& C)
429 {
430   myTolerance = Max(myTolerance, Precision::Confusion());
431   myCurve = C;
432   Standard_Real FirstPar = C->FirstParameter();
433   Standard_Real LastPar  = C->LastParameter();
434   GeomAbs_SurfaceType SType = mySurface->GetType();
435   GeomAbs_CurveType   CType = myCurve->GetType();
436   Standard_Boolean isAnalyticalSurf = Standard_True;
437   Standard_Boolean IsTrimmed[2] = { Standard_False, Standard_False };
438   Standard_Integer SingularCase[2];
439   const Standard_Real eps = 0.01;
440   Standard_Real TolConf = Precision::Confusion();
441   Standard_Real dt = (LastPar - FirstPar) * eps;
442   Standard_Real U1 = 0.0, U2 = 0.0, V1 = 0.0, V2 = 0.0;
443   U1 = mySurface->FirstUParameter();
444   U2 = mySurface->LastUParameter();
445   V1 = mySurface->FirstVParameter();
446   V2 = mySurface->LastVParameter();
447 
448   switch (SType)
449   {
450     case GeomAbs_Plane:
451       {
452         ProjLib_Plane P(mySurface->Plane());
453         Project(P,myCurve);
454         myResult = P;
455       }
456       break;
457 
458     case GeomAbs_Cylinder:
459       {
460         ProjLib_Cylinder P(mySurface->Cylinder());
461         Project(P,myCurve);
462         myResult = P;
463       }
464       break;
465 
466     case GeomAbs_Cone:
467       {
468         ProjLib_Cone P(mySurface->Cone());
469         Project(P,myCurve);
470         myResult = P;
471       }
472       break;
473 
474     case GeomAbs_Sphere:
475       {
476         ProjLib_Sphere P(mySurface->Sphere());
477         Project(P,myCurve);
478         if ( P.IsDone())
479         {
480           // on met dans la pseudo-periode ( car Sphere n'est pas
481           // periodique en V !)
482           P.SetInBounds(myCurve->FirstParameter());
483         }
484         else
485         {
486           const Standard_Real Vmax = M_PI / 2.;
487           const Standard_Real Vmin = -Vmax;
488           const Standard_Real minang = 1.e-5 * M_PI;
489           gp_Sphere aSph = mySurface->Sphere();
490           Standard_Real anR = aSph.Radius();
491           Standard_Real f = myCurve->FirstParameter();
492           Standard_Real l = myCurve->LastParameter();
493 
494           gp_Pnt Pf = myCurve->Value(f);
495           gp_Pnt Pl = myCurve->Value(l);
496           gp_Pnt aLoc = aSph.Position().Location();
497           Standard_Real maxdist = Max(Pf.Distance(aLoc), Pl.Distance(aLoc));
498           TolConf = Max(anR * minang, Abs(anR - maxdist));
499 
500           //Surface has pole at V = Vmin and Vmax
501           gp_Pnt Pole = mySurface->Value(U1, Vmin);
502           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
503           Pole = mySurface->Value(U1, Vmax);
504           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
505         }
506         myResult = P;
507       }
508       break;
509 
510     case GeomAbs_Torus:
511       {
512         ProjLib_Torus P(mySurface->Torus());
513         Project(P,myCurve);
514         myResult = P;
515       }
516       break;
517 
518     case GeomAbs_BezierSurface:
519     case GeomAbs_BSplineSurface:
520       {
521         isAnalyticalSurf = Standard_False;
522         Standard_Real f, l;
523         f = myCurve->FirstParameter();
524         l = myCurve->LastParameter();
525         dt = (l - f) * eps;
526 
527         const Adaptor3d_Surface& S = *mySurface;
528         U1 = S.FirstUParameter();
529         U2 = S.LastUParameter();
530         V1 = S.FirstVParameter();
531         V2 = S.LastVParameter();
532 
533         if(IsoIsDeg(S, U1, GeomAbs_IsoU, 0., myTolerance))
534         {
535           //Surface has pole at U = Umin
536           gp_Pnt Pole = mySurface->Value(U1, V1);
537           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1, TolConf);
538         }
539 
540         if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance))
541         {
542           //Surface has pole at U = Umax
543           gp_Pnt Pole = mySurface->Value(U2, V1);
544           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2, TolConf);
545         }
546 
547         if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance))
548         {
549           //Surface has pole at V = Vmin
550           gp_Pnt Pole = mySurface->Value(U1, V1);
551           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
552         }
553 
554         if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance))
555         {
556           //Surface has pole at V = Vmax
557           gp_Pnt Pole = mySurface->Value(U1, V2);
558           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
559         }
560 
561         ProjLib_ComputeApproxOnPolarSurface polar;
562         polar.SetTolerance(myTolerance);
563         polar.SetDegree(myDegMin, myDegMax);
564         polar.SetMaxSegments(myMaxSegments);
565         polar.SetBndPnt(myBndPnt);
566         polar.SetMaxDist(myMaxDist);
567         polar.Perform(myCurve, mySurface);
568 
569         Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
570 
571         if (!aRes.IsNull())
572         {
573           myTolerance = polar.Tolerance();
574           if( (IsTrimmed[0] || IsTrimmed[1]))
575           {
576             if(IsTrimmed[0])
577             {
578               //Add segment before start of curve
579               f = myCurve->FirstParameter();
580               ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
581             }
582             if(IsTrimmed[1])
583             {
584               //Add segment after end of curve
585               l = myCurve->LastParameter();
586               ExtendC2d(aRes, l,  dt, U1, U2, V1, V2, 1, SingularCase[1]);
587             }
588             Handle(Geom2d_Curve) NewCurve2d;
589             GeomLib::SameRange(Precision::PConfusion(), aRes,
590               aRes->FirstParameter(), aRes->LastParameter(),
591               FirstPar, LastPar, NewCurve2d);
592             aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
593           }
594           myResult.SetBSpline(aRes);
595           myResult.Done();
596           myResult.SetType(GeomAbs_BSplineCurve);
597         }
598       }
599       break;
600 
601     default:
602       {
603         isAnalyticalSurf = Standard_False;
604         Standard_Real Vsingular[2] = {0.0 , 0.0}; //for surfaces of revolution
605         Standard_Real f = 0.0, l = 0.0;
606         dt = 0.0;
607 
608         if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution)
609         {
610           //Check possible singularity
611 
612           gp_Pnt P = mySurface->AxeOfRevolution().Location();
613           gp_Dir N = mySurface->AxeOfRevolution().Direction();
614 
615           gp_Lin L(P, N);
616 
617           f = myCurve->FirstParameter();
618           l = myCurve->LastParameter();
619           dt = (l - f) * eps;
620 
621           P = myCurve->Value(f);
622           if(L.Distance(P) < Precision::Confusion())
623           {
624             IsTrimmed[0] = Standard_True;
625             f = f + dt;
626             myCurve = myCurve->Trim(f, l, Precision::Confusion());
627             // Searching the parameter on the basis curve for surface of revolution
628             Extrema_ExtPC anExtr(P, *mySurface->BasisCurve(), myTolerance);
629             if (anExtr.IsDone())
630             {
631               Standard_Real aMinDist = RealLast();
632               for(Standard_Integer anIdx = 1; anIdx <= anExtr.NbExt(); anIdx++)
633               {
634                 if (anExtr.IsMin(anIdx) &&
635                     anExtr.SquareDistance(anIdx) < aMinDist)
636                 {
637                   aMinDist = anExtr.SquareDistance(anIdx);
638                   Vsingular[0] = anExtr.Point(anIdx).Parameter();
639                 }
640               }
641             }
642             else
643               Vsingular[0] = ElCLib::Parameter(L, P);
644             //SingularCase[0] = 3;
645           }
646 
647           P = myCurve->Value(l);
648           if(L.Distance(P) < Precision::Confusion())
649           {
650             IsTrimmed[1] = Standard_True;
651             l = l - dt;
652             myCurve = myCurve->Trim(f, l, Precision::Confusion());
653             // Searching the parameter on the basis curve for surface of revolution
654             Extrema_ExtPC anExtr(P, *mySurface->BasisCurve(), myTolerance);
655             if (anExtr.IsDone())
656             {
657               Standard_Real aMinDist = RealLast();
658               for(Standard_Integer anIdx = 1; anIdx <= anExtr.NbExt(); anIdx++)
659               {
660                 if (anExtr.IsMin(anIdx) &&
661                     anExtr.SquareDistance(anIdx) < aMinDist)
662                 {
663                   aMinDist = anExtr.SquareDistance(anIdx);
664                   Vsingular[1] = anExtr.Point(anIdx).Parameter();
665                 }
666               }
667             }
668             else
669               Vsingular[1] = ElCLib::Parameter(L, P);
670             //SingularCase[1] = 4;
671           }
672         }
673 
674         Standard_Real aTolU = Max(ComputeTolU(mySurface, myTolerance), Precision::Confusion());
675         Standard_Real aTolV = Max(ComputeTolV(mySurface, myTolerance), Precision::Confusion());
676         Standard_Real aTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
677 
678         Standard_Real aMaxDist = 100. * myTolerance;
679         if(myMaxDist > 0.)
680         {
681           aMaxDist = myMaxDist;
682         }
683         Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (mySurface,myCurve, aTolU, aTolV, aMaxDist);
684 
685         // Normalement, dans le cadre de ProjLib, le resultat
686         // doit etre une et une seule courbe !!!
687         // De plus, cette courbe ne doit pas etre Single point
688         Standard_Integer NbCurves = HProjector->NbCurves();
689         Standard_Real Udeb = 0.0,Ufin = 0.0;
690         if (NbCurves > 0)
691         {
692           HProjector->Bounds(1, Udeb, Ufin);
693         }
694         else
695         {
696           return;
697         }
698         // Approximons cette courbe algorithmique.
699         Standard_Boolean Only3d = Standard_False;
700         Standard_Boolean Only2d = Standard_True;
701         GeomAbs_Shape Continuity = GeomAbs_C1;
702         if(myBndPnt == AppParCurves_PassPoint)
703         {
704           Continuity = GeomAbs_C0;
705         }
706         Standard_Integer MaxDegree = 14;
707         if(myDegMax > 0)
708         {
709           MaxDegree = myDegMax;
710         }
711         Standard_Integer MaxSeg    = 16;
712         if(myMaxSegments > 0)
713         {
714           MaxSeg = myMaxSegments;
715         }
716 
717         Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, myTolerance);
718         appr.Perform(MaxSeg, MaxDegree, Continuity, Only3d, Only2d);
719 
720         Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
721 
722         if (!aRes.IsNull())
723         {
724           aTolU = appr.MaxError2dU();
725           aTolV = appr.MaxError2dV();
726           Standard_Real aNewTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
727           myTolerance *= (aNewTol2d / aTol2d);
728           if(IsTrimmed[0] || IsTrimmed[1])
729           {
730             // Treatment only for surface of revolution
731             Standard_Real u1, u2, v1, v2;
732             u1 = mySurface->FirstUParameter();
733             u2 = mySurface->LastUParameter();
734             v1 = mySurface->FirstVParameter();
735             v2 = mySurface->LastVParameter();
736 
737             if(IsTrimmed[0])
738             {
739               //Add segment before start of curve
740               ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
741             }
742             if(IsTrimmed[1])
743             {
744               //Add segment after end of curve
745               ExtendC2d(aRes, l,  dt, u1, u2, v1, Vsingular[1], 1, 4);
746             }
747             Handle(Geom2d_Curve) NewCurve2d;
748             GeomLib::SameRange(Precision::PConfusion(), aRes,
749               aRes->FirstParameter(), aRes->LastParameter(),
750               FirstPar, LastPar, NewCurve2d);
751             aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
752             if(Continuity == GeomAbs_C0)
753             {
754               // try to smoother the Curve GeomAbs_C1.
755               Standard_Integer aDeg = aRes->Degree();
756               Standard_Boolean OK = Standard_True;
757               Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
758               for (Standard_Integer ij = 2; ij < aRes->NbKnots(); ij++) {
759                 OK = OK && aRes->RemoveKnot(ij, aDeg-1, aSmoothTol);
760               }
761             }
762           }
763 
764           myResult.SetBSpline(aRes);
765           myResult.Done();
766           myResult.SetType(GeomAbs_BSplineCurve);
767         }
768       }
769   }
770 
771   if ( !myResult.IsDone() && isAnalyticalSurf)
772   {
773     // Use advanced analytical projector if base analytical projection failed.
774     ProjLib_ComputeApprox Comp;
775     Comp.SetTolerance(myTolerance);
776     Comp.SetDegree(myDegMin, myDegMax);
777     Comp.SetMaxSegments(myMaxSegments);
778     Comp.SetBndPnt(myBndPnt);
779     Comp.Perform(myCurve, mySurface);
780     if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull())
781       return; // advanced projector has been failed too
782     myResult.Done();
783     Handle(Geom2d_BSplineCurve) aRes;
784     if (Comp.BSpline().IsNull())
785     {
786       aRes = Geom2dConvert::CurveToBSplineCurve(Comp.Bezier());
787     }
788     else
789     {
790       aRes = Comp.BSpline();
791     }
792     if ((IsTrimmed[0] || IsTrimmed[1]))
793     {
794       if (IsTrimmed[0])
795       {
796         //Add segment before start of curve
797         Standard_Real f = myCurve->FirstParameter();
798         ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
799       }
800       if (IsTrimmed[1])
801       {
802         //Add segment after end of curve
803         Standard_Real l = myCurve->LastParameter();
804         ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
805       }
806       Handle(Geom2d_Curve) NewCurve2d;
807       GeomLib::SameRange(Precision::PConfusion(), aRes,
808         aRes->FirstParameter(), aRes->LastParameter(),
809         FirstPar, LastPar, NewCurve2d);
810       aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
811       myResult.SetBSpline(aRes);
812       myResult.SetType(GeomAbs_BSplineCurve);
813     }
814     else
815     {
816       // set the type
817       if (SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve)
818       {
819         myResult.SetType(GeomAbs_BezierCurve);
820         myResult.SetBezier(Comp.Bezier());
821       }
822       else
823       {
824         myResult.SetType(GeomAbs_BSplineCurve);
825         myResult.SetBSpline(Comp.BSpline());
826       }
827     }
828     // set the periodicity flag
829     if (SType == GeomAbs_Plane        &&
830       CType == GeomAbs_BSplineCurve &&
831       myCurve->IsPeriodic())
832     {
833       myResult.SetPeriodic();
834     }
835     myTolerance = Comp.Tolerance();
836   }
837 
838   Standard_Boolean isPeriodic[] = {mySurface->IsUPeriodic(),
839                                    mySurface->IsVPeriodic()};
840   if (myResult.IsDone() &&
841      (isPeriodic[0] || isPeriodic[1]))
842   {
843     // Check result curve to be in params space.
844 
845     // U and V parameters space correspondingly.
846     const Standard_Real aSurfFirstPar[2] = {mySurface->FirstUParameter(),
847                                             mySurface->FirstVParameter()};
848     Standard_Real aSurfPeriod[2] = {0.0, 0.0};
849     if (isPeriodic[0])
850       aSurfPeriod[0] = mySurface->UPeriod();
851     if (isPeriodic[1])
852       aSurfPeriod[1] = mySurface->VPeriod();
853 
854     for(Standard_Integer anIdx = 1; anIdx <= 2; anIdx++)
855     {
856       if (!isPeriodic[anIdx - 1])
857         continue;
858 
859       if (myResult.GetType() == GeomAbs_BSplineCurve)
860       {
861         NCollection_DataMap<Standard_Integer, Standard_Integer> aMap;
862         Handle(Geom2d_BSplineCurve) aRes = myResult.BSpline();
863         const Standard_Integer aDeg = aRes->Degree();
864 
865         for(Standard_Integer aKnotIdx = aRes->FirstUKnotIndex();
866                              aKnotIdx < aRes->LastUKnotIndex();
867                              aKnotIdx++)
868         {
869           const Standard_Real aFirstParam = aRes->Knot(aKnotIdx);
870           const Standard_Real aLastParam  = aRes->Knot(aKnotIdx + 1);
871 
872           for(Standard_Integer anIntIdx = 0; anIntIdx <= aDeg; anIntIdx++)
873           {
874             const Standard_Real aCurrParam = aFirstParam + (aLastParam - aFirstParam) * anIntIdx / (aDeg + 1.0);
875             gp_Pnt2d aPnt2d;
876             aRes->D0(aCurrParam, aPnt2d);
877 
878             Standard_Integer aMapKey = Standard_Integer ((aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1]) / aSurfPeriod[anIdx - 1]);
879 
880             if (aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1] < 0.0)
881               aMapKey--;
882 
883             if (aMap.IsBound(aMapKey))
884               aMap.ChangeFind(aMapKey)++;
885             else
886               aMap.Bind(aMapKey, 1);
887           }
888         }
889 
890         Standard_Integer aMaxPoints = 0, aMaxIdx = 0;
891         NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator aMapIter(aMap);
892         for( ; aMapIter.More(); aMapIter.Next())
893         {
894           if (aMapIter.Value() > aMaxPoints)
895           {
896             aMaxPoints = aMapIter.Value();
897             aMaxIdx = aMapIter.Key();
898           }
899         }
900         if (aMaxIdx != 0)
901         {
902           gp_Pnt2d aFirstPnt = aRes->Value(aRes->FirstParameter());
903           gp_Pnt2d aSecondPnt = aFirstPnt;
904           aSecondPnt.SetCoord(anIdx, aFirstPnt.Coord(anIdx) - aSurfPeriod[anIdx - 1] * aMaxIdx);
905           aRes->Translate(gp_Vec2d(aFirstPnt, aSecondPnt));
906         }
907       }
908 
909       if (myResult.GetType() == GeomAbs_Line)
910       {
911         Standard_Real aT1 = myCurve->FirstParameter();
912         Standard_Real aT2 = myCurve->LastParameter();
913 
914         if (anIdx == 1)
915         {
916           // U param space.
917           myResult.UFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]);
918         }
919         else
920         {
921           // V param space.
922           myResult.VFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]);
923         }
924       }
925     }
926   }
927 }
928 
929 //=======================================================================
930 //function : SetDegree
931 //purpose  :
932 //=======================================================================
SetDegree(const Standard_Integer theDegMin,const Standard_Integer theDegMax)933 void ProjLib_ProjectedCurve::SetDegree(const Standard_Integer theDegMin,
934                                        const Standard_Integer theDegMax)
935 {
936   myDegMin = theDegMin;
937   myDegMax = theDegMax;
938 }
939 //=======================================================================
940 //function : SetMaxSegments
941 //purpose  :
942 //=======================================================================
SetMaxSegments(const Standard_Integer theMaxSegments)943 void ProjLib_ProjectedCurve::SetMaxSegments(const Standard_Integer theMaxSegments)
944 {
945   myMaxSegments = theMaxSegments;
946 }
947 
948 //=======================================================================
949 //function : SetBndPnt
950 //purpose  :
951 //=======================================================================
SetBndPnt(const AppParCurves_Constraint theBndPnt)952 void ProjLib_ProjectedCurve::SetBndPnt(const AppParCurves_Constraint theBndPnt)
953 {
954   myBndPnt = theBndPnt;
955 }
956 
957 //=======================================================================
958 //function : SetMaxDist
959 //purpose  :
960 //=======================================================================
SetMaxDist(const Standard_Real theMaxDist)961 void ProjLib_ProjectedCurve::SetMaxDist(const Standard_Real theMaxDist)
962 {
963   myMaxDist = theMaxDist;
964 }
965 
966 //=======================================================================
967 //function : GetSurface
968 //purpose  :
969 //=======================================================================
970 
Handle(Adaptor3d_Surface)971 const Handle(Adaptor3d_Surface)& ProjLib_ProjectedCurve::GetSurface() const
972 {
973   return mySurface;
974 }
975 
976 
977 //=======================================================================
978 //function : GetCurve
979 //purpose  :
980 //=======================================================================
981 
Handle(Adaptor3d_Curve)982 const Handle(Adaptor3d_Curve)& ProjLib_ProjectedCurve::GetCurve() const
983 {
984   return myCurve;
985 }
986 
987 
988 //=======================================================================
989 //function : GetTolerance
990 //purpose  :
991 //=======================================================================
992 
GetTolerance() const993 Standard_Real ProjLib_ProjectedCurve::GetTolerance() const
994 {
995   return myTolerance;
996 }
997 
998 
999 //=======================================================================
1000 //function : FirstParameter
1001 //purpose  :
1002 //=======================================================================
1003 
FirstParameter() const1004 Standard_Real ProjLib_ProjectedCurve::FirstParameter() const
1005 {
1006   return myCurve->FirstParameter();
1007 }
1008 
1009 
1010 //=======================================================================
1011 //function : LastParameter
1012 //purpose  :
1013 //=======================================================================
1014 
LastParameter() const1015 Standard_Real ProjLib_ProjectedCurve::LastParameter() const
1016 {
1017   return myCurve->LastParameter();
1018 }
1019 
1020 
1021 //=======================================================================
1022 //function : Continuity
1023 //purpose  :
1024 //=======================================================================
1025 
Continuity() const1026 GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
1027 {
1028   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Continuity() - method is not implemented");
1029 }
1030 
1031 
1032 //=======================================================================
1033 //function : NbIntervals
1034 //purpose  :
1035 //=======================================================================
1036 
NbIntervals(const GeomAbs_Shape) const1037 Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const
1038 {
1039   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::NbIntervals() - method is not implemented");
1040 }
1041 
1042 
1043 //=======================================================================
1044 //function : Intervals
1045 //purpose  :
1046 //=======================================================================
1047 
1048 //void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  T,
Intervals(TColStd_Array1OfReal &,const GeomAbs_Shape) const1049 void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  ,
1050 				       const GeomAbs_Shape ) const
1051 {
1052   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Intervals() - method is not implemented");
1053 }
1054 
1055 
1056 //=======================================================================
1057 //function : IsClosed
1058 //purpose  :
1059 //=======================================================================
1060 
IsClosed() const1061 Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
1062 {
1063   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::IsClosed() - method is not implemented");
1064 }
1065 
1066 
1067 //=======================================================================
1068 //function : IsPeriodic
1069 //purpose  :
1070 //=======================================================================
1071 
IsPeriodic() const1072 Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
1073 {
1074   return myResult.IsPeriodic();
1075 }
1076 
1077 
1078 //=======================================================================
1079 //function : Period
1080 //purpose  :
1081 //=======================================================================
1082 
Period() const1083 Standard_Real ProjLib_ProjectedCurve::Period() const
1084 {
1085   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Period() - method is not implemented");
1086 }
1087 
1088 
1089 //=======================================================================
1090 //function : Value
1091 //purpose  :
1092 //=======================================================================
1093 
Value(const Standard_Real) const1094 gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const
1095 {
1096   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Value() - method is not implemented");
1097 }
1098 
1099 
1100 //=======================================================================
1101 //function : D0
1102 //purpose  :
1103 //=======================================================================
1104 
D0(const Standard_Real,gp_Pnt2d &) const1105 void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
1106 {
1107   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D0() - method is not implemented");
1108 }
1109 
1110 
1111 //=======================================================================
1112 //function : D1
1113 //purpose  :
1114 //=======================================================================
1115 
D1(const Standard_Real,gp_Pnt2d &,gp_Vec2d &) const1116 void ProjLib_ProjectedCurve::D1(const Standard_Real ,
1117 			              gp_Pnt2d&     ,
1118                                       gp_Vec2d&     ) const
1119 {
1120   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D1() - method is not implemented");
1121 }
1122 
1123 
1124 //=======================================================================
1125 //function : D2
1126 //purpose  :
1127 //=======================================================================
1128 
D2(const Standard_Real,gp_Pnt2d &,gp_Vec2d &,gp_Vec2d &) const1129 void ProjLib_ProjectedCurve::D2(const Standard_Real ,
1130 			              gp_Pnt2d&     ,
1131                                       gp_Vec2d&     ,
1132                                       gp_Vec2d&     ) const
1133 {
1134   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D2() - method is not implemented");
1135 }
1136 
1137 
1138 //=======================================================================
1139 //function : D3
1140 //purpose  :
1141 //=======================================================================
1142 
D3(const Standard_Real,gp_Pnt2d &,gp_Vec2d &,gp_Vec2d &,gp_Vec2d &) const1143 void ProjLib_ProjectedCurve::D3(const Standard_Real,
1144 				      gp_Pnt2d&,
1145 			              gp_Vec2d&,
1146 				      gp_Vec2d&,
1147 			              gp_Vec2d&) const
1148 {
1149   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D3() - method is not implemented");
1150 }
1151 
1152 
1153 //=======================================================================
1154 //function : DN
1155 //purpose  :
1156 //=======================================================================
1157 
DN(const Standard_Real,const Standard_Integer) const1158 gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real,
1159 				    const Standard_Integer) const
1160 {
1161   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::DN() - method is not implemented");
1162 }
1163 
1164 
1165 //=======================================================================
1166 //function : Resolution
1167 //purpose  :
1168 //=======================================================================
1169 
Resolution(const Standard_Real) const1170 Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const
1171 {
1172   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Resolution() - method is not implemented");
1173 }
1174 
1175 
1176 //=======================================================================
1177 //function : GetType
1178 //purpose  :
1179 //=======================================================================
1180 
GetType() const1181 GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const
1182 {
1183   return myResult.GetType();
1184 }
1185 
1186 
1187 //=======================================================================
1188 //function : Line
1189 //purpose  :
1190 //=======================================================================
1191 
Line() const1192 gp_Lin2d ProjLib_ProjectedCurve::Line() const
1193 {
1194   return myResult.Line();
1195 }
1196 
1197 
1198 //=======================================================================
1199 //function : Circle
1200 //purpose  :
1201 //=======================================================================
1202 
Circle() const1203 gp_Circ2d ProjLib_ProjectedCurve::Circle() const
1204 {
1205   return myResult.Circle();
1206 }
1207 
1208 
1209 //=======================================================================
1210 //function : Ellipse
1211 //purpose  :
1212 //=======================================================================
1213 
Ellipse() const1214 gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const
1215 {
1216   return myResult.Ellipse();
1217 }
1218 
1219 
1220 //=======================================================================
1221 //function : Hyperbola
1222 //purpose  :
1223 //=======================================================================
1224 
Hyperbola() const1225 gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const
1226 {
1227   return myResult.Hyperbola();
1228 }
1229 
1230 
1231 //=======================================================================
1232 //function : Parabola
1233 //purpose  :
1234 //=======================================================================
1235 
Parabola() const1236 gp_Parab2d ProjLib_ProjectedCurve::Parabola() const
1237 {
1238   return myResult.Parabola();
1239 }
1240 
1241 
1242 
1243 //=======================================================================
1244 //function : Degree
1245 //purpose  :
1246 //=======================================================================
1247 
Degree() const1248 Standard_Integer ProjLib_ProjectedCurve::Degree() const
1249 {
1250   Standard_NoSuchObject_Raise_if
1251     ( (GetType() != GeomAbs_BSplineCurve) &&
1252       (GetType() != GeomAbs_BezierCurve),
1253      "ProjLib_ProjectedCurve:Degree");
1254   if (GetType() == GeomAbs_BSplineCurve) {
1255     return myResult.BSpline()->Degree();
1256   }
1257   else if (GetType() == GeomAbs_BezierCurve) {
1258     return myResult.Bezier()->Degree();
1259   }
1260 
1261   // portage WNT
1262   return 0;
1263 }
1264 
1265 //=======================================================================
1266 //function : IsRational
1267 //purpose  :
1268 //=======================================================================
1269 
IsRational() const1270 Standard_Boolean ProjLib_ProjectedCurve::IsRational() const
1271 {
1272   Standard_NoSuchObject_Raise_if
1273     ( (GetType() != GeomAbs_BSplineCurve) &&
1274       (GetType() != GeomAbs_BezierCurve),
1275      "ProjLib_ProjectedCurve:IsRational");
1276   if (GetType() == GeomAbs_BSplineCurve) {
1277     return myResult.BSpline()->IsRational();
1278   }
1279   else if (GetType() == GeomAbs_BezierCurve) {
1280     return myResult.Bezier()->IsRational();
1281   }
1282   // portage WNT
1283   return Standard_False;
1284 }
1285 
1286 //=======================================================================
1287 //function : NbPoles
1288 //purpose  :
1289 //=======================================================================
1290 
NbPoles() const1291 Standard_Integer ProjLib_ProjectedCurve::NbPoles() const
1292 {
1293   Standard_NoSuchObject_Raise_if
1294     ( (GetType() != GeomAbs_BSplineCurve) &&
1295       (GetType() != GeomAbs_BezierCurve)
1296      ,"ProjLib_ProjectedCurve:NbPoles"  );
1297   if (GetType() == GeomAbs_BSplineCurve) {
1298     return myResult.BSpline()->NbPoles();
1299   }
1300   else if (GetType() == GeomAbs_BezierCurve) {
1301     return myResult.Bezier()->NbPoles();
1302   }
1303 
1304   // portage WNT
1305   return 0;
1306 }
1307 
1308 //=======================================================================
1309 //function : NbKnots
1310 //purpose  :
1311 //=======================================================================
1312 
NbKnots() const1313 Standard_Integer ProjLib_ProjectedCurve::NbKnots() const
1314 {
1315   Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve,
1316 				  "ProjLib_ProjectedCurve:NbKnots");
1317   return myResult.BSpline()->NbKnots();
1318 }
1319 
1320 //=======================================================================
1321 //function : Bezier
1322 //purpose  :
1323 //=======================================================================
1324 
Handle(Geom2d_BezierCurve)1325 Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const
1326 {
1327  return myResult.Bezier() ;
1328 }
1329 
1330 //=======================================================================
1331 //function : BSpline
1332 //purpose  :
1333 //=======================================================================
1334 
Handle(Geom2d_BSplineCurve)1335 Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const
1336 {
1337  return myResult.BSpline() ;
1338 }
1339 //=======================================================================
1340 //function : Trim
1341 //purpose  :
1342 //=======================================================================
1343 
Handle(Adaptor2d_Curve2d)1344 Handle(Adaptor2d_Curve2d) ProjLib_ProjectedCurve::Trim
1345 //(const Standard_Real First,
1346 // const Standard_Real Last,
1347 // const Standard_Real Tolerance) const
1348 (const Standard_Real ,
1349  const Standard_Real ,
1350  const Standard_Real ) const
1351 {
1352   throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Trim() - method is not implemented");
1353 }
1354