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