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