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