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