0031939: Coding - correction of spelling errors in comments [part 10]
[occt.git] / src / ShapeCustom / ShapeCustom_BSplineRestriction.cxx
1 // Created on: 1999-06-18
2 // Created by: Galina Koulikova
3 // Copyright (c) 1999-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 <BRep_Builder.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_Modifier.hxx>
25 #include <Geom2d_BezierCurve.hxx>
26 #include <Geom2d_BSplineCurve.hxx>
27 #include <Geom2d_Conic.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_OffsetCurve.hxx>
31 #include <Geom2d_TrimmedCurve.hxx>
32 #include <Geom2dConvert.hxx>
33 #include <Geom2dConvert_ApproxCurve.hxx>
34 #include <Geom_BezierCurve.hxx>
35 #include <Geom_BezierSurface.hxx>
36 #include <Geom_BSplineCurve.hxx>
37 #include <Geom_BSplineSurface.hxx>
38 #include <Geom_Conic.hxx>
39 #include <Geom_ConicalSurface.hxx>
40 #include <Geom_Curve.hxx>
41 #include <Geom_CylindricalSurface.hxx>
42 #include <Geom_ElementarySurface.hxx>
43 #include <Geom_Line.hxx>
44 #include <Geom_OffsetCurve.hxx>
45 #include <Geom_OffsetSurface.hxx>
46 #include <Geom_Plane.hxx>
47 #include <Geom_RectangularTrimmedSurface.hxx>
48 #include <Geom_SphericalSurface.hxx>
49 #include <Geom_Surface.hxx>
50 #include <Geom_SurfaceOfLinearExtrusion.hxx>
51 #include <Geom_SurfaceOfRevolution.hxx>
52 #include <Geom_SweptSurface.hxx>
53 #include <Geom_ToroidalSurface.hxx>
54 #include <Geom_TrimmedCurve.hxx>
55 #include <GeomAdaptor_Surface.hxx>
56 #include <GeomConvert.hxx>
57 #include <GeomConvert_ApproxCurve.hxx>
58 #include <GeomConvert_ApproxSurface.hxx>
59 #include <gp_Ax1.hxx>
60 #include <gp_Pnt.hxx>
61 #include <Message_Msg.hxx>
62 #include <Precision.hxx>
63 #include <ShapeAnalysis.hxx>
64 #include <ShapeAnalysis_Curve.hxx>
65 #include <ShapeConstruct.hxx>
66 #include <ShapeCustom_BSplineRestriction.hxx>
67 #include <ShapeCustom_RestrictionParameters.hxx>
68 #include <Standard_ErrorHandler.hxx>
69 #include <Standard_Failure.hxx>
70 #include <Standard_Type.hxx>
71 #include <TColgp_Array1OfPnt.hxx>
72 #include <TColgp_Array2OfPnt.hxx>
73 #include <TColgp_HArray1OfPnt.hxx>
74 #include <TColgp_HArray1OfPnt2d.hxx>
75 #include <TColStd_Array1OfInteger.hxx>
76 #include <TColStd_Array1OfReal.hxx>
77 #include <TColStd_Array2OfReal.hxx>
78 #include <TopLoc_Location.hxx>
79 #include <TopoDS.hxx>
80 #include <TopoDS_Edge.hxx>
81 #include <TopoDS_Face.hxx>
82 #include <TopoDS_Vertex.hxx>
83
84 IMPLEMENT_STANDARD_RTTIEXT(ShapeCustom_BSplineRestriction,ShapeCustom_Modification)
85
86 static GeomAbs_Shape IntegerToGeomAbsShape(const Standard_Integer i)
87 {
88   GeomAbs_Shape result = GeomAbs_C0;
89   switch (i) {
90     case 0: result = GeomAbs_C0; break;
91     case 1: result = GeomAbs_C1; break;
92     case 2: result = GeomAbs_C2; break;
93     case 3: result = GeomAbs_C3; break;
94     default : result = GeomAbs_CN; break;
95   }
96   return result;
97 }
98
99 static Standard_Integer ContToInteger( const GeomAbs_Shape Cont)
100 {
101   Standard_Integer result =0;
102   switch(Cont) {
103     case GeomAbs_C0:
104     case GeomAbs_G1: result = 0; break;
105     case GeomAbs_C1:
106     case GeomAbs_G2: result = 1; break;
107     case GeomAbs_C2: result = 2; break;  
108     case GeomAbs_C3: result = 3; break;
109     default : result = 4; break;
110   }
111   return result;
112 }
113
114 static Standard_Boolean IsConvertCurve3d(const Handle(Geom_Curve)& aCurve,
115                                          Standard_Integer Degree,
116                                          Standard_Integer NbSeg,
117                                          Standard_Boolean myRational,
118                                          const Handle(ShapeCustom_RestrictionParameters)& aParameters)
119 {
120   if(aCurve.IsNull()) return Standard_False;
121   if(aParameters->ConvertCurve3d()) return Standard_True;
122   if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
123     Handle(Geom_TrimmedCurve) tmp = Handle(Geom_TrimmedCurve)::DownCast (aCurve);
124     Handle(Geom_Curve) BasCurve = tmp->BasisCurve();
125     return IsConvertCurve3d(BasCurve,Degree,NbSeg,myRational,aParameters);
126   }
127
128   if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
129     if(aParameters->ConvertOffsetCurv3d()) return Standard_True;
130     Handle(Geom_OffsetCurve) tmp = Handle(Geom_OffsetCurve)::DownCast (aCurve);
131     Handle(Geom_Curve) BasCurve = tmp->BasisCurve();
132     return IsConvertCurve3d(BasCurve,Degree,NbSeg,myRational,aParameters); 
133   }
134   if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
135     Handle(Geom_BSplineCurve) BsC = Handle(Geom_BSplineCurve)::DownCast(aCurve);
136     if( BsC->Degree() > Degree || ((BsC->NbKnots() - 1) >= NbSeg))
137       return Standard_True;
138     if(myRational && BsC->IsRational())
139       return Standard_True;
140     else return Standard_False;
141   }
142   if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)) && 
143     (Handle(Geom_BezierCurve)::DownCast(aCurve)->Degree() > Degree ||
144     (myRational &&  Handle(Geom_BezierCurve)::DownCast(aCurve)->IsRational())))
145     return Standard_True;
146   // else return Standard_False;
147   return Standard_False;
148 }
149
150 static Standard_Boolean IsConvertSurface(const Handle(Geom_Surface)& aSurface,
151                                          const Standard_Integer Degree,
152                                          const Standard_Integer NbSeg,
153                                          const Standard_Boolean myRational,
154                                          const Handle(ShapeCustom_RestrictionParameters)& aParameters)
155 {
156   if (aSurface.IsNull()) return Standard_False;
157   if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) {
158     return aParameters->ConvertPlane();
159   }
160   else if(aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))
161     return aParameters->ConvertConicalSurf();
162   else if(aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)))
163     return aParameters->ConvertSphericalSurf();
164   else if(aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
165     return aParameters->ConvertCylindricalSurf();
166   else if(aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
167     return aParameters->ConvertToroidalSurf();
168
169   //else if(aSurface->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))    {
170   //  return aParameters->ConvertElementarySurf();
171   // }
172   if (aSurface->IsKind(STANDARD_TYPE(Geom_SweptSurface))) {
173     if(aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)) && aParameters->ConvertRevolutionSurf())
174       return Standard_True;
175     if(aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) && aParameters->ConvertExtrusionSurf())
176       return Standard_True;   
177     Handle(Geom_SweptSurface) aSurf = Handle(Geom_SweptSurface)::DownCast(aSurface);
178     Handle(Geom_Curve) BasCurve = aSurf->BasisCurve();
179     return IsConvertCurve3d(BasCurve,Degree,NbSeg,myRational,aParameters);
180   }
181   if (aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
182     Handle(Geom_RectangularTrimmedSurface) aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
183     Handle(Geom_Surface) theSurf = aSurf->BasisSurface();
184     return IsConvertSurface(theSurf,Degree,NbSeg,myRational,aParameters);
185   }
186   if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) { 
187     if(aParameters->ConvertOffsetSurf()) return Standard_True;
188     Handle(Geom_OffsetSurface) aSurf = Handle(Geom_OffsetSurface)::DownCast(aSurface);
189     Handle(Geom_Surface) theSurf = aSurf->BasisSurface();
190     return IsConvertSurface(theSurf,Degree,NbSeg,myRational,aParameters);
191   }
192   if (aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
193
194     Handle(Geom_BSplineSurface) theSurf = Handle(Geom_BSplineSurface)::DownCast(aSurface);
195     if(theSurf->UDegree() > Degree || theSurf->VDegree() > Degree)  
196       return Standard_True;
197     if((theSurf->NbUKnots()-1) * (theSurf->NbVKnots()-1) > NbSeg)
198       return Standard_True;
199     if(myRational && (theSurf->IsURational() || theSurf->IsVRational())) 
200       return Standard_True; 
201     return Standard_False;
202   } 
203
204   if (aSurface->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
205     if(aParameters->ConvertBezierSurf())
206       return Standard_True;
207     Handle(Geom_BezierSurface) theSurf = Handle(Geom_BezierSurface)::DownCast(aSurface);
208     if(theSurf->UDegree() > Degree || theSurf->VDegree() > Degree)
209       return Standard_True;
210     if( myRational && (theSurf->IsURational() || theSurf->IsVRational()))
211       return Standard_True;
212     return Standard_False;
213   }
214   return Standard_False;
215 }
216
217 static Standard_Boolean IsConvertCurve2d(const Handle(Geom2d_Curve)& aCurve,
218                                          Standard_Integer Degree,
219                                          Standard_Integer NbSeg,
220                                          Standard_Boolean myRational,
221                                          const Handle(ShapeCustom_RestrictionParameters)& aParameters)
222 {
223   if (aCurve.IsNull()) return Standard_False;
224   if (aParameters->ConvertCurve2d()) return Standard_True;
225   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
226     Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve);
227     Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve();
228     return IsConvertCurve2d(BasCurve,Degree,NbSeg,myRational,aParameters);
229   }
230   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) {
231     if(aParameters->ConvertOffsetCurv2d()) return Standard_True;
232     Handle(Geom2d_OffsetCurve) tmp = Handle(Geom2d_OffsetCurve)::DownCast (aCurve);
233     Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve();
234     return IsConvertCurve2d(BasCurve,Degree,NbSeg,myRational,aParameters);
235   }
236   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) &&
237     ((Handle(Geom2d_BSplineCurve)::DownCast(aCurve)->Degree() > Degree || 
238     ((Handle(Geom2d_BSplineCurve)::DownCast(aCurve)->NbKnots() -1) > NbSeg )) ||
239     (myRational && Handle(Geom2d_BSplineCurve)::DownCast(aCurve)->IsRational()))) 
240     return Standard_True;
241   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) && 
242     ((Handle(Geom2d_BezierCurve)::DownCast(aCurve)->Degree() > Degree) ||
243     (myRational && Handle(Geom2d_BezierCurve)::DownCast(aCurve)->IsRational())))
244     return Standard_True;
245   // else return Standard_False;
246   return Standard_False;
247 }
248
249 //=======================================================================
250 //function : ShapeCustom_BSplineRestriction
251 //purpose  : 
252 //=======================================================================
253
254 ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction()
255 {
256   myApproxSurfaceFlag = Standard_True;
257   myApproxCurve3dFlag = Standard_True;
258   myApproxCurve2dFlag = Standard_True; 
259   myTol3d = 0.01;
260   myTol2d = 1E-6;
261   myContinuity3d = GeomAbs_C1;
262   myContinuity2d =GeomAbs_C2 ;
263   myMaxDegree = 9;
264   myNbMaxSeg = 10000;
265   mySurfaceError = Precision::Confusion();
266   myCurve3dError = Precision::Confusion();
267   myCurve2dError = Precision::PConfusion();
268   myNbOfSpan = 0;
269   myConvert = Standard_False;
270   myDeg =Standard_True;
271   myRational = Standard_False;
272   myParameters = new ShapeCustom_RestrictionParameters;
273
274 }
275
276 ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction(const Standard_Boolean anApproxSurfaceFlag,
277                                                                const Standard_Boolean anApproxCurve3dFlag,
278                                                                const Standard_Boolean anApproxCurve2dFlag,
279                                                                const Standard_Real aTol3d,
280                                                                const Standard_Real aTol2d,
281                                                                const GeomAbs_Shape aContinuity3d,
282                                                                const GeomAbs_Shape aContinuity2d,
283                                                                const Standard_Integer aMaxDegree,
284                                                                const Standard_Integer aNbMaxSeg,
285                                                                const Standard_Boolean Deg,
286                                                                const Standard_Boolean Rational)
287 {
288   myApproxSurfaceFlag = anApproxSurfaceFlag;
289   myApproxCurve3dFlag = anApproxCurve3dFlag;
290   myApproxCurve2dFlag = anApproxCurve2dFlag;
291   myTol3d = aTol3d;
292   myTol2d = aTol2d;
293   myMaxDegree = aMaxDegree;
294   myContinuity3d = aContinuity3d;
295   myContinuity2d = aContinuity2d;
296   myNbMaxSeg = aNbMaxSeg;
297   mySurfaceError = Precision::Confusion();
298   myCurve3dError = Precision::Confusion();
299   myCurve2dError = Precision::PConfusion();
300   myNbOfSpan = 0;
301   myConvert = Standard_False;
302   myDeg = Deg;
303   myRational = Rational;
304   myParameters = new ShapeCustom_RestrictionParameters;
305
306 }
307
308 ShapeCustom_BSplineRestriction::ShapeCustom_BSplineRestriction(const Standard_Boolean anApproxSurfaceFlag,
309                                                                const Standard_Boolean anApproxCurve3dFlag,
310                                                                const Standard_Boolean anApproxCurve2dFlag,
311                                                                const Standard_Real aTol3d,
312                                                                const Standard_Real aTol2d,
313                                                                const GeomAbs_Shape aContinuity3d,
314                                                                const GeomAbs_Shape aContinuity2d,
315                                                                const Standard_Integer aMaxDegree,
316                                                                const Standard_Integer aNbMaxSeg,
317                                                                const Standard_Boolean Deg,
318                                                                const Standard_Boolean Rational,
319                                                                const Handle(ShapeCustom_RestrictionParameters)& aModes)
320 {
321   myApproxSurfaceFlag = anApproxSurfaceFlag;
322   myApproxCurve3dFlag = anApproxCurve3dFlag;
323   myApproxCurve2dFlag = anApproxCurve2dFlag;
324   myTol3d = aTol3d;
325   myTol2d = aTol2d;
326   myMaxDegree = aMaxDegree;
327   myContinuity3d = aContinuity3d;
328   myContinuity2d = aContinuity2d;
329   myNbMaxSeg = aNbMaxSeg;
330   mySurfaceError = Precision::Confusion();
331   myCurve3dError = Precision::Confusion();
332   myCurve2dError = Precision::PConfusion();
333   myNbOfSpan = 0;
334   myConvert = Standard_False;
335   myDeg = Deg;
336   myRational = Rational;
337   myParameters = aModes;
338
339 }
340
341 //=======================================================================
342 //function : NewSurface
343 //purpose  : 
344 //=======================================================================
345
346 Standard_Boolean ShapeCustom_BSplineRestriction::NewSurface(const TopoDS_Face& F,
347                                                             Handle(Geom_Surface)& S,
348                                                             TopLoc_Location& L,
349                                                             Standard_Real& Tol,
350                                                             Standard_Boolean& RevWires,
351                                                             Standard_Boolean& RevFace)
352 {
353   if ( ! myApproxSurfaceFlag )
354     return Standard_False;
355   RevWires = Standard_False;
356   RevFace = Standard_False;
357   myConvert = Standard_False;
358   Handle(Geom_Surface) aSurface = BRep_Tool::Surface(F,L);
359   if(aSurface.IsNull()) return Standard_False;
360   Standard_Boolean IsOf = Standard_True;
361   if(myParameters->ConvertOffsetSurf()) IsOf = Standard_False;
362   Standard_Real UF,UL,VF,VL;
363   aSurface->Bounds(UF,UL,VF,VL);
364   Standard_Real Umin, Umax, Vmin, Vmax;
365   BRepTools::UVBounds(F,Umin, Umax, Vmin, Vmax);
366   if(myParameters->SegmentSurfaceMode()) {
367     UF = Umin; UL =  Umax;
368     VF = Vmin; VL =  Vmax;
369   }
370   else {
371     if(Precision::IsInfinite(UF) || Precision::IsInfinite(UL)) {
372       UF = Umin;
373       UL = Umax;
374     }
375     if(Precision::IsInfinite(VF) || Precision::IsInfinite(VL)) {
376       VF = Vmin;
377       VL = Vmax;
378     }
379   }
380
381   Standard_Boolean IsConv = ConvertSurface(aSurface,S,UF,UL,VF,VL,IsOf);
382   Tol = Precision::Confusion();//mySurfaceError;
383
384   if ( IsConv )
385   {
386     Standard_Boolean wasBSpline = aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface));
387     Handle(Geom_RectangularTrimmedSurface) rts = Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
388     if ( !rts.IsNull() )
389       wasBSpline = rts->BasisSurface()->IsKind(STANDARD_TYPE(Geom_BSplineSurface));
390
391     if ( wasBSpline )
392       SendMsg( F, Message_Msg("BSplineRestriction.NewSurface.MSG1"));
393     else
394       SendMsg( F, Message_Msg("BSplineRestriction.NewSurface.MSG0"));
395   }
396
397   return IsConv;
398 }
399
400 //=======================================================================
401 //function : ConvertSurface
402 //purpose  : 
403 //=======================================================================
404
405 static void ConvertExtrusion(const Handle(Geom_Curve)& C,/*const gp_Dir& direction,*/
406                              gp_Trsf& shiftF,gp_Trsf& shiftL,
407                              const Standard_Real VF,const Standard_Real VL,
408                              Handle(Geom_Surface)& bspline)
409 {
410   Handle(Geom_BSplineCurve) bspl = Handle(Geom_BSplineCurve)::DownCast(C);  
411   Standard_Integer nbPoles = bspl->NbPoles();
412   TColgp_Array1OfPnt poles(1,nbPoles);
413   TColStd_Array1OfReal weights(1,nbPoles);
414   Standard_Integer nbKnots = bspl->NbKnots();
415   TColStd_Array1OfReal knots(1,nbKnots);
416   TColStd_Array1OfInteger mults(1,nbKnots);
417
418   bspl->Poles(poles);
419   bspl->Knots(knots);
420   bspl->Multiplicities(mults);
421   bspl->Weights(weights);
422
423   TColgp_Array2OfPnt resPoles(1,nbPoles,1,2);
424   TColStd_Array2OfReal resWeigth(1,nbPoles,1,2);
425   for(Standard_Integer j = 1; j <= nbPoles; j++) {
426     resPoles(j,1) = poles(j).Transformed(shiftF);
427     resPoles(j,2) = poles(j).Transformed(shiftL);
428     resWeigth(j,1)= weights(j);
429     resWeigth(j,2)= weights(j);
430   }
431
432   TColStd_Array1OfReal vknots(1,2);
433   TColStd_Array1OfInteger vmults(1,2);
434   vknots(1) = VF;
435   vknots(2) = VL;
436   vmults(1) = vmults(2) = 2;
437
438   bspline = new Geom_BSplineSurface(resPoles, resWeigth, knots, vknots, mults, vmults,
439     bspl->Degree(),1,bspl->IsPeriodic(),Standard_False);
440 }
441
442
443 Standard_Boolean ShapeCustom_BSplineRestriction::ConvertSurface(const Handle(Geom_Surface)& aSurface,
444                                                                 Handle(Geom_Surface)& S,
445                                                                 const Standard_Real UF,
446                                                                 const Standard_Real UL,
447                                                                 const Standard_Real VF,
448                                                                 const Standard_Real VL,
449                                                                 const Standard_Boolean IsOf)
450
451   if(!IsConvertSurface(aSurface,myMaxDegree,myNbMaxSeg,myRational,myParameters))
452     return Standard_False;
453
454   Handle(Geom_Surface) aSurf = aSurface;
455   if (aSurf->IsKind(STANDARD_TYPE(Geom_Plane)) && myParameters->ConvertPlane()) {
456     Handle(Geom_Plane) pln = Handle(Geom_Plane)::DownCast(aSurf);
457     TColgp_Array2OfPnt poles(1,2,1,2);
458     TColStd_Array1OfReal uknots(1,2);
459     TColStd_Array1OfInteger umults(1,2);
460     TColStd_Array1OfReal vknots(1,2);
461     TColStd_Array1OfInteger vmults(1,2);
462
463     poles(1,1) = pln->Value(UF,VF); poles(1,2) = pln->Value(UF,VL);
464     poles(2,1) = pln->Value(UL,VF);  poles(2,2) = pln->Value(UL,VL);
465     uknots(1) = UF; uknots(2) = UL; 
466     vknots(1) = VF; vknots(2) = VL;
467     umults(1) = umults(2) = vmults(1) = vmults(2) = 2;
468     S = new Geom_BSplineSurface(poles, uknots, vknots, umults, vmults, 1, 1, Standard_False, Standard_False);
469     return Standard_True;    
470   }
471   if (aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {      
472     Handle(Geom_SurfaceOfRevolution) Surface = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
473     Handle(Geom_Curve) BasCurve = Surface->BasisCurve();
474     Handle(Geom_Curve) ResCurve;
475     Standard_Real TolS = Precision::Confusion(); 
476     if(myParameters->ConvertRevolutionSurf()) {
477       if(BasCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
478         GeomAbs_Shape cnt = BasCurve->Continuity();
479         cnt = (cnt > GeomAbs_C2 ? GeomAbs_C2: cnt);
480         if(ConvertCurve(BasCurve,ResCurve,Standard_False,Max(VF,BasCurve->FirstParameter()),Min(VL,BasCurve->LastParameter()),TolS,Standard_False)) {
481           Handle(Geom_SurfaceOfRevolution) newRevol = new Geom_SurfaceOfRevolution(ResCurve,Surface->Axis());
482           aSurf = newRevol;
483 #ifdef OCCT_DEBUG
484           std::cout <<" Revolution on offset converted" << std::endl;
485 #endif
486         }
487       }
488
489     }
490     else {
491       if(ConvertCurve(BasCurve,ResCurve,Standard_False,Max(VF,BasCurve->FirstParameter()),Min(VL,BasCurve->LastParameter()),TolS,IsOf)) {
492         S = new Geom_SurfaceOfRevolution(ResCurve,Surface->Axis());
493         return Standard_True;
494       }
495       else 
496         return Standard_False;
497     }
498   }
499   if (aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
500     Handle(Geom_SurfaceOfLinearExtrusion) Surface = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aSurf);
501     Handle(Geom_Curve) BasCurve = Surface->BasisCurve();
502     Handle(Geom_Curve) ResCurve;
503     Standard_Real TolS = Precision::Confusion();
504     if(myParameters->ConvertExtrusionSurf()) {
505       GeomAbs_Shape cnt = Surface->Continuity();
506       cnt = (cnt > GeomAbs_C2 ? GeomAbs_C2: cnt);
507       Handle(Geom_BSplineCurve) bspl = ShapeConstruct::ConvertCurveToBSpline(BasCurve, UF, UL, TolS, cnt, myNbMaxSeg, myMaxDegree);
508       BasCurve = bspl;
509       ConvertCurve(BasCurve,ResCurve,Standard_True,Max(UF,BasCurve->FirstParameter()),Min(UL,BasCurve->LastParameter()),TolS,IsOf);
510       gp_Trsf shiftF,shiftL;
511       shiftF.SetTranslation(Surface->Value(UF,0),Surface->Value(UF,VF));
512       shiftL.SetTranslation(Surface->Value(UF,0),Surface->Value(UF,VL));
513       ConvertExtrusion(ResCurve,/*Surface->Direction(),*/shiftF,shiftL,VF,VL,S);
514       return Standard_True;
515     }
516     else {
517       if(ConvertCurve(BasCurve,ResCurve,Standard_False,Max(UF,BasCurve->FirstParameter()),Min(UL,BasCurve->LastParameter()),TolS,IsOf)) {
518         S = new Geom_SurfaceOfLinearExtrusion(ResCurve,Surface->Direction());
519         return Standard_True;
520       }
521       else 
522         return Standard_False;
523     }
524   }
525   if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
526     Handle(Geom_RectangularTrimmedSurface) tmp = Handle(Geom_RectangularTrimmedSurface)::
527       DownCast (aSurf);
528     Standard_Real U1,U2,V1,V2;
529     tmp->Bounds(U1,U2,V1,V2);
530     Handle(Geom_Surface) theSurf = tmp->BasisSurface();
531     Handle(Geom_Surface) ResSurface;
532     if(ConvertSurface(theSurf,ResSurface,U1,U2,V1,V2,IsOf)) {
533       //S = new Geom_RectangularTrimmedSurface(ResSurface,U1,U2,V1,V2);
534       S = ResSurface;
535       return Standard_True;
536     }
537     else 
538       return Standard_False;
539
540   }
541   if (aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) && IsOf) {
542     Handle(Geom_OffsetSurface) tmp = Handle(Geom_OffsetSurface)::DownCast (aSurf);
543     Handle(Geom_Surface) theSurf = tmp->BasisSurface();
544     Handle(Geom_Surface) ResSurface;
545     if(ConvertSurface(theSurf,ResSurface,UF,UL,VF,VL)) {
546       if(ResSurface->Continuity() != GeomAbs_C0) {
547         S = new Geom_OffsetSurface(ResSurface,tmp->Offset());
548         return Standard_True;
549       }
550       else if(ConvertSurface(aSurf,S,UF,UL,VF,VL,Standard_False)) 
551         return Standard_True;
552       else return Standard_False;
553     }
554     else 
555       return Standard_False;
556
557   }
558   if (aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)) && myParameters->ConvertBezierSurf()) {
559     Handle(Geom_BezierSurface) bezier = Handle(Geom_BezierSurface)::DownCast(aSurf);
560     Standard_Integer nbUPoles = bezier->NbUPoles();
561     Standard_Integer nbVPoles = bezier->NbVPoles();
562     Standard_Integer uDegree = bezier->UDegree();
563     Standard_Integer vDegree = bezier->VDegree();
564     TColgp_Array2OfPnt aPoles(1,nbUPoles,1,nbVPoles);
565     TColStd_Array2OfReal aWeights(1,nbUPoles,1,nbVPoles);
566     bezier->Poles(aPoles);
567     bezier->Weights(aWeights);
568     TColStd_Array1OfReal uKnots(1,2), vKnots(1,2);
569     uKnots(1) = 0; uKnots(2) = 1;
570     vKnots(1) = 0; vKnots(2) = 1;
571     TColStd_Array1OfInteger uMults(1,2), vMults(1,2);
572     uMults.Init(uDegree+1);
573     vMults.Init(vDegree+1);
574     Handle(Geom_BSplineSurface) bspline = new Geom_BSplineSurface(aPoles,aWeights,uKnots,vKnots,
575       uMults,vMults,uDegree,vDegree);
576
577     if(!ConvertSurface(bspline,S,UF,UL,VF,VL,IsOf))
578       S = bspline;
579     return Standard_True;
580   }
581
582   Standard_Integer NbSeg = 1;
583   Standard_Boolean URat = Standard_False;
584   Standard_Boolean VRat = Standard_False;
585   //if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) || 
586   //    aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)) || 
587   //    (aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) && !IsOf) ||
588   //    aSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)) ||
589   //    aSurface->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))) {
590   Standard_Integer UDeg=1,VDeg=1;
591   if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
592     Handle(Geom_BSplineSurface) BsS =  Handle(Geom_BSplineSurface)::DownCast (aSurf);
593     UDeg = BsS->UDegree();
594     VDeg = BsS->VDegree();
595     NbSeg = (BsS->NbUKnots()-1)*(BsS->NbVKnots()-1);
596     URat = BsS->IsURational();
597     VRat = BsS->IsVRational();
598     Standard_Boolean IsR = (myRational && (URat || VRat));
599     if( UDeg <= myMaxDegree &&  VDeg <= myMaxDegree && NbSeg <=  myNbMaxSeg && !IsR ) 
600       return Standard_False;
601   }
602   if (aSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
603     Handle(Geom_BezierSurface) BsZ = Handle(Geom_BezierSurface)::DownCast (aSurf);
604     UDeg = BsZ->UDegree();
605     VDeg = BsZ->VDegree();
606     NbSeg =1;
607     URat = BsZ->IsURational();
608     VRat = BsZ->IsVRational();
609     Standard_Boolean IsR = (myRational && (URat || VRat));
610     if( UDeg <= myMaxDegree &&  VDeg <= myMaxDegree && NbSeg <=  myNbMaxSeg && !IsR ) 
611       return Standard_False;
612
613   }
614   GeomAbs_Shape Cont = myContinuity3d;
615   if(aSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) Cont = GeomAbs_C0;
616   /*    Standard_Boolean IsR = (myRational && (URat || VRat));
617   if( UDeg <= myMaxDegree &&  VDeg <= myMaxDegree && NbSeg <=  myNbMaxSeg && !IsR ) {
618   return Standard_False;
619
620   }*/
621
622   Standard_Real aTol3d;
623   Standard_Integer nbOfSpan,imax=10;
624   Standard_Integer MaxSeg = myNbMaxSeg;
625   Standard_Integer MaxDeg = myMaxDegree;
626   Standard_Real u1,u2,v1,v2;
627   aSurf->Bounds(u1,u2,v1,v2);
628   Standard_Real ShiftU = 0, ShiftV = 0;
629   if( Abs(u1-UF) > Precision::PConfusion() || Abs(u2- UL) > Precision::PConfusion() || 
630     Abs(v1-VF) > Precision::PConfusion() || Abs(v2- VL) > Precision::PConfusion()) {
631       /*if(aSurf->IsUPeriodic() ) {
632       Standard_Real aDelta = (UL > UF ? UL - UF : UF - UL );
633       u1 = (aDelta > 2.*M_PI ? 0. : UF + ShapeAnalysis::AdjustByPeriod(UF,0.5*(UL+UF),2*M_PI)); 
634       u2 = (aDelta > 2.*M_PI ? 2.*M_PI : u1 + aDelta); 
635       }*/
636       Standard_Boolean isTrim = Standard_False;
637       if(!aSurf->IsUPeriodic() ) { //else {
638         u1 = Max(u1,UF); u2 = Min(u2,UL);
639         isTrim = Standard_True;
640       }
641       /*if(aSurf->IsVPeriodic()) {
642
643       Standard_Real aDelta = (VL > VF ? VL - VF : VF - VL );
644       v1 = (aDelta > 2.*M_PI ? 0. : VF + ShapeAnalysis::AdjustByPeriod(VF,0.5*(UL+UF),2*M_PI));
645       v2 = (aDelta > 2.*M_PI ? 2.* M_PI : v1 + aDelta); 
646       }*/
647       if(!aSurf->IsVPeriodic()) {//else 
648         v1 = Max(v1,VF); v2 = Min(v2,VL);
649         isTrim = Standard_True;
650       }
651
652       if(isTrim && (u1 != u2) && (v1 != v2)) {
653         Handle(Geom_RectangularTrimmedSurface) trSurface = new Geom_RectangularTrimmedSurface(aSurf,u1,u2,v1,v2);
654         Standard_Real ur1,ur2,vr1,vr2;
655         trSurface->Bounds(ur1,ur2,vr1,vr2);
656         ShiftU = u1-ur1;
657         ShiftV = v1-vr1;
658         aSurf = trSurface;
659       }
660   }
661   Standard_Integer aCU= Min(ContToInteger(Cont),ContToInteger(aSurf->Continuity()));
662   Standard_Integer aCV = Min(ContToInteger(Cont),ContToInteger( aSurf->Continuity()));
663   if(!aCU)
664     aCU = ContToInteger(Cont);
665   if(!aCV)
666     aCV = ContToInteger(Cont);
667
668   for(; ;) {
669     Standard_Real prevTol = RealLast(),newTol =0;
670     for (Standard_Integer i=1; i <= imax; i++) {
671       aTol3d = myTol3d*i/2;
672       while (aCU >= 0 || aCV >= 0) {
673         try {
674           OCC_CATCH_SIGNALS
675             GeomAbs_Shape aContV = IntegerToGeomAbsShape(aCV);
676           GeomAbs_Shape aContU = IntegerToGeomAbsShape(aCU);
677
678           GeomConvert_ApproxSurface anApprox(aSurf,aTol3d,aContU,aContV,MaxDeg,MaxDeg,MaxSeg,0);
679           Standard_Boolean Done = anApprox.IsDone();
680           newTol = anApprox.MaxError();
681           if (anApprox.MaxError() <= myTol3d && Done) {
682
683             nbOfSpan = (anApprox.Surface()->NbUKnots()-1)*(anApprox.Surface()->NbVKnots()-1);
684 #ifdef OCCT_DEBUG
685             if((imax-i+1)!=1) {
686               std::cout << " iteration = " << i
687                 <<    "\terror = " << anApprox.MaxError()
688                 <<    "\tspans = " << nbOfSpan << std::endl;
689               std::cout<< " Surface is approximated with continuity " << IntegerToGeomAbsShape(Min(aCU,aCV)) <<std::endl;
690             }
691 #endif
692             S = anApprox.Surface();
693             Handle(Geom_BSplineSurface) Bsc = Handle(Geom_BSplineSurface)::DownCast(S);
694             if(aSurface->IsUPeriodic() )
695               Bsc->SetUPeriodic();
696             if(aSurface->IsVPeriodic() )
697               Bsc->SetVPeriodic();
698             //Standard_Integer DegU = Bsc->UDegree(); // DegU not used (skl)
699             //Standard_Integer DegV = Bsc->VDegree(); // DegV not used (skl)
700             //Standard_Integer nbVK = Bsc->NbVKnots(); // nbVK not used (skl)
701             //Standard_Integer nbUK = Bsc->NbUKnots(); // nbUK not used (skl)
702             myConvert = Standard_True;
703             myNbOfSpan = myNbOfSpan + nbOfSpan;
704             mySurfaceError = Max(mySurfaceError,anApprox.MaxError());
705             if(Abs(ShiftU) > Precision::PConfusion()) {
706               Standard_Integer nb = Bsc->NbUKnots();
707               TColStd_Array1OfReal uknots(1,nb);
708               Bsc->UKnots(uknots);
709               for(Standard_Integer j = 1; j <= nb; j++)
710                 uknots(j)+=ShiftU;
711               Bsc->SetUKnots(uknots);
712             }
713             if(Abs(ShiftV) > Precision::PConfusion()) {
714               Standard_Integer nb = Bsc->NbVKnots();
715               TColStd_Array1OfReal vknots(1,nb);
716               Bsc->VKnots(vknots);
717               for(Standard_Integer j = 1; j <= nb; j++)
718                 vknots(j)+=ShiftV;
719               Bsc->SetVKnots(vknots);
720             }
721
722             return Standard_True;
723           }
724           else {
725             break;
726           }
727
728         }
729
730         catch (Standard_Failure const& anException) {
731 #ifdef OCCT_DEBUG
732           std::cout << "Warning: GeomConvert_ApproxSurface Exception: try to decrease continuity ";
733           anException.Print(std::cout); std::cout << std::endl;
734 #endif
735           (void)anException;
736           //szv: protection against loop
737           if(aCU == 0 && aCV == 0) break;
738           if(aCU > 0) aCU--;
739           if(aCV > 0) aCV--;
740         }
741       }
742       if(prevTol <= newTol) break;
743       else prevTol = newTol;
744     }
745     //Standard_Integer GMaxDegree = 15;//Geom_BSplineSurface::MaxDegree();
746
747     if(myDeg) {
748       if(MaxSeg < myParameters->GMaxSeg()){ 
749         if(aCV != 0 || aCU != 0) {
750           if(aCV > 0) aCV--;
751           if(aCU > 0) aCU--;
752         }
753         else MaxSeg = 2*MaxSeg; //myGMaxSeg; 
754         if(MaxSeg > myParameters->GMaxSeg()) 
755           MaxSeg = myParameters->GMaxSeg();
756         else continue;
757       }
758       else { 
759 #ifdef OCCT_DEBUG
760         std::cout<<" Approximation iteration out. Surface is not approximated." << std::endl;
761 #endif
762         return Standard_False;
763       }
764     }
765     else {
766       if(MaxDeg < myParameters->GMaxDegree())
767       { MaxDeg = myParameters->GMaxDegree(); continue;}
768       else {
769 #ifdef OCCT_DEBUG       
770         std::cout<<" Approximation iteration out. Surface is not approximated." << std::endl;
771 #endif
772         return Standard_False;
773       }
774     }
775   }
776   //}
777   //else 
778   //Surface is not BSpline or Bezier
779   //  return Standard_False;
780 }
781
782 //=======================================================================
783 //function : NewCurve
784 //purpose  : 
785 //=======================================================================
786
787 Standard_Boolean ShapeCustom_BSplineRestriction::NewCurve(const TopoDS_Edge& E,
788                                                           Handle(Geom_Curve)& C,
789                                                           TopLoc_Location& L,
790                                                           Standard_Real& Tol) 
791 {
792   if ( ! myApproxCurve3dFlag )
793     return Standard_False;
794   Standard_Real First, Last;
795   Handle(Geom_Curve) aCurve = BRep_Tool::Curve(E,L,First, Last);
796   Standard_Real TolCur = BRep_Tool::Tolerance(E);
797   //if(aCurve.IsNull()) return Standard_False;
798   Standard_Boolean IsConvert = Standard_False;
799   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
800   // iterate on pcurves
801   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
802   for ( ; itcr.More(); itcr.Next() ) {
803     Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
804     if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
805     Handle(Geom_Surface) aSurface = GC->Surface();
806     Handle(Geom2d_Curve) aCurve2d = GC->PCurve();
807     if((myApproxSurfaceFlag && 
808       IsConvertSurface(aSurface,myMaxDegree,myNbMaxSeg,myRational,myParameters)) || 
809       (myApproxCurve2dFlag && IsConvertCurve2d(aCurve2d,myMaxDegree,myNbMaxSeg,myRational,myParameters))) {
810         IsConvert = Standard_True;
811         break;
812     }
813   }
814   if(aCurve.IsNull()) {
815     if(IsConvert) {
816       C = aCurve;
817       Tol = TolCur;
818       return Standard_True;
819     }
820     else return Standard_False;
821   }
822   Standard_Boolean IsOf = Standard_True;
823   if(myParameters->ConvertOffsetCurv3d())  IsOf = Standard_False;
824   Standard_Boolean IsConv = ConvertCurve(aCurve,C,IsConvert,First,Last,TolCur,IsOf);
825   Tol= BRep_Tool::Tolerance(E);//TolCur;
826
827   if ( IsConv )
828   {
829     Standard_Boolean wasBSpline = aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
830     Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
831     if ( !tc.IsNull() )
832       wasBSpline = tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
833
834     if ( wasBSpline )
835       SendMsg( E, Message_Msg("BSplineRestriction.NewCurve.MSG1"));
836     else
837       SendMsg( E, Message_Msg("BSplineRestriction.NewCurve.MSG0"));
838   }
839   return IsConv;
840 }
841
842 //=======================================================================
843 //function : ConvertCurve
844 //purpose  : 
845 //=======================================================================
846
847 Standard_Boolean ShapeCustom_BSplineRestriction::ConvertCurve(const Handle(Geom_Curve)& aCurve,
848                                                               Handle(Geom_Curve)& C,
849                                                               const Standard_Boolean IsConvert,
850                                                               const Standard_Real First,
851                                                               const Standard_Real Last,
852                                                               Standard_Real& TolCur,
853                                                               const Standard_Boolean IsOf) 
854 {
855   //  TolCur =  Precision::Confusion();
856   if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
857     Handle(Geom_TrimmedCurve) tmp = Handle(Geom_TrimmedCurve)::DownCast (aCurve);
858     //Standard_Real pf =tmp->FirstParameter(), pl =  tmp->LastParameter(); // pf,pl not used - see below (skl)
859     Handle(Geom_Curve) BasCurve = tmp->BasisCurve();
860     Handle(Geom_Curve) ResCurve;
861     if(ConvertCurve(BasCurve,ResCurve,IsConvert,First,Last,TolCur,IsOf)) {
862       //      Stanadrd_Real F = Max(pf,First), L = Min(pl,Last);
863       //      if(First != Last)
864       //        C = new Geom_TrimmedCurve(ResCurve,Max(First,ResCurve->FirstParameter()),Min(Last,ResCurve->LastParameter()));
865       //else 
866       C = ResCurve;
867       return Standard_True;
868     }
869     else {
870       if(IsConvert) {
871         C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
872         TolCur =  Precision::Confusion();
873         return Standard_True;
874       }
875
876       return Standard_False;
877     }
878   }
879
880   if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)) && myParameters->ConvertCurve3d()) {
881     Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve);
882     TColgp_Array1OfPnt poles(1,2);
883     poles(1) = aLine->Value(First);
884     poles(2) = aLine->Value(Last);
885     TColStd_Array1OfReal knots(1,2);
886     knots(1) = First; knots(2) = Last;
887     TColStd_Array1OfInteger mults(1,2);
888     mults.Init(2);
889     Handle(Geom_BSplineCurve) res = new Geom_BSplineCurve(poles,knots,mults,1);
890     C = res;
891     return Standard_True;
892   }
893
894   if (aCurve->IsKind(STANDARD_TYPE(Geom_Conic)) && myParameters->ConvertCurve3d()) {
895     Handle(Geom_BSplineCurve) aBSpline;
896     Handle(Geom_Curve) tcurve = new Geom_TrimmedCurve(aCurve,First,Last); //protection against parabols ets
897     GeomConvert_ApproxCurve approx (tcurve, myTol3d/*Precision::Approximation()*/, myContinuity2d, myNbMaxSeg, 6 );
898     if ( approx.HasResult() )
899       aBSpline = approx.Curve();
900     else 
901       aBSpline = GeomConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
902
903     Standard_Real Shift = First - aBSpline->FirstParameter();
904     if(Abs(Shift) > Precision::PConfusion()) {
905       Standard_Integer nbKnots = aBSpline->NbKnots();
906       TColStd_Array1OfReal newKnots(1,nbKnots);
907       aBSpline->Knots(newKnots);
908       for (Standard_Integer i = 1; i <= nbKnots; i++)
909         newKnots(i)+=Shift;
910       aBSpline->SetKnots(newKnots);
911     }
912     Handle(Geom_Curve) ResCurve;
913     if(ConvertCurve(aBSpline,ResCurve,IsConvert,First,Last,TolCur,Standard_False)) {
914       C = ResCurve;
915       return Standard_True;
916     }
917     else {
918       C = aBSpline;
919       TolCur = Precision::PConfusion();
920       return Standard_True;
921     } 
922   }
923
924   if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)) && myParameters->ConvertCurve3d()) {
925     Handle(Geom_Curve) aBSpline 
926       = GeomConvert::CurveToBSplineCurve(aCurve,Convert_QuasiAngular);
927     Handle(Geom_Curve) ResCurve;
928     if(ConvertCurve(aBSpline,ResCurve,IsConvert,First,Last,TolCur,Standard_False)) {
929       C = ResCurve;
930       return Standard_True;
931     }
932     else {
933       C = aBSpline;
934       TolCur = Precision::PConfusion();
935       return Standard_True;
936     } 
937   }
938
939   if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)) && IsOf) {
940     Handle(Geom_OffsetCurve) tmp = Handle(Geom_OffsetCurve)::DownCast (aCurve);
941     Handle(Geom_Curve) BasCurve = tmp->BasisCurve();
942     Handle(Geom_Curve) ResCurve;
943     if(ConvertCurve(BasCurve,ResCurve,IsConvert,First,Last,TolCur)) {
944       if(ResCurve->Continuity() != GeomAbs_C0) {
945         C = new Geom_OffsetCurve(ResCurve,tmp->Offset(),tmp->Direction());
946         return Standard_True;
947       }
948       else if(ConvertCurve(aCurve,C,IsConvert,First,Last,TolCur,Standard_False))
949         return Standard_True;
950       else {
951         if(IsConvert) {
952           C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
953           TolCur =  Precision::Confusion();
954           return Standard_True;
955         }
956         return Standard_False;
957       }
958     } 
959     else {
960       if(IsConvert) {
961         C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
962         TolCur =  Precision::Confusion();
963         return Standard_True;
964       }
965       return Standard_False;
966     }
967   }
968   if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || 
969     aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ||
970     (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)) && !IsOf))  {
971       Standard_Integer Deg=1;
972
973       if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
974         Handle(Geom_BSplineCurve) BsC = Handle(Geom_BSplineCurve)::DownCast (aCurve);
975         Deg =BsC->Degree();
976         Standard_Boolean IsR = (myRational && BsC->IsRational());
977         if(!IsR && Deg <= myMaxDegree && (BsC->NbKnots() - 1) <= myNbMaxSeg) {
978           if(IsConvert) {
979             C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
980             TolCur =  Precision::Confusion();
981             return Standard_True;
982           }
983           else return Standard_False;
984         }
985       }
986       if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
987         Handle(Geom_BezierCurve) BzC =  Handle(Geom_BezierCurve)::DownCast (aCurve);
988         Deg =BzC->Degree();
989         Standard_Boolean IsR = (myRational && BzC->IsRational());
990         if(!IsR && Deg <= myMaxDegree ) {
991           if(IsConvert) {
992             C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
993             TolCur =  Precision::Confusion();
994             return Standard_True;
995           }
996           else return Standard_False;
997         }
998       }
999       Handle(Geom_Curve) aCurve1;
1000       Standard_Real pf =aCurve->FirstParameter(), pl =  aCurve->LastParameter();
1001       // 15.11.2002 PTV OCC966
1002       if(ShapeAnalysis_Curve::IsPeriodic(aCurve) && (First != Last))  aCurve1 = new Geom_TrimmedCurve(aCurve,First,Last);
1003       else if(pf < (First - Precision::PConfusion()) || 
1004         pl > (Last + Precision::PConfusion())) {
1005           Standard_Real F = Max(First,pf),
1006             L = Min(Last,pl);
1007           if(F != L)
1008             aCurve1 = new Geom_TrimmedCurve(aCurve,F,L);
1009           else aCurve1 = aCurve; 
1010       }
1011       else aCurve1 = aCurve; 
1012       Standard_Integer  aC = Min(ContToInteger(myContinuity3d),ContToInteger(aCurve->Continuity()));
1013       if(!aC)
1014         aC = ContToInteger(myContinuity3d);
1015       //aC = Min(aC,(Deg -1));
1016       Standard_Integer MaxSeg = myNbMaxSeg;
1017       Standard_Integer MaxDeg = myMaxDegree;
1018       //GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
1019       Standard_Integer aC1 = aC;
1020       //Standard_Integer GMaxDegree = 15; //Geom_BSplineCurve::MaxDegree();
1021       for(; aC >= 0; aC--) {
1022         try {
1023           OCC_CATCH_SIGNALS
1024             for(Standard_Integer j = 1; j <=2 ; j++) {
1025               GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
1026               GeomConvert_ApproxCurve anApprox(aCurve1,myTol3d,aCont,MaxSeg,MaxDeg);
1027               Standard_Boolean Done = anApprox.IsDone();
1028               C=anApprox.Curve();
1029               Standard_Integer Nbseg = Handle(Geom_BSplineCurve)::DownCast(C)->NbKnots() - 1;
1030               Standard_Integer DegC = Handle(Geom_BSplineCurve)::DownCast(C)->Degree();
1031               if( myDeg && ((DegC > MaxDeg) || !Done || 
1032                 (anApprox.MaxError() >= Max(TolCur,myTol3d)))) {
1033                   if(MaxSeg < myParameters->GMaxSeg()) { MaxSeg = myParameters->GMaxSeg(); aC =aC1; continue;}
1034                   else {
1035 #ifdef OCCT_DEBUG
1036                     std::cout << "Curve is not aproxed with continuity  "<< aCont<<std::endl;
1037 #endif        
1038                     if(IsConvert) {
1039                       C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
1040                       TolCur =  Precision::Confusion();
1041                       return Standard_True;
1042                     } 
1043                   }
1044               }
1045               if(!myDeg && ((Nbseg > myParameters->GMaxSeg()) || !Done || 
1046                 (anApprox.MaxError() >= Max(TolCur,myTol3d)))) {
1047                   if(MaxDeg < myParameters->GMaxDegree()) { 
1048                     MaxDeg = myParameters->GMaxDegree(); aC = aC1; continue;
1049                   }
1050                   else {
1051 #ifdef OCCT_DEBUG
1052                     std::cout << "Curve is not aproxed with continuity  "<< aCont<<std::endl;
1053 #endif
1054                     if(IsConvert) {
1055                       C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
1056                       TolCur =  Precision::Confusion();
1057                       return Standard_True;
1058                     } 
1059                   }
1060               }
1061               myConvert = Standard_True;
1062               TolCur =  anApprox.MaxError();
1063               myCurve3dError = Max(myCurve3dError,anApprox.MaxError());
1064               return Standard_True;
1065             }
1066         }
1067         catch (Standard_Failure const& anException) {
1068 #ifdef OCCT_DEBUG
1069           std::cout << "Warning: GeomConvert_ApproxCurve Exception: Wrong Coefficient : Decrease continuity    ";
1070           anException.Print(std::cout); std::cout << std::endl;
1071 #endif
1072           (void)anException;
1073           continue;
1074         } 
1075       }
1076       return Standard_False;
1077   }  
1078   else {
1079     if(IsConvert) {
1080       C = Handle(Geom_Curve)::DownCast(aCurve->Copy());
1081       TolCur =  Precision::Confusion();
1082       return Standard_True;
1083     }
1084     return Standard_False;
1085   }
1086 }
1087
1088 //=======================================================================
1089 //function : NewCurve2d
1090 //purpose  : 
1091 //=======================================================================
1092
1093 Standard_Boolean ShapeCustom_BSplineRestriction::NewCurve2d(const TopoDS_Edge& E,
1094                                                             const TopoDS_Face& F,
1095                                                             const TopoDS_Edge& NewE,
1096                                                             const TopoDS_Face& /*NewF*/,
1097                                                             Handle(Geom2d_Curve)& C,
1098                                                             Standard_Real& Tol)
1099 {
1100   if ( ! myApproxCurve2dFlag && !myApproxSurfaceFlag)
1101     return Standard_False;
1102   Standard_Real First, Last,F1,L1;
1103   TopLoc_Location L,Loc1;
1104   Handle(Geom_Surface) aSurface = BRep_Tool::Surface(F,L);
1105   GeomAdaptor_Surface AdS(aSurface);
1106   Standard_Real TolCur = Min(AdS.UResolution(BRep_Tool::Tolerance(E)),AdS.VResolution(BRep_Tool::Tolerance(E)));
1107   Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(E,F,First, Last);
1108   if(aCurve.IsNull()) return Standard_False;
1109   Handle(Geom_Curve) aCur3d = BRep_Tool::Curve(E,Loc1,F1, L1);
1110   //  Standard_Boolean IsConvert = (IsConvertSurface(aSurface,myMaxDegree,myNbMaxSeg) || !E.IsSame(NewE));
1111
1112   Standard_Boolean IsConvert = 
1113     ((myApproxSurfaceFlag && IsConvertSurface(aSurface,myMaxDegree,myNbMaxSeg,myRational,myParameters)) || 
1114     (myApproxCurve3dFlag && IsConvertCurve3d(aCur3d,myMaxDegree,myNbMaxSeg,myRational,myParameters)));
1115
1116   if(!IsConvert) {
1117     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
1118     // iterate on pcurves
1119     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
1120     for ( ; itcr.More(); itcr.Next() ) {
1121       Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
1122       if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
1123       Handle(Geom_Surface) aSurf = GC->Surface();
1124       Handle(Geom2d_Curve) aCur2d = GC->PCurve();
1125       if((myApproxSurfaceFlag && IsConvertSurface(aSurf,myMaxDegree,myNbMaxSeg,myRational,myParameters)) || 
1126         (myApproxCurve2dFlag && IsConvertCurve2d(aCur2d,myMaxDegree,myNbMaxSeg,myRational,myParameters))) {
1127           IsConvert = Standard_True;
1128           break;
1129       }
1130     }
1131   }
1132   if(! myApproxCurve2dFlag){
1133     if(IsConvert) {
1134       C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1135       return Standard_True;
1136     }
1137     else
1138       return Standard_False;
1139   }
1140   Standard_Boolean IsOf = Standard_True;
1141   if(myParameters->ConvertOffsetCurv2d())  IsOf = Standard_False;
1142   Standard_Boolean IsConv = ConvertCurve2d(aCurve,C,IsConvert,First,Last,TolCur,IsOf);
1143
1144   Tol= BRep_Tool::Tolerance(E);//TolCur;
1145   BRep_Builder B;
1146   if(!IsConv && !NewE.IsSame( E)) 
1147     B.Range(NewE,First,Last);
1148   return IsConv;
1149 }
1150
1151 //=======================================================================
1152 //function : ConvertCurve2d
1153 //purpose  : 
1154 //=======================================================================
1155
1156 Standard_Boolean ShapeCustom_BSplineRestriction::ConvertCurve2d(const Handle(Geom2d_Curve)& aCurve,
1157                                                                 Handle(Geom2d_Curve)& C, 
1158                                                                 const Standard_Boolean IsConvert,
1159                                                                 const Standard_Real First, 
1160                                                                 const Standard_Real Last,
1161                                                                 Standard_Real& TolCur,
1162                                                                 const Standard_Boolean IsOf) 
1163 {  
1164   //TolCur = Precision::PConfusion();
1165   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
1166     Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve);
1167     // Standard_Real pf =tmp->FirstParameter(), pl =  tmp->LastParameter();
1168     Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve();
1169     Handle(Geom2d_Curve) ResCurve;
1170     if(ConvertCurve2d(BasCurve,ResCurve,IsConvert,First,Last,TolCur,IsOf)) {
1171       //      Standard_Real F = Max(ResCurve->FirstParameter(),First), L = Min(ResCurve->LastParameter(),Last);
1172       //      if(F != Last)
1173       //C = new Geom2d_TrimmedCurve(ResCurve,Max(First,ResCurve->FirstParameter()),Min(Last,ResCurve->LastParameter()));
1174       //else 
1175       C = ResCurve;
1176       return Standard_True;
1177     }
1178     else {
1179       if(IsConvert) {
1180         C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1181         TolCur = Precision::PConfusion();
1182         return Standard_True;
1183       }
1184       else return Standard_False;
1185     }
1186   }
1187
1188   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_Line)) && myParameters->ConvertCurve2d()) {
1189     Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve);
1190     TColgp_Array1OfPnt2d poles(1,2);
1191     poles(1) = aLine2d->Value(First);
1192     poles(2) = aLine2d->Value(Last);
1193     TColStd_Array1OfReal knots(1,2);
1194     knots(1) = First; knots(2) = Last;
1195     TColStd_Array1OfInteger mults(1,2);
1196     mults.Init(2);
1197     Handle(Geom2d_BSplineCurve) res = new Geom2d_BSplineCurve(poles,knots,mults,1);
1198     C = res;
1199     return Standard_True;
1200   }
1201
1202   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_Conic)) && myParameters->ConvertCurve2d()) {
1203     Handle(Geom2d_BSplineCurve) aBSpline2d;
1204     Handle(Geom2d_Curve) tcurve = new Geom2d_TrimmedCurve(aCurve,First,Last); //protection against parabols ets
1205     Geom2dConvert_ApproxCurve approx (tcurve, myTol2d,myContinuity2d,myNbMaxSeg , 6 );
1206     if ( approx.HasResult() )
1207       aBSpline2d = approx.Curve();
1208     else 
1209       aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
1210
1211     Standard_Real Shift = First - aBSpline2d->FirstParameter();
1212     if(Abs(Shift) > Precision::PConfusion()) {
1213       Standard_Integer nbKnots = aBSpline2d->NbKnots();
1214       TColStd_Array1OfReal newKnots(1,nbKnots);
1215       aBSpline2d->Knots(newKnots);
1216       for (Standard_Integer i = 1; i <= nbKnots; i++)
1217         newKnots(i)+=Shift;
1218       aBSpline2d->SetKnots(newKnots);
1219     }
1220     Handle(Geom2d_Curve) ResCurve;
1221     if(ConvertCurve2d(aBSpline2d,ResCurve,IsConvert,First,Last,TolCur,Standard_False)) {
1222       C = ResCurve;
1223       return Standard_True;
1224     }
1225     else {
1226       C = aBSpline2d;
1227       TolCur = Precision::PConfusion();
1228       return Standard_True;
1229     } 
1230   }
1231
1232   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) && myParameters->ConvertCurve2d()) {
1233     Handle(Geom2d_Curve) aBSpline2d 
1234       = Geom2dConvert::CurveToBSplineCurve(aCurve,Convert_QuasiAngular);
1235     Handle(Geom2d_Curve) ResCurve;
1236     if(ConvertCurve2d(aBSpline2d,ResCurve,IsConvert,First,Last,TolCur,Standard_False)) {
1237       C = ResCurve;
1238       return Standard_True;
1239     }
1240     else {
1241       C = aBSpline2d;
1242       TolCur = Precision::PConfusion();
1243       return Standard_True;
1244     } 
1245   }
1246
1247   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)) && IsOf) {
1248     Handle(Geom2d_OffsetCurve) tmp = Handle(Geom2d_OffsetCurve)::DownCast (aCurve);
1249     Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve();
1250     Handle(Geom2d_Curve) ResCurve;
1251     if(ConvertCurve2d(BasCurve,ResCurve,IsConvert,First,Last,TolCur)) {
1252       if(ResCurve->Continuity() != GeomAbs_C0) {
1253         C = new Geom2d_OffsetCurve(ResCurve,tmp->Offset());
1254         return Standard_True;
1255       }
1256       else if (ConvertCurve2d(aCurve,ResCurve,IsConvert,First,Last,TolCur,Standard_False))
1257         return Standard_True;
1258       else {
1259         if(IsConvert) {
1260           C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1261           TolCur = Precision::PConfusion();
1262           return Standard_True;
1263         }
1264         else return Standard_False;
1265
1266       }
1267     } 
1268     else {
1269       if(IsConvert) {
1270         C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1271         TolCur = Precision::PConfusion();
1272         return Standard_True;
1273       }
1274       else return Standard_False;
1275     }
1276   }
1277   if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) || 
1278       aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))  ||
1279       ((aCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) && !IsOf ))  {
1280       Standard_Integer Deg=1;
1281
1282       if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
1283         Handle(Geom2d_BSplineCurve) BsC = Handle(Geom2d_BSplineCurve)::DownCast (aCurve);
1284         Deg =BsC->Degree();
1285         Standard_Boolean IsR = (myRational && BsC->IsRational());
1286         if(!IsR && Deg <= myMaxDegree && (BsC->NbKnots() -1) <= myNbMaxSeg) {
1287           if(IsConvert) {
1288             C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1289             TolCur = Precision::PConfusion();
1290             return Standard_True;
1291           }
1292           else return Standard_False;
1293         }
1294       }
1295       if (aCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
1296         Handle(Geom2d_BezierCurve)BzC =  Handle(Geom2d_BezierCurve)::DownCast (aCurve);
1297         Deg =BzC->Degree();
1298         Standard_Boolean IsR = (myRational && BzC->IsRational());
1299         if(!IsR && Deg <= myMaxDegree) {
1300           if(IsConvert) {
1301             C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1302             TolCur = Precision::PConfusion();
1303             return Standard_True;
1304           }
1305           else return Standard_False;
1306         }
1307       }
1308       Handle(Geom2d_Curve) aCurve1;
1309       Standard_Real pf =aCurve->FirstParameter(), pl =  aCurve->LastParameter();
1310       // 15.11.2002 PTV OCC966
1311       if(ShapeAnalysis_Curve::IsPeriodic(aCurve) && (First != Last)) aCurve1 = new Geom2d_TrimmedCurve(aCurve,First,Last);
1312       else if(aCurve->FirstParameter() < (First - Precision::PConfusion())  || 
1313         aCurve->LastParameter() > (Last + Precision::PConfusion())) {
1314           Standard_Real F = Max(First,pf),
1315             L = Min(Last,pl);
1316           if(F != L)
1317             aCurve1 = new Geom2d_TrimmedCurve(aCurve,F,L);
1318           else aCurve1 = aCurve;
1319       }
1320       else aCurve1 = aCurve;
1321       Standard_Integer aC = Min(ContToInteger(myContinuity2d),ContToInteger( aCurve->Continuity()));
1322       if(!aC)
1323         aC = ContToInteger(myContinuity2d);
1324       //aC = Min(aC,(Deg -1));
1325       Standard_Integer aC1 = aC;
1326       //GeomAbs_Shape aCont =IntegerToGeomAbsShape(aC);
1327       Standard_Integer MaxSeg = myNbMaxSeg;
1328       Standard_Integer MaxDeg = myMaxDegree;
1329       //Standard_Integer GMaxDegree = 15;//Geom2d_BSplineCurve::MaxDegree();
1330       for(; aC >= 0; aC--) {
1331         try {
1332           OCC_CATCH_SIGNALS
1333             GeomAbs_Shape aCont = IntegerToGeomAbsShape(aC);
1334           for(Standard_Integer j =1;j<=2 ;j++) {
1335             Geom2dConvert_ApproxCurve anApprox(aCurve1,myTol2d,aCont,MaxSeg,MaxDeg);
1336             Standard_Boolean Done = anApprox.IsDone();
1337             C=anApprox.Curve();
1338             Standard_Integer Nbseg = Handle(Geom2d_BSplineCurve)::DownCast(C)->NbKnots() -1;
1339             Standard_Integer DegC = Handle(Geom2d_BSplineCurve)::DownCast(C)->Degree();
1340
1341             if(myDeg && ((DegC > MaxDeg)  || !Done || ( anApprox.MaxError() >= Max(myTol2d,TolCur)))) {
1342               if(MaxSeg < myParameters->GMaxSeg()) { MaxSeg = myParameters->GMaxSeg(); aC =aC1; continue;}
1343               else {
1344 #ifdef OCCT_DEBUG
1345                 std::cout << "Curve is not aproxed with continuity  "<< aCont<<std::endl;
1346 #endif
1347                 if(IsConvert) {
1348                   C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1349                   TolCur = Precision::PConfusion();
1350                   return Standard_True;
1351                 } 
1352               }
1353             }
1354
1355             if(!myDeg && (( Nbseg >= MaxSeg)|| !Done || ( anApprox.MaxError() >= Max(myTol2d,TolCur)))) {
1356               if(MaxDeg < myParameters->GMaxDegree()) { 
1357                 MaxDeg = myParameters->GMaxDegree(); aC =aC1; continue;
1358               }
1359               else {
1360 #ifdef OCCT_DEBUG
1361                 std::cout << "Curve is not aproxed with continuity  "<< aCont<<std::endl;
1362 #endif
1363                 if(IsConvert) {
1364                   C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1365                   TolCur = Precision::PConfusion();
1366                   return Standard_True;
1367                 } 
1368               }
1369             }
1370             myConvert= Standard_True; 
1371             TolCur = anApprox.MaxError();
1372             myCurve2dError = Max(myCurve2dError,anApprox.MaxError());
1373             return Standard_True;
1374           }
1375         }
1376         catch (Standard_Failure const& anException) {
1377 #ifdef OCCT_DEBUG
1378           std::cout << "Warning: Geom2dConvert_ApproxCurve Exception: Wrong Cofficient :Decrease Continuity    ";
1379           anException.Print(std::cout); std::cout << std::endl;
1380 #endif
1381           (void)anException;
1382           continue;
1383         }
1384       }
1385       return Standard_False;
1386   }  
1387   else {
1388     if(IsConvert) {
1389       C = Handle(Geom2d_Curve)::DownCast(aCurve->Copy());
1390       TolCur = Precision::PConfusion();
1391       return Standard_True;
1392     }
1393     else return Standard_False;
1394   }
1395 }
1396
1397 //=======================================================================
1398 //function : NewPoint
1399 //purpose  : 
1400 //=======================================================================
1401
1402 Standard_Boolean ShapeCustom_BSplineRestriction::NewPoint(const TopoDS_Vertex& V,
1403                                                           gp_Pnt& P,
1404                                                           Standard_Real& Tol)
1405 {
1406   Tol = BRep_Tool::Tolerance(V);
1407   if(myConvert) {
1408     gp_Pnt p1(BRep_Tool::Pnt(V).XYZ());
1409     P = p1; 
1410     return Standard_True;
1411   }
1412   else 
1413     return Standard_False;
1414 }
1415
1416 //=======================================================================
1417 //function : NewParameter
1418 //purpose  : 
1419 //=======================================================================
1420
1421 Standard_Boolean ShapeCustom_BSplineRestriction::NewParameter(const TopoDS_Vertex& /*V*/,
1422                                                               const TopoDS_Edge& /*E*/,
1423                                                               Standard_Real& /*P*/,
1424                                                               Standard_Real& /*Tol*/)
1425 {
1426   return Standard_False;
1427 }
1428
1429 //=======================================================================
1430 //function : Continuity
1431 //purpose  : 
1432 //=======================================================================
1433
1434 GeomAbs_Shape ShapeCustom_BSplineRestriction::Continuity(const TopoDS_Edge& E,
1435                                                          const TopoDS_Face& F1,
1436                                                          const TopoDS_Face& F2,
1437                                                          const TopoDS_Edge& /*NewE*/,
1438                                                          const TopoDS_Face& /*NewF1*/,
1439                                                          const TopoDS_Face& /*NewF2*/)
1440 {
1441   return BRep_Tool::Continuity(E,F1,F2);
1442 }
1443
1444 //=======================================================================
1445 //function : MaxErrors
1446 //purpose  : 
1447 //=======================================================================
1448
1449 Standard_Real ShapeCustom_BSplineRestriction::MaxErrors(Standard_Real& aCurve3dErr,Standard_Real& aCurve2dErr) const
1450 {
1451   aCurve3dErr = myCurve3dError;
1452   aCurve2dErr = myCurve2dError;
1453   return mySurfaceError;
1454 }
1455
1456 //=======================================================================
1457 //function : NbOfSpan
1458 //purpose  : 
1459 //======================================================================
1460
1461 Standard_Integer ShapeCustom_BSplineRestriction::NbOfSpan() const
1462 {
1463   return myNbOfSpan;
1464 }
1465