diff --git a/src/BRepClass/BRepClass_FaceExplorer.cxx b/src/BRepClass/BRepClass_FaceExplorer.cxx index cee8ce6f56..3fb9b5baf5 100644 --- a/src/BRepClass/BRepClass_FaceExplorer.cxx +++ b/src/BRepClass/BRepClass_FaceExplorer.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,51 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) : myFace.Orientation(TopAbs_FORWARD); } +//======================================================================= +//function : CheckPoint +//purpose : +//======================================================================= + +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)) + { + BRepTools::UVBounds(myFace, anUMin, anUMax, aVMin, aVMax); + if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) || + Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax)) + { + return Standard_True; + } + } + + gp_Pnt2d aCenterPnt(( anUMin + anUMax ) / 2, ( aVMin + aVMax ) / 2); + Standard_Real aDistance = aCenterPnt.Distance(thePoint); + if (Precision::IsInfinite(aDistance)) + { + thePoint.SetCoord(anUMin - ( anUMax - anUMin ), + aVMin - ( aVMax - aVMin )); + return Standard_False; + } + else + { + Standard_Real anEpsilon = Epsilon(aDistance); + if (anEpsilon > Max(anUMax - anUMin, aVMax - aVMin)) + { + gp_Vec2d aLinVec(aCenterPnt, thePoint); + gp_Dir2d aLinDir(aLinVec); + thePoint = aCenterPnt.XY() + aLinDir.XY() * ( 2. * anEpsilon ); + return Standard_False; + } + } + + return Standard_True; +} + //======================================================================= //function : Reject //purpose : diff --git a/src/BRepClass/BRepClass_FaceExplorer.hxx b/src/BRepClass/BRepClass_FaceExplorer.hxx index 54e03ec233..3e404b8df4 100644 --- a/src/BRepClass/BRepClass_FaceExplorer.hxx +++ b/src/BRepClass/BRepClass_FaceExplorer.hxx @@ -43,6 +43,12 @@ public: Standard_EXPORT BRepClass_FaceExplorer(const TopoDS_Face& F); + + //! Checks the point and change its coords if it is located too far + //! from the bounding box of the face. New Coordinates of the point + //! will be on the line between the point and the center of the + //! bounding box. Returns True if point was not changed. + Standard_EXPORT Standard_Boolean CheckPoint (gp_Pnt2d& thePoint); //! Should return True if the point is outside a //! bounding volume of the face. diff --git a/src/Geom2dHatch/Geom2dHatch_Elements.cxx b/src/Geom2dHatch/Geom2dHatch_Elements.cxx index c9e635470c..d487ee769d 100644 --- a/src/Geom2dHatch/Geom2dHatch_Elements.cxx +++ b/src/Geom2dHatch/Geom2dHatch_Elements.cxx @@ -73,6 +73,16 @@ Geom2dHatch_Element& Geom2dHatch_Elements::ChangeFind(const Standard_Integer K) return(myMap.ChangeFind(K)); } +//======================================================================= +//function : CheckPoint +//purpose : +//======================================================================= + +Standard_Boolean Geom2dHatch_Elements::CheckPoint(gp_Pnt2d&) +{ + return Standard_True; +} + //======================================================================= //function : Reject //purpose : diff --git a/src/Geom2dHatch/Geom2dHatch_Elements.hxx b/src/Geom2dHatch/Geom2dHatch_Elements.hxx index 3106c52918..5ef0623894 100644 --- a/src/Geom2dHatch/Geom2dHatch_Elements.hxx +++ b/src/Geom2dHatch/Geom2dHatch_Elements.hxx @@ -70,7 +70,8 @@ Geom2dHatch_Element& operator() (const Standard_Integer K) { return ChangeFind(K); } - + Standard_EXPORT Standard_Boolean CheckPoint (gp_Pnt2d& P); + Standard_EXPORT Standard_Boolean Reject (const gp_Pnt2d& P) const; Standard_EXPORT Standard_Boolean Segment (const gp_Pnt2d& P, gp_Lin2d& L, Standard_Real& Par); diff --git a/src/TopClass/TopClass_FaceClassifier.gxx b/src/TopClass/TopClass_FaceClassifier.gxx index 8740ed5f76..7f86749285 100644 --- a/src/TopClass/TopClass_FaceClassifier.gxx +++ b/src/TopClass/TopClass_FaceClassifier.gxx @@ -25,7 +25,10 @@ //purpose : //======================================================================= -TopClass_FaceClassifier::TopClass_FaceClassifier() +TopClass_FaceClassifier::TopClass_FaceClassifier() : +myEdgeParameter(0.0), +rejected(Standard_False), +nowires(Standard_True) { } @@ -36,7 +39,10 @@ TopClass_FaceClassifier::TopClass_FaceClassifier() TopClass_FaceClassifier::TopClass_FaceClassifier(TheFaceExplorer& FExp, const gp_Pnt2d& P, - const Standard_Real Tol) + const Standard_Real Tol) : +myEdgeParameter(0.0), +rejected(Standard_False), +nowires(Standard_True) { Perform(FExp,P,Tol); } @@ -50,15 +56,22 @@ void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp, const gp_Pnt2d& P, const Standard_Real Tol) { + gp_Pnt2d aPoint(P); + Standard_Boolean aResOfPointCheck = Standard_False; + while (aResOfPointCheck == Standard_False) + { + aResOfPointCheck = Fexp.CheckPoint(aPoint); + } + // Test for rejection. - rejected = Fexp.Reject(P); + rejected = Fexp.Reject(aPoint); if (rejected) return; gp_Lin2d aLine; Standard_Real aParam; - Standard_Boolean IsValidSegment = Fexp.Segment(P, aLine, aParam); + Standard_Boolean IsValidSegment = Fexp.Segment(aPoint, aLine, aParam); TheEdge anEdge; TopAbs_Orientation anEdgeOri; Standard_Integer aClosestInd; @@ -135,7 +148,7 @@ void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp, break; // Bad case for classification. Trying to get another segment. - IsValidSegment = Fexp.OtherSegment(P, aLine, aParam); + IsValidSegment = Fexp.OtherSegment(aPoint, aLine, aParam); } } diff --git a/tests/bugs/modalg_6/bug27434 b/tests/bugs/modalg_6/bug27434 new file mode 100644 index 0000000000..efef2c5a8c --- /dev/null +++ b/tests/bugs/modalg_6/bug27434 @@ -0,0 +1,21 @@ +puts "============" +puts "OCC27434" +puts "============" +puts "" +############################### +## Wrong result of classification of the point in "infinity". +############################### + +set BugNumber OCC27434 + +restore [locate_data_file bug27434_ff.brep] ff +point pp 3.5104958975622309 1.4497931574922160e+031 + +set info [b2dclassify ff pp] +set check [regexp "OUT" $info] + +if { ${check} == 1 } { + puts "OK ${BugNumber}" +} else { + puts "Faulty ${BugNumber}" +}