0024513: Suspicious code highlighted by 0024510
[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         {
367           // on met dans la pseudo-periode ( car Sphere n'est pas
368           // periodique en V !)
369           P.SetInBounds(myCurve->FirstParameter());
370         }
371         myResult = P;
372       }
373       break;
374
375     case GeomAbs_Torus:
376       {
377         ProjLib_Torus P(mySurface->Torus());
378         Project(P,myCurve);
379         myResult = P;
380       }
381       break;
382
383     case GeomAbs_BezierSurface:
384     case GeomAbs_BSplineSurface:
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.0, U2=0.0, V1=0.0, V2=0.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         {
403           //Surface has pole at U = Umin
404           gp_Pnt Pole = mySurface->Value(U1, V1);
405           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1);
406         }
407
408         if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance))
409         {
410           //Surface has pole at U = Umax
411           gp_Pnt Pole = mySurface->Value(U2, V1);
412           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2);
413         }
414
415         if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance))
416         {
417           //Surface has pole at V = Vmin
418           gp_Pnt Pole = mySurface->Value(U1, V1);
419           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3);
420         }
421
422         if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance))
423         {
424           //Surface has pole at V = Vmax
425           gp_Pnt Pole = mySurface->Value(U1, V2);
426           TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4);
427         }
428
429         ProjLib_ComputeApproxOnPolarSurface polar(myCurve, mySurface, myTolerance);
430
431         Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
432
433         if(IsTrimmed[0] || IsTrimmed[1])
434         {
435           if(IsTrimmed[0])
436           {
437             //Add segment before start of curve
438             f = myCurve->FirstParameter();
439             ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
440           }
441           if(IsTrimmed[1])
442           {
443             //Add segment after end of curve
444             l = myCurve->LastParameter();
445             ExtendC2d(aRes, l,  dt, U1, U2, V1, V2, 1, SingularCase[1]);
446           }
447           Handle(Geom2d_Curve) NewCurve2d;
448           GeomLib::SameRange(Precision::PConfusion(), aRes,
449                              aRes->FirstParameter(), aRes->LastParameter(),
450                              FirstPar, LastPar, NewCurve2d);
451           aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
452         }
453         myResult.SetBSpline(aRes);
454         myResult.Done();
455         myResult.SetType(GeomAbs_BSplineCurve);
456       }
457       break;
458
459     default:
460       {
461         Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
462         Standard_Real Vsingular[2] = {0.0 , 0.0}; //for surfaces of revolution
463         Standard_Real f = 0.0, l = 0.0, dt = 0.0;
464         const Standard_Real eps = 0.01;
465
466         if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution)
467         {
468           //Check possible singularity
469
470           gp_Pnt P = mySurface->AxeOfRevolution().Location();
471           gp_Dir N = mySurface->AxeOfRevolution().Direction();
472
473           gp_Lin L(P, N);
474
475           f = myCurve->FirstParameter();
476           l = myCurve->LastParameter();
477           dt = (l - f) * eps;
478
479           P = myCurve->Value(f);
480           if(L.Distance(P) < Precision::Confusion())
481           {
482             IsTrimmed[0] = Standard_True;
483             f = f + dt;
484             myCurve = myCurve->Trim(f, l, Precision::Confusion());
485             Vsingular[0] = ElCLib::Parameter(L, P);
486             //SingularCase[0] = 3;
487           }
488
489           P = myCurve->Value(l);
490           if(L.Distance(P) < Precision::Confusion())
491           {
492             IsTrimmed[1] = Standard_True;
493             l = l - dt;
494             myCurve = myCurve->Trim(f, l, Precision::Confusion());
495             Vsingular[1] = ElCLib::Parameter(L, P);
496             //SingularCase[1] = 4;
497           }
498         }
499
500         ProjLib_CompProjectedCurve Projector(mySurface,myCurve, myTolerance, myTolerance);
501         Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
502         HProjector->Set(Projector);
503
504         // Normalement, dans le cadre de ProjLib, le resultat 
505         // doit etre une et une seule courbe !!!
506         // De plus, cette courbe ne doit pas etre Single point
507         Standard_Integer NbCurves = Projector.NbCurves();
508         Standard_Real Udeb = 0.0,Ufin = 0.0;
509         if (NbCurves > 0)
510         {
511           Projector.Bounds(1, Udeb, Ufin);
512         }
513         else 
514         {
515           StdFail_NotDone::Raise("ProjLib CompProjectedCurve Not Done");
516         }
517         // Approximons cette courbe algorithmique.
518         Standard_Boolean Only3d = Standard_False;
519         Standard_Boolean Only2d = Standard_True;
520         GeomAbs_Shape Continuity = GeomAbs_C1;
521         Standard_Integer MaxDegree = 14;
522         Standard_Integer MaxSeg    = 16;
523
524         Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, 
525                                    myTolerance, Continuity, MaxDegree, MaxSeg, 
526                                    Only3d, Only2d);
527
528         Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
529
530         if(IsTrimmed[0] || IsTrimmed[1])
531         {
532           // Treatment only for surface of revolution
533           Standard_Real u1, u2, v1, v2;
534           u1 = mySurface->FirstUParameter();
535           u2 = mySurface->LastUParameter();
536           v1 = mySurface->FirstVParameter();
537           v2 = mySurface->LastVParameter();
538
539           if(IsTrimmed[0])
540           {
541             //Add segment before start of curve
542             ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
543           }
544           if(IsTrimmed[1])
545           {
546             //Add segment after end of curve
547             ExtendC2d(aRes, l,  dt, u1, u2, v1, Vsingular[1], 1, 4);
548           }
549           Handle(Geom2d_Curve) NewCurve2d;
550           GeomLib::SameRange(Precision::PConfusion(), aRes,
551                              aRes->FirstParameter(), aRes->LastParameter(),
552                              FirstPar, LastPar, NewCurve2d);
553           aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
554         }
555
556         myResult.SetBSpline(aRes);
557         myResult.Done();
558         myResult.SetType(GeomAbs_BSplineCurve);
559       }
560   }
561   if ( !myResult.IsDone()) 
562   {
563     ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
564     myResult.Done();
565
566     // set the type
567     if ( SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve)
568     {
569       myResult.SetType(GeomAbs_BezierCurve);
570       myResult.SetBezier(Comp.Bezier()) ;
571     }
572     else
573     {
574       myResult.SetType(GeomAbs_BSplineCurve);
575       myResult.SetBSpline(Comp.BSpline()) ;
576     }
577     // set the periodicity flag
578     if (SType == GeomAbs_Plane        &&
579         CType == GeomAbs_BSplineCurve &&
580         myCurve->IsPeriodic()   )
581     {
582       myResult.SetPeriodic();
583     }
584     myTolerance = Comp.Tolerance();
585   }
586
587   else
588   {
589     // On remet arbitrairement la tol atteinte a une valeur
590     // petite en attendant mieux. dub lbo 11/03/97
591     myTolerance = Min(myTolerance,Precision::Confusion());
592     
593     // Translate the projected curve to keep the first point
594     // In the canonical boundaries of periodic surfaces.
595     if (mySurface->IsUPeriodic())
596     {
597       // xf
598       Standard_Real aT1, aT2, aU1, aU2, aUPeriod, aUr, aUm, aUmid, dUm, dUr;
599       GeomAbs_CurveType aTypeR;
600       ProjLib_Projector aResult;
601       //
602       aT1 = myCurve->FirstParameter();
603       aT2 = myCurve->LastParameter();
604       aU1 = mySurface->FirstUParameter();
605       aU2 = mySurface->LastUParameter();
606       aUPeriod = mySurface->UPeriod();
607       //
608       aTypeR = myResult.GetType();
609       if ((aU2 - aU1) < (aUPeriod - myTolerance) && aTypeR == GeomAbs_Line)
610       {
611         aResult = myResult;
612         aResult.UFrame(aT1, aT2, aU1, aUPeriod);
613         //
614         gp_Lin2d &aLr = (gp_Lin2d &) aResult.Line();
615         aUr=aLr.Location().X();
616         gp_Lin2d &aLm = (gp_Lin2d &) myResult.Line();
617         aUm=aLm.Location().X();
618         //
619         aUmid = 0.5 * (aU2 + aU1);
620         dUm = fabs(aUm - aUmid);
621         dUr = fabs(aUr - aUmid);
622         if (dUr < dUm)
623         {
624           myResult = aResult;
625         }
626       }
627       else
628       {
629         myResult.UFrame(aT1, aT2, aU1, aUPeriod);
630       }
631       //
632       /*
633       myResult.UFrame(myCurve->FirstParameter(),
634       myCurve->LastParameter(),
635       mySurface->FirstUParameter(),
636       mySurface->UPeriod());
637       */
638       //xt
639       //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
640       //  Correct the U isoline in periodical surface
641       // to be inside restriction boundaries.
642       if (myResult.GetType() == GeomAbs_Line)
643       {
644         gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
645
646         Standard_Real aPeriod = mySurface->UPeriod();
647         Standard_Real aFUPar  = mySurface->FirstUParameter();
648         Standard_Real aLUPar  = mySurface->LastUParameter();
649
650         // Check if the parametric range is lower then the period.
651         if (aLUPar - aFUPar < aPeriod - myTolerance)
652         {
653           Standard_Real aU = aLine.Location().X();
654
655           if (Abs(aU + aPeriod - aFUPar) < myTolerance ||
656               Abs(aU - aPeriod - aFUPar) < myTolerance)
657           {
658               gp_Pnt2d aNewLoc(aFUPar, aLine.Location().Y());
659
660               aLine.SetLocation(aNewLoc);
661           }
662           else if (Abs(aU + aPeriod - aLUPar) < myTolerance ||
663                    Abs(aU - aPeriod - aLUPar) < myTolerance)
664           {
665               gp_Pnt2d aNewLoc(aLUPar, aLine.Location().Y());
666               aLine.SetLocation(aNewLoc);
667           }
668         }
669       }
670     }
671     //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
672
673     if (mySurface->IsVPeriodic())
674     {
675       myResult.VFrame(myCurve->FirstParameter(), myCurve->LastParameter(),
676         mySurface->FirstVParameter(), mySurface->VPeriod());
677       //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin
678       //  Correct the V isoline in a periodical surface
679       // to be inside restriction boundaries.
680       if (myResult.GetType() == GeomAbs_Line)
681       {
682         gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line();
683
684         Standard_Real aPeriod = mySurface->VPeriod();
685         Standard_Real aFVPar  = mySurface->FirstVParameter();
686         Standard_Real aLVPar  = mySurface->LastVParameter();
687
688         // Check if the parametric range is lower then the period.
689         if (aLVPar - aFVPar < aPeriod - myTolerance)
690         {
691           Standard_Real aV = aLine.Location().Y();
692
693           if (Abs(aV + aPeriod - aFVPar) < myTolerance ||
694               Abs(aV - aPeriod - aFVPar) < myTolerance)
695           {
696             gp_Pnt2d aNewLoc(aLine.Location().X(), aFVPar);
697             aLine.SetLocation(aNewLoc);
698           }
699           else if (Abs(aV + aPeriod - aLVPar) < myTolerance ||
700                    Abs(aV - aPeriod - aLVPar) < myTolerance)
701           {
702             gp_Pnt2d aNewLoc(aLine.Location().X(), aLVPar);
703             aLine.SetLocation(aNewLoc);
704           }
705         }
706       }
707     }
708     //  Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End
709   } 
710 }
711
712
713 //=======================================================================
714 //function : GetSurface
715 //purpose  : 
716 //=======================================================================
717
718 const Handle(Adaptor3d_HSurface)& ProjLib_ProjectedCurve::GetSurface() const
719 {
720   return mySurface;
721 }
722
723
724 //=======================================================================
725 //function : GetCurve
726 //purpose  : 
727 //=======================================================================
728
729 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectedCurve::GetCurve() const
730 {
731   return myCurve;
732 }
733
734
735 //=======================================================================
736 //function : GetTolerance
737 //purpose  : 
738 //=======================================================================
739
740 Standard_Real ProjLib_ProjectedCurve::GetTolerance() const 
741 {
742   return myTolerance;
743 }
744
745
746 //=======================================================================
747 //function : FirstParameter
748 //purpose  : 
749 //=======================================================================
750
751 Standard_Real ProjLib_ProjectedCurve::FirstParameter() const 
752 {
753   return myCurve->FirstParameter();
754 }
755
756
757 //=======================================================================
758 //function : LastParameter
759 //purpose  : 
760 //=======================================================================
761
762 Standard_Real ProjLib_ProjectedCurve::LastParameter() const 
763 {
764   return myCurve->LastParameter();
765 }
766
767
768 //=======================================================================
769 //function : Continuity
770 //purpose  : 
771 //=======================================================================
772
773 GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
774 {
775   Standard_NotImplemented::Raise("");
776   return GeomAbs_C0;
777 }
778
779
780 //=======================================================================
781 //function : NbIntervals
782 //purpose  : 
783 //=======================================================================
784
785 Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const 
786 {
787   Standard_NotImplemented::Raise("");
788   return 0;
789 }
790
791
792 //=======================================================================
793 //function : Intervals
794 //purpose  : 
795 //=======================================================================
796
797 //void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  T,
798 void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal&  ,
799                                        const GeomAbs_Shape ) const 
800 {
801   Standard_NotImplemented::Raise("");
802 }
803
804
805 //=======================================================================
806 //function : IsClosed
807 //purpose  : 
808 //=======================================================================
809
810 Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
811 {
812   Standard_NotImplemented::Raise("");
813   return Standard_True;
814 }
815
816
817 //=======================================================================
818 //function : IsPeriodic
819 //purpose  : 
820 //=======================================================================
821
822 Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
823 {
824   return myResult.IsPeriodic();
825 }
826
827
828 //=======================================================================
829 //function : Period
830 //purpose  : 
831 //=======================================================================
832
833 Standard_Real ProjLib_ProjectedCurve::Period() const
834 {
835   Standard_NotImplemented::Raise("");
836   return 0.;
837 }
838
839
840 //=======================================================================
841 //function : Value
842 //purpose  : 
843 //=======================================================================
844
845 gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const 
846 {
847   Standard_NotImplemented::Raise("");
848   return gp_Pnt2d(0.,0.);
849 }
850
851
852 //=======================================================================
853 //function : D0
854 //purpose  : 
855 //=======================================================================
856
857 void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
858 {
859   Standard_NotImplemented::Raise("");
860 }
861
862
863 //=======================================================================
864 //function : D1
865 //purpose  : 
866 //=======================================================================
867
868 void ProjLib_ProjectedCurve::D1(const Standard_Real ,
869                                       gp_Pnt2d&     , 
870                                       gp_Vec2d&     ) const 
871 {
872   Standard_NotImplemented::Raise("");
873 }
874
875
876 //=======================================================================
877 //function : D2
878 //purpose  : 
879 //=======================================================================
880
881 void ProjLib_ProjectedCurve::D2(const Standard_Real , 
882                                       gp_Pnt2d&     , 
883                                       gp_Vec2d&     , 
884                                       gp_Vec2d&     ) const 
885 {
886   Standard_NotImplemented::Raise("");
887 }
888
889
890 //=======================================================================
891 //function : D3
892 //purpose  : 
893 //=======================================================================
894
895 void ProjLib_ProjectedCurve::D3(const Standard_Real, 
896                                       gp_Pnt2d&, 
897                                       gp_Vec2d&, 
898                                       gp_Vec2d&, 
899                                       gp_Vec2d&) const 
900 {
901   Standard_NotImplemented::Raise("");
902 }
903
904
905 //=======================================================================
906 //function : DN
907 //purpose  : 
908 //=======================================================================
909
910 gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real, 
911                                     const Standard_Integer) const 
912 {
913   Standard_NotImplemented::Raise("");
914   return gp_Vec2d(0.,0.);
915 }
916
917
918 //=======================================================================
919 //function : Resolution
920 //purpose  : 
921 //=======================================================================
922
923 Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const 
924 {
925   Standard_NotImplemented::Raise("");
926   return 0.;
927 }
928     
929
930 //=======================================================================
931 //function : GetType
932 //purpose  : 
933 //=======================================================================
934
935 GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const
936 {
937   return myResult.GetType();
938 }
939
940
941 //=======================================================================
942 //function : Line
943 //purpose  : 
944 //=======================================================================
945
946 gp_Lin2d ProjLib_ProjectedCurve::Line() const
947 {
948   return myResult.Line();
949 }
950
951
952 //=======================================================================
953 //function : Circle
954 //purpose  : 
955 //=======================================================================
956
957 gp_Circ2d ProjLib_ProjectedCurve::Circle() const
958 {
959   return myResult.Circle();
960 }
961
962
963 //=======================================================================
964 //function : Ellipse
965 //purpose  : 
966 //=======================================================================
967
968 gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const
969 {
970   return myResult.Ellipse();
971 }
972
973
974 //=======================================================================
975 //function : Hyperbola
976 //purpose  : 
977 //=======================================================================
978
979 gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const
980 {
981   return myResult.Hyperbola();
982 }
983
984
985 //=======================================================================
986 //function : Parabola
987 //purpose  : 
988 //=======================================================================
989
990 gp_Parab2d ProjLib_ProjectedCurve::Parabola() const
991 {
992   return myResult.Parabola();
993 }
994
995
996
997 //=======================================================================
998 //function : Degree
999 //purpose  : 
1000 //=======================================================================
1001
1002 Standard_Integer ProjLib_ProjectedCurve::Degree() const
1003 {
1004   Standard_NoSuchObject_Raise_if 
1005     ( (GetType() != GeomAbs_BSplineCurve) &&
1006       (GetType() != GeomAbs_BezierCurve),
1007      "ProjLib_ProjectedCurve:Degree");
1008   if (GetType() == GeomAbs_BSplineCurve) {
1009     return myResult.BSpline()->Degree();
1010   }
1011   else if (GetType() == GeomAbs_BezierCurve) {
1012     return myResult.Bezier()->Degree();
1013   }
1014
1015   // portage WNT
1016   return 0;
1017 }
1018
1019 //=======================================================================
1020 //function : IsRational
1021 //purpose  : 
1022 //=======================================================================
1023
1024 Standard_Boolean ProjLib_ProjectedCurve::IsRational() const 
1025 {
1026   Standard_NoSuchObject_Raise_if 
1027     ( (GetType() != GeomAbs_BSplineCurve) &&
1028       (GetType() != GeomAbs_BezierCurve),
1029      "ProjLib_ProjectedCurve:IsRational");
1030   if (GetType() == GeomAbs_BSplineCurve) {
1031     return myResult.BSpline()->IsRational();
1032   }
1033   else if (GetType() == GeomAbs_BezierCurve) {
1034     return myResult.Bezier()->IsRational();
1035   }
1036   // portage WNT
1037   return Standard_False;
1038 }
1039
1040 //=======================================================================
1041 //function : NbPoles
1042 //purpose  : 
1043 //=======================================================================
1044
1045 Standard_Integer ProjLib_ProjectedCurve::NbPoles() const
1046 {
1047   Standard_NoSuchObject_Raise_if 
1048     ( (GetType() != GeomAbs_BSplineCurve) &&
1049       (GetType() != GeomAbs_BezierCurve)   
1050      ,"ProjLib_ProjectedCurve:NbPoles"  );
1051   if (GetType() == GeomAbs_BSplineCurve) {
1052     return myResult.BSpline()->NbPoles();
1053   }
1054   else if (GetType() == GeomAbs_BezierCurve) {
1055     return myResult.Bezier()->NbPoles();
1056   }
1057
1058   // portage WNT
1059   return 0;
1060 }
1061
1062 //=======================================================================
1063 //function : NbKnots
1064 //purpose  : 
1065 //=======================================================================
1066
1067 Standard_Integer ProjLib_ProjectedCurve::NbKnots() const 
1068 {
1069   Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve, 
1070                                   "ProjLib_ProjectedCurve:NbKnots");
1071   return myResult.BSpline()->NbKnots();
1072 }
1073
1074 //=======================================================================
1075 //function : Bezier
1076 //purpose  : 
1077 //=======================================================================
1078
1079 Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const 
1080 {
1081  return myResult.Bezier() ;
1082 }
1083
1084 //=======================================================================
1085 //function : BSpline
1086 //purpose  : 
1087 //=======================================================================
1088
1089 Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const 
1090 {
1091  return myResult.BSpline() ;
1092 }
1093 //=======================================================================
1094 //function : Trim
1095 //purpose  : 
1096 //=======================================================================
1097
1098 Handle(Adaptor2d_HCurve2d) ProjLib_ProjectedCurve::Trim 
1099 //(const Standard_Real First,
1100 // const Standard_Real Last,
1101 // const Standard_Real Tolerance) const 
1102 (const Standard_Real ,
1103  const Standard_Real ,
1104  const Standard_Real ) const 
1105 {
1106   Standard_NotImplemented::Raise("");
1107   return NULL ;
1108 }
1109