| 1 | // Created on: 2000-11-16 |
| 2 | // Created by: Peter KURNEV |
| 3 | // Copyright (c) 2000-2014 OPEN CASCADE SAS |
| 4 | // |
| 5 | // This file is part of Open CASCADE Technology software library. |
| 6 | // |
| 7 | // This library is free software; you can redistribute it and/or modify it under |
| 8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 9 | // by the Free Software Foundation, with special exception defined in the file |
| 10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 11 | // distribution for complete text of the license and disclaimer of any warranty. |
| 12 | // |
| 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 14 | // commercial license or contractual agreement. |
| 15 | |
| 16 | #include <IntTools_Tools.ixx> |
| 17 | |
| 18 | #include <Precision.hxx> |
| 19 | |
| 20 | #include <TopExp_Explorer.hxx> |
| 21 | #include <TopTools_IndexedDataMapOfShapeShape.hxx> |
| 22 | |
| 23 | #include <TopoDS.hxx> |
| 24 | #include <TopoDS_Shape.hxx> |
| 25 | #include <TopoDS_Vertex.hxx> |
| 26 | #include <TopoDS_Edge.hxx> |
| 27 | #include <TopoDS_Face.hxx> |
| 28 | #include <TopoDS_Wire.hxx> |
| 29 | #include <TopLoc_Location.hxx> |
| 30 | |
| 31 | #include <BRep_Builder.hxx> |
| 32 | #include <BRep_Tool.hxx> |
| 33 | #include <BRepAdaptor_Surface.hxx> |
| 34 | #include <BRepAdaptor_Curve.hxx> |
| 35 | #include <BRepAdaptor_Surface.hxx> |
| 36 | |
| 37 | #include <gp_Pnt.hxx> |
| 38 | #include <gp_Pnt2d.hxx> |
| 39 | #include <gp.hxx> |
| 40 | #include <gp_Lin.hxx> |
| 41 | #include <gp_Dir.hxx> |
| 42 | #include <gp_Ax1.hxx> |
| 43 | |
| 44 | #include <Geom_Curve.hxx> |
| 45 | #include <GeomAdaptor_Surface.hxx> |
| 46 | #include <Geom_Surface.hxx> |
| 47 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
| 48 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
| 49 | #include <GeomAdaptor_Curve.hxx> |
| 50 | #include <GeomAbs_CurveType.hxx> |
| 51 | #include <Geom_Line.hxx> |
| 52 | #include <Geom2d_Curve.hxx> |
| 53 | #include <Geom_BoundedCurve.hxx> |
| 54 | #include <Geom_Geometry.hxx> |
| 55 | #include <Geom_TrimmedCurve.hxx> |
| 56 | #include <Geom2d_TrimmedCurve.hxx> |
| 57 | |
| 58 | #include <IntTools_FClass2d.hxx> |
| 59 | #include <IntTools_Curve.hxx> |
| 60 | #include <IntTools_SequenceOfCurves.hxx> |
| 61 | |
| 62 | static |
| 63 | void ParabolaTolerance(const Handle(Geom_Curve)& , |
| 64 | const Standard_Real , |
| 65 | const Standard_Real , |
| 66 | const Standard_Real , |
| 67 | Standard_Real& , |
| 68 | Standard_Real& ); |
| 69 | |
| 70 | //======================================================================= |
| 71 | //function : HasInternalEdge |
| 72 | //purpose : |
| 73 | //======================================================================= |
| 74 | Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW) |
| 75 | { |
| 76 | Standard_Boolean bFlag=Standard_True; |
| 77 | |
| 78 | TopExp_Explorer anExp(aW, TopAbs_EDGE); |
| 79 | for (; anExp.More(); anExp.Next()) { |
| 80 | const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current()); |
| 81 | TopAbs_Orientation anOr=aE.Orientation(); |
| 82 | if (anOr==TopAbs_INTERNAL) { |
| 83 | return bFlag; |
| 84 | } |
| 85 | } |
| 86 | return !bFlag; |
| 87 | } |
| 88 | |
| 89 | //======================================================================= |
| 90 | //function : IsClosed |
| 91 | //purpose : |
| 92 | //======================================================================= |
| 93 | Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D) |
| 94 | { |
| 95 | Standard_Boolean bRet; |
| 96 | Standard_Real aF, aL, aDist, aPC; |
| 97 | gp_Pnt aP1, aP2; |
| 98 | |
| 99 | Handle (Geom_BoundedCurve) aGBC= |
| 100 | Handle (Geom_BoundedCurve)::DownCast(aC3D); |
| 101 | if (aGBC.IsNull()) { |
| 102 | return Standard_False; |
| 103 | } |
| 104 | |
| 105 | aF=aC3D->FirstParameter(); |
| 106 | aL=aC3D-> LastParameter(); |
| 107 | |
| 108 | aC3D->D0(aF, aP1); |
| 109 | aC3D->D0(aL, aP2); |
| 110 | |
| 111 | |
| 112 | // |
| 113 | //modified by NIZNHY-PKV Mon Jul 04 11:58:23 2011f |
| 114 | aPC=Precision::Confusion(); |
| 115 | aPC=aPC*aPC; |
| 116 | aDist=aP1.SquareDistance(aP2); |
| 117 | bRet=aDist<aPC; |
| 118 | return bRet; |
| 119 | // |
| 120 | //aDist=aP1.Distance(aP2); |
| 121 | //return (aDist < Precision::Confusion()); |
| 122 | //modified by NIZNHY-PKV Mon Jul 04 11:59:50 2011t |
| 123 | } |
| 124 | |
| 125 | //======================================================================= |
| 126 | //function : RejectLines |
| 127 | //purpose : |
| 128 | //======================================================================= |
| 129 | void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn, |
| 130 | IntTools_SequenceOfCurves& aSOut) |
| 131 | { |
| 132 | Standard_Integer i, j, aNb; |
| 133 | Standard_Boolean bFlag; |
| 134 | Handle (Geom_Curve) aC3D; |
| 135 | |
| 136 | gp_Dir aD1, aD2; |
| 137 | |
| 138 | aSOut.Clear(); |
| 139 | |
| 140 | aNb=aSIn.Length(); |
| 141 | for (i=1; i<=aNb; i++) { |
| 142 | const IntTools_Curve& IC=aSIn(i); |
| 143 | aC3D=IC.Curve(); |
| 144 | // |
| 145 | Handle (Geom_TrimmedCurve) aGTC= |
| 146 | Handle (Geom_TrimmedCurve)::DownCast(aC3D); |
| 147 | |
| 148 | if (!aGTC.IsNull()) { |
| 149 | aC3D=aGTC->BasisCurve(); |
| 150 | IntTools_Curve* pIC=(IntTools_Curve*) &IC; |
| 151 | pIC->SetCurve(aC3D); |
| 152 | } |
| 153 | // |
| 154 | Handle (Geom_Line) aGLine= |
| 155 | Handle (Geom_Line)::DownCast(aC3D); |
| 156 | |
| 157 | if (aGLine.IsNull()) { |
| 158 | aSOut.Clear(); |
| 159 | for (j=1; j<=aNb; j++) { |
| 160 | aSOut.Append(aSIn(j)); |
| 161 | } |
| 162 | return; |
| 163 | } |
| 164 | // |
| 165 | gp_Lin aLin=aGLine->Lin(); |
| 166 | aD2=aLin.Direction(); |
| 167 | if (i==1) { |
| 168 | aSOut.Append(IC); |
| 169 | aD1=aD2; |
| 170 | continue; |
| 171 | } |
| 172 | |
| 173 | bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2); |
| 174 | if (!bFlag) { |
| 175 | aSOut.Append(IC); |
| 176 | return; |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | //======================================================================= |
| 182 | //function : IsDirsCoinside |
| 183 | //purpose : |
| 184 | //======================================================================= |
| 185 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2) |
| 186 | { |
| 187 | Standard_Boolean bFlag; |
| 188 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); |
| 189 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); |
| 190 | Standard_Real dLim=0.0002, d; |
| 191 | d=P1.Distance (P2); |
| 192 | bFlag= (d<dLim || fabs (2.-d)<dLim); |
| 193 | return bFlag; |
| 194 | } |
| 195 | |
| 196 | //======================================================================= |
| 197 | //function : IsDirsCoinside |
| 198 | //purpose : |
| 199 | //======================================================================= |
| 200 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, |
| 201 | const gp_Dir& D2, |
| 202 | const Standard_Real dLim) |
| 203 | { |
| 204 | Standard_Boolean bFlag; |
| 205 | Standard_Real d; |
| 206 | // |
| 207 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); |
| 208 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); |
| 209 | d=P1.Distance (P2); |
| 210 | bFlag= (d<dLim || fabs (2.-d)<dLim); |
| 211 | return bFlag; |
| 212 | } |
| 213 | //======================================================================= |
| 214 | //function : SplitCurve |
| 215 | //purpose : |
| 216 | //======================================================================= |
| 217 | Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC, |
| 218 | IntTools_SequenceOfCurves& aCvs) |
| 219 | { |
| 220 | Handle (Geom_Curve) aC3D =IC.Curve(); |
| 221 | if(aC3D.IsNull()) |
| 222 | return 0; |
| 223 | // |
| 224 | Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d(); |
| 225 | Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d(); |
| 226 | Standard_Boolean bIsClosed; |
| 227 | |
| 228 | bIsClosed=IntTools_Tools::IsClosed(aC3D); |
| 229 | if (!bIsClosed) { |
| 230 | return 0; |
| 231 | } |
| 232 | |
| 233 | Standard_Real aF, aL, aMid; |
| 234 | |
| 235 | // |
| 236 | aF=aC3D->FirstParameter(); |
| 237 | aL=aC3D->LastParameter(); |
| 238 | aMid=0.5*(aF+aL); |
| 239 | GeomAdaptor_Curve aGAC(aC3D); |
| 240 | GeomAbs_CurveType aCT=aGAC.GetType(); |
| 241 | if (aCT==GeomAbs_BSplineCurve || |
| 242 | aCT==GeomAbs_BezierCurve) { |
| 243 | //aMid=0.5*aMid; |
| 244 | aMid=IntTools_Tools::IntermediatePoint(aF, aL); |
| 245 | } |
| 246 | // |
| 247 | Handle(Geom_Curve) aC3DNewF, aC3DNewL; |
| 248 | aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid); |
| 249 | aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL); |
| 250 | |
| 251 | // |
| 252 | Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L; |
| 253 | // |
| 254 | if(!aC2D1.IsNull()) { |
| 255 | aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid); |
| 256 | aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL); |
| 257 | } |
| 258 | |
| 259 | if(!aC2D2.IsNull()) { |
| 260 | aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid); |
| 261 | aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL); |
| 262 | } |
| 263 | // |
| 264 | |
| 265 | IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F); |
| 266 | IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L); |
| 267 | // |
| 268 | aCvs.Append(aIC1); |
| 269 | // |
| 270 | aCvs.Append(aIC2); |
| 271 | // |
| 272 | return 2; |
| 273 | } |
| 274 | |
| 275 | //======================================================================= |
| 276 | //function : IntermediatePoint |
| 277 | //purpose : |
| 278 | //======================================================================= |
| 279 | Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst, |
| 280 | const Standard_Real aLast) |
| 281 | { |
| 282 | //define parameter division number as 10*e^(-M_PI) = 0.43213918 |
| 283 | const Standard_Real PAR_T = 0.43213918; |
| 284 | Standard_Real aParm; |
| 285 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; |
| 286 | return aParm; |
| 287 | } |
| 288 | |
| 289 | //======================================================================= |
| 290 | //function : IsVertex |
| 291 | //purpose : |
| 292 | //======================================================================= |
| 293 | Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP, |
| 294 | const Standard_Real aTolPV, |
| 295 | const TopoDS_Vertex& aV) |
| 296 | { |
| 297 | Standard_Boolean bRet; |
| 298 | Standard_Real aTolV, aD, dTol; |
| 299 | gp_Pnt aPv; |
| 300 | |
| 301 | aTolV=BRep_Tool::Tolerance(aV); |
| 302 | // |
| 303 | dTol=Precision::Confusion(); |
| 304 | aTolV=aTolV+aTolPV+dTol; |
| 305 | // |
| 306 | aPv=BRep_Tool::Pnt(aV); |
| 307 | // |
| 308 | //modified by NIZNHY-PKV Mon Jul 04 12:00:37 2011f |
| 309 | aD=aPv.SquareDistance(aP); |
| 310 | aTolV=aTolV*aTolV; |
| 311 | bRet=(aD<=aTolV); |
| 312 | return bRet; |
| 313 | // |
| 314 | //aD=aPv.Distance(aP); |
| 315 | //return (aD<=aTolV); |
| 316 | //modified by NIZNHY-PKV Mon Jul 04 12:00:40 2011t |
| 317 | } |
| 318 | |
| 319 | |
| 320 | //======================================================================= |
| 321 | //function : IsVertex |
| 322 | //purpose : |
| 323 | //======================================================================= |
| 324 | Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt) |
| 325 | { |
| 326 | Standard_Boolean anIsVertex; |
| 327 | Standard_Real aParam; |
| 328 | |
| 329 | const TopoDS_Edge& aE1=aCmnPrt.Edge1(); |
| 330 | const IntTools_Range& aR1=aCmnPrt.Range1(); |
| 331 | aParam=0.5*(aR1.First()+aR1.Last()); |
| 332 | anIsVertex=IntTools_Tools::IsVertex (aE1, aParam); |
| 333 | |
| 334 | if (anIsVertex) { |
| 335 | return Standard_True; |
| 336 | } |
| 337 | |
| 338 | const TopoDS_Edge& aE2=aCmnPrt.Edge2(); |
| 339 | const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2(); |
| 340 | const IntTools_Range& aR2=aRs2(1); |
| 341 | aParam=0.5*(aR2.First()+aR2.Last()); |
| 342 | anIsVertex=IntTools_Tools::IsVertex (aE2, aParam); |
| 343 | if (anIsVertex) { |
| 344 | return Standard_True; |
| 345 | } |
| 346 | return Standard_False; |
| 347 | } |
| 348 | |
| 349 | //======================================================================= |
| 350 | //function : IsVertex |
| 351 | //purpose : |
| 352 | //======================================================================= |
| 353 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, |
| 354 | const TopoDS_Vertex& aV, |
| 355 | const Standard_Real t) |
| 356 | { |
| 357 | Standard_Real aTolV, aTolV2, d2; |
| 358 | gp_Pnt aPv, aPt; |
| 359 | |
| 360 | BRepAdaptor_Curve aBAC(aE); |
| 361 | aBAC.D0(t, aPt); |
| 362 | |
| 363 | aTolV=BRep_Tool::Tolerance(aV); |
| 364 | aTolV2=aTolV*aTolV; |
| 365 | aPv=BRep_Tool::Pnt(aV); |
| 366 | d2=aPv.SquareDistance (aPt); |
| 367 | if (d2 < aTolV2) { |
| 368 | return Standard_True; |
| 369 | } |
| 370 | return Standard_False; |
| 371 | } |
| 372 | //======================================================================= |
| 373 | //function : IsVertex |
| 374 | //purpose : |
| 375 | //======================================================================= |
| 376 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, |
| 377 | const Standard_Real t) |
| 378 | { |
| 379 | Standard_Real aTolV, aTolV2, d2; |
| 380 | TopoDS_Vertex aV; |
| 381 | gp_Pnt aPv, aPt; |
| 382 | |
| 383 | BRepAdaptor_Curve aBAC(aE); |
| 384 | aBAC.D0(t, aPt); |
| 385 | |
| 386 | TopExp_Explorer anExp(aE, TopAbs_VERTEX); |
| 387 | for (; anExp.More(); anExp.Next()) { |
| 388 | aV=TopoDS::Vertex (anExp.Current()); |
| 389 | aTolV=BRep_Tool::Tolerance(aV); |
| 390 | aTolV2=aTolV*aTolV; |
| 391 | aTolV2=1.e-12; |
| 392 | aPv=BRep_Tool::Pnt(aV); |
| 393 | d2=aPv.SquareDistance (aPt); |
| 394 | if (d2 < aTolV2) { |
| 395 | return Standard_True; |
| 396 | } |
| 397 | } |
| 398 | return Standard_False; |
| 399 | } |
| 400 | |
| 401 | |
| 402 | //======================================================================= |
| 403 | //function : ComputeVV |
| 404 | //purpose : |
| 405 | //======================================================================= |
| 406 | Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1, |
| 407 | const TopoDS_Vertex& aV2) |
| 408 | { |
| 409 | Standard_Real aTolV1, aTolV2, aTolSum, d; |
| 410 | gp_Pnt aP1, aP2; |
| 411 | |
| 412 | aTolV1=BRep_Tool::Tolerance(aV1); |
| 413 | aTolV2=BRep_Tool::Tolerance(aV2); |
| 414 | aTolSum=aTolV1+aTolV2; |
| 415 | |
| 416 | aP1=BRep_Tool::Pnt(aV1); |
| 417 | aP2=BRep_Tool::Pnt(aV2); |
| 418 | //modified by NIZNHY-PKV Mon Jul 04 11:55:52 2011f |
| 419 | aTolSum=aTolSum*aTolSum; |
| 420 | d=aP1.SquareDistance(aP2); |
| 421 | //d=aP1.Distance(aP2); |
| 422 | //modified by NIZNHY-PKV Mon Jul 04 11:55:53 2011t |
| 423 | if (d<aTolSum) { |
| 424 | return 0; |
| 425 | } |
| 426 | return -1; |
| 427 | } |
| 428 | |
| 429 | //======================================================================= |
| 430 | //function : MakeFaceFromWireAndFace |
| 431 | //purpose : |
| 432 | //======================================================================= |
| 433 | void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW, |
| 434 | const TopoDS_Face& aF, |
| 435 | TopoDS_Face& aFNew) |
| 436 | { |
| 437 | TopoDS_Face aFF; |
| 438 | aFF=aF; |
| 439 | aFF.Orientation(TopAbs_FORWARD); |
| 440 | aFNew=TopoDS::Face (aFF.EmptyCopied()); |
| 441 | BRep_Builder BB; |
| 442 | BB.Add(aFNew, aW); |
| 443 | } |
| 444 | |
| 445 | //======================================================================= |
| 446 | //function : ClassifyPointByFace |
| 447 | //purpose : |
| 448 | //======================================================================= |
| 449 | TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF, |
| 450 | const gp_Pnt2d& aP2d) |
| 451 | { |
| 452 | Standard_Real aFaceTolerance; |
| 453 | TopAbs_State aState; |
| 454 | |
| 455 | aFaceTolerance=BRep_Tool::Tolerance(aF); |
| 456 | IntTools_FClass2d aClass2d(aF, aFaceTolerance); |
| 457 | aState=aClass2d.Perform(aP2d); |
| 458 | |
| 459 | return aState; |
| 460 | } |
| 461 | |
| 462 | //======================================================================= |
| 463 | //function : IsMiddlePointsEqual |
| 464 | //purpose : |
| 465 | //======================================================================= |
| 466 | Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1, |
| 467 | const TopoDS_Edge& aE2) |
| 468 | |
| 469 | { |
| 470 | Standard_Boolean bRet; |
| 471 | Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2; |
| 472 | gp_Pnt aP1, aP2; |
| 473 | |
| 474 | aTol1=BRep_Tool::Tolerance(aE1); |
| 475 | Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1); |
| 476 | m1=0.5*(f1+l1); |
| 477 | C1->D0(m1, aP1); |
| 478 | |
| 479 | aTol2=BRep_Tool::Tolerance(aE2); |
| 480 | Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2); |
| 481 | m2=0.5*(f2+l2); |
| 482 | C2->D0(m2, aP2); |
| 483 | |
| 484 | aSumTol=aTol1+aTol2; |
| 485 | //modified by NIZNHY-PKV Mon Jul 04 12:02:20 2011f |
| 486 | aSumTol=aSumTol*aSumTol; |
| 487 | aD2=aP1.SquareDistance(aP2); |
| 488 | bRet=aD2<aSumTol; |
| 489 | return bRet; |
| 490 | // |
| 491 | //if (aP1.Distance(aP2) < aSumTol) { |
| 492 | // return Standard_True; |
| 493 | //} |
| 494 | //return Standard_False; |
| 495 | //modified by NIZNHY-PKV Mon Jul 04 12:02:24 2011t |
| 496 | } |
| 497 | |
| 498 | //======================================================================= |
| 499 | //function : CurveTolerance |
| 500 | //purpose : |
| 501 | //======================================================================= |
| 502 | Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D, |
| 503 | const Standard_Real aTolBase) |
| 504 | { |
| 505 | Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax; |
| 506 | |
| 507 | aTolReached=aTolBase; |
| 508 | // |
| 509 | if (aC3D.IsNull()) { |
| 510 | return aTolReached; |
| 511 | } |
| 512 | // |
| 513 | Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D); |
| 514 | if (aCT3D.IsNull()) { |
| 515 | return aTolReached; |
| 516 | } |
| 517 | // |
| 518 | aTolMin=aTolBase; |
| 519 | aTolMax=aTolBase; |
| 520 | // |
| 521 | aTf=aCT3D->FirstParameter(); |
| 522 | aTl=aCT3D->LastParameter(); |
| 523 | // |
| 524 | GeomAdaptor_Curve aGAC(aCT3D); |
| 525 | GeomAbs_CurveType aCType=aGAC.GetType(); |
| 526 | // |
| 527 | if (aCType==GeomAbs_Parabola) { |
| 528 | Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve(); |
| 529 | ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax); |
| 530 | aTolReached=aTolMax; |
| 531 | } |
| 532 | // |
| 533 | return aTolReached; |
| 534 | } |
| 535 | |
| 536 | #include <Geom_Parabola.hxx> |
| 537 | #include <gp_Parab.hxx> |
| 538 | //======================================================================= |
| 539 | //function : ParabolaTolerance |
| 540 | //purpose : |
| 541 | //======================================================================= |
| 542 | void ParabolaTolerance(const Handle(Geom_Curve)& aC3D, |
| 543 | const Standard_Real aTf, |
| 544 | const Standard_Real aTl, |
| 545 | const Standard_Real aTol, |
| 546 | Standard_Real& aTolMin, |
| 547 | Standard_Real& aTolMax) |
| 548 | { |
| 549 | |
| 550 | aTolMin=aTol; |
| 551 | aTolMax=aTol; |
| 552 | |
| 553 | Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D); |
| 554 | if (aGP.IsNull()){ |
| 555 | return; |
| 556 | } |
| 557 | |
| 558 | Standard_Integer aNbPoints; |
| 559 | Standard_Real aFocal, aX1, aX2, aTol1, aTol2; |
| 560 | gp_Pnt aPf, aPl; |
| 561 | gp_Parab aParab=aGP->Parab(); |
| 562 | gp_Ax1 aXAxis=aParab.XAxis(); |
| 563 | Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis); |
| 564 | |
| 565 | aFocal=aGP->Focal(); |
| 566 | if (aFocal==0.) { |
| 567 | return; |
| 568 | } |
| 569 | // |
| 570 | // aTol1 |
| 571 | aTol1=aTol; |
| 572 | aX1=0.; |
| 573 | aGP->D0(aTf, aPf); |
| 574 | GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis); |
| 575 | aNbPoints=aProj1.NbPoints(); |
| 576 | if (aNbPoints) { |
| 577 | aX1=aProj1.LowerDistanceParameter(); |
| 578 | } |
| 579 | if (aX1>=0.) { |
| 580 | aTol1=aTol*sqrt(0.5*aX1/aFocal); |
| 581 | } |
| 582 | if (aTol1==0.) { |
| 583 | aTol1=aTol; |
| 584 | } |
| 585 | // |
| 586 | // aTol2 |
| 587 | aTol2=aTol; |
| 588 | aX2=0.; |
| 589 | aGP->D0(aTl, aPl); |
| 590 | GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis); |
| 591 | aNbPoints=aProj2.NbPoints(); |
| 592 | if (aNbPoints) { |
| 593 | aX2=aProj2.LowerDistanceParameter(); |
| 594 | } |
| 595 | |
| 596 | if (aX2>=0.) { |
| 597 | aTol2=aTol*sqrt(0.5*aX2/aFocal); |
| 598 | } |
| 599 | if (aTol2==0.) { |
| 600 | aTol2=aTol; |
| 601 | } |
| 602 | // |
| 603 | aTolMax=(aTol1>aTol2) ? aTol1 : aTol2; |
| 604 | aTolMin=(aTol1<aTol2) ? aTol1 : aTol2; |
| 605 | } |
| 606 | |