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