| 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 | aPC=Precision::Confusion(); |
| 114 | aPC=aPC*aPC; |
| 115 | aDist=aP1.SquareDistance(aP2); |
| 116 | bRet=aDist<aPC; |
| 117 | return bRet; |
| 118 | } |
| 119 | |
| 120 | //======================================================================= |
| 121 | //function : RejectLines |
| 122 | //purpose : |
| 123 | //======================================================================= |
| 124 | void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn, |
| 125 | IntTools_SequenceOfCurves& aSOut) |
| 126 | { |
| 127 | Standard_Integer i, j, aNb; |
| 128 | Standard_Boolean bFlag; |
| 129 | Handle (Geom_Curve) aC3D; |
| 130 | |
| 131 | gp_Dir aD1, aD2; |
| 132 | |
| 133 | aSOut.Clear(); |
| 134 | |
| 135 | aNb=aSIn.Length(); |
| 136 | for (i=1; i<=aNb; i++) { |
| 137 | const IntTools_Curve& IC=aSIn(i); |
| 138 | aC3D=IC.Curve(); |
| 139 | // |
| 140 | Handle (Geom_TrimmedCurve) aGTC= |
| 141 | Handle (Geom_TrimmedCurve)::DownCast(aC3D); |
| 142 | |
| 143 | if (!aGTC.IsNull()) { |
| 144 | aC3D=aGTC->BasisCurve(); |
| 145 | IntTools_Curve* pIC=(IntTools_Curve*) &IC; |
| 146 | pIC->SetCurve(aC3D); |
| 147 | } |
| 148 | // |
| 149 | Handle (Geom_Line) aGLine= |
| 150 | Handle (Geom_Line)::DownCast(aC3D); |
| 151 | |
| 152 | if (aGLine.IsNull()) { |
| 153 | aSOut.Clear(); |
| 154 | for (j=1; j<=aNb; j++) { |
| 155 | aSOut.Append(aSIn(j)); |
| 156 | } |
| 157 | return; |
| 158 | } |
| 159 | // |
| 160 | gp_Lin aLin=aGLine->Lin(); |
| 161 | aD2=aLin.Direction(); |
| 162 | if (i==1) { |
| 163 | aSOut.Append(IC); |
| 164 | aD1=aD2; |
| 165 | continue; |
| 166 | } |
| 167 | |
| 168 | bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2); |
| 169 | if (!bFlag) { |
| 170 | aSOut.Append(IC); |
| 171 | return; |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | //======================================================================= |
| 177 | //function : IsDirsCoinside |
| 178 | //purpose : |
| 179 | //======================================================================= |
| 180 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2) |
| 181 | { |
| 182 | Standard_Boolean bFlag; |
| 183 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); |
| 184 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); |
| 185 | Standard_Real dLim=0.0002, d; |
| 186 | d=P1.Distance (P2); |
| 187 | bFlag= (d<dLim || fabs (2.-d)<dLim); |
| 188 | return bFlag; |
| 189 | } |
| 190 | |
| 191 | //======================================================================= |
| 192 | //function : IsDirsCoinside |
| 193 | //purpose : |
| 194 | //======================================================================= |
| 195 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, |
| 196 | const gp_Dir& D2, |
| 197 | const Standard_Real dLim) |
| 198 | { |
| 199 | Standard_Boolean bFlag; |
| 200 | Standard_Real d; |
| 201 | // |
| 202 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); |
| 203 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); |
| 204 | d=P1.Distance (P2); |
| 205 | bFlag= (d<dLim || fabs (2.-d)<dLim); |
| 206 | return bFlag; |
| 207 | } |
| 208 | //======================================================================= |
| 209 | //function : SplitCurve |
| 210 | //purpose : |
| 211 | //======================================================================= |
| 212 | Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC, |
| 213 | IntTools_SequenceOfCurves& aCvs) |
| 214 | { |
| 215 | Handle (Geom_Curve) aC3D =IC.Curve(); |
| 216 | if(aC3D.IsNull()) |
| 217 | return 0; |
| 218 | // |
| 219 | Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d(); |
| 220 | Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d(); |
| 221 | Standard_Boolean bIsClosed; |
| 222 | |
| 223 | bIsClosed=IntTools_Tools::IsClosed(aC3D); |
| 224 | if (!bIsClosed) { |
| 225 | return 0; |
| 226 | } |
| 227 | |
| 228 | Standard_Real aF, aL, aMid; |
| 229 | |
| 230 | // |
| 231 | aF=aC3D->FirstParameter(); |
| 232 | aL=aC3D->LastParameter(); |
| 233 | aMid=0.5*(aF+aL); |
| 234 | GeomAdaptor_Curve aGAC(aC3D); |
| 235 | GeomAbs_CurveType aCT=aGAC.GetType(); |
| 236 | if (aCT==GeomAbs_BSplineCurve || |
| 237 | aCT==GeomAbs_BezierCurve) { |
| 238 | //aMid=0.5*aMid; |
| 239 | aMid=IntTools_Tools::IntermediatePoint(aF, aL); |
| 240 | } |
| 241 | // |
| 242 | Handle(Geom_Curve) aC3DNewF, aC3DNewL; |
| 243 | aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid); |
| 244 | aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL); |
| 245 | |
| 246 | // |
| 247 | Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L; |
| 248 | // |
| 249 | if(!aC2D1.IsNull()) { |
| 250 | aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid); |
| 251 | aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL); |
| 252 | } |
| 253 | |
| 254 | if(!aC2D2.IsNull()) { |
| 255 | aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid); |
| 256 | aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL); |
| 257 | } |
| 258 | // |
| 259 | |
| 260 | IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F); |
| 261 | IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L); |
| 262 | // |
| 263 | aCvs.Append(aIC1); |
| 264 | // |
| 265 | aCvs.Append(aIC2); |
| 266 | // |
| 267 | return 2; |
| 268 | } |
| 269 | |
| 270 | //======================================================================= |
| 271 | //function : IntermediatePoint |
| 272 | //purpose : |
| 273 | //======================================================================= |
| 274 | Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst, |
| 275 | const Standard_Real aLast) |
| 276 | { |
| 277 | //define parameter division number as 10*e^(-M_PI) = 0.43213918 |
| 278 | const Standard_Real PAR_T = 0.43213918; |
| 279 | Standard_Real aParm; |
| 280 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; |
| 281 | return aParm; |
| 282 | } |
| 283 | |
| 284 | //======================================================================= |
| 285 | //function : IsVertex |
| 286 | //purpose : |
| 287 | //======================================================================= |
| 288 | Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP, |
| 289 | const Standard_Real aTolPV, |
| 290 | const TopoDS_Vertex& aV) |
| 291 | { |
| 292 | Standard_Boolean bRet; |
| 293 | Standard_Real aTolV, aD, dTol; |
| 294 | gp_Pnt aPv; |
| 295 | |
| 296 | aTolV=BRep_Tool::Tolerance(aV); |
| 297 | // |
| 298 | dTol=Precision::Confusion(); |
| 299 | aTolV=aTolV+aTolPV+dTol; |
| 300 | // |
| 301 | aPv=BRep_Tool::Pnt(aV); |
| 302 | // |
| 303 | aD=aPv.SquareDistance(aP); |
| 304 | aTolV=aTolV*aTolV; |
| 305 | bRet=(aD<=aTolV); |
| 306 | return bRet; |
| 307 | } |
| 308 | |
| 309 | |
| 310 | //======================================================================= |
| 311 | //function : IsVertex |
| 312 | //purpose : |
| 313 | //======================================================================= |
| 314 | Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt) |
| 315 | { |
| 316 | Standard_Boolean anIsVertex; |
| 317 | Standard_Real aParam; |
| 318 | |
| 319 | const TopoDS_Edge& aE1=aCmnPrt.Edge1(); |
| 320 | const IntTools_Range& aR1=aCmnPrt.Range1(); |
| 321 | aParam=0.5*(aR1.First()+aR1.Last()); |
| 322 | anIsVertex=IntTools_Tools::IsVertex (aE1, aParam); |
| 323 | |
| 324 | if (anIsVertex) { |
| 325 | return Standard_True; |
| 326 | } |
| 327 | |
| 328 | const TopoDS_Edge& aE2=aCmnPrt.Edge2(); |
| 329 | const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2(); |
| 330 | const IntTools_Range& aR2=aRs2(1); |
| 331 | aParam=0.5*(aR2.First()+aR2.Last()); |
| 332 | anIsVertex=IntTools_Tools::IsVertex (aE2, aParam); |
| 333 | if (anIsVertex) { |
| 334 | return Standard_True; |
| 335 | } |
| 336 | return Standard_False; |
| 337 | } |
| 338 | |
| 339 | //======================================================================= |
| 340 | //function : IsVertex |
| 341 | //purpose : |
| 342 | //======================================================================= |
| 343 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, |
| 344 | const TopoDS_Vertex& aV, |
| 345 | const Standard_Real t) |
| 346 | { |
| 347 | Standard_Real aTolV, aTolV2, d2; |
| 348 | gp_Pnt aPv, aPt; |
| 349 | |
| 350 | BRepAdaptor_Curve aBAC(aE); |
| 351 | aBAC.D0(t, aPt); |
| 352 | |
| 353 | aTolV=BRep_Tool::Tolerance(aV); |
| 354 | aTolV2=aTolV*aTolV; |
| 355 | aPv=BRep_Tool::Pnt(aV); |
| 356 | d2=aPv.SquareDistance (aPt); |
| 357 | if (d2 < aTolV2) { |
| 358 | return Standard_True; |
| 359 | } |
| 360 | return Standard_False; |
| 361 | } |
| 362 | //======================================================================= |
| 363 | //function : IsVertex |
| 364 | //purpose : |
| 365 | //======================================================================= |
| 366 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, |
| 367 | const Standard_Real t) |
| 368 | { |
| 369 | Standard_Real aTolV, aTolV2, d2; |
| 370 | TopoDS_Vertex aV; |
| 371 | gp_Pnt aPv, aPt; |
| 372 | |
| 373 | BRepAdaptor_Curve aBAC(aE); |
| 374 | aBAC.D0(t, aPt); |
| 375 | |
| 376 | TopExp_Explorer anExp(aE, TopAbs_VERTEX); |
| 377 | for (; anExp.More(); anExp.Next()) { |
| 378 | aV=TopoDS::Vertex (anExp.Current()); |
| 379 | aTolV=BRep_Tool::Tolerance(aV); |
| 380 | aTolV2=aTolV*aTolV; |
| 381 | aTolV2=1.e-12; |
| 382 | aPv=BRep_Tool::Pnt(aV); |
| 383 | d2=aPv.SquareDistance (aPt); |
| 384 | if (d2 < aTolV2) { |
| 385 | return Standard_True; |
| 386 | } |
| 387 | } |
| 388 | return Standard_False; |
| 389 | } |
| 390 | |
| 391 | |
| 392 | //======================================================================= |
| 393 | //function : ComputeVV |
| 394 | //purpose : |
| 395 | //======================================================================= |
| 396 | Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1, |
| 397 | const TopoDS_Vertex& aV2) |
| 398 | { |
| 399 | Standard_Real aTolV1, aTolV2, aTolSum, d; |
| 400 | gp_Pnt aP1, aP2; |
| 401 | |
| 402 | aTolV1=BRep_Tool::Tolerance(aV1); |
| 403 | aTolV2=BRep_Tool::Tolerance(aV2); |
| 404 | aTolSum=aTolV1+aTolV2; |
| 405 | |
| 406 | aP1=BRep_Tool::Pnt(aV1); |
| 407 | aP2=BRep_Tool::Pnt(aV2); |
| 408 | aTolSum=aTolSum*aTolSum; |
| 409 | d=aP1.SquareDistance(aP2); |
| 410 | if (d<aTolSum) { |
| 411 | return 0; |
| 412 | } |
| 413 | return -1; |
| 414 | } |
| 415 | |
| 416 | //======================================================================= |
| 417 | //function : MakeFaceFromWireAndFace |
| 418 | //purpose : |
| 419 | //======================================================================= |
| 420 | void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW, |
| 421 | const TopoDS_Face& aF, |
| 422 | TopoDS_Face& aFNew) |
| 423 | { |
| 424 | TopoDS_Face aFF; |
| 425 | aFF=aF; |
| 426 | aFF.Orientation(TopAbs_FORWARD); |
| 427 | aFNew=TopoDS::Face (aFF.EmptyCopied()); |
| 428 | BRep_Builder BB; |
| 429 | BB.Add(aFNew, aW); |
| 430 | } |
| 431 | |
| 432 | //======================================================================= |
| 433 | //function : ClassifyPointByFace |
| 434 | //purpose : |
| 435 | //======================================================================= |
| 436 | TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF, |
| 437 | const gp_Pnt2d& aP2d) |
| 438 | { |
| 439 | Standard_Real aFaceTolerance; |
| 440 | TopAbs_State aState; |
| 441 | |
| 442 | aFaceTolerance=BRep_Tool::Tolerance(aF); |
| 443 | IntTools_FClass2d aClass2d(aF, aFaceTolerance); |
| 444 | aState=aClass2d.Perform(aP2d); |
| 445 | |
| 446 | return aState; |
| 447 | } |
| 448 | |
| 449 | //======================================================================= |
| 450 | //function : IsMiddlePointsEqual |
| 451 | //purpose : |
| 452 | //======================================================================= |
| 453 | Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1, |
| 454 | const TopoDS_Edge& aE2) |
| 455 | |
| 456 | { |
| 457 | Standard_Boolean bRet; |
| 458 | Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2; |
| 459 | gp_Pnt aP1, aP2; |
| 460 | |
| 461 | aTol1=BRep_Tool::Tolerance(aE1); |
| 462 | Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1); |
| 463 | m1=0.5*(f1+l1); |
| 464 | C1->D0(m1, aP1); |
| 465 | |
| 466 | aTol2=BRep_Tool::Tolerance(aE2); |
| 467 | Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2); |
| 468 | m2=0.5*(f2+l2); |
| 469 | C2->D0(m2, aP2); |
| 470 | |
| 471 | aSumTol=aTol1+aTol2; |
| 472 | aSumTol=aSumTol*aSumTol; |
| 473 | aD2=aP1.SquareDistance(aP2); |
| 474 | bRet=aD2<aSumTol; |
| 475 | return bRet; |
| 476 | } |
| 477 | |
| 478 | //======================================================================= |
| 479 | //function : CurveTolerance |
| 480 | //purpose : |
| 481 | //======================================================================= |
| 482 | Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D, |
| 483 | const Standard_Real aTolBase) |
| 484 | { |
| 485 | Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax; |
| 486 | |
| 487 | aTolReached=aTolBase; |
| 488 | // |
| 489 | if (aC3D.IsNull()) { |
| 490 | return aTolReached; |
| 491 | } |
| 492 | // |
| 493 | Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D); |
| 494 | if (aCT3D.IsNull()) { |
| 495 | return aTolReached; |
| 496 | } |
| 497 | // |
| 498 | aTolMin=aTolBase; |
| 499 | aTolMax=aTolBase; |
| 500 | // |
| 501 | aTf=aCT3D->FirstParameter(); |
| 502 | aTl=aCT3D->LastParameter(); |
| 503 | // |
| 504 | GeomAdaptor_Curve aGAC(aCT3D); |
| 505 | GeomAbs_CurveType aCType=aGAC.GetType(); |
| 506 | // |
| 507 | if (aCType==GeomAbs_Parabola) { |
| 508 | Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve(); |
| 509 | ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax); |
| 510 | aTolReached=aTolMax; |
| 511 | } |
| 512 | // |
| 513 | return aTolReached; |
| 514 | } |
| 515 | |
| 516 | #include <Geom_Parabola.hxx> |
| 517 | #include <gp_Parab.hxx> |
| 518 | #include <BndLib_Add3dCurve.hxx> |
| 519 | //======================================================================= |
| 520 | //function : ParabolaTolerance |
| 521 | //purpose : |
| 522 | //======================================================================= |
| 523 | void ParabolaTolerance(const Handle(Geom_Curve)& aC3D, |
| 524 | const Standard_Real aTf, |
| 525 | const Standard_Real aTl, |
| 526 | const Standard_Real aTol, |
| 527 | Standard_Real& aTolMin, |
| 528 | Standard_Real& aTolMax) |
| 529 | { |
| 530 | |
| 531 | aTolMin=aTol; |
| 532 | aTolMax=aTol; |
| 533 | |
| 534 | Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D); |
| 535 | if (aGP.IsNull()){ |
| 536 | return; |
| 537 | } |
| 538 | |
| 539 | Standard_Integer aNbPoints; |
| 540 | Standard_Real aFocal, aX1, aX2, aTol1, aTol2; |
| 541 | gp_Pnt aPf, aPl; |
| 542 | gp_Parab aParab=aGP->Parab(); |
| 543 | gp_Ax1 aXAxis=aParab.XAxis(); |
| 544 | Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis); |
| 545 | |
| 546 | aFocal=aGP->Focal(); |
| 547 | if (aFocal==0.) { |
| 548 | return; |
| 549 | } |
| 550 | // |
| 551 | // aTol1 |
| 552 | aTol1=aTol; |
| 553 | aX1=0.; |
| 554 | aGP->D0(aTf, aPf); |
| 555 | GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis); |
| 556 | aNbPoints=aProj1.NbPoints(); |
| 557 | if (aNbPoints) { |
| 558 | aX1=aProj1.LowerDistanceParameter(); |
| 559 | } |
| 560 | if (aX1>=0.) { |
| 561 | aTol1=aTol*sqrt(0.5*aX1/aFocal); |
| 562 | } |
| 563 | if (aTol1==0.) { |
| 564 | aTol1=aTol; |
| 565 | } |
| 566 | // |
| 567 | // aTol2 |
| 568 | aTol2=aTol; |
| 569 | aX2=0.; |
| 570 | aGP->D0(aTl, aPl); |
| 571 | GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis); |
| 572 | aNbPoints=aProj2.NbPoints(); |
| 573 | if (aNbPoints) { |
| 574 | aX2=aProj2.LowerDistanceParameter(); |
| 575 | } |
| 576 | |
| 577 | if (aX2>=0.) { |
| 578 | aTol2=aTol*sqrt(0.5*aX2/aFocal); |
| 579 | } |
| 580 | if (aTol2==0.) { |
| 581 | aTol2=aTol; |
| 582 | } |
| 583 | // |
| 584 | aTolMax=(aTol1>aTol2) ? aTol1 : aTol2; |
| 585 | aTolMin=(aTol1<aTol2) ? aTol1 : aTol2; |
| 586 | } |
| 587 | ///////////////////////////////////////////////////////////////////////// |
| 588 | //======================================================================= |
| 589 | //function : CheckCurve |
| 590 | //purpose : |
| 591 | //======================================================================= |
| 592 | Standard_Boolean IntTools_Tools::CheckCurve(const Handle (Geom_Curve)& aC3D, |
| 593 | const Standard_Real aTolR3D, |
| 594 | Bnd_Box& aBox) |
| 595 | { |
| 596 | Standard_Boolean bRet; |
| 597 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dX, dY, dZ; |
| 598 | Standard_Real dS, aTol; |
| 599 | GeomAdaptor_Curve aGAC; |
| 600 | // |
| 601 | aGAC.Load(aC3D); |
| 602 | BndLib_Add3dCurve::Add(aGAC, aTolR3D, aBox); |
| 603 | // 910/B1 |
| 604 | aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); |
| 605 | dX=aXmax-aXmin; |
| 606 | dY=aYmax-aYmin; |
| 607 | dZ=aZmax-aZmin; |
| 608 | dS=1.e-12; |
| 609 | aTol=2.*aTolR3D+dS; |
| 610 | bRet=(dX>aTol || dY>aTol || dZ>aTol); |
| 611 | // |
| 612 | return bRet; |
| 613 | } |
| 614 | //======================================================================= |
| 615 | //function : IsOnPave |
| 616 | //purpose : |
| 617 | //======================================================================= |
| 618 | Standard_Boolean IntTools_Tools::IsOnPave(const Standard_Real aT1, |
| 619 | const IntTools_Range& aRange, |
| 620 | const Standard_Real aTolerance) |
| 621 | { |
| 622 | Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave; |
| 623 | // |
| 624 | firstisonpave1 = (Abs(aRange.First() - aT1) < aTolerance); |
| 625 | firstisonpave2 = (Abs(aRange.Last() - aT1) < aTolerance); |
| 626 | bIsOnPave=(firstisonpave1 || firstisonpave2); |
| 627 | return bIsOnPave; |
| 628 | } |
| 629 | //======================================================================= |
| 630 | // function: VertexParameters |
| 631 | // purpose: |
| 632 | //======================================================================= |
| 633 | void IntTools_Tools::VertexParameters(const IntTools_CommonPrt& aCPart, |
| 634 | Standard_Real& aT1, |
| 635 | Standard_Real& aT2) |
| 636 | { |
| 637 | const IntTools_Range& aR1=aCPart.Range1(); |
| 638 | aT1=0.5*(aR1.First()+aR1.Last()); |
| 639 | // |
| 640 | if((aCPart.VertexParameter1() >= aR1.First()) && |
| 641 | (aCPart.VertexParameter1() <= aR1.Last())) { |
| 642 | aT1 = aCPart.VertexParameter1(); |
| 643 | } |
| 644 | // |
| 645 | const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2(); |
| 646 | const IntTools_Range& aR2=aRanges2(1); |
| 647 | aT2=0.5*(aR2.First()+aR2.Last()); |
| 648 | // |
| 649 | if((aCPart.VertexParameter2() >= aR2.First()) && |
| 650 | (aCPart.VertexParameter2() <= aR2.Last())) { |
| 651 | aT2 = aCPart.VertexParameter2(); |
| 652 | } |
| 653 | } |
| 654 | //======================================================================= |
| 655 | // function: VertexParameter |
| 656 | // purpose: |
| 657 | //======================================================================= |
| 658 | void IntTools_Tools::VertexParameter(const IntTools_CommonPrt& aCPart, |
| 659 | Standard_Real& aT) |
| 660 | { |
| 661 | const IntTools_Range& aR=aCPart.Range1(); |
| 662 | aT=0.5*(aR.First()+aR.Last()); |
| 663 | if((aCPart.VertexParameter1() >= aR.First()) && |
| 664 | (aCPart.VertexParameter1() <= aR.Last())) { |
| 665 | aT = aCPart.VertexParameter1(); |
| 666 | } |
| 667 | } |
| 668 | //======================================================================= |
| 669 | // function: IsOnPave1 |
| 670 | // purpose: |
| 671 | //======================================================================= |
| 672 | Standard_Boolean IntTools_Tools::IsOnPave1(const Standard_Real aTR, |
| 673 | const IntTools_Range& aCPRange, |
| 674 | const Standard_Real aTolerance) |
| 675 | { |
| 676 | Standard_Boolean bIsOnPave; |
| 677 | Standard_Real aT1, aT2, dT1, dT2; |
| 678 | // |
| 679 | aT1=aCPRange.First(); |
| 680 | aT2=aCPRange.Last(); |
| 681 | bIsOnPave=(aTR>=aT1 && aTR<=aT1); |
| 682 | if (bIsOnPave) { |
| 683 | return bIsOnPave; |
| 684 | } |
| 685 | // |
| 686 | dT1=Abs(aTR-aT1); |
| 687 | dT2=Abs(aTR-aT2); |
| 688 | bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance); |
| 689 | return bIsOnPave; |
| 690 | } |
| 691 | //======================================================================= |
| 692 | // function: IsInRange |
| 693 | // purpose: |
| 694 | //======================================================================= |
| 695 | Standard_Boolean IntTools_Tools::IsInRange(const IntTools_Range& aRRef, |
| 696 | const IntTools_Range& aR, |
| 697 | const Standard_Real aTolerance) |
| 698 | { |
| 699 | Standard_Boolean bIsIn; |
| 700 | Standard_Real aT1, aT2, aTRef1, aTRef2; |
| 701 | // |
| 702 | aR.Range(aT1, aT2); |
| 703 | aRRef.Range(aTRef1, aTRef2); |
| 704 | // |
| 705 | aTRef1-=aTolerance; |
| 706 | aTRef2+=aTolerance; |
| 707 | // |
| 708 | bIsIn = (aT1>=aTRef1 && aT1<=aTRef2) || |
| 709 | (aT2>=aTRef1 && aT2<=aTRef2); |
| 710 | // |
| 711 | return bIsIn; |
| 712 | } |
| 713 | //======================================================================= |
| 714 | //function : SegPln |
| 715 | //purpose : |
| 716 | //======================================================================= |
| 717 | Standard_Integer IntTools_Tools::SegPln(const gp_Lin& theLin, |
| 718 | const Standard_Real theTLin1, |
| 719 | const Standard_Real theTLin2, |
| 720 | const Standard_Real theTolLin, |
| 721 | const gp_Pln& thePln, |
| 722 | const Standard_Real theTolPln, |
| 723 | gp_Pnt& theP, |
| 724 | Standard_Real& theTP, |
| 725 | Standard_Real& theTolP, |
| 726 | Standard_Real& theTPmin, |
| 727 | Standard_Real& theTPmax) |
| 728 | { |
| 729 | Standard_Integer iRet; |
| 730 | Standard_Real aTol, aA, aB, aC, aD, aE, aH, aTP, aDist1, aDist2; |
| 731 | gp_Pnt aP1, aP2; |
| 732 | // |
| 733 | iRet=0; |
| 734 | aTol=theTolLin+theTolPln; |
| 735 | // |
| 736 | const gp_Ax3& aPosPln=thePln.Position(); |
| 737 | const gp_Dir& aDirPln=aPosPln.Direction(); |
| 738 | const gp_Pnt& aLocPln=aPosPln.Location(); |
| 739 | // |
| 740 | const gp_Dir& aDirLin=theLin.Direction(); |
| 741 | const gp_Pnt& aLocLin=theLin.Location(); |
| 742 | // |
| 743 | aP1.SetXYZ(aLocLin.XYZ()+theTLin1*aDirLin.XYZ()); |
| 744 | aDist1=aDirPln.X()*(aP1.X()-aLocPln.X())+ |
| 745 | aDirPln.Y()*(aP1.Y()-aLocPln.Y())+ |
| 746 | aDirPln.Z()*(aP1.Z()-aLocPln.Z()); |
| 747 | // |
| 748 | aP2.SetXYZ(aLocLin.XYZ()+theTLin2*aDirLin.XYZ()); |
| 749 | aDist2=aDirPln.X()*(aP2.X()-aLocPln.X())+ |
| 750 | aDirPln.Y()*(aP2.Y()-aLocPln.Y())+ |
| 751 | aDirPln.Z()*(aP2.Z()-aLocPln.Z()); |
| 752 | // |
| 753 | if (aDist1<aTol && aDist2<aTol){ |
| 754 | iRet=1; // common block |
| 755 | return iRet; |
| 756 | } |
| 757 | // |
| 758 | if (aDist1*aDist2 > 0.) { |
| 759 | iRet=2; // segment lays on one side to the Plane |
| 760 | return iRet; |
| 761 | } |
| 762 | // |
| 763 | thePln.Coefficients(aA, aB, aC, aD); |
| 764 | aE=aA*aLocLin.X()+aB*aLocLin.Y()+aC*aLocLin.Z()+aD; |
| 765 | aH=aA*aDirLin.X()+aB*aDirLin.Y()+aC*aDirLin.Z(); |
| 766 | aTP=-aE/aH; |
| 767 | if (aTP < theTLin1-aTol || aTP > theTLin2+aTol) { |
| 768 | iRet=3; // no intersections due to range of the Line |
| 769 | return iRet; |
| 770 | } |
| 771 | // |
| 772 | theTP=aTP; |
| 773 | theP.SetXYZ(aLocLin.XYZ()+aTP*aDirLin.XYZ()); |
| 774 | theTolP=aTol; |
| 775 | theTPmin=theTP-theTolPln; |
| 776 | theTPmax=theTP+theTolPln; |
| 777 | iRet=0; // intersection point |
| 778 | return iRet; |
| 779 | } |