0023839: Projection algorithm produces wrong results for set of data
[occt.git] / src / ProjLib / ProjLib_ComputeApproxOnPolarSurface.cxx
1 // Created by: Bruno DUMORTIER
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
21 #include <AppCont_Function2d.hxx>
22 #include <ElSLib.hxx>
23 #include <ElCLib.hxx>
24 #include <BSplCLib.hxx>
25 #include <PLib.hxx>
26 #include <Standard_NoSuchObject.hxx>
27 #include <Geom_UndefinedDerivative.hxx>
28 #include <gp_Trsf.hxx>
29 #include <Precision.hxx>
30 #include <Approx_FitAndDivide2d.hxx>
31 #include <math.hxx>
32 #include <AppParCurves_MultiCurve.hxx>
33 #include <Geom_Surface.hxx>
34 #include <Geom2d_BSplineCurve.hxx>
35 #include <Geom2d_BezierCurve.hxx>
36 #include <Geom2d_Line.hxx>
37 #include <Geom2d_Circle.hxx>
38 #include <Geom2d_Ellipse.hxx>
39 #include <Geom2d_Hyperbola.hxx>
40 #include <Geom2d_Parabola.hxx>
41 #include <Geom2d_TrimmedCurve.hxx>
42 #include <Geom_BSplineSurface.hxx>
43 #include <Geom_BezierSurface.hxx>
44 #include <Geom_BSplineCurve.hxx>
45 #include <Geom_BezierCurve.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47
48 #include <TColgp_Array1OfPnt2d.hxx>
49 #include <TColgp_Array2OfPnt2d.hxx>
50 #include <TColgp_Array1OfPnt.hxx>
51 #include <TColgp_SequenceOfPnt2d.hxx>
52 #include <TColStd_Array1OfReal.hxx>
53 #include <TColStd_Array1OfInteger.hxx>
54 #include <TColStd_SequenceOfReal.hxx>
55 #include <TColStd_ListOfTransient.hxx>
56
57 #include <GeomAbs_SurfaceType.hxx>
58 #include <GeomAbs_CurveType.hxx>
59 #include <Handle_Adaptor3d_HCurve.hxx>
60 #include <Handle_Adaptor3d_HSurface.hxx>
61 #include <Adaptor3d_Surface.hxx>
62 #include <Adaptor3d_Curve.hxx>
63 #include <Adaptor3d_HSurface.hxx>
64 #include <Adaptor3d_HCurve.hxx>
65 #include <Adaptor2d_HCurve2d.hxx>
66 #include <Geom2dAdaptor_Curve.hxx>
67 #include <Geom2dAdaptor_HCurve.hxx>
68 #include <GeomAdaptor_HCurve.hxx>
69 #include <GeomAdaptor.hxx>
70 #include <GeomAdaptor_Surface.hxx>
71 #include <TColgp_SequenceOfPnt.hxx>
72
73 #include <gp_Pnt.hxx>
74 #include <gp_Pnt2d.hxx>
75 #include <gp_Vec2d.hxx>
76 #include <Extrema_GenLocateExtPS.hxx>
77 #include <Extrema_ExtPS.hxx>
78 #include <GCPnts_QuasiUniformAbscissa.hxx>
79 #include <Standard_DomainError.hxx>
80 //#include <GeomLib_IsIso.hxx>
81 //#include <GeomLib_CheckSameParameter.hxx>
82
83 #ifdef DEB
84 #ifdef DRAW
85 #include <DrawTrSurf.hxx>
86 #endif
87 //static Standard_Integer compteur = 0;
88 #endif
89
90 //=======================================================================
91 //function : Value
92 //purpose  : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
93 //            <InitCurve2d> use for calculate start 2D point.
94 //=======================================================================
95
96 static gp_Pnt2d Function_Value(const Standard_Real U,
97                                const Handle(Adaptor3d_HSurface)& Surf,    
98                                const Handle(Adaptor3d_HCurve)& Curve,
99                                const Handle(Adaptor2d_HCurve2d)& InitCurve2d,
100                                //OCC217
101                                const Standard_Real DistTol3d, const Standard_Real tolU, const Standard_Real tolV)
102                                //const Standard_Real Tolerance)
103 {
104   //OCC217
105   //Standard_Real Tol3d = 100*Tolerance;
106
107   gp_Pnt2d p2d = InitCurve2d->Value(U) ;
108   gp_Pnt p = Curve->Value(U);
109 //  Curve->D0(U,p) ;
110   Standard_Real Uinf, Usup, Vinf, Vsup;
111   Uinf = Surf->Surface().FirstUParameter();
112   Usup = Surf->Surface().LastUParameter();
113   Vinf = Surf->Surface().FirstVParameter();
114   Vsup = Surf->Surface().LastVParameter();
115   Standard_Integer decalU = 0, decalV = 0;
116   Standard_Real U0 = p2d.X(), V0 = p2d.Y();
117   
118   GeomAbs_SurfaceType Type = Surf->GetType();
119   if((Type != GeomAbs_BSplineSurface) && 
120      (Type != GeomAbs_BezierSurface)  &&
121      (Type != GeomAbs_OffsetSurface)    ) {
122     Standard_Real S, T;
123     switch (Type) {
124 //    case GeomAbs_Plane:
125 //      {
126 //      gp_Pln Plane = Surf->Plane();
127 //      ElSLib::Parameters( Plane, p, S, T);
128 //      break;
129 //      }
130     case GeomAbs_Cylinder:
131       {
132         gp_Cylinder Cylinder = Surf->Cylinder();
133         ElSLib::Parameters( Cylinder, p, S, T);
134         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
135         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
136         S += decalU*2*M_PI;
137         break;
138       }
139     case GeomAbs_Cone:
140       {
141         gp_Cone Cone = Surf->Cone();
142         ElSLib::Parameters( Cone, p, S, T);
143         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
144         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
145         S += decalU*2*M_PI;
146         break;
147       }
148     case GeomAbs_Sphere:
149       {
150         gp_Sphere Sphere = Surf->Sphere();
151         ElSLib::Parameters( Sphere, p, S, T);
152         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
153         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
154         S += decalU*2*M_PI;
155         if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
156         if(V0 > (Vsup+(Vsup-Vinf))) decalV =  int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
157         T += decalV*2*M_PI;
158         if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI) {
159           T = M_PI - T;
160           if(U0 < S)
161             S -= M_PI;
162           else
163             S += M_PI;
164         }
165         break;
166       }
167     case GeomAbs_Torus:
168       {
169         gp_Torus Torus = Surf->Torus();
170         ElSLib::Parameters( Torus, p, S, T);
171         if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
172         if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
173         if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
174         if(V0 > Vsup) decalV =  int((V0 - Vsup)/(2*M_PI))+1;
175         S += decalU*2*M_PI; T += decalV*2*M_PI;
176         break;
177       }
178     default:
179       Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::Value");
180     }
181     return gp_Pnt2d(S, T);
182   }
183   
184   //////////////////
185   Standard_Real Dist2Min = RealLast();
186   //OCC217
187   //Standard_Real tolU,tolV ;
188   //tolU = Tolerance;
189   //tolV = Tolerance;
190   
191   Standard_Real uperiod =0, vperiod = 0, u, v;
192   // U0 and V0 are the points within the initialized period 
193   // (periode with u and v),
194   // U1 and V1 are the points for construction of tops
195   
196   if(Surf->IsUPeriodic() || Surf->IsUClosed()) {
197     uperiod =  Surf->LastUParameter() - Surf->FirstUParameter();
198   }
199   if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
200     vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
201   } 
202   if(U0 < Uinf)
203     if(!uperiod)
204       U0 = Uinf;
205     else {
206       decalU = int((Uinf - U0)/uperiod)+1;
207       U0 += decalU*uperiod;
208     }
209   if(U0 > Usup)
210     if(!uperiod)
211       U0 = Usup;
212     else {
213       decalU = -(int((U0 - Usup)/uperiod)+1);
214       U0 += decalU*uperiod;
215     }
216   if(V0 < Vinf)
217     if(!vperiod)
218       V0 = Vinf;
219     else {
220       decalV = int((Vinf - V0)/vperiod)+1;
221       V0 += decalV*vperiod;
222     }
223   if(V0 > Vsup)
224     if(!vperiod)
225       V0 = Vsup;
226     else {
227       decalV = -int((V0 - Vsup)/vperiod)-1;
228       V0 += decalV*vperiod;
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           Pts2d(i).SetCoord(S+usens*2*M_PI,T);
776         }
777         myProjIsDone = Standard_True;
778         break;
779       }
780     case GeomAbs_Cone:
781       {
782 //      Standard_Real Sloc, Tloc;
783         Standard_Real Sloc;
784         Standard_Integer usens = 0;
785         gp_Cone Cone = Surf->Cone();
786         ElSLib::Parameters( Cone, Pts(1), S, T);
787         Pts2d(1).SetCoord(S,T);
788         for ( i = 2 ; i <= NbOfPnts ; i++) { 
789           Sloc = S;
790           ElSLib::Parameters( Cone, Pts(i), S, T);
791           if(Abs(Sloc - S) > M_PI)
792             if(Sloc > S)
793               usens++;
794             else
795               usens--;
796           Pts2d(i).SetCoord(S+usens*2*M_PI,T);
797         }
798         myProjIsDone = Standard_True;
799         break;
800       }
801     case GeomAbs_Sphere:
802       {
803         Standard_Real Sloc, Tloc;
804         Standard_Integer usens = 0, vsens = 0; //usens steps by half-period
805         Standard_Boolean vparit = Standard_False;
806         gp_Sphere Sphere = Surf->Sphere();
807         ElSLib::Parameters( Sphere, Pts(1), S, T);
808         Pts2d(1).SetCoord(S,T);
809         for ( i = 2 ; i <= NbOfPnts ; i++) { 
810           Sloc = S;Tloc = T;
811           ElSLib::Parameters( Sphere, Pts(i), S, T);
812           if(1.6*M_PI < Abs(Sloc - S))
813             if(Sloc > S)
814               usens += 2;
815             else
816               usens -= 2;
817           if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
818             vparit = !vparit;
819             if(Sloc > S)
820               usens++;
821             else
822               usens--;
823             if(Abs(Tloc - Vsup) < (Vsup - Vinf)/5)
824               vsens++;
825             else
826               vsens--;
827           }
828           if(vparit) {
829             Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
830           }       
831           else {
832             Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
833             
834           }
835         }
836         myProjIsDone = Standard_True;
837         break;
838       }
839     case GeomAbs_Torus:
840       {
841         Standard_Real Sloc, Tloc;
842         Standard_Integer usens = 0, vsens = 0;
843         gp_Torus Torus = Surf->Torus();
844         ElSLib::Parameters( Torus, Pts(1), S, T);
845         Pts2d(1).SetCoord(S,T);
846         for ( i = 2 ; i <= NbOfPnts ; i++) { 
847           Sloc = S; Tloc = T;
848           ElSLib::Parameters( Torus, Pts(i), S, T);
849           if(Abs(Sloc - S) > M_PI)
850             if(Sloc > S)
851               usens++;
852             else
853               usens--;
854           if(Abs(Tloc - T) > M_PI)
855             if(Tloc > T)
856               vsens++;
857             else
858               vsens--;
859           Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
860         }
861         myProjIsDone = Standard_True;
862         break;
863       }
864     default:
865       Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
866     }
867   }
868   else {
869     myProjIsDone = Standard_False;
870     Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
871     gp_Pnt pntproj;
872
873     TColgp_SequenceOfPnt2d Sols;
874     Standard_Boolean areManyZeros = Standard_False;
875     
876     Curve->D0(Param.Value(1), pntproj) ;
877     Extrema_ExtPS  aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
878     Standard_Real aMinSqDist = RealLast();
879     if (aExtPS.IsDone())
880     {
881       for (i = 1; i <= aExtPS.NbExt(); i++)
882       {
883         Standard_Real aSqDist = aExtPS.SquareDistance(i);
884         if (aSqDist < aMinSqDist)
885           aMinSqDist = aSqDist;
886       }
887     }
888     if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
889     {
890       TolU = Min(TolU, Precision::PConfusion());
891       TolV = Min(TolV, Precision::PConfusion());
892       aExtPS.Initialize(Surf->Surface(),
893                         Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(), 
894                         Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
895                         TolU, TolV);
896       aExtPS.Perform(pntproj);
897     }
898
899     if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
900
901       Standard_Integer GoodValue = 1;
902
903       for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
904         if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) {
905           if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
906             aExtPS.Point(i).Parameter(u,v);
907             gp_Pnt2d p2d(u,v);
908             Standard_Boolean isSame = Standard_False;
909             for( j = 1; j <= Sols.Length(); j++ ) {
910               if( p2d.SquareDistance( Sols.Value(j) ) <= 1.e-18 ) {
911                 isSame = Standard_True;
912                 break;
913               }
914             }
915             if( !isSame ) Sols.Append( p2d );
916           }
917           if( Dist2Min > aExtPS.SquareDistance(i) ) {
918             Dist2Min = aExtPS.SquareDistance(i);
919             GoodValue = i;
920           }
921         }
922       }
923
924       if( Sols.Length() > 1 ) areManyZeros = Standard_True;
925
926       if( Dist2Min <= DistTol3d * DistTol3d) {
927         if( !areManyZeros ) {
928           aExtPS.Point(GoodValue).Parameter(u,v);
929           Pts2d(1).SetCoord(u,v);
930           myProjIsDone = Standard_True;
931         }
932         else {
933           Standard_Integer nbSols = Sols.Length();
934           Standard_Real Dist2Max = -1.e+200;
935           for( i = 1; i <= nbSols; i++ ) {
936             const gp_Pnt2d& aP1 = Sols.Value(i);
937             for( j = i+1; j <= nbSols; j++ ) {
938               const gp_Pnt2d& aP2 = Sols.Value(j);
939               Standard_Real aDist2 = aP1.SquareDistance(aP2);
940               if( aDist2 > Dist2Max ) Dist2Max = aDist2;
941             }
942           }
943       Standard_Real aMaxT2 = Max(TolU,TolV);
944       aMaxT2 *= aMaxT2;
945           if( Dist2Max > aMaxT2 ) {
946             Standard_Integer tPp = 0;
947             for( i = 1; i <= 5; i++ ) {
948               Standard_Integer nbExtOk = 0;
949               Standard_Integer indExt = 0;
950               Standard_Integer iT = 1 + (NbOfPnts - 1)/5*i;
951               Curve->D0( Param.Value(iT), pntproj );
952               Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
953               Dist2Min = 1.e+200;
954               if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
955                 for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
956                   if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) {
957                     nbExtOk++;
958                     if( aTPS.SquareDistance(j) < Dist2Min ) {
959                       Dist2Min = aTPS.SquareDistance(j);
960                       indExt = j;
961                     }
962                   }
963                 }
964               }
965               if( nbExtOk == 1 ) {
966                 tPp = iT;
967                 aTPS.Point(indExt).Parameter(u,v);
968                 break;
969               }
970             }
971
972             if( tPp != 0 ) {
973               gp_Pnt2d aPp = gp_Pnt2d(u,v);
974               gp_Pnt2d aPn;
975               j = 1;
976               Standard_Boolean isFound = Standard_False;
977               while( !isFound ) { 
978                 Curve->D0( Param.Value(tPp+j), pntproj );
979                 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
980                 Dist2Min = 1.e+200;
981                 Standard_Integer indExt = 0;
982                 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
983                   for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
984                     if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) {
985                       Dist2Min = aTPS.SquareDistance(i);
986                       indExt = i;
987                       isFound = Standard_True;
988                     }
989                   }
990                 }
991                 if( isFound ) {
992                   aTPS.Point(indExt).Parameter(u,v);
993                   aPn = gp_Pnt2d(u,v);
994                   break;
995                 }
996                 j++;
997                 if( (tPp+j) > NbOfPnts ) break;
998               }
999
1000               if( isFound ) {
1001                 gp_Vec2d atV(aPp,aPn);
1002                 Standard_Boolean isChosen = Standard_False;
1003                 for( i = 1; i <= nbSols; i++ ) {
1004                   const gp_Pnt2d& aP1 = Sols.Value(i);
1005                   gp_Vec2d asV(aP1,aPp);
1006                   if( asV.Dot(atV) > 0. ) {
1007                     isChosen = Standard_True;
1008                     Pts2d(1).SetCoord(aP1.X(),aP1.Y());
1009                     myProjIsDone = Standard_True;
1010                     break;
1011                   }
1012                 }
1013                 if( !isChosen ) {
1014                   aExtPS.Point(GoodValue).Parameter(u,v);
1015                   Pts2d(1).SetCoord(u,v);
1016                   myProjIsDone = Standard_True;
1017                 }
1018               }
1019               else {
1020                 aExtPS.Point(GoodValue).Parameter(u,v);
1021                 Pts2d(1).SetCoord(u,v);
1022                 myProjIsDone = Standard_True;
1023               }
1024             }
1025             else {
1026               aExtPS.Point(GoodValue).Parameter(u,v);
1027               Pts2d(1).SetCoord(u,v);
1028               myProjIsDone = Standard_True;
1029             }
1030           }
1031           else {
1032             aExtPS.Point(GoodValue).Parameter(u,v);
1033             Pts2d(1).SetCoord(u,v);
1034             myProjIsDone = Standard_True;
1035           }
1036         }
1037       }
1038       
1039       //  calculate the following points with GenLocate_ExtPS
1040       // (and store the result and each parameter in a sequence)
1041       Standard_Integer usens = 0, vsens = 0; 
1042       // to know the position relatively to the period
1043       Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
1044       // U0 and V0 are the points in the initialized period 
1045       // (period with u and v),
1046       // U1 and V1 are the points for construction of poles
1047
1048       for ( i = 2 ; i <= NbOfPnts ; i++) 
1049         if(myProjIsDone) {
1050           myProjIsDone = Standard_False;
1051           Dist2Min = RealLast();
1052           Curve->D0(Param.Value(i), pntproj);
1053           Extrema_GenLocateExtPS  aLocateExtPS
1054             (pntproj, Surf->Surface(), U0, V0, TolU, TolV) ;
1055           
1056           if (aLocateExtPS.IsDone())
1057             if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1058             //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
1059               (aLocateExtPS.Point()).Parameter(U0,V0);
1060               U1 = U0 + usens*uperiod;
1061               V1 = V0 + vsens*vperiod;
1062               Pts2d(i).SetCoord(U1,V1);
1063               myProjIsDone = Standard_True;
1064             }
1065           if(!myProjIsDone && uperiod) {
1066             Standard_Real Uinf, Usup, Uaux;
1067             Uinf = Surf->Surface().FirstUParameter();
1068             Usup = Surf->Surface().LastUParameter();
1069             if((Usup - U0) > (U0 - Uinf)) 
1070               Uaux = 2*Uinf - U0 + uperiod;
1071             else 
1072               Uaux = 2*Usup - U0 - uperiod;
1073             Extrema_GenLocateExtPS  locext(pntproj, 
1074                                            Surf->Surface(), 
1075                                            Uaux, V0, TolU, TolV);
1076             if (locext.IsDone())
1077               if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1078               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1079                 (locext.Point()).Parameter(u,v);
1080                 if((Usup - U0) > (U0 - Uinf)) 
1081                   usens--;
1082                 else 
1083                   usens++;
1084                 U0 = u; V0 = v;
1085                 U1 = U0 + usens*uperiod;
1086                 V1 = V0 + vsens*vperiod;
1087                 Pts2d(i).SetCoord(U1,V1);
1088                 myProjIsDone = Standard_True;
1089               }
1090           }
1091           if(!myProjIsDone && vperiod) {
1092             Standard_Real Vinf, Vsup, Vaux;
1093             Vinf = Surf->Surface().FirstVParameter();
1094             Vsup = Surf->Surface().LastVParameter();
1095             if((Vsup - V0) > (V0 - Vinf)) 
1096               Vaux = 2*Vinf - V0 + vperiod;
1097             else 
1098               Vaux = 2*Vsup - V0 - vperiod;
1099             Extrema_GenLocateExtPS  locext(pntproj, 
1100                                            Surf->Surface(), 
1101                                            U0, Vaux, TolU, TolV) ;
1102             if (locext.IsDone())
1103               if (locext.SquareDistance() < DistTol3d * DistTol3d) {  //OCC217
1104               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1105                 (locext.Point()).Parameter(u,v);
1106                 if((Vsup - V0) > (V0 - Vinf)) 
1107                   vsens--;
1108                 else 
1109                   vsens++;
1110                 U0 = u; V0 = v;
1111                 U1 = U0 + usens*uperiod;
1112                 V1 = V0 + vsens*vperiod;
1113                 Pts2d(i).SetCoord(U1,V1);
1114                 myProjIsDone = Standard_True;
1115               }
1116           }     
1117           if(!myProjIsDone && uperiod && vperiod) {
1118             Standard_Real Uaux, Vaux;
1119             if((Usup - U0) > (U0 - Uinf)) 
1120               Uaux = 2*Uinf - U0 + uperiod;
1121             else 
1122               Uaux = 2*Usup - U0 - uperiod;
1123             if((Vsup - V0) > (V0 - Vinf)) 
1124               Vaux = 2*Vinf - V0 + vperiod;
1125             else 
1126               Vaux = 2*Vsup - V0 - vperiod;
1127             Extrema_GenLocateExtPS  locext(pntproj, 
1128                                            Surf->Surface(), 
1129                                            Uaux, Vaux, TolU, TolV);
1130             if (locext.IsDone())
1131               if (locext.SquareDistance() < DistTol3d * DistTol3d) {
1132               //if (locext.SquareDistance() < Tol3d * Tol3d) {
1133                 (locext.Point()).Parameter(u,v);
1134                 if((Usup - U0) > (U0 - Uinf)) 
1135                   usens--;
1136                 else 
1137                   usens++;
1138                 if((Vsup - V0) > (V0 - Vinf)) 
1139                   vsens--;
1140                 else 
1141                   vsens++;
1142                 U0 = u; V0 = v;
1143                 U1 = U0 + usens*uperiod;
1144                 V1 = V0 + vsens*vperiod;
1145                 Pts2d(i).SetCoord(U1,V1);
1146                 myProjIsDone = Standard_True;
1147               }
1148           }
1149           if(!myProjIsDone) {
1150             Extrema_ExtPS ext(pntproj, Surf->Surface(), TolU, TolV) ;
1151             if (ext.IsDone()) {
1152               Dist2Min = ext.SquareDistance(1);
1153               Standard_Integer GoodValue = 1;
1154               for ( j = 2 ; j <= ext.NbExt() ; j++ )
1155                 if( Dist2Min > ext.SquareDistance(j)) {
1156                   Dist2Min = ext.SquareDistance(j);
1157                   GoodValue = j;
1158                 }
1159               if (Dist2Min < DistTol3d * DistTol3d) {
1160               //if (Dist2Min < Tol3d * Tol3d) {
1161                 (ext.Point(GoodValue)).Parameter(u,v);
1162                 if(uperiod)
1163                   if((U0 - u) > (2*uperiod/3)) {
1164                     usens++;
1165                   }
1166                   else
1167                     if((u - U0) > (2*uperiod/3)) {
1168                       usens--;
1169                     }
1170                 if(vperiod)
1171                   if((V0 - v) > (vperiod/2)) {
1172                     vsens++;
1173                   }
1174                   else
1175                     if((v - V0) > (vperiod/2)) {
1176                       vsens--;
1177                     }
1178                 U0 = u; V0 = v;
1179                 U1 = U0 + usens*uperiod;
1180                 V1 = V0 + vsens*vperiod;
1181                 Pts2d(i).SetCoord(U1,V1);
1182                 myProjIsDone = Standard_True;
1183               }
1184             }
1185           }
1186         }
1187         else break;
1188     }    
1189   }
1190   // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
1191   if(myProjIsDone) {
1192     myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
1193     //jgv: put the curve into parametric range
1194     gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
1195     Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
1196     Standard_Real sense = 0.;
1197     if (uperiod)
1198     {
1199       if (TestU < Uinf - TolU)
1200         sense = 1.;
1201       else if (TestU > Usup + TolU)
1202         sense = -1;
1203       while (TestU < Uinf - TolU || TestU > Usup + TolU)
1204         TestU += sense * uperiod;
1205     }
1206     if (vperiod)
1207     {
1208       sense = 0.;
1209       if (TestV < Vinf - TolV)
1210         sense = 1.;
1211       else if (TestV > Vsup + TolV)
1212         sense = -1.;
1213       while (TestV < Vinf - TolV || TestV > Vsup + TolV)
1214         TestV += sense * vperiod;
1215     }
1216     gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
1217     if (Abs(Offset.X()) > gp::Resolution() ||
1218         Abs(Offset.Y()) > gp::Resolution())
1219       myBSpline->Translate(Offset);
1220     //////////////////////////////////////////
1221     Geom2dAdaptor_Curve GAC(myBSpline);
1222     Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
1223 #ifdef DEB
1224 //    char name [100];
1225 //    sprintf(name,"%s_%d","build",compteur++);
1226 //    DrawTrSurf::Set(name,myBSpline);
1227 #endif
1228     return IC2d;
1229   }
1230   else {
1231 //  Modified by Sergey KHROMOV - Thu Apr 18 10:57:50 2002 Begin
1232 //     Standard_NoSuchObject_Raise_if(1,"ProjLib_Compu: build echec");
1233 //  Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
1234     return Handle(Adaptor2d_HCurve2d)();
1235   }
1236 //  myProjIsDone = Standard_False;
1237 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
1238 //   Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
1239 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
1240 }
1241
1242
1243
1244
1245 //=======================================================================
1246 //function : ProjLib_ProjectUsingInitialCurve2d
1247 //purpose  : 
1248 //=======================================================================
1249 Handle(Geom2d_BSplineCurve) 
1250      ProjLib_ComputeApproxOnPolarSurface::
1251      ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
1252                                 const Handle(Adaptor3d_HSurface)& Surf,
1253                                 const Handle(Adaptor2d_HCurve2d)& InitCurve2d) 
1254 {  
1255   //OCC217
1256   Standard_Real Tol3d = myTolerance;
1257   Standard_Real DistTol3d = 1.0*Tol3d;
1258   Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
1259   Standard_Real Tol2d = Sqrt(TolU*TolU + TolV*TolV);
1260
1261   Standard_Integer i;
1262   GeomAbs_SurfaceType TheTypeS = Surf->GetType();
1263   GeomAbs_CurveType TheTypeC = Curve->GetType();
1264 //  Handle(Standard_Type) TheTypeS = Surf->DynamicType();
1265 //  Handle(Standard_Type) TheTypeC = Curve->DynamicType();   // si on a :
1266 //  if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
1267   if(TheTypeS == GeomAbs_Plane) {
1268     Standard_Real S, T;
1269     gp_Pln Plane = Surf->Plane();
1270     if(TheTypeC == GeomAbs_BSplineCurve) {
1271       Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1272       TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1273       for(i = 1;i <= Curve->NbPoles();i++) {
1274         ElSLib::Parameters( Plane, BSC->Pole(i), S, T);
1275         Poles2d(i).SetCoord(S,T);
1276       }
1277       TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1278       BSC->Knots(Knots);
1279       TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1280       BSC->Multiplicities(Mults);
1281       if(BSC->IsRational()) {
1282         TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1283         BSC->Weights(Weights); 
1284         return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1285                                        BSC->Degree(), BSC->IsPeriodic()) ;
1286       }
1287       return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1288                                      BSC->Degree(), BSC->IsPeriodic()) ;
1289       
1290     }
1291     if(TheTypeC == GeomAbs_BezierCurve) {
1292       Handle(Geom_BezierCurve) BC = Curve->Bezier();
1293       TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1294       for(i = 1;i <= Curve->NbPoles();i++) {
1295         ElSLib::Parameters( Plane, BC->Pole(i), S, T);
1296         Poles2d(i).SetCoord(S,T);
1297       }
1298       TColStd_Array1OfReal Knots(1, 2);
1299       Knots.SetValue(1,0.0);
1300       Knots.SetValue(2,1.0);
1301       TColStd_Array1OfInteger Mults(1, 2);
1302       Mults.Init(BC->NbPoles());
1303       if(BC->IsRational()) {
1304         TColStd_Array1OfReal Weights(1, BC->NbPoles());
1305         BC->Weights(Weights); 
1306         return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1307                                        BC->Degree(), BC->IsPeriodic()) ;
1308       }
1309       return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1310                                      BC->Degree(), BC->IsPeriodic()) ;
1311     }
1312   }
1313   if(TheTypeS == GeomAbs_BSplineSurface) {
1314     Handle(Geom_BSplineSurface) BSS = Surf->BSpline();
1315     if((BSS->MaxDegree() == 1) &&
1316        (BSS->NbUPoles() == 2) &&
1317        (BSS->NbVPoles() == 2)) {
1318       gp_Pnt p11 = BSS->Pole(1,1);
1319       gp_Pnt p12 = BSS->Pole(1,2);
1320       gp_Pnt p21 = BSS->Pole(2,1);
1321       gp_Pnt p22 = BSS->Pole(2,2);
1322       gp_Vec V1(p11,p12);
1323       gp_Vec V2(p21,p22);
1324       if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){  //OCC217
1325       //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
1326         //  so the polar surface is plane
1327         //  and if it is enough to projet the  poles of Curve
1328         Standard_Integer Dist2Min = IntegerLast();
1329         Standard_Real u,v;
1330         //OCC217
1331         //Standard_Real TolU = Surf->UResolution(myTolerance)
1332         //  , TolV = Surf->VResolution(myTolerance);
1333 //      gp_Pnt pntproj;
1334         if(TheTypeC == GeomAbs_BSplineCurve) {
1335           Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1336           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1337           for(i = 1;i <= Curve->NbPoles();i++) {
1338             myProjIsDone = Standard_False;
1339             Dist2Min = IntegerLast();
1340             Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1341                                             (p11.Y()+p22.Y())/2,TolU,TolV) ;
1342             if (extrloc.IsDone()) {
1343               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1344               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1345               //if (Dist2Min < myTolerance * myTolerance) {
1346                 (extrloc.Point()).Parameter(u,v);
1347                 Poles2d(i).SetCoord(u,v);
1348                 myProjIsDone = Standard_True;
1349               }
1350               else break;
1351             }
1352             else break;
1353             if(!myProjIsDone) 
1354               break;
1355           }
1356           if(myProjIsDone) {
1357             TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1358             BSC->Knots(Knots);
1359             TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1360             BSC->Multiplicities(Mults);
1361             if(BSC->IsRational()) {
1362               TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1363               BSC->Weights(Weights); 
1364               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1365                                              BSC->Degree(), BSC->IsPeriodic()) ;
1366             }
1367             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1368                                            BSC->Degree(), BSC->IsPeriodic()) ;
1369             
1370             
1371           }
1372         } 
1373         if(TheTypeC == GeomAbs_BezierCurve) {
1374           Handle(Geom_BezierCurve) BC = Curve->Bezier();
1375           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1376           for(i = 1;i <= Curve->NbPoles();i++) {
1377             Dist2Min = IntegerLast();
1378             Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
1379                                             0.5,TolU,TolV) ;
1380             if (extrloc.IsDone()) {
1381               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1382               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1383               //if (Dist2Min < myTolerance * myTolerance) {
1384                 (extrloc.Point()).Parameter(u,v);
1385                 Poles2d(i).SetCoord(u,v);
1386                 myProjIsDone = Standard_True;
1387               }
1388               else break;
1389             }
1390             else break;
1391             if(myProjIsDone) 
1392               myProjIsDone = Standard_False;
1393             else break;
1394           }
1395           if(myProjIsDone) {
1396             TColStd_Array1OfReal Knots(1, 2);
1397             Knots.SetValue(1,0.0);
1398             Knots.SetValue(2,1.0);
1399             TColStd_Array1OfInteger Mults(1, 2);
1400             Mults.Init(BC->NbPoles());
1401             if(BC->IsRational()) {
1402               TColStd_Array1OfReal Weights(1, BC->NbPoles());
1403               BC->Weights(Weights); 
1404               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1405                                                     BC->Degree(), BC->IsPeriodic()) ;
1406             }
1407             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1408                                                   BC->Degree(), BC->IsPeriodic()) ;
1409           }
1410         } 
1411       }
1412     }
1413   }
1414   else if(TheTypeS == GeomAbs_BezierSurface) {
1415     Handle(Geom_BezierSurface) BS = Surf->Bezier();
1416     if((BS->MaxDegree() == 1) &&
1417        (BS->NbUPoles() == 2) &&
1418        (BS->NbVPoles() == 2)) {
1419       gp_Pnt p11 = BS->Pole(1,1);
1420       gp_Pnt p12 = BS->Pole(1,2);
1421       gp_Pnt p21 = BS->Pole(2,1);
1422       gp_Pnt p22 = BS->Pole(2,2);
1423       gp_Vec V1(p11,p12);
1424       gp_Vec V2(p21,p22);
1425       if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1426       //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){ 
1427         //    and if it is enough to project the poles of Curve
1428         Standard_Integer Dist2Min = IntegerLast();
1429         Standard_Real u,v;
1430         //OCC217
1431         //Standard_Real TolU = Surf->UResolution(myTolerance)
1432         //  , TolV = Surf->VResolution(myTolerance);
1433
1434 //      gp_Pnt pntproj;
1435         if(TheTypeC == GeomAbs_BSplineCurve) {
1436           Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1437           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1438           for(i = 1;i <= Curve->NbPoles();i++) {
1439             myProjIsDone = Standard_False;
1440             Dist2Min = IntegerLast();
1441             Extrema_GenLocateExtPS  extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1442                                             (p11.Y()+p22.Y())/2,TolU,TolV) ;
1443             if (extrloc.IsDone()) {
1444               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1445               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1446               //if (Dist2Min < myTolerance * myTolerance) {
1447                 (extrloc.Point()).Parameter(u,v);
1448                 Poles2d(i).SetCoord(u,v);
1449                 myProjIsDone = Standard_True;
1450               }
1451               else break;
1452             }
1453             else break;
1454             if(!myProjIsDone) 
1455               break;
1456           }
1457           if(myProjIsDone) {
1458             TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1459             BSC->Knots(Knots);
1460             TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1461             BSC->Multiplicities(Mults);
1462             if(BSC->IsRational()) {
1463               TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1464               BSC->Weights(Weights); 
1465               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1466                                                     BSC->Degree(), BSC->IsPeriodic()) ;
1467             }
1468             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1469                                                   BSC->Degree(), BSC->IsPeriodic()) ;
1470             
1471             
1472           }
1473         } 
1474         if(TheTypeC == GeomAbs_BezierCurve) {
1475           Handle(Geom_BezierCurve) BC = Curve->Bezier();
1476           TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1477           for(i = 1;i <= Curve->NbPoles();i++) {
1478             Dist2Min = IntegerLast();
1479             Extrema_GenLocateExtPS  extrloc(BC->Pole(i),Surf->Surface(),0.5,
1480                                             0.5,TolU,TolV) ;
1481             if (extrloc.IsDone()) {
1482               Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1483               if (Dist2Min < DistTol3d * DistTol3d) {  //OCC217
1484               //if (Dist2Min < myTolerance * myTolerance) {
1485                 (extrloc.Point()).Parameter(u,v);
1486                 Poles2d(i).SetCoord(u,v);
1487                 myProjIsDone = Standard_True;
1488               }
1489               else break;
1490             }
1491             else break;
1492             if(myProjIsDone) 
1493               myProjIsDone = Standard_False;
1494             else break;
1495           }
1496           if(myProjIsDone) {
1497             TColStd_Array1OfReal Knots(1, 2);
1498             Knots.SetValue(1,0.0);
1499             Knots.SetValue(2,1.0);
1500             TColStd_Array1OfInteger Mults(1, 2);
1501             Mults.Init(BC->NbPoles());
1502             if(BC->IsRational()) {
1503               TColStd_Array1OfReal Weights(1, BC->NbPoles());
1504               BC->Weights(Weights); 
1505               return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1506                                                     BC->Degree(), BC->IsPeriodic()) ;
1507             }
1508             return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1509                                                   BC->Degree(), BC->IsPeriodic()) ;
1510           }
1511         } 
1512       }
1513     }
1514   }
1515
1516   ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ;  //OCC217
1517   //ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ;
1518
1519 #ifdef DEB
1520   Standard_Integer Nb = 50;
1521   
1522   Standard_Real U, U1, U2;
1523   U1 = F.FirstParameter();
1524   U2 = F.LastParameter();
1525   
1526   TColgp_Array1OfPnt2d    DummyPoles(1,Nb+1);
1527   TColStd_Array1OfReal    DummyKnots(1,Nb+1);
1528   TColStd_Array1OfInteger DummyMults(1,Nb+1);
1529   DummyMults.Init(1);
1530   DummyMults(1) = 2;
1531   DummyMults(Nb+1) = 2;
1532   for (Standard_Integer ij = 0; ij <= Nb; ij++) {
1533     U = (Nb-ij)*U1 + ij*U2;
1534     U /= Nb;
1535     DummyPoles(ij+1) = F.Value(U);
1536     DummyKnots(ij+1) = ij;
1537   }
1538   Handle(Geom2d_BSplineCurve) DummyC2d =
1539     new Geom2d_BSplineCurve(DummyPoles, DummyKnots, DummyMults, 1);
1540   Standard_CString Temp = "bs2d";
1541 #ifdef DRAW
1542   DrawTrSurf::Set(Temp,DummyC2d);
1543 #endif
1544 //  DrawTrSurf::Set((Standard_CString ) "bs2d",DummyC2d);
1545   Handle(Geom2dAdaptor_HCurve) DDD = 
1546     Handle(Geom2dAdaptor_HCurve)::DownCast(InitCurve2d);
1547   
1548   Temp = "initc2d";
1549 #ifdef DRAW
1550   DrawTrSurf::Set(Temp,DDD->ChangeCurve2d().Curve());
1551 #endif
1552 //  DrawTrSurf::Set((Standard_CString ) "initc2d",DDD->ChangeCurve2d().Curve());
1553 #endif
1554
1555   Standard_Integer Deg1,Deg2;
1556 //  Deg1 = 8;
1557 //  Deg2 = 8;
1558   Deg1 = 2; //IFV
1559   Deg2 = 8; //IFV 
1560
1561   Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217
1562   //Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
1563                             Standard_True);
1564
1565   if(Fit.IsAllApproximated()) {
1566     Standard_Integer i;
1567     Standard_Integer NbCurves = Fit.NbMultiCurves();
1568     Standard_Integer MaxDeg = 0;
1569     // To transform the MultiCurve into BSpline, it is required that all  
1570     // Bezier constituing it have the same degree -> Calculation of MaxDeg
1571     Standard_Integer NbPoles  = 1;
1572     for (i = 1; i <= NbCurves; i++) {
1573       Standard_Integer Deg = Fit.Value(i).Degree();
1574       MaxDeg = Max ( MaxDeg, Deg);
1575     }
1576
1577     NbPoles = MaxDeg * NbCurves + 1;               //Tops on the BSpline
1578     TColgp_Array1OfPnt2d  Poles( 1, NbPoles);
1579       
1580     TColgp_Array1OfPnt2d TempPoles( 1, MaxDeg + 1);//to augment the degree
1581     
1582     TColStd_Array1OfReal Knots( 1, NbCurves + 1);  //Nodes of the BSpline
1583     
1584     Standard_Integer Compt = 1;
1585     for (i = 1; i <= NbCurves; i++) {
1586       Fit.Parameters(i, Knots(i), Knots(i+1)); 
1587       AppParCurves_MultiCurve MC = Fit.Value( i);       //Load the Ith Curve
1588       TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Retrieve the tops
1589       MC.Curve(1, Poles2d);
1590       
1591       //Eventual augmentation of the degree
1592       Standard_Integer Inc = MaxDeg - MC.Degree();
1593       if ( Inc > 0) {
1594 //      BSplCLib::IncreaseDegree( Inc, Poles2d, PLib::NoWeights(), 
1595         BSplCLib::IncreaseDegree( MaxDeg, Poles2d, PLib::NoWeights(), 
1596                          TempPoles, PLib::NoWeights());
1597         //update of tops of the PCurve
1598         for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1599           Poles.SetValue( Compt, TempPoles( j));
1600           Compt++;
1601         }
1602       }
1603       else {
1604         //update of tops of the PCurve
1605         for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1606           Poles.SetValue( Compt, Poles2d( j));
1607           Compt++;
1608         }
1609       } 
1610       
1611       Compt--;
1612     }
1613     
1614     //update of fields of  ProjLib_Approx
1615     Standard_Integer NbKnots = NbCurves + 1;
1616     
1617     // The start and end nodes are not correct : Cf: opening of the interval
1618     //Knots( 1) -= 1.e-9;
1619     //Knots(NbKnots) += 1.e-9; 
1620     
1621     
1622     TColStd_Array1OfInteger   Mults( 1, NbKnots);
1623     Mults.Init(MaxDeg);
1624     Mults.SetValue( 1, MaxDeg + 1);
1625     Mults.SetValue(NbKnots, MaxDeg + 1);
1626     myProjIsDone = Standard_True;
1627     Handle(Geom2d_BSplineCurve) Dummy =
1628       new Geom2d_BSplineCurve(Poles,Knots,Mults,MaxDeg);
1629     
1630     // try to smoother the Curve GeomAbs_C1.
1631
1632     Standard_Boolean OK = Standard_True;
1633
1634     for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
1635       OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d);  //OCC217
1636       //OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance);
1637     }
1638 #ifdef DEB
1639     if (!OK) {
1640       cout << "ProjLib_ComputeApproxOnPolarSurface : Smoothing echoue"<<endl;
1641     }
1642 #endif 
1643     return Dummy;
1644   }
1645   return Handle(Geom2d_BSplineCurve)();
1646 }
1647
1648 //=======================================================================
1649 //function : BSpline
1650 //purpose  : 
1651 //=======================================================================
1652
1653 Handle(Geom2d_BSplineCurve)  
1654      ProjLib_ComputeApproxOnPolarSurface::BSpline() const 
1655      
1656 {
1657 //  Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End
1658 //   Standard_NoSuchObject_Raise_if
1659 //     (!myProjIsDone,
1660 //      "ProjLib_ComputeApproxOnPolarSurface:BSpline");
1661 //  Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End
1662   return myBSpline ;
1663 }
1664
1665 //=======================================================================
1666 //function : Curve2d
1667 //purpose  : 
1668 //=======================================================================
1669
1670 Handle(Geom2d_Curve)  
1671      ProjLib_ComputeApproxOnPolarSurface::Curve2d() const 
1672      
1673 {
1674   Standard_NoSuchObject_Raise_if
1675     (!myProjIsDone,
1676      "ProjLib_ComputeApproxOnPolarSurface:2ndCurve2d");
1677   return my2ndCurve ;
1678 }
1679
1680
1681 //=======================================================================
1682 //function : IsDone
1683 //purpose  : 
1684 //=======================================================================
1685
1686 Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const 
1687      
1688 {
1689   return myProjIsDone;
1690 }