1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0027434: Wrong result of classification of the point in "infinity"

In the case of infinite point due to not enough machine precision the distance from the point to each edge of the face is computed the same, and the algorithm cannot correctly select the nearest edge. To solve this problem checking of point was added, if the point is located too far from the bounding box of the face, then it will be replaced with another point located on the line between the point and the center of the bounding box.
    The new point has the same state as initial one but its state can be resolved without ambiguity.

Corrections in CheckPoint method
Small correction of test case for issue CR27434
This commit is contained in:
aka
2016-12-08 16:33:47 +03:00
committed by apn
parent 8013367c92
commit a148c938b0
6 changed files with 103 additions and 6 deletions

View File

@@ -20,6 +20,7 @@
#include <BRep_Tool.hxx>
#include <BRepClass_Edge.hxx>
#include <BRepClass_FaceExplorer.hxx>
#include <BRepTools.hxx>
#include <Geom2d_Curve.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx>
@@ -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 :

View File

@@ -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.