diff --git a/src/BRepClass/BRepClass_FaceExplorer.cxx b/src/BRepClass/BRepClass_FaceExplorer.cxx index 3fb9b5baf5..8f32e9c067 100644 --- a/src/BRepClass/BRepClass_FaceExplorer.cxx +++ b/src/BRepClass/BRepClass_FaceExplorer.cxx @@ -27,6 +27,7 @@ #include #include #include +#include static const Standard_Real Probing_Start = 0.123; static const Standard_Real Probing_End = 0.7; @@ -41,27 +42,28 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) : myFace(F), myCurEdgeInd(1), myCurEdgePar(Probing_Start) -{ + { myFace.Orientation(TopAbs_FORWARD); } + //======================================================================= //function : CheckPoint //purpose : //======================================================================= -Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint) +Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint) { Standard_Real anUMin = 0.0, anUMax = 0.0, aVMin = 0.0, aVMax = 0.0; TopLoc_Location aLocation; const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(myFace, aLocation); aSurface->Bounds(anUMin, anUMax, aVMin, aVMax); if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) || - Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax)) + Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax)) { BRepTools::UVBounds(myFace, anUMin, anUMax, aVMin, aVMax); if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) || - Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax)) + Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax)) { return Standard_True; } @@ -71,14 +73,14 @@ Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint) Standard_Real aDistance = aCenterPnt.Distance(thePoint); if (Precision::IsInfinite(aDistance)) { - thePoint.SetCoord(anUMin - ( anUMax - anUMin ), - aVMin - ( aVMax - aVMin )); + thePoint.SetCoord (anUMin - (anUMax - anUMin ), + aVMin - (aVMax - aVMin )); return Standard_False; } else { Standard_Real anEpsilon = Epsilon(aDistance); - if (anEpsilon > Max(anUMax - anUMin, aVMax - aVMin)) + if (anEpsilon > Max (anUMax - anUMin, aVMax - aVMin)) { gp_Vec2d aLinVec(aCenterPnt, thePoint); gp_Dir2d aLinDir(aLinVec); @@ -124,7 +126,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par) { - TopExp_Explorer anExpF(myFace,TopAbs_EDGE); + TopExp_Explorer anExpF(myFace, TopAbs_EDGE); Standard_Integer i; Standard_Real aFPar; Standard_Real aLPar; @@ -137,7 +139,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, if (i != myCurEdgeInd) continue; - const TopoDS_Shape &aLocalShape = anExpF.Current(); + const TopoDS_Shape &aLocalShape = anExpF.Current(); const TopAbs_Orientation anOrientation = aLocalShape.Orientation(); if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) { @@ -146,27 +148,29 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar); if (!aC2d.IsNull()) { - // Treatment of infinite cases. - if (Precision::IsNegativeInfinite(aFPar)) { - if (Precision::IsPositiveInfinite(aLPar)) { - aFPar = -1.; - aLPar = 1.; - } else { - aFPar = aLPar - 1.; - } - } else if (Precision::IsPositiveInfinite(aLPar)) - aLPar = aFPar + 1.; + // Treatment of infinite cases. + if (Precision::IsNegativeInfinite(aFPar)) { + if (Precision::IsPositiveInfinite(aLPar)) { + aFPar = -1.; + aLPar = 1.; + } + else { + aFPar = aLPar - 1.; + } + } + else if (Precision::IsPositiveInfinite(aLPar)) + aLPar = aFPar + 1.; - for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) { - aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar; + for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) { + aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar; gp_Vec2d aTanVec; - aC2d->D1(aParamIn, aPOnC, aTanVec); - Par = aPOnC.SquareDistance(P); + aC2d->D1(aParamIn, aPOnC, aTanVec); + Par = aPOnC.SquareDistance(P); - if (Par > aTolParConf2) { - gp_Vec2d aLinVec(P, aPOnC); - gp_Dir2d aLinDir(aLinVec); + if (Par > aTolParConf2) { + gp_Vec2d aLinVec(P, aPOnC); + gp_Dir2d aLinDir(aLinVec); Standard_Real aTanMod = aTanVec.SquareMagnitude(); if (aTanMod < aTolParConf2) @@ -174,8 +178,10 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, aTanVec /= Sqrt(aTanMod); Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY()); const Standard_Real SmallAngle = 0.001; + Standard_Boolean isSmallAngle = Standard_False; if (Abs(aSinA) < SmallAngle) { + isSmallAngle = Standard_True; // The line from the input point P to the current point on edge // is tangent to the edge curve. This condition is bad for classification. // Therefore try to go to another point in the hope that there will be @@ -185,28 +191,62 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, continue; } - L = gp_Lin2d(P, aLinDir); + L = gp_Lin2d(P, aLinDir); - // Check if ends of a curve lie on a line. - aC2d->D0(aFPar, aPOnC); + // Check if ends of a curve lie on a line. + aC2d->D0(aFPar, aPOnC); + Standard_Real aFDist = P.SquareDistance(aPOnC); + if (L.SquareDistance(aPOnC) > aTolParConf2) { + aC2d->D0(aLPar, aPOnC); + if (L.SquareDistance(aPOnC) > aTolParConf2) { + Standard_Real aLDist = P.SquareDistance(aPOnC); - if (L.SquareDistance(aPOnC) > aTolParConf2) { - aC2d->D0(aLPar, aPOnC); + if (isSmallAngle) + { + //Try to find minimal distance between curve and line - if (L.SquareDistance(aPOnC) > aTolParConf2) { - myCurEdgePar += Probing_Step; + Geom2dAPI_ProjectPointOnCurve aProj; + aProj.Init(P, aC2d, aFPar, aLPar); + if (aProj.NbPoints() > 0) + { + Standard_Real aMinDist = aProj.LowerDistance(); + aMinDist *= aMinDist; + Standard_Real aTMin = aProj.LowerDistanceParameter(); + if (aMinDist > aFDist) + { + aMinDist = aFDist; + aTMin = aFPar; + } + if (aMinDist > aLDist) + { + aMinDist = aLDist; + aTMin = aLPar; + } + if (aMinDist < Par) + { + Par = aMinDist; + if (Par < aTolParConf2) + { + continue; + } + aC2d->D1(aTMin, aPOnC, aTanVec); + aLinDir.SetXY(aTanVec.XY()); + L = gp_Lin2d(P, aLinDir); + } + } + } + myCurEdgePar += Probing_Step; + if (myCurEdgePar >= Probing_End) { + myCurEdgeInd++; + myCurEdgePar = Probing_Start; + } - if (myCurEdgePar >= Probing_End) { - myCurEdgeInd++; - myCurEdgePar = Probing_Start; - } - - Par = Sqrt(Par); - return Standard_True; - } - } - } - } + Par = Sqrt(Par); + return Standard_True; + } + } + } + } } // if (!aC2d.IsNull()) { } // if (anOrientation == TopAbs_FORWARD ... @@ -217,7 +257,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, // nothing found, return an horizontal line Par = RealLast(); - L = gp_Lin2d(P,gp_Dir2d(1,0)); + L = gp_Lin2d(P, gp_Dir2d(1, 0)); return Standard_False; }