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