0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / BRepTools / BRepTools_NurbsConvertModification.cxx
1 // Created on: 1996-07-12
2 // Created by: Stagiaire Mary FABIEN
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepTools_NurbsConvertModification.ixx>
18
19 #include <BRepTools.hxx>
20 #include <Standard_NoSuchObject.hxx>
21 #include <Geom_TrimmedCurve.hxx>
22 #include <Geom2d_TrimmedCurve.hxx>
23 #include <Geom_RectangularTrimmedSurface.hxx>
24 #include <Geom_BSplineSurface.hxx>
25 #include <Geom_BSplineCurve.hxx>
26 #include <Geom_BezierSurface.hxx>
27 #include <Geom_BezierCurve.hxx>
28 #include <Geom2d_BSplineCurve.hxx>
29 #include <GeomConvert.hxx>
30 #include <Geom2dConvert.hxx>
31 #include <Geom_Plane.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom2dAdaptor_Curve.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36 #include <Geom2dAdaptor_HCurve.hxx>
37 #include <Geom2dAdaptor_HCurve.hxx>
38 #include <GeomAdaptor_HCurve.hxx>
39 #include <GeomAdaptor_HSurface.hxx>
40
41 #include <BSplCLib.hxx>
42 #include <Approx_SameParameter.hxx>
43 #include <BRep_Tool.hxx>
44 #include <Extrema_LocateExtPC.hxx>
45 #include <OSD_Chronometer.hxx>
46 #include <gp_GTrsf2d.hxx>
47 #include <gp_TrsfForm.hxx>
48 #include <TopAbs.hxx>
49 #include <TopoDS.hxx>
50 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <TColStd_ListIteratorOfListOfTransient.hxx>
52 #include <ProjLib_ComputeApprox.hxx>
53 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
54 #include <ElSLib.hxx>
55 #include <BSplCLib.hxx>
56 #include <Geom_Circle.hxx>
57 #include <Geom_Ellipse.hxx>
58 #include <Geom_CylindricalSurface.hxx>
59
60 #include <TColStd_Array1OfReal.hxx>
61 #include <BRep_TEdge.hxx>
62 #include <BRep_GCurve.hxx>
63 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
64
65 static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
66                   const Standard_Real newU1,
67                   const Standard_Real newU2)
68 {
69   TColStd_Array1OfReal  knots(1,aSurface->NbUKnots()) ;
70   aSurface->UKnots(knots) ;
71   BSplCLib::Reparametrize(newU1,
72               newU2,
73               knots) ;
74   aSurface->SetUKnots(knots) ;
75 }
76 static void GeomLib_ChangeVBounds(Handle(Geom_BSplineSurface)& aSurface,
77                   const Standard_Real newV1,
78                   const Standard_Real newV2)
79 {
80   TColStd_Array1OfReal  knots(1,aSurface->NbVKnots()) ;
81   aSurface->VKnots(knots) ;
82   BSplCLib::Reparametrize(newV1,
83               newV2,
84               knots) ;
85   aSurface->SetVKnots(knots) ;
86 }
87
88 //=======================================================================
89 //function : BRepTools_NurbsConvertModification
90 //purpose  : 
91 //=======================================================================
92
93 BRepTools_NurbsConvertModification::BRepTools_NurbsConvertModification()
94 {
95 }
96
97
98
99 //=======================================================================
100 //function : NewSurface
101 //purpose  : 
102 //=======================================================================
103
104 Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
105       (const TopoDS_Face& F,
106        Handle(Geom_Surface)& S,
107        TopLoc_Location& L,
108        Standard_Real& Tol,
109        Standard_Boolean& RevWires,
110        Standard_Boolean& RevFace)
111 {
112   Standard_Real U1, U2, curvU1, curvU2, surfU1, surfU2, UTol;
113   Standard_Real V1, V2, curvV1, curvV2, surfV1, surfV2, VTol;
114   RevWires = Standard_False;
115   RevFace = Standard_False;
116   Handle(Geom_Surface) SS = BRep_Tool::Surface(F,L);
117   Handle(Standard_Type) TheTypeSS = SS->DynamicType();
118   if ((TheTypeSS == STANDARD_TYPE(Geom_BSplineSurface)) ||
119       (TheTypeSS == STANDARD_TYPE(Geom_BezierSurface))) {
120     return Standard_False;
121   }
122   S = SS;
123   BRepTools::UVBounds(F,curvU1,curvU2,curvV1,curvV2);
124   Tol = BRep_Tool::Tolerance(F);
125   Standard_Real TolPar = 0.1*Tol;
126   Standard_Boolean IsUp = S->IsUPeriodic(), IsVp = S->IsVPeriodic();
127   //OCC466(apo)->
128   U1 = curvU1;  U2 = curvU2;  
129   V1 = curvV1;  V2 = curvV2;
130   SS->Bounds(surfU1,surfU2,surfV1,surfV2);
131
132   if (Abs(U1 - surfU1) <= TolPar)
133     U1 = surfU1;
134   if (Abs(U2 - surfU2) <= TolPar)
135     U2 = surfU2;
136   if (Abs(V1 - surfV1) <= TolPar)
137     V1 = surfV1;
138   if (Abs(V2 - surfV2) <= TolPar)
139     V2 = surfV2;
140   
141   if(!IsUp){
142     U1 = Max(surfU1,curvU1);
143     U2 = Min(surfU2,curvU2);
144   }
145   if(!IsVp){
146     V1 = Max(surfV1,curvV1);
147     V2 = Min(surfV2,curvV2);
148   }
149   //<-OCC466(apo)
150
151   if (IsUp)
152   {
153     Standard_Real Up = S->UPeriod();
154     if (U2 - U1 > Up)
155       U2 = U1 + Up;
156   }
157   if (IsVp)
158   {
159     Standard_Real Vp = S->VPeriod();
160     if (V2 - V1 > Vp)
161       V2 = V1 + Vp;
162   }
163   
164   /*
165   if(IsUp && IsVp) {
166     Standard_Real dU = Abs(U2 - U1), dV = Abs(V2 - V1);
167     Standard_Real Up = S->UPeriod(), Vp = S->VPeriod();
168     if(Abs(dU - Up) <= TolPar && U2 <= Up) {
169       if(Abs(dV - Vp) <= TolPar && V2 <= Vp) { }
170       else {
171     SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
172       }
173     }
174     else {
175       if(Abs(dV - Vp) <= TolPar && V2 <= Vp) 
176     SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
177       else
178     SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
179     }
180   }
181
182   if(IsUp && !IsVp) {
183     Standard_Real dU = Abs(U2 - U1);
184     Standard_Real Up = S->UPeriod();
185     if(Abs(dU - Up) <= TolPar && U2 <= Up) 
186       SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
187     else 
188       SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
189   }
190     
191   if(!IsUp && IsVp) {
192     Standard_Real dV = Abs(V2 - V1);
193     Standard_Real Vp = S->VPeriod();
194     if(Abs(dV - Vp) <= TolPar && V2 <= Vp) 
195       SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
196     else
197       SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
198   }
199
200   if(!IsUp && !IsVp) {
201     SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
202   }
203   */
204
205   if (Abs(surfU1-U1) > Tol || Abs(surfU2-U2) > Tol ||
206       Abs(surfV1-V1) > Tol || Abs(surfV2-V2) > Tol)
207     SS = new Geom_RectangularTrimmedSurface(S, U1, U2, V1, V2);
208   SS->Bounds(surfU1,surfU2,surfV1,surfV2); 
209
210   S = GeomConvert::SurfaceToBSplineSurface(SS);
211   Handle(Geom_BSplineSurface) BS = Handle(Geom_BSplineSurface)::DownCast(S) ;
212   BS->Resolution(Tol, UTol, VTol) ;
213   
214   // 
215   // on recadre les bornes de S  sinon les anciennes PCurves sont aux fraises
216   //
217
218   if (Abs(curvU1-surfU1) > UTol && !BS->IsUPeriodic()) {
219     GeomLib_ChangeUBounds(BS, U1,U2) ;
220   }
221   if (Abs(curvV1-surfV1) > VTol && !BS->IsVPeriodic()) {
222     GeomLib_ChangeVBounds(BS, V1, V2) ;
223   }
224
225   return Standard_True;
226 }
227
228 static Standard_Boolean IsConvert(const TopoDS_Edge& E)
229 {
230   Standard_Boolean isConvert = Standard_False;
231   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
232   // iterate on pcurves
233   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
234   for ( ; itcr.More() && !isConvert; itcr.Next() ) {
235     Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
236     if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
237     Handle(Geom_Surface) aSurface = GC->Surface();
238     Handle(Geom2d_Curve) aCurve2d = GC->PCurve();
239     isConvert =((!aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) && 
240                 !aSurface->IsKind(STANDARD_TYPE(Geom_BezierSurface))) ||
241                (!aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) &&
242                !aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))));
243      
244   }
245   return isConvert;
246   
247 }
248
249 //=======================================================================
250 //function : NewCurve
251 //purpose  : 
252 //=======================================================================
253
254 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve
255 (const TopoDS_Edge& E, 
256  Handle(Geom_Curve)& C,
257  TopLoc_Location& L,
258  Standard_Real& Tol)
259 {
260
261   Tol = BRep_Tool::Tolerance(E);
262   if(BRep_Tool::Degenerated(E)) {
263     C.Nullify();
264     L.Identity();
265     return Standard_True;
266   }
267   Standard_Real f, l;
268
269   Handle(Geom_Curve) Caux = BRep_Tool::Curve(E, L, f, l);
270
271   if ( Caux.IsNull()) {
272     L.Identity();    
273     return Standard_False;
274   }
275   Handle(Standard_Type) TheType = Caux->DynamicType();
276   if ((TheType == STANDARD_TYPE(Geom_BSplineCurve)) ||
277       (TheType == STANDARD_TYPE(Geom_BezierCurve))) {
278     if(IsConvert(E)) {
279       C = Handle(Geom_Curve)::DownCast(Caux->Copy());
280       return Standard_True;
281     }
282     return Standard_False;
283   } 
284
285   C = Caux; 
286
287   Standard_Real TolPar = Tol *.1;
288
289   if(C->IsPeriodic()) {
290     Standard_Real p = C->Period();
291     Standard_Real d = Abs(l - f);
292     if(Abs(d - p) <= TolPar && l <= p) {}
293     else
294       C = new Geom_TrimmedCurve(C, f, l);
295   } 
296   else 
297     C = new Geom_TrimmedCurve(C, f, l);
298
299 //modif WOK++ portage hp (fbi du 14/03/97)
300 //  gp_Trsf trsf(L);
301 //  gp_Trsf trsf = L.Transformation();
302
303 //  C = GeomConvert::CurveToBSplineCurve(C,Convert_QuasiAngular);
304
305   C = GeomConvert::CurveToBSplineCurve(C);
306
307   Standard_Real fnew = C->FirstParameter(), lnew = C->LastParameter(), UTol;
308
309   Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(C) ;
310
311   if(!BC->IsPeriodic()) {
312     BC->Resolution(Tol, UTol) ;
313     if(Abs(f - fnew) > UTol || Abs(l - lnew) > UTol) {
314       TColStd_Array1OfReal  knots(1,BC->NbKnots()) ;
315       BC->Knots(knots) ;
316       BSplCLib::Reparametrize(f, l, knots) ;
317       BC->SetKnots(knots) ;
318     }
319   }
320
321   if(!myMap.Contains(Caux)) {
322     myMap.Add(Caux,C);
323   }
324   return Standard_True ;
325 }
326
327 //=======================================================================
328 //function : NewPoint
329 //purpose  : 
330 //=======================================================================
331
332 Standard_Boolean BRepTools_NurbsConvertModification::NewPoint
333     (const TopoDS_Vertex&, gp_Pnt&, Standard_Real& )
334 {
335   return Standard_False;
336 }
337
338
339 //=======================================================================
340 //function : NewCurve2d
341 //purpose  : 
342 //=======================================================================
343
344 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
345   (const TopoDS_Edge& E, 
346    const TopoDS_Face& F, 
347    const TopoDS_Edge& newE, 
348    const TopoDS_Face& newF, 
349    Handle(Geom2d_Curve)& Curve2d,
350    Standard_Real& Tol)
351 {
352
353   Tol = BRep_Tool::Tolerance(E);
354   Standard_Real f2d,l2d;
355   Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
356   Standard_Real f3d,l3d;
357   TopLoc_Location Loc;
358   Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
359   Standard_Boolean isConvert2d = ((!C3d.IsNull() && !C3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) &&
360     !C3d->IsKind(STANDARD_TYPE(Geom_BezierCurve))) ||
361     IsConvert(E));
362
363   if(BRep_Tool::Degenerated(E)) {
364     //Curve2d = C2d;
365     if(!C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
366     {
367       Handle(Geom2d_TrimmedCurve) aTrimC = new Geom2d_TrimmedCurve(C2d,f2d,l2d);
368       C2d = aTrimC;
369     }
370     Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
371     return Standard_True;
372   }
373   if(!BRepTools::IsReallyClosed(E,F)) {
374     Handle(Standard_Type) TheTypeC2d = C2d->DynamicType();
375
376     if(TheTypeC2d == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
377       Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C2d);
378       C2d = TC->BasisCurve();
379     }
380
381     Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter();
382
383     if(!C2d->IsPeriodic()) {
384       if(fc - f2d > Precision::PConfusion()) f2d = fc;
385       if(l2d - lc > Precision::PConfusion()) l2d = lc;
386     }
387
388     C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
389
390     Geom2dAdaptor_Curve   G2dAC(C2d, f2d, l2d);
391     Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
392     
393     TopLoc_Location Loc;
394     Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
395     if(!newE.IsNull()) {
396       C3d = BRep_Tool::Curve(newE, f3d, l3d);
397     }
398     else {
399       C3d = BRep_Tool::Curve(E,f3d,l3d);
400     }
401     GeomAdaptor_Curve   G3dAC(C3d, f3d, l3d);
402     Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
403     
404     Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
405     Handle(Geom_Surface) S = BRep_Tool::Surface(F);
406     Handle(Standard_Type) myT = S->DynamicType();
407     if(myT != STANDARD_TYPE(Geom_Plane)) {
408       if(newF.IsNull()) {
409         Handle(Standard_Type) st = C2d->DynamicType();
410         if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
411             (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
412           if(isConvert2d) {
413             Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
414             return Standard_True;
415           }
416           return Standard_False;
417         }
418       }
419       else {
420         S = BRep_Tool::Surface(newF);
421       }
422       S->Bounds(Uinf, Usup, Vinf, Vsup);
423       //Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
424       u = (Usup - Uinf)*0.1;
425       v = (Vsup - Vinf)*0.1;
426       if(S->IsUPeriodic()) {
427         Standard_Real uperiod = S->UPeriod();
428         if(uperiod < (Usup+2*u-Uinf)) {
429           if(uperiod <= (Usup-Uinf))  {
430             u = 0;
431           } 
432           else {
433             u = (uperiod-(Usup-Uinf))*0.5;
434           }
435         }
436       }
437       if(S->IsVPeriodic()) {
438         Standard_Real vperiod = S->VPeriod();
439         if(vperiod < (Vsup+2*v-Vinf)) {
440           if(vperiod <= (Vsup-Vinf)) {
441             v = 0;
442           }
443           else {
444             v = (vperiod-(Vsup-Vinf))*0.5;
445           }
446         }
447       }
448     }
449     else {
450       S = BRep_Tool::Surface(F);// Si S est un plan, pas de changement de parametrisation
451       GeomAdaptor_Surface GAS(S);
452       Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
453       ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
454       if(ProjOnCurve.BSpline().IsNull()) {
455         Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
456         return Standard_True;
457       }
458       Curve2d = ProjOnCurve.BSpline();
459       return Standard_True;
460     }
461     GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
462
463     Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
464
465     ProjLib_ComputeApproxOnPolarSurface ProjOnCurve(G2dAHC,G3dAHC,GAHS,Tol);
466
467     if(ProjOnCurve.IsDone()) {
468       Curve2d = ProjOnCurve.BSpline();
469       return Standard_True;
470     }
471     else {
472       Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
473       return Standard_True;
474     }
475   }
476   else  {
477     TopTools_ListIteratorOfListOfShape itled;
478     TColStd_ListIteratorOfListOfTransient itlcu;
479     
480     for (itled.Initialize(myled), itlcu.Initialize(mylcu);
481       itled.More(); // itlcu.More()
482       itled.Next(),itlcu.Next()) {
483       if (itled.Value().IsSame(E)) {
484         // deja traitee
485         break;
486       }
487     }
488     if (!itled.More()) { // on stocke l`edge et la curve2d
489       Handle(Geom2d_Curve) C2dBis;
490       Standard_Real f3d,l3d,f2dBis,l2dBis;
491       C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
492       Geom2dAdaptor_Curve G2dAC(C2d, f2d, l2d);
493       Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
494       TopoDS_Edge ERevers = E;
495       ERevers.Reverse();
496       C2dBis = BRep_Tool::CurveOnSurface(ERevers,F,f2dBis,l2dBis);
497       Handle(Standard_Type) TheTypeC2dBis = C2dBis->DynamicType();
498       C2dBis = new Geom2d_TrimmedCurve(C2dBis,f2dBis, l2dBis);
499       Geom2dAdaptor_Curve   G2dACBis(C2dBis, f2dBis, l2dBis); 
500       Handle(Geom2dAdaptor_HCurve) G2dAHCBis = new Geom2dAdaptor_HCurve(G2dACBis);
501       
502       TopLoc_Location Loc;
503       Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, f3d,l3d);
504       if(C3d.IsNull()) {
505          if(isConvert2d) {
506            Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
507            return Standard_True;
508          }
509         return Standard_False;
510       }
511       if(!newE.IsNull()) {
512         C3d = BRep_Tool::Curve(newE, f3d,l3d);
513       }
514       GeomAdaptor_Curve G3dAC(C3d, f3d, l3d);
515       Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
516       
517       Handle(Geom_Surface) S = BRep_Tool::Surface(F);
518       Handle(Standard_Type) myT = S->DynamicType();
519       if(newF.IsNull()) {
520         mylcu.Append(C2dBis);
521         Handle(Standard_Type) st = C2d->DynamicType();
522         if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
523             (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
524           if(isConvert2d) {
525             Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
526             return Standard_True;
527           }
528           return Standard_False;
529         }
530       }
531       else {
532         S = BRep_Tool::Surface(newF);// S est une BSplineSurface : pas besoin de la trimmed
533       }
534       Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
535       S->Bounds(Uinf, Usup, Vinf, Vsup);
536       //Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
537       u = (Usup - Uinf)*0.1;
538       v = (Vsup - Vinf)*0.1;
539       if(S->IsUPeriodic()) {
540         Standard_Real uperiod = S->UPeriod();
541         if(uperiod < (Usup+2*u-Uinf)) {
542           if(uperiod <= (Usup-Uinf))
543             u = 0;
544           else
545             u = (uperiod-(Usup-Uinf))*0.5;
546         }
547       }
548       if(S->IsVPeriodic()) {
549         Standard_Real vperiod = S->VPeriod();
550         if(vperiod < (Vsup+2*v-Vinf)) {
551           if(vperiod <= (Vsup-Vinf))
552             v = 0;
553           else
554             v = (vperiod-(Vsup-Vinf))*0.5;
555         }
556       }
557       GeomAdaptor_Surface GAS(S, Uinf-u,Usup+u,Vinf-v,Vsup+v);
558       Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
559       myled.Append(E);
560
561       ProjLib_ComputeApproxOnPolarSurface 
562       ProjOnCurve(G2dAHC,G2dAHCBis,G3dAHC,GAHS,Tol);
563
564       if(ProjOnCurve.IsDone()) {
565         Curve2d = ProjOnCurve.BSpline();
566         mylcu.Append(ProjOnCurve.Curve2d());
567         return Standard_True;
568       }
569       else {
570         Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
571         mylcu.Append(C2dBis);
572         return Standard_True;
573       }
574     }
575     else { // on est au 2ieme tour 
576       C2d = Handle(Geom2d_Curve)::DownCast(itlcu.Value());
577       Handle(Standard_Type) st = C2d->DynamicType();
578       if (!(st == STANDARD_TYPE(Geom2d_BSplineCurve)) &&
579       !(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
580         return Standard_False;
581       }
582       Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
583       return Standard_True;
584     }
585   }
586 }
587
588 //=======================================================================
589 //function : NewParameter
590 //purpose  : 
591 //=======================================================================
592
593 Standard_Boolean BRepTools_NurbsConvertModification::NewParameter
594    (const TopoDS_Vertex& V, 
595     const TopoDS_Edge& E, 
596     Standard_Real& P, 
597     Standard_Real& Tol)
598 {
599   if(BRep_Tool::Degenerated(E))
600     return Standard_False;
601   Standard_Real f, l, param = BRep_Tool::Parameter(V,E);
602   TopLoc_Location L;
603
604   Handle(Geom_Curve) gc = BRep_Tool::Curve(E, L, f, l);
605   if(!myMap.Contains(gc))
606     return Standard_False;
607
608   Handle(Geom_BSplineCurve) gcc = 
609     Handle(Geom_BSplineCurve)::DownCast(myMap.FindFromKey(gc));
610
611   gcc = Handle(Geom_BSplineCurve)::DownCast(gcc->Transformed(L.Transformation()));
612
613   GeomAdaptor_Curve ac(gcc);
614   gp_Pnt pnt = BRep_Tool::Pnt(V);
615
616   Extrema_LocateExtPC proj(pnt, ac, param, f, l, Tol);
617   if(proj.IsDone()) {
618     Standard_Real Dist2Min = proj.SquareDistance();
619     if (Dist2Min < Tol*Tol) {
620       P = proj.Point().Parameter();
621       return Standard_True;
622     }
623   }
624   return Standard_False;
625 }
626
627 //=======================================================================
628 //function : Continuity
629 //purpose  : 
630 //=======================================================================
631
632 GeomAbs_Shape BRepTools_NurbsConvertModification::Continuity
633   (const TopoDS_Edge& E,
634    const TopoDS_Face& F1,
635    const TopoDS_Face& F2,
636    const TopoDS_Edge&,
637    const TopoDS_Face&,
638    const TopoDS_Face&)
639 {
640   return BRep_Tool::Continuity(E,F1,F2);
641 }
642
643