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