6be1457708c5c16f861d538798b83d2fa018a606
[occt.git] / src / ProjLib / ProjLib_ProjectedCurve.cxx
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_HCurve.hxx>
29 #include <Adaptor3d_HSurface.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 <TColStd_Array1OfReal.hxx>
46 #include <TColStd_Array1OfInteger.hxx>
47 #include <TColgp_Array1OfPnt2d.hxx>
48 #include <TColgp_HArray1OfVec2d.hxx>
49 #include <TColStd_HArray1OfBoolean.hxx>
50 #include <BSplCLib.hxx>
51 #include <GeomAbs_IsoType.hxx>
52 #include <Geom2d_Line.hxx>
53 #include <Geom2d_TrimmedCurve.hxx>
54 #include <ElCLib.hxx>
55 #include <GeomLib.hxx>
56
57 //=======================================================================
58 //function : IsoIsDeg
59 //purpose  : 
60 //=======================================================================
61
62 static Standard_Boolean IsoIsDeg  (const Adaptor3d_Surface& S,
63                                    const Standard_Real      Param,
64                                    const GeomAbs_IsoType    IT,
65                                    const Standard_Real      TolMin,
66                                    const Standard_Real      TolMax) 
67 {
68     Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
69     Standard_Boolean Along = Standard_True;
70     U1 = S.FirstUParameter();
71     U2 = S.LastUParameter();
72     V1 = S.FirstVParameter();
73     V2 = S.LastVParameter();
74     gp_Vec D1U,D1V;
75     gp_Pnt P;
76     Standard_Real Step,D1NormMax;
77     if (IT == GeomAbs_IsoV) 
78     {
79       Step = (U2 - U1)/10;
80       D1NormMax=0.;
81       for (T=U1;T<=U2;T=T+Step) 
82       {
83         S.D1(T,Param,P,D1U,D1V);
84         D1NormMax=Max(D1NormMax,D1U.Magnitude());
85       }
86
87       if (D1NormMax >TolMax || D1NormMax < TolMin ) 
88            Along = Standard_False;
89     }
90     else 
91     {
92       Step = (V2 - V1)/10;
93       D1NormMax=0.;
94       for (T=V1;T<=V2;T=T+Step) 
95       {
96         S.D1(Param,T,P,D1U,D1V);
97         D1NormMax=Max(D1NormMax,D1V.Magnitude());
98       }
99
100       if (D1NormMax >TolMax || D1NormMax < TolMin ) 
101            Along = Standard_False;
102
103
104     }
105     return Along;
106 }
107
108 //=======================================================================
109 //function : TrimC3d
110 //purpose  : 
111 //=======================================================================
112
113 static void TrimC3d(Handle(Adaptor3d_HCurve)& myCurve,
114                     Standard_Boolean* IsTrimmed,
115                     const Standard_Real dt,
116                     const gp_Pnt& Pole,
117                     Standard_Integer* SingularCase,
118                     const Standard_Integer NumberOfSingularCase)
119 {
120   Standard_Real f = myCurve->FirstParameter();
121   Standard_Real l = myCurve->LastParameter();
122
123   gp_Pnt P = myCurve->Value(f);
124
125   if(P.Distance(Pole) < Precision::Confusion()) {
126     IsTrimmed[0] = Standard_True;
127     f = f+dt;
128     myCurve = myCurve->Trim(f, l, Precision::Confusion());
129     SingularCase[0] = NumberOfSingularCase;
130   }
131   
132   P = myCurve->Value(l);
133   if(P.Distance(Pole) < Precision::Confusion()) {
134     IsTrimmed[1] = Standard_True;
135     l = l-dt;
136     myCurve = myCurve->Trim(f, l, Precision::Confusion());
137     SingularCase[1] = NumberOfSingularCase;
138   }
139 }
140
141 //=======================================================================
142 //function : ExtendC2d
143 //purpose  : 
144 //=======================================================================
145
146 static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
147                        const Standard_Real /*t*/,
148                        const Standard_Real /*dt*/,
149                        const Standard_Real u1,
150                        const Standard_Real u2,
151                        const Standard_Real v1,
152                        const Standard_Real v2,
153                        const Standard_Integer FirstOrLast,
154                        const Standard_Integer NumberOfSingularCase)
155 {
156   Standard_Real theParam = (FirstOrLast == 0)? aRes->FirstParameter()
157     : aRes->LastParameter();
158
159   gp_Pnt2d                              aPBnd;
160   gp_Vec2d                              aVBnd;
161   gp_Dir2d                              aDBnd;
162   Handle(Geom2d_TrimmedCurve)           aSegment;
163   Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aRes, Convert_RationalC1);
164   Standard_Real                         aTol = Precision::Confusion();
165
166   aRes->D1(theParam, aPBnd, aVBnd);
167   aDBnd.SetXY(aVBnd.XY());
168   gp_Lin2d aLin(aPBnd, aDBnd); //line in direction of derivative
169
170   gp_Pnt2d thePole;
171   gp_Dir2d theBoundDir;
172   switch (NumberOfSingularCase)
173   {
174   case 1:
175     {
176       thePole.SetCoord(u1, v1);
177       theBoundDir.SetCoord(0., 1.);
178       break;
179     }
180   case 2:
181     {
182       thePole.SetCoord(u2, v1);
183       theBoundDir.SetCoord(0., 1.);
184       break;
185     }
186   case 3:
187     {
188       thePole.SetCoord(u1, v1);
189       theBoundDir.SetCoord(1., 0.);
190       break;
191     }
192   case 4:
193     {
194       thePole.SetCoord(u1, v2);
195       theBoundDir.SetCoord(1., 0.);
196       break;
197     }
198   }
199   gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
200
201   Standard_Real U1x = BoundLin.Direction().X();
202   Standard_Real U1y = BoundLin.Direction().Y();
203   Standard_Real U2x = aLin.Direction().X();
204   Standard_Real U2y = aLin.Direction().Y();
205   Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X();
206   Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y();
207   
208   Standard_Real D = U1y*U2x-U1x*U2y;
209   
210   Standard_Real ParOnLin = (Uo21y * U1x - Uo21x * U1y)/D; //parameter of intersection point
211   
212   Handle(Geom2d_Line) aSegLine = new Geom2d_Line(aLin);
213   aSegment = (FirstOrLast == 0)?
214     new Geom2d_TrimmedCurve(aSegLine, ParOnLin, 0.) :
215     new Geom2d_TrimmedCurve(aSegLine, 0., ParOnLin);
216
217   aCompCurve.Add(aSegment, aTol);
218   aRes = aCompCurve.BSplineCurve();
219 }
220
221 //=======================================================================
222 //function : Project
223 //purpose  : 
224 //=======================================================================
225
226 static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C)
227 {
228   GeomAbs_CurveType CType = C->GetType();
229   switch (CType) {
230     case GeomAbs_Line:
231       P.Project(C->Line());
232       break;
233     case GeomAbs_Circle:
234       P.Project(C->Circle());
235       break;
236     case GeomAbs_Ellipse:
237       P.Project(C->Ellipse());
238       break;
239     case GeomAbs_Hyperbola:
240       P.Project(C->Hyperbola());
241       break;
242     case GeomAbs_Parabola:
243       P.Project(C->Parabola());
244       break;
245     case GeomAbs_BSplineCurve:
246     case GeomAbs_BezierCurve:
247     case GeomAbs_OtherCurve:    // try the approximation
248       break;
249     default:
250       Standard_NoSuchObject::Raise(" ");
251   }
252 }
253
254 //=======================================================================
255 //function : ProjLib_ProjectedCurve
256 //purpose  : 
257 //=======================================================================
258
259 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve()
260
261 {
262   myTolerance = Precision::Confusion();
263 }
264
265
266 //=======================================================================
267 //function : ProjLib_ProjectedCurve
268 //purpose  : 
269 //=======================================================================
270
271 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
272 (const Handle(Adaptor3d_HSurface)& S)
273 {
274   myTolerance = Precision::Confusion();
275   Load(S);
276 }
277
278
279 //=======================================================================
280 //function : ProjLib_ProjectedCurve
281 //purpose  : 
282 //=======================================================================
283
284 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
285 (const Handle(Adaptor3d_HSurface)& S,
286  const Handle(Adaptor3d_HCurve)& C)
287 {
288   myTolerance = Precision::Confusion();
289   Load(S);
290   Load(C);
291 }
292
293
294 //=======================================================================
295 //function : ProjLib_ProjectedCurve
296 //purpose  : 
297 //=======================================================================
298
299 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
300 (const Handle(Adaptor3d_HSurface)& S,
301  const Handle(Adaptor3d_HCurve)&   C,
302  const Standard_Real             Tol)
303 {
304   myTolerance = Max(Tol, Precision::Confusion());
305   Load(S);
306   Load(C);
307 }
308
309
310 //=======================================================================
311 //function : Load
312 //purpose  : 
313 //=======================================================================
314
315 void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S)
316 {
317   mySurface = S ;
318 }
319
320
321 //=======================================================================
322 //function : Load
323 //purpose  : 
324 //=======================================================================
325
326 void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
327 {
328   myTolerance = Max(myTolerance, Precision::Confusion());
329   myCurve = C;
330   Standard_Real FirstPar = C->FirstParameter();
331   Standard_Real LastPar  = C->LastParameter();
332   GeomAbs_SurfaceType SType = mySurface->GetType();    
333   GeomAbs_CurveType   CType = myCurve->GetType();
334
335   switch (SType) {
336
337     case GeomAbs_Plane:
338       {
339         ProjLib_Plane P(mySurface->Plane());
340         Project(P,myCurve);
341         myResult = P;
342       }
343       break;
344
345     case GeomAbs_Cylinder:
346       {
347         ProjLib_Cylinder P(mySurface->Cylinder());
348         Project(P,myCurve);
349         myResult = P;
350       }
351       break;
352
353     case GeomAbs_Cone:
354       {
355         ProjLib_Cone P(mySurface->Cone());
356         Project(P,myCurve);
357         myResult = P;
358       }
359       break;
360
361     case GeomAbs_Sphere:
362       {
363         ProjLib_Sphere P(mySurface->Sphere());
364         Project(P,myCurve);
365         if ( P.IsDone()) { 
366           // on met dans la pseudo-periode ( car Sphere n'est pas
367           // periodique en V !)
368           P.SetInBounds(myCurve->FirstParameter());
369         }
370         myResult = P;
371       }
372       break;
373
374     case GeomAbs_Torus:
375       {
376         ProjLib_Torus P(mySurface->Torus());
377         Project(P,myCurve);
378         myResult = P;
379       }
380       break;
381
382     case GeomAbs_BezierSurface:
383     case GeomAbs_BSplineSurface:
384       {
385         
386         Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
387         Standard_Integer SingularCase[2];
388         Standard_Real f, l, dt;
389         const Standard_Real eps = 0.01;
390         f = myCurve->FirstParameter();
391         l = myCurve->LastParameter();
392         dt = (l-f)*eps;
393
394         Standard_Real U1=0.,U2=0.,V1=0.,V2=0;
395         const Adaptor3d_Surface& S = mySurface->Surface();
396         U1 = S.FirstUParameter();
397         U2 = S.LastUParameter();
398         V1 = S.FirstVParameter();
399         V2 = S.LastVParameter();
400
401         if(IsoIsDeg(S, U1, GeomAbs_IsoU, 0., myTolerance) ) {
402           //Surface has pole at U = Umin
403           gp_Pnt Pole = mySurface->Value(U1, V1);
404           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1);
405         }
406
407         if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance) ) {
408           //Surface has pole at U = Umax
409           gp_Pnt Pole = mySurface->Value(U2, V1);
410           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2);
411         }
412           
413         if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance) ) {
414           //Surface has pole at V = Vmin
415           gp_Pnt Pole = mySurface->Value(U1, V1);
416           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3);
417         }
418
419         if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance) ) {
420           //Surface has pole at V = Vmax
421           gp_Pnt Pole = mySurface->Value(U1, V2);
422           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4);
423         }
424
425         ProjLib_ComputeApproxOnPolarSurface polar(myCurve, 
426                                                   mySurface,
427                                                   myTolerance);
428
429         Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
430
431         if(IsTrimmed[0] || IsTrimmed[1]) {
432           if(IsTrimmed[0]) {
433             //Add segment before start of curve
434             f = myCurve->FirstParameter();
435             ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
436           }
437           if(IsTrimmed[1]) {
438             //Add segment after end of curve
439             l = myCurve->LastParameter();
440             ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
441           }
442           Handle(Geom2d_Curve) NewCurve2d;
443           GeomLib::SameRange(Precision::PConfusion(), aRes,
444                              aRes->FirstParameter(), aRes->LastParameter(),
445                              FirstPar, LastPar,
446                              NewCurve2d);
447           aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
448         }
449         myResult.SetBSpline(aRes);
450         myResult.Done();
451         myResult.SetType(GeomAbs_BSplineCurve);
452       }
453       break;
454
455     default:
456       {
457         Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
458         Standard_Real Vsingular[2] = { 0.0 , 0.0 }; //for surfaces of revolution
459         Standard_Real f = 0., l = 0., dt = 0.;
460         const Standard_Real eps = 0.01;
461         
462         if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution) {
463           //Check possible singularity
464
465           gp_Pnt P = mySurface->AxeOfRevolution().Location();
466           gp_Dir N = mySurface->AxeOfRevolution().Direction();
467
468           gp_Lin L(P, N);
469
470           f = myCurve->FirstParameter();
471           l = myCurve->LastParameter();
472           dt = (l-f)*eps;
473
474           P = myCurve->Value(f);
475           if(L.Distance(P) < Precision::Confusion()) {
476             IsTrimmed[0] = Standard_True;
477             f = f+dt;
478             myCurve = myCurve->Trim(f, l, Precision::Confusion());
479             Vsingular[0] = ElCLib::Parameter(L, P);
480             //SingularCase[0] = 3;
481           }
482
483           P = myCurve->Value(l);
484           if(L.Distance(P) < Precision::Confusion()) {
485             IsTrimmed[1] = Standard_True;
486             l = l-dt;
487             myCurve = myCurve->Trim(f, l, Precision::Confusion());
488             Vsingular[1] = ElCLib::Parameter(L, P);
489             //SingularCase[1] = 3;
490           }
491         }
492
493         ProjLib_CompProjectedCurve Projector(mySurface,myCurve,
494                                              myTolerance,myTolerance);
495         Handle(ProjLib_HCompProjectedCurve) HProjector = 
496           new ProjLib_HCompProjectedCurve();
497         HProjector->Set(Projector);
498
499         // Normalement, dans le cadre de ProjLib, le resultat 
500         // doit etre une et une seule courbe !!!
501         // De plus, cette courbe ne doit pas etre Single point
502         Standard_Integer NbCurves = Projector.NbCurves();
503         Standard_Real Udeb = 0.,Ufin = 0.;
504         if (NbCurves > 0) {
505           Projector.Bounds(1,Udeb,Ufin);
506         }
507         else {
508           StdFail_NotDone::Raise("ProjLib CompProjectedCurve Not Done");
509         }
510         // Approximons cette courbe algorithmique.
511         Standard_Boolean Only3d = Standard_False;
512         Standard_Boolean Only2d = Standard_True;
513         GeomAbs_Shape Continuity = GeomAbs_C1;
514         Standard_Integer MaxDegree = 14;
515         Standard_Integer MaxSeg    = 16;
516
517         Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, 
518                                    myTolerance, 
519                                    Continuity, MaxDegree, MaxSeg, 
520                                    Only3d, Only2d);
521
522         Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
523
524         if(IsTrimmed[0] || IsTrimmed[1]) {
525           // Treatment only for surface of revolution
526           Standard_Real u1, u2, v1, v2;
527           u1 = mySurface->FirstUParameter();
528           u2 = mySurface->LastUParameter();
529           v1 = mySurface->FirstVParameter();
530           v2 = mySurface->LastVParameter();
531           
532           if(IsTrimmed[0]) {
533             //Add segment before start of curve
534             ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
535           }
536           if(IsTrimmed[1]) {
537             //Add segment after end of curve
538             ExtendC2d(aRes, l, dt, u1, u2, Vsingular[1], v2, 1, 3);
539           }
540           Handle(Geom2d_Curve) NewCurve2d;
541           GeomLib::SameRange(Precision::PConfusion(), aRes,
542                              aRes->FirstParameter(), aRes->LastParameter(),
543                              FirstPar, LastPar,
544                              NewCurve2d);
545           aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
546         }
547           
548         myResult.SetBSpline(aRes);
549         myResult.Done();
550         myResult.SetType(GeomAbs_BSplineCurve);
551       }
552   }
553   if ( !myResult.IsDone()) {
554     ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
555     myResult.Done();
556     
557     // set the type
558     if ( SType == GeomAbs_Plane  &&  CType == GeomAbs_BezierCurve) {
559       myResult.SetType(GeomAbs_BezierCurve);
560       myResult.SetBezier(Comp.Bezier()) ;
561     }
562     else {
563       myResult.SetType(GeomAbs_BSplineCurve);
564       myResult.SetBSpline(Comp.BSpline()) ;
565     }
566     // set the periodicity flag
567     if ( SType == GeomAbs_Plane               && 
568          CType == GeomAbs_BSplineCurve        &&
569          myCurve->IsPeriodic()   ) {
570       myResult.SetPeriodic();
571     }
572     myTolerance = Comp.Tolerance();
573   }
574
575   else {
576     // On remet arbitrairement la tol atteinte a une valeur
577     // petite en attendant mieux. dub lbo 11/03/97
578     myTolerance = Min(myTolerance,Precision::Confusion());
579     
580     // Translate the projected curve to keep the first point
581     // In the canonical boundaries of periodic surfaces.
582     if (mySurface->IsUPeriodic()) {
583       // xf
584       Standard_Real aT1, aT2, aU1, aU2, aUPeriod, aUr, aUm, aUmid, dUm, dUr;
585       GeomAbs_CurveType aTypeR;
586       ProjLib_Projector aResult;
587       //
588       aT1=myCurve->FirstParameter();
589       aT2=myCurve->LastParameter();
590       aU1=mySurface->FirstUParameter();
591       aU2=mySurface->LastUParameter();
592       aUPeriod=mySurface->UPeriod();
593       //
594       aTypeR=myResult.GetType();
595       if ((aU2-aU1)<(aUPeriod-myTolerance) && aTypeR == GeomAbs_Line) {
596         aResult=myResult;
597         aResult.UFrame(aT1, aT2, aU1, aUPeriod);
598         //
599         gp_Lin2d &aLr = (gp_Lin2d &) aResult.Line();
600         aUr=aLr.Location().X();
601         gp_Lin2d &aLm = (gp_Lin2d &) myResult.Line();
602         aUm=aLm.Location().X();
603         //
604         aUmid=0.5*(aU2+aU1);
605         dUm=fabs(aUm-aUmid);
606         dUr=fabs(aUr-aUmid);
607         if (dUr<dUm) {
608           myResult=aResult;
609         }
610       }
611       else {
612         myResult.UFrame(aT1, aT2, aU1, aUPeriod);
613       }
614       //
615       /*
616       myResult.UFrame(myCurve->FirstParameter(),
617                       myCurve->LastParameter(),
618                       mySurface->FirstUParameter(),
619                       mySurface->UPeriod());
620       */
621       //xt
622       //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
623       //  Correct the U isoline in periodical surface
624       // to be inside restriction boundaries.
625       if (myResult.GetType() == GeomAbs_Line) {
626         gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
627
628         Standard_Real aPeriod = mySurface->UPeriod();
629         Standard_Real aFUPar  = mySurface->FirstUParameter();
630         Standard_Real aLUPar  = mySurface->LastUParameter();
631
632         // Check if the parametric range is lower then the period.
633         if (aLUPar - aFUPar < aPeriod - myTolerance) {
634           Standard_Real aU = aLine.Location().X();
635
636           if (Abs(aU + aPeriod - aFUPar) < myTolerance ||
637               Abs(aU - aPeriod - aFUPar) < myTolerance) {
638             gp_Pnt2d aNewLoc(aFUPar, aLine.Location().Y());
639
640             aLine.SetLocation(aNewLoc);
641           } else if (Abs(aU + aPeriod - aLUPar) < myTolerance ||
642                      Abs(aU - aPeriod - aLUPar) < myTolerance) {
643             gp_Pnt2d aNewLoc(aLUPar, aLine.Location().Y());
644
645             aLine.SetLocation(aNewLoc);
646           }
647         }
648       }
649     }
650 //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
651
652     if (mySurface->IsVPeriodic()) {
653       myResult.VFrame(myCurve->FirstParameter(),
654                          myCurve->LastParameter(),
655                          mySurface->FirstVParameter(),
656                          mySurface->VPeriod());
657 //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
658 //  Correct the V isoline in a periodical surface
659 // to be inside restriction boundaries.
660       if (myResult.GetType() == GeomAbs_Line) {
661         gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
662
663         Standard_Real aPeriod = mySurface->VPeriod();
664         Standard_Real aFVPar  = mySurface->FirstVParameter();
665         Standard_Real aLVPar  = mySurface->LastVParameter();
666
667         // Check if the parametric range is lower then the period.
668         if (aLVPar - aFVPar < aPeriod - myTolerance) {
669           Standard_Real aV = aLine.Location().Y();
670
671           if (Abs(aV + aPeriod - aFVPar) < myTolerance ||
672               Abs(aV - aPeriod - aFVPar) < myTolerance) {
673             gp_Pnt2d aNewLoc(aLine.Location().X(), aFVPar);
674
675             aLine.SetLocation(aNewLoc);
676           } else if (Abs(aV + aPeriod - aLVPar) < myTolerance ||
677                      Abs(aV - aPeriod - aLVPar) < myTolerance) {
678             gp_Pnt2d aNewLoc(aLine.Location().X(), aLVPar);
679
680             aLine.SetLocation(aNewLoc);
681           }
682         }
683       }
684     }
685 //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
686   } 
687 }
688
689
690 //=======================================================================
691 //function : GetSurface
692 //purpose  : 
693 //=======================================================================
694
695 const Handle(Adaptor3d_HSurface)& ProjLib_ProjectedCurve::GetSurface() const
696 {
697   return mySurface;
698 }
699
700
701 //=======================================================================
702 //function : GetCurve
703 //purpose  : 
704 //=======================================================================
705
706 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectedCurve::GetCurve() const
707 {
708   return myCurve;
709 }
710
711
712 //=======================================================================
713 //function : GetTolerance
714 //purpose  : 
715 //=======================================================================
716
717 Standard_Real ProjLib_ProjectedCurve::GetTolerance() const 
718 {
719   return myTolerance;
720 }
721
722
723 //=======================================================================
724 //function : FirstParameter
725 //purpose  : 
726 //=======================================================================
727
728 Standard_Real ProjLib_ProjectedCurve::FirstParameter() const 
729 {
730   return myCurve->FirstParameter();
731 }
732
733
734 //=======================================================================
735 //function : LastParameter
736 //purpose  : 
737 //=======================================================================
738
739 Standard_Real ProjLib_ProjectedCurve::LastParameter() const 
740 {
741   return myCurve->LastParameter();
742 }
743
744
745 //=======================================================================
746 //function : Continuity
747 //purpose  : 
748 //=======================================================================
749
750 GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
751 {
752   Standard_NotImplemented::Raise("");
753   return GeomAbs_C0;
754 }
755
756
757 //=======================================================================
758 //function : NbIntervals
759 //purpose  : 
760 //=======================================================================
761
762 Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const 
763 {
764   Standard_NotImplemented::Raise("");
765   return 0;
766 }
767
768
769 //=======================================================================
770 //function : Intervals
771 //purpose  : 
772 //=======================================================================
773
774 //void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  T,
775 void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  ,
776                                        const GeomAbs_Shape ) const 
777 {
778   Standard_NotImplemented::Raise("");
779 }
780
781
782 //=======================================================================
783 //function : IsClosed
784 //purpose  : 
785 //=======================================================================
786
787 Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
788 {
789   Standard_NotImplemented::Raise("");
790   return Standard_True;
791 }
792
793
794 //=======================================================================
795 //function : IsPeriodic
796 //purpose  : 
797 //=======================================================================
798
799 Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
800 {
801   return myResult.IsPeriodic();
802 }
803
804
805 //=======================================================================
806 //function : Period
807 //purpose  : 
808 //=======================================================================
809
810 Standard_Real ProjLib_ProjectedCurve::Period() const
811 {
812   Standard_NotImplemented::Raise("");
813   return 0.;
814 }
815
816
817 //=======================================================================
818 //function : Value
819 //purpose  : 
820 //=======================================================================
821
822 gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const 
823 {
824   Standard_NotImplemented::Raise("");
825   return gp_Pnt2d(0.,0.);
826 }
827
828
829 //=======================================================================
830 //function : D0
831 //purpose  : 
832 //=======================================================================
833
834 void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
835 {
836   Standard_NotImplemented::Raise("");
837 }
838
839
840 //=======================================================================
841 //function : D1
842 //purpose  : 
843 //=======================================================================
844
845 void ProjLib_ProjectedCurve::D1(const Standard_Real ,
846                                       gp_Pnt2d&     , 
847                                       gp_Vec2d&     ) const 
848 {
849   Standard_NotImplemented::Raise("");
850 }
851
852
853 //=======================================================================
854 //function : D2
855 //purpose  : 
856 //=======================================================================
857
858 void ProjLib_ProjectedCurve::D2(const Standard_Real , 
859                                       gp_Pnt2d&     , 
860                                       gp_Vec2d&     , 
861                                       gp_Vec2d&     ) const 
862 {
863   Standard_NotImplemented::Raise("");
864 }
865
866
867 //=======================================================================
868 //function : D3
869 //purpose  : 
870 //=======================================================================
871
872 void ProjLib_ProjectedCurve::D3(const Standard_Real, 
873                                       gp_Pnt2d&, 
874                                       gp_Vec2d&, 
875                                       gp_Vec2d&, 
876                                       gp_Vec2d&) const 
877 {
878   Standard_NotImplemented::Raise("");
879 }
880
881
882 //=======================================================================
883 //function : DN
884 //purpose  : 
885 //=======================================================================
886
887 gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real, 
888                                     const Standard_Integer) const 
889 {
890   Standard_NotImplemented::Raise("");
891   return gp_Vec2d(0.,0.);
892 }
893
894
895 //=======================================================================
896 //function : Resolution
897 //purpose  : 
898 //=======================================================================
899
900 Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const 
901 {
902   Standard_NotImplemented::Raise("");
903   return 0.;
904 }
905     
906
907 //=======================================================================
908 //function : GetType
909 //purpose  : 
910 //=======================================================================
911
912 GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const
913 {
914   return myResult.GetType();
915 }
916
917
918 //=======================================================================
919 //function : Line
920 //purpose  : 
921 //=======================================================================
922
923 gp_Lin2d ProjLib_ProjectedCurve::Line() const
924 {
925   return myResult.Line();
926 }
927
928
929 //=======================================================================
930 //function : Circle
931 //purpose  : 
932 //=======================================================================
933
934 gp_Circ2d ProjLib_ProjectedCurve::Circle() const
935 {
936   return myResult.Circle();
937 }
938
939
940 //=======================================================================
941 //function : Ellipse
942 //purpose  : 
943 //=======================================================================
944
945 gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const
946 {
947   return myResult.Ellipse();
948 }
949
950
951 //=======================================================================
952 //function : Hyperbola
953 //purpose  : 
954 //=======================================================================
955
956 gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const
957 {
958   return myResult.Hyperbola();
959 }
960
961
962 //=======================================================================
963 //function : Parabola
964 //purpose  : 
965 //=======================================================================
966
967 gp_Parab2d ProjLib_ProjectedCurve::Parabola() const
968 {
969   return myResult.Parabola();
970 }
971
972
973
974 //=======================================================================
975 //function : Degree
976 //purpose  : 
977 //=======================================================================
978
979 Standard_Integer ProjLib_ProjectedCurve::Degree() const
980 {
981   Standard_NoSuchObject_Raise_if 
982     ( (GetType() != GeomAbs_BSplineCurve) &&
983       (GetType() != GeomAbs_BezierCurve),
984      "ProjLib_ProjectedCurve:Degree");
985   if (GetType() == GeomAbs_BSplineCurve) {
986     return myResult.BSpline()->Degree();
987   }
988   else if (GetType() == GeomAbs_BezierCurve) {
989     return myResult.Bezier()->Degree();
990   }
991
992   // portage WNT
993   return 0;
994 }
995
996 //=======================================================================
997 //function : IsRational
998 //purpose  : 
999 //=======================================================================
1000
1001 Standard_Boolean ProjLib_ProjectedCurve::IsRational() const 
1002 {
1003   Standard_NoSuchObject_Raise_if 
1004     ( (GetType() != GeomAbs_BSplineCurve) &&
1005       (GetType() != GeomAbs_BezierCurve),
1006      "ProjLib_ProjectedCurve:IsRational");
1007   if (GetType() == GeomAbs_BSplineCurve) {
1008     return myResult.BSpline()->IsRational();
1009   }
1010   else if (GetType() == GeomAbs_BezierCurve) {
1011     return myResult.Bezier()->IsRational();
1012   }
1013   // portage WNT
1014   return Standard_False;
1015 }
1016
1017 //=======================================================================
1018 //function : NbPoles
1019 //purpose  : 
1020 //=======================================================================
1021
1022 Standard_Integer ProjLib_ProjectedCurve::NbPoles() const
1023 {
1024   Standard_NoSuchObject_Raise_if 
1025     ( (GetType() != GeomAbs_BSplineCurve) &&
1026       (GetType() != GeomAbs_BezierCurve)   
1027      ,"ProjLib_ProjectedCurve:NbPoles"  );
1028   if (GetType() == GeomAbs_BSplineCurve) {
1029     return myResult.BSpline()->NbPoles();
1030   }
1031   else if (GetType() == GeomAbs_BezierCurve) {
1032     return myResult.Bezier()->NbPoles();
1033   }
1034
1035   // portage WNT
1036   return 0;
1037 }
1038
1039 //=======================================================================
1040 //function : NbKnots
1041 //purpose  : 
1042 //=======================================================================
1043
1044 Standard_Integer ProjLib_ProjectedCurve::NbKnots() const 
1045 {
1046   Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve, 
1047                                   "ProjLib_ProjectedCurve:NbKnots");
1048   return myResult.BSpline()->NbKnots();
1049 }
1050
1051 //=======================================================================
1052 //function : Bezier
1053 //purpose  : 
1054 //=======================================================================
1055
1056 Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const 
1057 {
1058  return myResult.Bezier() ;
1059 }
1060
1061 //=======================================================================
1062 //function : BSpline
1063 //purpose  : 
1064 //=======================================================================
1065
1066 Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const 
1067 {
1068  return myResult.BSpline() ;
1069 }
1070 //=======================================================================
1071 //function : Trim
1072 //purpose  : 
1073 //=======================================================================
1074
1075 Handle(Adaptor2d_HCurve2d) ProjLib_ProjectedCurve::Trim 
1076 //(const Standard_Real First,
1077 // const Standard_Real Last,
1078 // const Standard_Real Tolerance) const 
1079 (const Standard_Real ,
1080  const Standard_Real ,
1081  const Standard_Real ) const 
1082 {
1083   Standard_NotImplemented::Raise("");
1084   return NULL ;
1085 }
1086