| 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 | |
| 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 | |
| 80 | static 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 | |
| 93 | static 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 | |
| 108 | static 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 | |
| 144 | static 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 | |
| 211 | static 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 | |
| 248 | ShapeCustom_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 | |
| 270 | ShapeCustom_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 | |
| 302 | ShapeCustom_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 | |
| 340 | Standard_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 | |
| 385 | static 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 | |
| 423 | Standard_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 ); |
| 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); |
| 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 ); |
| 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); |
| 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 || aCU != 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 | |
| 771 | Standard_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 | |
| 818 | Standard_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 | |
| 1063 | Standard_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 | |
| 1126 | Standard_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 | |
| 1371 | Standard_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 | |
| 1390 | Standard_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 | |
| 1403 | GeomAbs_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 | |
| 1418 | Standard_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 | |
| 1430 | Standard_Integer ShapeCustom_BSplineRestriction::NbOfSpan() const |
| 1431 | { |
| 1432 | return myNbOfSpan; |
| 1433 | } |
| 1434 | |