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