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