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