0024428: Implementation of LGPL license
[occt.git] / src / ProjLib / ProjLib_ComputeApproxOnPolarSurface.cxx
1 // Created by: Bruno DUMORTIER
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
17 #include <AppCont_Function2d.hxx>
18 #include <ElSLib.hxx>
19 #include <ElCLib.hxx>
20 #include <BSplCLib.hxx>
21 #include <PLib.hxx>
22 #include <Standard_NoSuchObject.hxx>
23 #include <Geom_UndefinedDerivative.hxx>
24 #include <gp_Trsf.hxx>
25 #include <Precision.hxx>
26 #include <Approx_FitAndDivide2d.hxx>
27 #include <math.hxx>
28 #include <AppParCurves_MultiCurve.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom2d_BezierCurve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_Circle.hxx>
34 #include <Geom2d_Ellipse.hxx>
35 #include <Geom2d_Hyperbola.hxx>
36 #include <Geom2d_Parabola.hxx>
37 #include <Geom2d_TrimmedCurve.hxx>
38 #include <Geom_BSplineSurface.hxx>
39 #include <Geom_BezierSurface.hxx>
40 #include <Geom_BSplineCurve.hxx>
41 #include <Geom_BezierCurve.hxx>
42 #include <Geom_TrimmedCurve.hxx>
43
44 #include <TColgp_Array1OfPnt2d.hxx>
45 #include <TColgp_Array2OfPnt2d.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
47 #include <TColgp_SequenceOfPnt2d.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_Array1OfInteger.hxx>
50 #include <TColStd_SequenceOfReal.hxx>
51 #include <TColStd_ListOfTransient.hxx>
52
53 #include <GeomAbs_SurfaceType.hxx>
54 #include <GeomAbs_CurveType.hxx>
55 #include <Handle_Adaptor3d_HCurve.hxx>
56 #include <Handle_Adaptor3d_HSurface.hxx>
57 #include <Adaptor3d_Surface.hxx>
58 #include <Adaptor3d_Curve.hxx>
59 #include <Adaptor3d_HSurface.hxx>
60 #include <Adaptor3d_HCurve.hxx>
61 #include <Adaptor2d_HCurve2d.hxx>
62 #include <Geom2dAdaptor_Curve.hxx>
63 #include <Geom2dAdaptor_HCurve.hxx>
64 #include <GeomAdaptor_HCurve.hxx>
65 #include <GeomAdaptor.hxx>
66 #include <GeomAdaptor_Surface.hxx>
67 #include <TColgp_SequenceOfPnt.hxx>
68
69 #include <gp_Pnt.hxx>
70 #include <gp_Pnt2d.hxx>
71 #include <gp_Vec2d.hxx>
72 #include <Extrema_GenLocateExtPS.hxx>
73 #include <Extrema_ExtPS.hxx>
74 #include <GCPnts_QuasiUniformAbscissa.hxx>
75 #include <Standard_DomainError.hxx>
76 //#include <GeomLib_IsIso.hxx>
77 //#include <GeomLib_CheckSameParameter.hxx>
78
79 #ifdef DEB
80 #ifdef DRAW
81 #include <DrawTrSurf.hxx>
82 #endif
83 //static Standard_Integer compteur = 0;
84 #endif
85
86 //=======================================================================
87 //function : Value
88 //purpose  : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
89 //            <InitCurve2d> use for calculate start 2D point.
90 //=======================================================================
91
92 static gp_Pnt2d Function_Value(const Standard_Real U,
93                                const Handle(Adaptor3d_HSurface)& Surf,    
94                                const Handle(Adaptor3d_HCurve)& Curve,
95                                const Handle(Adaptor2d_HCurve2d)& InitCurve2d,
96                                //OCC217
97                                const Standard_Real DistTol3d, const Standard_Real tolU, const Standard_Real tolV)
98                                //const Standard_Real Tolerance)
99 {
100   //OCC217
101   //Standard_Real Tol3d = 100*Tolerance;
102
103   gp_Pnt2d p2d = InitCurve2d->Value(U) ;
104   gp_Pnt p = Curve->Value(U);
105 //  Curve->D0(U,p) ;
106   Standard_Real Uinf, Usup, Vinf, Vsup;
107   Uinf = Surf->Surface().FirstUParameter();
108   Usup = Surf->Surface().LastUParameter();
109   Vinf = Surf->Surface().FirstVParameter();
110   Vsup = Surf->Surface().LastVParameter();
111   Standard_Integer decalU = 0, decalV = 0;
112   Standard_Real U0 = p2d.X(), V0 = p2d.Y();
113   
114   GeomAbs_SurfaceType Type = Surf->GetType();
115   if((Type != GeomAbs_BSplineSurface) && 
116      (Type != GeomAbs_BezierSurface)  &&
117      (Type != GeomAbs_OffsetSurface)    ) {
118     Standard_Real S = 0., T = 0.;
119     switch (Type) {
120 //    case GeomAbs_Plane:
121 //      {
122 //      gp_Pln Plane = Surf->Plane();
123 //      ElSLib::Parameters( Plane, p, S, T);
124 //      break;
125 //      }
126     case GeomAbs_Cylinder:
127       {
128         gp_Cylinder Cylinder = Surf->Cylinder();
129         ElSLib::Parameters( Cylinder, p, S, T);
130         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
131         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
132         S += decalU*2*M_PI;
133         break;
134       }
135     case GeomAbs_Cone:
136       {
137         gp_Cone Cone = Surf->Cone();
138         ElSLib::Parameters( Cone, p, S, T);
139         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
140         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
141         S += decalU*2*M_PI;
142         break;
143       }
144     case GeomAbs_Sphere:
145       {
146         gp_Sphere Sphere = Surf->Sphere();
147         ElSLib::Parameters( Sphere, p, S, T);
148         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
149         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
150         S += decalU*2*M_PI;
151         if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
152         if(V0 > (Vsup+(Vsup-Vinf))) decalV =  int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
153         T += decalV*2*M_PI;
154         if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI) {
155           T = M_PI - T;
156           if(U0 < S)
157             S -= M_PI;
158           else
159             S += M_PI;
160         }
161         break;
162       }
163     case GeomAbs_Torus:
164       {
165         gp_Torus Torus = Surf->Torus();
166         ElSLib::Parameters( Torus, p, S, T);
167         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
168         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
169         if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
170         if(V0 > Vsup) decalV =  int((V0 - Vsup)/(2*M_PI))+1;
171         S += decalU*2*M_PI; T += decalV*2*M_PI;
172         break;
173       }
174     default:
175       Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::Value");
176     }
177     return gp_Pnt2d(S, T);
178   }
179   
180   //////////////////
181   Standard_Real Dist2Min = RealLast();
182   //OCC217
183   //Standard_Real tolU,tolV ;
184   //tolU = Tolerance;
185   //tolV = Tolerance;
186   
187   Standard_Real uperiod =0, vperiod = 0, u, v;
188   // U0 and V0 are the points within the initialized period 
189   // (periode with u and v),
190   // U1 and V1 are the points for construction of tops
191   
192   if(Surf->IsUPeriodic() || Surf->IsUClosed()) {
193     uperiod =  Surf->LastUParameter() - Surf->FirstUParameter();
194   }
195   if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
196     vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
197   } 
198   if(U0 < Uinf) {
199     if(!uperiod)
200       U0 = Uinf;
201     else {
202       decalU = int((Uinf - U0)/uperiod)+1;
203       U0 += decalU*uperiod;
204     }
205   }
206   if(U0 > Usup) {
207     if(!uperiod)
208       U0 = Usup;
209     else {
210       decalU = -(int((U0 - Usup)/uperiod)+1);
211       U0 += decalU*uperiod;
212     }
213   }
214   if(V0 < Vinf) {
215     if(!vperiod)
216       V0 = Vinf;
217     else {
218       decalV = int((Vinf - V0)/vperiod)+1;
219       V0 += decalV*vperiod;
220     }
221   }
222   if(V0 > Vsup) {
223     if(!vperiod)
224       V0 = Vsup;
225     else {
226       decalV = -int((V0 - Vsup)/vperiod)-1;
227       V0 += decalV*vperiod;
228     }
229   }
230   
231   // The surface around U0 is reduced
232   Standard_Real uLittle = (Usup - Uinf)/10, vLittle = (Vsup - Vinf)/10;
233   Standard_Real uInfLi = 0, vInfLi = 0,uSupLi = 0, vSupLi = 0;
234   if((U0 - Uinf) > uLittle) uInfLi = U0 - uLittle; else uInfLi = Uinf;
235   if((V0 - Vinf) > vLittle) vInfLi = V0 - vLittle; else vInfLi = Vinf;
236   if((Usup - U0) > uLittle) uSupLi = U0 + uLittle; else uSupLi = Usup;
237   if((Vsup - V0) > vLittle) vSupLi = V0 + vLittle; else vSupLi = Vsup;
238   
239   //  const Adaptor3d_Surface GAS = Surf->Surface();
240
241   GeomAdaptor_Surface SurfLittle;
242   if (Type == GeomAbs_BSplineSurface) {
243     Handle(Geom_Surface) GBSS(Surf->Surface().BSpline());
244     SurfLittle.Load(GBSS, uInfLi, uSupLi, vInfLi, vSupLi);
245   }
246   else if (Type == GeomAbs_BezierSurface) {
247     Handle(Geom_Surface) GS(Surf->Surface().Bezier());
248     SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
249   }
250   else if (Type == GeomAbs_OffsetSurface) {
251     Handle(Geom_Surface) GS = GeomAdaptor::MakeSurface(Surf->Surface());
252     SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
253   }
254   else {
255     Standard_NoSuchObject::Raise("");
256   }
257
258   Extrema_GenLocateExtPS  locext(p, SurfLittle, U0, V0, tolU, tolV);
259   if (locext.IsDone()) {
260     Dist2Min = locext.SquareDistance();
261     if (Dist2Min < DistTol3d * DistTol3d) {
262       (locext.Point()).Parameter(u, v);
263       gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
264       return pnt;
265     }
266   } 
267   
268   Extrema_ExtPS  ext(p, SurfLittle, tolU, tolV) ;
269   if (ext.IsDone() && ext.NbExt()>=1 ) {
270     Dist2Min = ext.SquareDistance(1);
271     Standard_Integer GoodValue = 1;
272     for ( Standard_Integer i = 2 ; i <= ext.NbExt() ; i++ ) 
273       if( Dist2Min > ext.SquareDistance(i)) {
274         Dist2Min = ext.SquareDistance(i);
275         GoodValue = i;
276       }
277     if (Dist2Min < DistTol3d * DistTol3d) {
278       (ext.Point(GoodValue)).Parameter(u,v);
279       gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
280       return pnt;
281     }
282   }
283   
284   return p2d;
285 }
286
287
288 //=======================================================================
289 //function : ProjLib_PolarFunction
290 //purpose  : (OCC217 - apo)- This class produce interface to call "gp_Pnt2d Function_Value(...)"
291 //=======================================================================
292
293 class ProjLib_PolarFunction : public AppCont_Function2d
294 {
295   Handle(Adaptor3d_HCurve)           myCurve;
296   Handle(Adaptor2d_HCurve2d)         myInitialCurve2d ;
297   Handle(Adaptor3d_HSurface)         mySurface ;
298   //OCC217
299   Standard_Real                      myTolU, myTolV; 
300   Standard_Real                      myDistTol3d; 
301   //Standard_Real                    myTolerance ; 
302   
303   public :
304   
305   ProjLib_PolarFunction(const Handle(Adaptor3d_HCurve) & C, 
306                         const Handle(Adaptor3d_HSurface)& Surf,
307                         const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
308                         //OCC217
309                         const Standard_Real Tol3d) :
310                         //const Standard_Real Tolerance) :
311   myCurve(C),
312   myInitialCurve2d(InitialCurve2d),
313   mySurface(Surf),
314   //OCC217              
315   myTolU(Surf->UResolution(Tol3d)),
316   myTolV(Surf->VResolution(Tol3d)),
317   myDistTol3d(100.0*Tol3d){} ;
318   //myTolerance(Tolerance){} ;
319   
320   ~ProjLib_PolarFunction() {}
321   
322   Standard_Real FirstParameter() const
323   {return (myCurve->FirstParameter()/*+1.e-9*/);}
324   
325   Standard_Real LastParameter() const
326   {return (myCurve->LastParameter()/*-1.e-9*/);}
327   
328   gp_Pnt2d Value(const Standard_Real t) const {
329     return Function_Value
330       (t,mySurface,myCurve,myInitialCurve2d,myDistTol3d,myTolU,myTolV) ;  //OCC217
331       //(t,mySurface,myCurve,myInitialCurve2d,myTolerance) ;
332   }
333   
334 //  Standard_Boolean D1(const Standard_Real t, gp_Pnt2d& P, gp_Vec2d& V) const
335   Standard_Boolean D1(const Standard_Real , gp_Pnt2d& , gp_Vec2d& ) const
336     {return Standard_False;}
337 };
338
339 //=======================================================================
340 //function : ProjLib_ComputeApproxOnPolarSurface
341 //purpose  : 
342 //=======================================================================
343
344 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface(){}
345
346
347 //=======================================================================
348 //function : ProjLib_ComputeApproxOnPolarSurface
349 //purpose  : 
350 //=======================================================================
351
352 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
353 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
354  const Handle(Adaptor3d_HCurve)& Curve,
355  const Handle(Adaptor3d_HSurface)& S,
356  const Standard_Real tol3d):myProjIsDone(Standard_False)  //OCC217
357  //const Standard_Real tolerance):myProjIsDone(Standard_False)
358 {
359   myTolerance = tol3d; //OCC217
360   //myTolerance = Max(Tolerance,Precision::PApproximation());
361   myBSpline = Perform(InitialCurve2d,Curve,S);
362 }
363 //=======================================================================
364 //function : ProjLib_ComputeApproxOnPolarSurface
365 //purpose  : Process the case of sewing
366 //=======================================================================
367
368 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
369 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
370  const Handle(Adaptor2d_HCurve2d)& InitialCurve2dBis,
371  const Handle(Adaptor3d_HCurve)& Curve,
372  const Handle(Adaptor3d_HSurface)& S,
373  const Standard_Real tol3d):myProjIsDone(Standard_False)  //OCC217
374  //const Standard_Real tolerance):myProjIsDone(Standard_False)
375 {// InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing 
376   myTolerance = tol3d; //OCC217
377   //myTolerance = Max(tolerance,Precision::PApproximation());
378   Handle(Geom2d_BSplineCurve) bsc = Perform(InitialCurve2d,Curve,S);
379   if(myProjIsDone) {
380     gp_Pnt2d P2dproj, P2d, P2dBis;
381     P2dproj = bsc->StartPoint();
382     P2d    = InitialCurve2d->Value(InitialCurve2d->FirstParameter());
383     P2dBis = InitialCurve2dBis->Value(InitialCurve2dBis->FirstParameter());
384
385     Standard_Real Dist, DistBis;
386     Dist    = P2dproj.Distance(P2d);
387     DistBis = P2dproj.Distance(P2dBis);
388     if( Dist < DistBis)  {
389       // myBSpline2d is the pcurve that is found. It is translated to obtain myCurve2d
390       myBSpline = bsc;
391       Handle(Geom2d_Geometry) GG = myBSpline->Translated(P2d, P2dBis);
392       my2ndCurve = Handle(Geom2d_Curve)::DownCast(GG);
393     }
394     else {
395       my2ndCurve = bsc;
396       Handle(Geom2d_Geometry) GG = my2ndCurve->Translated(P2dBis, P2d);
397       myBSpline = Handle(Geom2d_BSplineCurve)::DownCast(GG);
398     }
399   }
400 }
401
402 //=======================================================================
403 //function : ProjLib_ComputeApproxOnPolarSurface
404 //purpose  : case without curve of initialization
405 //=======================================================================
406
407 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
408 (const Handle(Adaptor3d_HCurve)& Curve,
409  const Handle(Adaptor3d_HSurface)& S,
410  const Standard_Real tol3d):myProjIsDone(Standard_False)  //OCC217
411  //const Standard_Real tolerance):myProjIsDone(Standard_False)
412 {
413   myTolerance = tol3d; //OCC217
414   //myTolerance = Max(tolerance,Precision::PApproximation());
415   const Handle_Adaptor2d_HCurve2d InitCurve2d ;
416   myBSpline = Perform(InitCurve2d,Curve,S);  
417
418
419 static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1,
420                                           Handle(Geom2d_BSplineCurve) C2)
421 {
422   Standard_Integer deg, deg1, deg2;
423   deg1 = C1->Degree();
424   deg2 = C2->Degree();
425   
426   if ( deg1 < deg2) {
427     C1->IncreaseDegree(deg2);
428     deg = deg2;
429   }
430   else if ( deg2 < deg1) {
431     C2->IncreaseDegree(deg1);
432     deg = deg1;
433   }
434   else deg = deg1;
435
436   Standard_Integer np1,np2,nk1,nk2,np,nk;
437   np1 = C1->NbPoles();
438   nk1 = C1->NbKnots();
439   np2 = C2->NbPoles();
440   nk2 = C2->NbKnots();
441   nk = nk1 + nk2 -1;
442   np = np1 + np2 -1;
443
444   TColStd_Array1OfReal    K1(1,nk1); C1->Knots(K1);
445   TColStd_Array1OfInteger M1(1,nk1); C1->Multiplicities(M1);
446   TColgp_Array1OfPnt2d    P1(1,np1); C1->Poles(P1);
447   TColStd_Array1OfReal    K2(1,nk2); C2->Knots(K2);
448   TColStd_Array1OfInteger M2(1,nk2); C2->Multiplicities(M2);
449   TColgp_Array1OfPnt2d    P2(1,np2); C2->Poles(P2);
450
451   // Compute the new BSplineCurve
452   TColStd_Array1OfReal    K(1,nk);
453   TColStd_Array1OfInteger M(1,nk);
454   TColgp_Array1OfPnt2d    P(1,np);
455
456   Standard_Integer i, count = 0;
457   // Set Knots and Mults
458   for ( i = 1; i <= nk1; i++) {
459     count++;
460     K(count) = K1(i);
461     M(count) = M1(i);
462   }
463   M(count) = deg;
464   for ( i = 2; i <= nk2; i++) {
465     count++;
466     K(count) = K2(i);
467     M(count) = M2(i);
468   }
469   // Set the Poles
470   count = 0;
471   for (i = 1; i <= np1; i++) {
472     count++;
473     P(count) = P1(i);
474   }
475   for (i = 2; i <= np2; i++) {
476     count++;
477     P(count) = P2(i);
478   }
479
480   Handle(Geom2d_BSplineCurve) BS = 
481     new Geom2d_BSplineCurve(P,K,M,deg);
482   return BS;
483 }
484
485
486 //=======================================================================
487 //function : Perform
488 //purpose  : 
489 //=======================================================================
490 Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
491 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
492  const Handle(Adaptor3d_HCurve)& Curve,
493  const Handle(Adaptor3d_HSurface)& S) 
494 {
495   //OCC217
496   Standard_Real Tol3d = myTolerance; 
497   Standard_Real ParamTol = Precision::PApproximation();
498
499   Handle(Adaptor2d_HCurve2d) AHC2d = InitialCurve2d;
500   Handle(Adaptor3d_HCurve) AHC = Curve;
501   
502 // if the curve 3d is a BSpline with degree C0, it is cut into sections with degree C1
503 // -> bug cts18237
504   GeomAbs_CurveType typeCurve = Curve->GetType();
505   if(typeCurve == GeomAbs_BSplineCurve) {
506     TColStd_ListOfTransient LOfBSpline2d;
507     Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
508     Standard_Integer nbInter = Curve->NbIntervals(GeomAbs_C1);
509     if(nbInter > 1) {
510       Standard_Integer i, j;
511       Handle(Geom_TrimmedCurve) GTC;
512       Handle(Geom2d_TrimmedCurve) G2dTC;
513       TColStd_Array1OfReal Inter(1,nbInter+1);
514       Curve->Intervals(Inter,GeomAbs_C1);
515       Standard_Real firstinter = Inter.Value(1), secondinter = Inter.Value(2);
516       // initialization 3d
517       GTC = new Geom_TrimmedCurve(BSC, firstinter, secondinter);
518       AHC = new GeomAdaptor_HCurve(GTC);
519       
520       // if there is an initialization curve: 
521       // - either this is a BSpline C0, with discontinuity at the same parameters of nodes
522       // and the sections C1 are taken
523       // - or this is a curve C1 and the sections of intrest are taken otherwise the curve is created.
524       
525       // initialization 2d
526       Standard_Integer nbInter2d;
527       Standard_Boolean C2dIsToCompute;
528       C2dIsToCompute = InitialCurve2d.IsNull();
529       Handle(Geom2d_BSplineCurve) BSC2d;
530       Handle(Geom2d_Curve) G2dC;
531       
532       if(!C2dIsToCompute) {
533         nbInter2d = InitialCurve2d->NbIntervals(GeomAbs_C1);
534         TColStd_Array1OfReal Inter2d(1,nbInter2d+1);
535         InitialCurve2d->Intervals(Inter2d,GeomAbs_C1);
536         j = 1;
537         for(i = 1,j = 1;i <= nbInter;i++)
538           if(Abs(Inter.Value(i) - Inter2d.Value(j)) < ParamTol) { //OCC217
539           //if(Abs(Inter.Value(i) - Inter2d.Value(j)) < myTolerance) {
540             if (j > nbInter2d) break;
541             j++;
542           }
543         if(j != (nbInter2d+1)) {
544           C2dIsToCompute = Standard_True;
545         }
546       }
547       
548       if(C2dIsToCompute) {
549         AHC2d = BuildInitialCurve2d(AHC, S);
550       }
551       else {
552         typeCurve = InitialCurve2d->GetType();
553         switch (typeCurve) {
554         case GeomAbs_Line: {
555           G2dC = new Geom2d_Line(InitialCurve2d->Line());
556           break;
557         }
558         case GeomAbs_Circle: {
559           G2dC = new Geom2d_Circle(InitialCurve2d->Circle());
560           break;
561         }
562         case GeomAbs_Ellipse: {
563           G2dC = new Geom2d_Ellipse(InitialCurve2d->Ellipse());
564           break;
565         }
566         case GeomAbs_Hyperbola: {
567           G2dC = new Geom2d_Hyperbola(InitialCurve2d->Hyperbola());
568           break;
569         }
570         case GeomAbs_Parabola: {
571           G2dC = new Geom2d_Parabola(InitialCurve2d->Parabola());
572           break;
573         }
574         case GeomAbs_BezierCurve: {
575           G2dC = InitialCurve2d->Bezier();
576           break;
577         }
578         case GeomAbs_BSplineCurve: {
579           G2dC = InitialCurve2d->BSpline();
580           break;
581         }
582         case GeomAbs_OtherCurve:
583         default:
584           break;
585         }
586         gp_Pnt2d fp2d = G2dC->Value(firstinter), lp2d = G2dC->Value(secondinter);
587         gp_Pnt fps, lps, fpc, lpc;
588         S->D0(fp2d.X(), fp2d.Y(), fps);
589         S->D0(lp2d.X(), lp2d.Y(), lps);
590         Curve->D0(firstinter, fpc);
591         Curve->D0(secondinter, lpc);
592         //OCC217
593         if((fps.IsEqual(fpc, Tol3d)) &&
594            (lps.IsEqual(lpc, Tol3d))) {
595         //if((fps.IsEqual(fpc, myTolerance)) &&
596         //   (lps.IsEqual(lpc, myTolerance))) {
597           G2dTC = new Geom2d_TrimmedCurve(G2dC, firstinter, secondinter);
598           Geom2dAdaptor_Curve G2dAC(G2dTC);
599           AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
600           myProjIsDone = Standard_True;
601         }
602         else {
603           AHC2d = BuildInitialCurve2d(AHC, S);
604           C2dIsToCompute = Standard_True;
605         }
606       }
607         
608       if(myProjIsDone) {
609         BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);  
610         if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV
611         LOfBSpline2d.Append(BSC2d);
612       }
613       else {
614         return Handle(Geom2d_BSplineCurve)();
615       }
616       
617
618
619       Standard_Real iinter, ip1inter;
620       Standard_Integer nbK2d, deg;
621       nbK2d = BSC2d->NbKnots(); deg = BSC2d->Degree();
622
623       for(i = 2;i <= nbInter;i++) {
624         iinter = Inter.Value(i);
625         ip1inter = Inter.Value(i+1);
626         // general case 3d
627         GTC->SetTrim(iinter, ip1inter);
628         AHC = new GeomAdaptor_HCurve(GTC);
629         
630         // general case 2d
631         if(C2dIsToCompute) {
632           AHC2d = BuildInitialCurve2d(AHC, S);
633         }
634         else {
635           gp_Pnt2d fp2d = G2dC->Value(iinter), lp2d = G2dC->Value(ip1inter);
636           gp_Pnt fps, lps, fpc, lpc;
637           S->D0(fp2d.X(), fp2d.Y(), fps);
638           S->D0(lp2d.X(), lp2d.Y(), lps);
639           Curve->D0(iinter, fpc);
640           Curve->D0(ip1inter, lpc);
641           //OCC217
642           if((fps.IsEqual(fpc, Tol3d)) &&
643              (lps.IsEqual(lpc, Tol3d))) {
644           //if((fps.IsEqual(fpc, myTolerance)) &&
645           //   (lps.IsEqual(lpc, myTolerance))) {
646             G2dTC->SetTrim(iinter, ip1inter);
647             Geom2dAdaptor_Curve G2dAC(G2dTC);
648             AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
649             myProjIsDone = Standard_True;
650           }
651           else {
652             AHC2d = BuildInitialCurve2d(AHC, S);
653           }
654         }
655         if(myProjIsDone) {
656           BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);  
657           if(BSC2d.IsNull()) {
658             return Handle(Geom2d_BSplineCurve)();
659           }
660           LOfBSpline2d.Append(BSC2d);
661           nbK2d += BSC2d->NbKnots() - 1;
662           deg = Max(deg, BSC2d->Degree());
663         }
664         else {
665           return Handle(Geom2d_BSplineCurve)();
666         }
667       }
668
669       Standard_Integer NbC = LOfBSpline2d.Extent();
670       Handle(Geom2d_BSplineCurve) CurBS;
671       CurBS = Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
672       LOfBSpline2d.RemoveFirst();
673       for (Standard_Integer ii = 2; ii <= NbC; ii++) {
674         Handle(Geom2d_BSplineCurve) BS = 
675           Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
676         CurBS = Concat(CurBS,BS);
677         LOfBSpline2d.RemoveFirst();
678       }
679       return CurBS;
680     }
681   }
682   
683   if(InitialCurve2d.IsNull()) {
684     AHC2d = BuildInitialCurve2d(Curve, S);
685     if(!myProjIsDone) 
686       return Handle(Geom2d_BSplineCurve)(); 
687   }
688   return ProjectUsingInitialCurve2d(AHC, S, AHC2d);    
689 }
690
691 //=======================================================================
692 //function : ProjLib_BuildInitialCurve2d
693 //purpose  : 
694 //=======================================================================
695
696 Handle(Adaptor2d_HCurve2d) 
697      ProjLib_ComputeApproxOnPolarSurface::
698      BuildInitialCurve2d(const Handle(Adaptor3d_HCurve)&   Curve,
699                          const Handle(Adaptor3d_HSurface)& Surf)
700 {
701   //  discretize the Curve with quasiuniform deflection
702   //  density at least NbOfPnts points
703   myProjIsDone = Standard_False;
704   
705   //OCC217
706   Standard_Real Tol3d = myTolerance; 
707   Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
708   Standard_Real DistTol3d = 100.0*Tol3d;
709
710   Standard_Real uperiod = 0., vperiod = 0.;
711   if(Surf->IsUPeriodic() || Surf->IsUClosed())
712     uperiod = Surf->LastUParameter() - Surf->FirstUParameter(); 
713   
714   if(Surf->IsVPeriodic() || Surf->IsVClosed())
715     vperiod = Surf->LastVParameter() - Surf->FirstVParameter(); 
716
717   
718   // NO myTol is Tol2d !!!!
719   //Standard_Real TolU = myTolerance, TolV = myTolerance;
720   //Standard_Real Tol3d = 100*myTolerance; // At random Balthazar.
721
722   Standard_Integer NbOfPnts = 61; 
723   GCPnts_QuasiUniformAbscissa QUA(Curve->GetCurve(),NbOfPnts);
724   TColgp_Array1OfPnt Pts(1,NbOfPnts);
725   TColStd_Array1OfReal Param(1,NbOfPnts);
726   Standard_Integer i, j;
727   for( i = 1; i <= NbOfPnts ; i++ ) { 
728     Param(i) = QUA.Parameter(i);
729     Pts(i) = Curve->Value(Param(i));
730   }
731   
732   TColgp_Array1OfPnt2d Pts2d(1,NbOfPnts);
733   TColStd_Array1OfInteger Mult(1,NbOfPnts);
734   Mult.Init(1);
735   Mult(1) = Mult(NbOfPnts) = 2;
736   
737   Standard_Real Uinf, Usup, Vinf, Vsup;
738   Uinf = Surf->Surface().FirstUParameter();
739   Usup = Surf->Surface().LastUParameter();
740   Vinf = Surf->Surface().FirstVParameter();
741   Vsup = Surf->Surface().LastVParameter();
742   GeomAbs_SurfaceType Type = Surf->GetType();
743   if((Type != GeomAbs_BSplineSurface) && (Type != GeomAbs_BezierSurface) &&
744      (Type != GeomAbs_OffsetSurface)) {
745     Standard_Real S, T;
746 //    Standard_Integer usens = 0, vsens = 0; 
747     // to know the position relatively to the period
748     switch (Type) {
749 //    case GeomAbs_Plane:
750 //      {
751 //      gp_Pln Plane = Surf->Plane();
752 //      for ( i = 1 ; i <= NbOfPnts ; i++) { 
753 //        ElSLib::Parameters( Plane, Pts(i), S, T);
754 //        Pts2d(i).SetCoord(S,T);
755 //      }
756 //      myProjIsDone = Standard_True;
757 //      break;
758 //      }
759     case GeomAbs_Cylinder:
760       {
761 //      Standard_Real Sloc, Tloc;
762         Standard_Real Sloc;
763         Standard_Integer usens = 0;
764         gp_Cylinder Cylinder = Surf->Cylinder();
765         ElSLib::Parameters( Cylinder, Pts(1), S, T);
766         Pts2d(1).SetCoord(S,T);
767         for ( i = 2 ; i <= NbOfPnts ; i++) { 
768           Sloc = S;
769           ElSLib::Parameters( Cylinder, Pts(i), S, T);
770           if(Abs(Sloc - S) > M_PI) {
771             if(Sloc > S)
772               usens++;
773             else
774               usens--;
775           }
776           Pts2d(i).SetCoord(S+usens*2*M_PI,T);
777         }
778         myProjIsDone = Standard_True;
779         break;
780       }
781     case GeomAbs_Cone:
782       {
783 //      Standard_Real Sloc, Tloc;
784         Standard_Real Sloc;
785         Standard_Integer usens = 0;
786         gp_Cone Cone = Surf->Cone();
787         ElSLib::Parameters( Cone, Pts(1), S, T);
788         Pts2d(1).SetCoord(S,T);
789         for ( i = 2 ; i <= NbOfPnts ; i++) { 
790           Sloc = S;
791           ElSLib::Parameters( Cone, Pts(i), S, T);
792           if(Abs(Sloc - S) > M_PI) {
793             if(Sloc > S)
794               usens++;
795             else
796               usens--;
797           }
798           Pts2d(i).SetCoord(S+usens*2*M_PI,T);
799         }
800         myProjIsDone = Standard_True;
801         break;
802       }
803     case GeomAbs_Sphere:
804       {
805         Standard_Real Sloc, Tloc;
806         Standard_Integer usens = 0, vsens = 0; //usens steps by half-period
807         Standard_Boolean vparit = Standard_False;
808         gp_Sphere Sphere = Surf->Sphere();
809         ElSLib::Parameters( Sphere, Pts(1), S, T);
810         Pts2d(1).SetCoord(S,T);
811         for ( i = 2 ; i <= NbOfPnts ; i++) { 
812           Sloc = S;Tloc = T;
813           ElSLib::Parameters( Sphere, Pts(i), S, T);
814           if(1.6*M_PI < Abs(Sloc - S)) {
815             if(Sloc > S)
816               usens += 2;
817             else
818               usens -= 2;
819     }
820           if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
821             vparit = !vparit;
822             if(Sloc > S)
823               usens++;
824             else
825               usens--;
826             if(Abs(Tloc - Vsup) < (Vsup - Vinf)/5)
827               vsens++;
828             else
829               vsens--;
830           }
831           if(vparit) {
832             Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
833           }       
834           else {
835             Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
836             
837           }
838         }
839         myProjIsDone = Standard_True;
840         break;
841       }
842     case GeomAbs_Torus:
843       {
844         Standard_Real Sloc, Tloc;
845         Standard_Integer usens = 0, vsens = 0;
846         gp_Torus Torus = Surf->Torus();
847         ElSLib::Parameters( Torus, Pts(1), S, T);
848         Pts2d(1).SetCoord(S,T);
849         for ( i = 2 ; i <= NbOfPnts ; i++) { 
850           Sloc = S; Tloc = T;
851           ElSLib::Parameters( Torus, Pts(i), S, T);
852           if(Abs(Sloc - S) > M_PI) {
853             if(Sloc > S)
854               usens++;
855             else
856               usens--;
857     }
858           if(Abs(Tloc - T) > M_PI) {
859             if(Tloc > T)
860               vsens++;
861             else
862               vsens--;
863     }
864           Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
865         }
866         myProjIsDone = Standard_True;
867         break;
868       }
869     default:
870       Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
871     }
872   }
873   else {
874     myProjIsDone = Standard_False;
875     Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
876     gp_Pnt pntproj;
877
878     TColgp_SequenceOfPnt2d Sols;
879     Standard_Boolean areManyZeros = Standard_False;
880     
881     Curve->D0(Param.Value(1), pntproj) ;
882     Extrema_ExtPS  aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
883     Standard_Real aMinSqDist = RealLast();
884     if (aExtPS.IsDone())
885     {
886       for (i = 1; i <= aExtPS.NbExt(); i++)
887       {
888         Standard_Real aSqDist = aExtPS.SquareDistance(i);
889         if (aSqDist < aMinSqDist)
890           aMinSqDist = aSqDist;
891       }
892     }
893     if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
894     {
895       TolU = Min(TolU, Precision::PConfusion());
896       TolV = Min(TolV, Precision::PConfusion());
897       aExtPS.Initialize(Surf->Surface(),
898                         Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(), 
899                         Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
900                         TolU, TolV);
901       aExtPS.Perform(pntproj);
902     }
903
904     if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
905
906       Standard_Integer GoodValue = 1;
907
908       for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
909         if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) {
910           if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
911             aExtPS.Point(i).Parameter(u,v);
912             gp_Pnt2d p2d(u,v);
913             Standard_Boolean isSame = Standard_False;
914             for( j = 1; j <= Sols.Length(); j++ ) {
915               if( p2d.SquareDistance( Sols.Value(j) ) <= 1.e-18 ) {
916                 isSame = Standard_True;
917                 break;
918               }
919             }
920             if( !isSame ) Sols.Append( p2d );
921           }
922           if( Dist2Min > aExtPS.SquareDistance(i) ) {
923             Dist2Min = aExtPS.SquareDistance(i);
924             GoodValue = i;
925           }
926         }
927       }
928
929       if( Sols.Length() > 1 ) areManyZeros = Standard_True;
930
931       if( Dist2Min <= DistTol3d * DistTol3d) {
932         if( !areManyZeros ) {
933           aExtPS.Point(GoodValue).Parameter(u,v);
934           Pts2d(1).SetCoord(u,v);
935           myProjIsDone = Standard_True;
936         }
937         else {
938           Standard_Integer nbSols = Sols.Length();
939           Standard_Real Dist2Max = -1.e+200;
940           for( i = 1; i <= nbSols; i++ ) {
941             const gp_Pnt2d& aP1 = Sols.Value(i);
942             for( j = i+1; j <= nbSols; j++ ) {
943               const gp_Pnt2d& aP2 = Sols.Value(j);
944               Standard_Real aDist2 = aP1.SquareDistance(aP2);
945               if( aDist2 > Dist2Max ) Dist2Max = aDist2;
946             }
947           }
948       Standard_Real aMaxT2 = Max(TolU,TolV);
949       aMaxT2 *= aMaxT2;
950           if( Dist2Max > aMaxT2 ) {
951             Standard_Integer tPp = 0;
952             for( i = 1; i <= 5; i++ ) {
953               Standard_Integer nbExtOk = 0;
954               Standard_Integer indExt = 0;
955               Standard_Integer iT = 1 + (NbOfPnts - 1)/5*i;
956               Curve->D0( Param.Value(iT), pntproj );
957               Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
958               Dist2Min = 1.e+200;
959               if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
960                 for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
961                   if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) {
962                     nbExtOk++;
963                     if( aTPS.SquareDistance(j) < Dist2Min ) {
964                       Dist2Min = aTPS.SquareDistance(j);
965                       indExt = j;
966                     }
967                   }
968                 }
969               }
970               if( nbExtOk == 1 ) {
971                 tPp = iT;
972                 aTPS.Point(indExt).Parameter(u,v);
973                 break;
974               }
975             }
976
977             if( tPp != 0 ) {
978               gp_Pnt2d aPp = gp_Pnt2d(u,v);
979               gp_Pnt2d aPn;
980               j = 1;
981               Standard_Boolean isFound = Standard_False;
982               while( !isFound ) { 
983                 Curve->D0( Param.Value(tPp+j), pntproj );
984                 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
985                 Dist2Min = 1.e+200;
986                 Standard_Integer indExt = 0;
987                 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
988                   for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
989                     if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) {
990                       Dist2Min = aTPS.SquareDistance(i);
991                       indExt = i;
992                       isFound = Standard_True;
993                     }
994                   }
995                 }
996                 if( isFound ) {
997                   aTPS.Point(indExt).Parameter(u,v);
998                   aPn = gp_Pnt2d(u,v);
999                   break;
1000                 }
1001                 j++;
1002                 if( (tPp+j) > NbOfPnts ) break;
1003               }
1004
1005               if( isFound ) {
1006                 gp_Vec2d atV(aPp,aPn);
1007                 Standard_Boolean isChosen = Standard_False;
1008                 for( i = 1; i <= nbSols; i++ ) {
1009                   const gp_Pnt2d& aP1 = Sols.Value(i);
1010                   gp_Vec2d asV(aP1,aPp);
1011                   if( asV.Dot(atV) > 0. ) {
1012                     isChosen = Standard_True;
1013                     Pts2d(1).SetCoord(aP1.X(),aP1.Y());
1014                     myProjIsDone = Standard_True;
1015                     break;
1016                   }
1017                 }
1018                 if( !isChosen ) {
1019                   aExtPS.Point(GoodValue).Parameter(u,v);
1020                   Pts2d(1).SetCoord(u,v);
1021                   myProjIsDone = Standard_True;
1022                 }
1023               }
1024               else {
1025                 aExtPS.Point(GoodValue).Parameter(u,v);
1026                 Pts2d(1).SetCoord(u,v);
1027                 myProjIsDone = Standard_True;
1028               }
1029             }
1030             else {
1031               aExtPS.Point(GoodValue).Parameter(u,v);
1032               Pts2d(1).SetCoord(u,v);
1033               myProjIsDone = Standard_True;
1034             }
1035           }
1036           else {
1037             aExtPS.Point(GoodValue).Parameter(u,v);
1038             Pts2d(1).SetCoord(u,v);
1039             myProjIsDone = Standard_True;
1040           }
1041         }
1042       }
1043       
1044       //  calculate the following points with GenLocate_ExtPS
1045       // (and store the result and each parameter in a sequence)
1046       Standard_Integer usens = 0, vsens = 0; 
1047       // to know the position relatively to the period
1048       Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
1049       // U0 and V0 are the points in the initialized period 
1050       // (period with u and v),
1051       // U1 and V1 are the points for construction of poles
1052
1053       for ( i = 2 ; i <= NbOfPnts ; i++) 
1054         if(myProjIsDone) {
1055           myProjIsDone = Standard_False;
1056           Dist2Min = RealLast();
1057           Curve->D0(Param.Value(i), pntproj);
1058           Extrema_GenLocateExtPS  aLocateExtPS
1059             (pntproj, Surf->Surface(), U0, V0, TolU, TolV) ;
1060           
1061           if (aLocateExtPS.IsDone())
1062             if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1063             //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
1064               (aLocateExtPS.Point()).Parameter(U0,V0);
1065               U1 = U0 + usens*uperiod;
1066               V1 = V0 + vsens*vperiod;
1067               Pts2d(i).SetCoord(U1,V1);
1068               myProjIsDone = Standard_True;
1069             }
1070           if(!myProjIsDone && uperiod) {
1071             Standard_Real Uinf, Usup, Uaux;
1072             Uinf = Surf->Surface().FirstUParameter();
1073             Usup = Surf->Surface().LastUParameter();
1074             if((Usup - U0) > (U0 - Uinf)) 
1075               Uaux = 2*Uinf - U0 + uperiod;
1076             else 
1077               Uaux = 2*Usup - U0 - uperiod;
1078             Extrema_GenLocateExtPS  locext(pntproj, 
1079                                            Surf->Surface(), 
1080                                            Uaux, V0, TolU, TolV);
1081             if (locext.IsDone())
1082               if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1083               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1084                 (locext.Point()).Parameter(u,v);
1085                 if((Usup - U0) > (U0 - Uinf)) 
1086                   usens--;
1087                 else 
1088                   usens++;
1089                 U0 = u; V0 = v;
1090                 U1 = U0 + usens*uperiod;
1091                 V1 = V0 + vsens*vperiod;
1092                 Pts2d(i).SetCoord(U1,V1);
1093                 myProjIsDone = Standard_True;
1094               }
1095           }
1096           if(!myProjIsDone && vperiod) {
1097             Standard_Real Vinf, Vsup, Vaux;
1098             Vinf = Surf->Surface().FirstVParameter();
1099             Vsup = Surf->Surface().LastVParameter();
1100             if((Vsup - V0) > (V0 - Vinf)) 
1101               Vaux = 2*Vinf - V0 + vperiod;
1102             else 
1103               Vaux = 2*Vsup - V0 - vperiod;
1104             Extrema_GenLocateExtPS  locext(pntproj, 
1105                                            Surf->Surface(), 
1106                                            U0, Vaux, TolU, TolV) ;
1107             if (locext.IsDone())
1108               if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1109               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1110                 (locext.Point()).Parameter(u,v);
1111                 if((Vsup - V0) > (V0 - Vinf)) 
1112                   vsens--;
1113                 else 
1114                   vsens++;
1115                 U0 = u; V0 = v;
1116                 U1 = U0 + usens*uperiod;
1117                 V1 = V0 + vsens*vperiod;
1118                 Pts2d(i).SetCoord(U1,V1);
1119                 myProjIsDone = Standard_True;
1120               }
1121           }     
1122           if(!myProjIsDone && uperiod && vperiod) {
1123             Standard_Real Uaux, Vaux;
1124             if((Usup - U0) > (U0 - Uinf)) 
1125               Uaux = 2*Uinf - U0 + uperiod;
1126             else 
1127               Uaux = 2*Usup - U0 - uperiod;
1128             if((Vsup - V0) > (V0 - Vinf)) 
1129               Vaux = 2*Vinf - V0 + vperiod;
1130             else 
1131               Vaux = 2*Vsup - V0 - vperiod;
1132             Extrema_GenLocateExtPS  locext(pntproj, 
1133                                            Surf->Surface(), 
1134                                            Uaux, Vaux, TolU, TolV);
1135             if (locext.IsDone())
1136               if (locext.SquareDistance() < DistTol3d * DistTol3d) {
1137               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1138                 (locext.Point()).Parameter(u,v);
1139                 if((Usup - U0) > (U0 - Uinf)) 
1140                   usens--;
1141                 else 
1142                   usens++;
1143                 if((Vsup - V0) > (V0 - Vinf)) 
1144                   vsens--;
1145                 else 
1146                   vsens++;
1147                 U0 = u; V0 = v;
1148                 U1 = U0 + usens*uperiod;
1149                 V1 = V0 + vsens*vperiod;
1150                 Pts2d(i).SetCoord(U1,V1);
1151                 myProjIsDone = Standard_True;
1152               }
1153           }
1154           if(!myProjIsDone) {
1155             Extrema_ExtPS ext(pntproj, Surf->Surface(), TolU, TolV) ;
1156             if (ext.IsDone()) {
1157               Dist2Min = ext.SquareDistance(1);
1158               Standard_Integer GoodValue = 1;
1159               for ( j = 2 ; j <= ext.NbExt() ; j++ )
1160                 if( Dist2Min > ext.SquareDistance(j)) {
1161                   Dist2Min = ext.SquareDistance(j);
1162                   GoodValue = j;
1163                 }
1164               if (Dist2Min < DistTol3d * DistTol3d) {
1165               //if (Dist2Min < Tol3d * Tol3d) {
1166                 (ext.Point(GoodValue)).Parameter(u,v);
1167                 if(uperiod) {
1168                   if((U0 - u) > (2*uperiod/3)) {
1169                     usens++;
1170                   }
1171                   else
1172                     if((u - U0) > (2*uperiod/3)) {
1173                       usens--;
1174                     }
1175     }
1176                 if(vperiod) {
1177                   if((V0 - v) > (vperiod/2)) {
1178                     vsens++;
1179                   }
1180                   else
1181                     if((v - V0) > (vperiod/2)) {
1182                       vsens--;
1183                     }
1184       }
1185                 U0 = u; V0 = v;
1186                 U1 = U0 + usens*uperiod;
1187                 V1 = V0 + vsens*vperiod;
1188                 Pts2d(i).SetCoord(U1,V1);
1189                 myProjIsDone = Standard_True;
1190               }
1191             }
1192           }
1193         }
1194         else break;
1195     }    
1196   }
1197   // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
1198   if(myProjIsDone) {
1199     myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
1200     //jgv: put the curve into parametric range
1201     gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
1202     Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
1203     Standard_Real sense = 0.;
1204     if (uperiod)
1205     {
1206       if (TestU < Uinf - TolU)
1207         sense = 1.;
1208       else if (TestU > Usup + TolU)
1209         sense = -1;
1210       while (TestU < Uinf - TolU || TestU > Usup + TolU)
1211         TestU += sense * uperiod;
1212     }
1213     if (vperiod)
1214     {
1215       sense = 0.;
1216       if (TestV < Vinf - TolV)
1217         sense = 1.;
1218       else if (TestV > Vsup + TolV)
1219         sense = -1.;
1220       while (TestV < Vinf - TolV || TestV > Vsup + TolV)
1221         TestV += sense * vperiod;
1222     }
1223     gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
1224     if (Abs(Offset.X()) > gp::Resolution() ||
1225         Abs(Offset.Y()) > gp::Resolution())
1226       myBSpline->Translate(Offset);
1227     //////////////////////////////////////////
1228     Geom2dAdaptor_Curve GAC(myBSpline);
1229     Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
1230 #ifdef DEB
1231 //    char name [100];
1232 //    sprintf(name,"%s_%d","build",compteur++);
1233 //    DrawTrSurf::Set(name,myBSpline);
1234 #endif
1235     return IC2d;
1236   }
1237   else {
1238 //  Modified by Sergey KHROMOV - Thu Apr 18 10:57:50 2002 Begin
1239 //     Standard_NoSuchObject_Raise_if(1,"ProjLib_Compu: build echec");
1240 //  Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
1241     return Handle(Adaptor2d_HCurve2d)();
1242   }
1243 //  myProjIsDone = Standard_False;
1244 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
1245 //   Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
1246 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
1247 }
1248
1249
1250
1251
1252 //=======================================================================
1253 //function : ProjLib_ProjectUsingInitialCurve2d
1254 //purpose  : 
1255 //=======================================================================
1256 Handle(Geom2d_BSplineCurve) 
1257      ProjLib_ComputeApproxOnPolarSurface::
1258      ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
1259                                 const Handle(Adaptor3d_HSurface)& Surf,
1260                                 const Handle(Adaptor2d_HCurve2d)& InitCurve2d) 
1261 {  
1262   //OCC217
1263   Standard_Real Tol3d = myTolerance;
1264   Standard_Real DistTol3d = 1.0*Tol3d;
1265   Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
1266   Standard_Real Tol2d = Sqrt(TolU*TolU + TolV*TolV);
1267
1268   Standard_Integer i;
1269   GeomAbs_SurfaceType TheTypeS = Surf->GetType();
1270   GeomAbs_CurveType TheTypeC = Curve->GetType();
1271 //  Handle(Standard_Type) TheTypeS = Surf->DynamicType();
1272 //  Handle(Standard_Type) TheTypeC = Curve->DynamicType();   // si on a :
1273 //  if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
1274   if(TheTypeS == GeomAbs_Plane) {
1275     Standard_Real S, T;
1276     gp_Pln Plane = Surf->Plane();
1277     if(TheTypeC == GeomAbs_BSplineCurve) {
1278       Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1279       TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1280       for(i = 1;i <= Curve->NbPoles();i++) {
1281         ElSLib::Parameters( Plane, BSC->Pole(i), S, T);
1282         Poles2d(i).SetCoord(S,T);
1283       }
1284       TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1285       BSC->Knots(Knots);
1286       TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1287       BSC->Multiplicities(Mults);
1288       if(BSC->IsRational()) {
1289         TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1290         BSC->Weights(Weights); 
1291         return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1292                                        BSC->Degree(), BSC->IsPeriodic()) ;
1293       }
1294       return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1295                                      BSC->Degree(), BSC->IsPeriodic()) ;
1296       
1297     }
1298     if(TheTypeC == GeomAbs_BezierCurve) {
1299       Handle(Geom_BezierCurve) BC = Curve->Bezier();
1300       TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1301       for(i = 1;i <= Curve->NbPoles();i++) {
1302         ElSLib::Parameters( Plane, BC->Pole(i), S, T);
1303         Poles2d(i).SetCoord(S,T);
1304       }
1305       TColStd_Array1OfReal Knots(1, 2);
1306       Knots.SetValue(1,0.0);
1307       Knots.SetValue(2,1.0);
1308       TColStd_Array1OfInteger Mults(1, 2);
1309       Mults.Init(BC->NbPoles());
1310       if(BC->IsRational()) {
1311         TColStd_Array1OfReal Weights(1, BC->NbPoles());
1312         BC->Weights(Weights); 
1313         return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1314                                        BC->Degree(), BC->IsPeriodic()) ;
1315       }
1316       return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1317                                      BC->Degree(), BC->IsPeriodic()) ;
1318     }
1319   }
1320   if(TheTypeS == GeomAbs_BSplineSurface) {
1321     Handle(Geom_BSplineSurface) BSS = Surf->BSpline();
1322     if((BSS->MaxDegree() == 1) &&
1323        (BSS->NbUPoles() == 2) &&
1324        (BSS->NbVPoles() == 2)) {
1325       gp_Pnt p11 = BSS->Pole(1,1);
1326       gp_Pnt p12 = BSS->Pole(1,2);
1327       gp_Pnt p21 = BSS->Pole(2,1);
1328       gp_Pnt p22 = BSS->Pole(2,2);
1329       gp_Vec V1(p11,p12);
1330       gp_Vec V2(p21,p22);
1331       if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){  //OCC217
1332       //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
1333         //  so the polar surface is plane
1334         //  and if it is enough to projet the  poles of Curve
1335         Standard_Integer Dist2Min = IntegerLast();
1336         Standard_Real u,v;
1337         //OCC217
1338         //Standard_Real TolU = Surf->UResolution(myTolerance)
1339         //  , TolV = Surf->VResolution(myTolerance);
1340 //      gp_Pnt pntproj;
1341         if(TheTypeC == GeomAbs_BSplineCurve) {
1342           Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1343           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1344           for(i = 1;i <= Curve->NbPoles();i++) {
1345             myProjIsDone = Standard_False;
1346             Dist2Min = IntegerLast();
1347             Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1348                                             (p11.Y()+p22.Y())/2,TolU,TolV) ;
1349             if (extrloc.IsDone()) {
1350               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1351               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1352               //if (Dist2Min < myTolerance * myTolerance) {
1353                 (extrloc.Point()).Parameter(u,v);
1354                 Poles2d(i).SetCoord(u,v);
1355                 myProjIsDone = Standard_True;
1356               }
1357               else break;
1358             }
1359             else break;
1360             if(!myProjIsDone) 
1361               break;
1362           }
1363           if(myProjIsDone) {
1364             TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1365             BSC->Knots(Knots);
1366             TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1367             BSC->Multiplicities(Mults);
1368             if(BSC->IsRational()) {
1369               TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1370               BSC->Weights(Weights); 
1371               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1372                                              BSC->Degree(), BSC->IsPeriodic()) ;
1373             }
1374             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1375                                            BSC->Degree(), BSC->IsPeriodic()) ;
1376             
1377             
1378           }
1379         } 
1380         if(TheTypeC == GeomAbs_BezierCurve) {
1381           Handle(Geom_BezierCurve) BC = Curve->Bezier();
1382           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1383           for(i = 1;i <= Curve->NbPoles();i++) {
1384             Dist2Min = IntegerLast();
1385             Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
1386                                             0.5,TolU,TolV) ;
1387             if (extrloc.IsDone()) {
1388               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1389               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1390               //if (Dist2Min < myTolerance * myTolerance) {
1391                 (extrloc.Point()).Parameter(u,v);
1392                 Poles2d(i).SetCoord(u,v);
1393                 myProjIsDone = Standard_True;
1394               }
1395               else break;
1396             }
1397             else break;
1398             if(myProjIsDone) 
1399               myProjIsDone = Standard_False;
1400             else break;
1401           }
1402           if(myProjIsDone) {
1403             TColStd_Array1OfReal Knots(1, 2);
1404             Knots.SetValue(1,0.0);
1405             Knots.SetValue(2,1.0);
1406             TColStd_Array1OfInteger Mults(1, 2);
1407             Mults.Init(BC->NbPoles());
1408             if(BC->IsRational()) {
1409               TColStd_Array1OfReal Weights(1, BC->NbPoles());
1410               BC->Weights(Weights); 
1411               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1412                                                     BC->Degree(), BC->IsPeriodic()) ;
1413             }
1414             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1415                                                   BC->Degree(), BC->IsPeriodic()) ;
1416           }
1417         } 
1418       }
1419     }
1420   }
1421   else if(TheTypeS == GeomAbs_BezierSurface) {
1422     Handle(Geom_BezierSurface) BS = Surf->Bezier();
1423     if((BS->MaxDegree() == 1) &&
1424        (BS->NbUPoles() == 2) &&
1425        (BS->NbVPoles() == 2)) {
1426       gp_Pnt p11 = BS->Pole(1,1);
1427       gp_Pnt p12 = BS->Pole(1,2);
1428       gp_Pnt p21 = BS->Pole(2,1);
1429       gp_Pnt p22 = BS->Pole(2,2);
1430       gp_Vec V1(p11,p12);
1431       gp_Vec V2(p21,p22);
1432       if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1433       //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){ 
1434         //    and if it is enough to project the poles of Curve
1435         Standard_Integer Dist2Min = IntegerLast();
1436         Standard_Real u,v;
1437         //OCC217
1438         //Standard_Real TolU = Surf->UResolution(myTolerance)
1439         //  , TolV = Surf->VResolution(myTolerance);
1440
1441 //      gp_Pnt pntproj;
1442         if(TheTypeC == GeomAbs_BSplineCurve) {
1443           Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1444           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1445           for(i = 1;i <= Curve->NbPoles();i++) {
1446             myProjIsDone = Standard_False;
1447             Dist2Min = IntegerLast();
1448             Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1449                                             (p11.Y()+p22.Y())/2,TolU,TolV) ;
1450             if (extrloc.IsDone()) {
1451               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1452               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1453               //if (Dist2Min < myTolerance * myTolerance) {
1454                 (extrloc.Point()).Parameter(u,v);
1455                 Poles2d(i).SetCoord(u,v);
1456                 myProjIsDone = Standard_True;
1457               }
1458               else break;
1459             }
1460             else break;
1461             if(!myProjIsDone) 
1462               break;
1463           }
1464           if(myProjIsDone) {
1465             TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1466             BSC->Knots(Knots);
1467             TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1468             BSC->Multiplicities(Mults);
1469             if(BSC->IsRational()) {
1470               TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1471               BSC->Weights(Weights); 
1472               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1473                                                     BSC->Degree(), BSC->IsPeriodic()) ;
1474             }
1475             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1476                                                   BSC->Degree(), BSC->IsPeriodic()) ;
1477             
1478             
1479           }
1480         } 
1481         if(TheTypeC == GeomAbs_BezierCurve) {
1482           Handle(Geom_BezierCurve) BC = Curve->Bezier();
1483           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1484           for(i = 1;i <= Curve->NbPoles();i++) {
1485             Dist2Min = IntegerLast();
1486             Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
1487                                             0.5,TolU,TolV) ;
1488             if (extrloc.IsDone()) {
1489               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1490               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1491               //if (Dist2Min < myTolerance * myTolerance) {
1492                 (extrloc.Point()).Parameter(u,v);
1493                 Poles2d(i).SetCoord(u,v);
1494                 myProjIsDone = Standard_True;
1495               }
1496               else break;
1497             }
1498             else break;
1499             if(myProjIsDone) 
1500               myProjIsDone = Standard_False;
1501             else break;
1502           }
1503           if(myProjIsDone) {
1504             TColStd_Array1OfReal Knots(1, 2);
1505             Knots.SetValue(1,0.0);
1506             Knots.SetValue(2,1.0);
1507             TColStd_Array1OfInteger Mults(1, 2);
1508             Mults.Init(BC->NbPoles());
1509             if(BC->IsRational()) {
1510               TColStd_Array1OfReal Weights(1, BC->NbPoles());
1511               BC->Weights(Weights); 
1512               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1513                                                     BC->Degree(), BC->IsPeriodic()) ;
1514             }
1515             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1516                                                   BC->Degree(), BC->IsPeriodic()) ;
1517           }
1518         } 
1519       }
1520     }
1521   }
1522
1523   ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ;  //OCC217
1524   //ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ;
1525
1526 #ifdef DEB
1527   Standard_Integer Nb = 50;
1528   
1529   Standard_Real U, U1, U2;
1530   U1 = F.FirstParameter();
1531   U2 = F.LastParameter();
1532   
1533   TColgp_Array1OfPnt2d    DummyPoles(1,Nb+1);
1534   TColStd_Array1OfReal    DummyKnots(1,Nb+1);
1535   TColStd_Array1OfInteger DummyMults(1,Nb+1);
1536   DummyMults.Init(1);
1537   DummyMults(1) = 2;
1538   DummyMults(Nb+1) = 2;
1539   for (Standard_Integer ij = 0; ij <= Nb; ij++) {
1540     U = (Nb-ij)*U1 + ij*U2;
1541     U /= Nb;
1542     DummyPoles(ij+1) = F.Value(U);
1543     DummyKnots(ij+1) = ij;
1544   }
1545   Handle(Geom2d_BSplineCurve) DummyC2d =
1546     new Geom2d_BSplineCurve(DummyPoles, DummyKnots, DummyMults, 1);
1547   Standard_CString Temp = "bs2d";
1548 #ifdef DRAW
1549   DrawTrSurf::Set(Temp,DummyC2d);
1550 #endif
1551 //  DrawTrSurf::Set((Standard_CString ) "bs2d",DummyC2d);
1552   Handle(Geom2dAdaptor_HCurve) DDD = 
1553     Handle(Geom2dAdaptor_HCurve)::DownCast(InitCurve2d);
1554   
1555   Temp = "initc2d";
1556 #ifdef DRAW
1557   DrawTrSurf::Set(Temp,DDD->ChangeCurve2d().Curve());
1558 #endif
1559 //  DrawTrSurf::Set((Standard_CString ) "initc2d",DDD->ChangeCurve2d().Curve());
1560 #endif
1561
1562   Standard_Integer Deg1,Deg2;
1563 //  Deg1 = 8;
1564 //  Deg2 = 8;
1565   Deg1 = 2; //IFV
1566   Deg2 = 8; //IFV 
1567
1568   Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217
1569   //Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
1570                             Standard_True);
1571
1572   if(Fit.IsAllApproximated()) {
1573     Standard_Integer i;
1574     Standard_Integer NbCurves = Fit.NbMultiCurves();
1575     Standard_Integer MaxDeg = 0;
1576     // To transform the MultiCurve into BSpline, it is required that all  
1577     // Bezier constituing it have the same degree -> Calculation of MaxDeg
1578     Standard_Integer NbPoles  = 1;
1579     for (i = 1; i <= NbCurves; i++) {
1580       Standard_Integer Deg = Fit.Value(i).Degree();
1581       MaxDeg = Max ( MaxDeg, Deg);
1582     }
1583
1584     NbPoles = MaxDeg * NbCurves + 1;               //Tops on the BSpline
1585     TColgp_Array1OfPnt2d  Poles( 1, NbPoles);
1586       
1587     TColgp_Array1OfPnt2d TempPoles( 1, MaxDeg + 1);//to augment the degree
1588     
1589     TColStd_Array1OfReal Knots( 1, NbCurves + 1);  //Nodes of the BSpline
1590     
1591     Standard_Integer Compt = 1;
1592     for (i = 1; i <= NbCurves; i++) {
1593       Fit.Parameters(i, Knots(i), Knots(i+1)); 
1594       AppParCurves_MultiCurve MC = Fit.Value( i);       //Load the Ith Curve
1595       TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Retrieve the tops
1596       MC.Curve(1, Poles2d);
1597       
1598       //Eventual augmentation of the degree
1599       Standard_Integer Inc = MaxDeg - MC.Degree();
1600       if ( Inc > 0) {
1601 //      BSplCLib::IncreaseDegree( Inc, Poles2d, PLib::NoWeights(), 
1602         BSplCLib::IncreaseDegree( MaxDeg, Poles2d, PLib::NoWeights(), 
1603                          TempPoles, PLib::NoWeights());
1604         //update of tops of the PCurve
1605         for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1606           Poles.SetValue( Compt, TempPoles( j));
1607           Compt++;
1608         }
1609       }
1610       else {
1611         //update of tops of the PCurve
1612         for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1613           Poles.SetValue( Compt, Poles2d( j));
1614           Compt++;
1615         }
1616       } 
1617       
1618       Compt--;
1619     }
1620     
1621     //update of fields of  ProjLib_Approx
1622     Standard_Integer NbKnots = NbCurves + 1;
1623     
1624     // The start and end nodes are not correct : Cf: opening of the interval
1625     //Knots( 1) -= 1.e-9;
1626     //Knots(NbKnots) += 1.e-9; 
1627     
1628     
1629     TColStd_Array1OfInteger   Mults( 1, NbKnots);
1630     Mults.Init(MaxDeg);
1631     Mults.SetValue( 1, MaxDeg + 1);
1632     Mults.SetValue(NbKnots, MaxDeg + 1);
1633     myProjIsDone = Standard_True;
1634     Handle(Geom2d_BSplineCurve) Dummy =
1635       new Geom2d_BSplineCurve(Poles,Knots,Mults,MaxDeg);
1636     
1637     // try to smoother the Curve GeomAbs_C1.
1638
1639     Standard_Boolean OK = Standard_True;
1640
1641     for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
1642       OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d);  //OCC217
1643       //OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance);
1644     }
1645 #ifdef DEB
1646     if (!OK) {
1647       cout << "ProjLib_ComputeApproxOnPolarSurface : Smoothing echoue"<<endl;
1648     }
1649 #endif 
1650     return Dummy;
1651   }
1652   return Handle(Geom2d_BSplineCurve)();
1653 }
1654
1655 //=======================================================================
1656 //function : BSpline
1657 //purpose  : 
1658 //=======================================================================
1659
1660 Handle(Geom2d_BSplineCurve)  
1661      ProjLib_ComputeApproxOnPolarSurface::BSpline() const 
1662      
1663 {
1664 //  Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End
1665 //   Standard_NoSuchObject_Raise_if
1666 //     (!myProjIsDone,
1667 //      "ProjLib_ComputeApproxOnPolarSurface:BSpline");
1668 //  Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End
1669   return myBSpline ;
1670 }
1671
1672 //=======================================================================
1673 //function : Curve2d
1674 //purpose  : 
1675 //=======================================================================
1676
1677 Handle(Geom2d_Curve)  
1678      ProjLib_ComputeApproxOnPolarSurface::Curve2d() const 
1679      
1680 {
1681   Standard_NoSuchObject_Raise_if
1682     (!myProjIsDone,
1683      "ProjLib_ComputeApproxOnPolarSurface:2ndCurve2d");
1684   return my2ndCurve ;
1685 }
1686
1687
1688 //=======================================================================
1689 //function : IsDone
1690 //purpose  : 
1691 //=======================================================================
1692
1693 Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const 
1694      
1695 {
1696   return myProjIsDone;
1697 }