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