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

0027830: Infinite HLR looping

Make protection of HLR algo against garbage data in faces. In particular case, there are faces built on a periodical surfaces, which U bounds exceed period thousands times. Such faces are excluded from the process of edges hiding.

In addition, while fitting the intersection point in period for periodical faces, replace looping with the single call to AdjustPeriodic method.

- Add new test case.
- Update tests of HLR according to new numbers of subshapes.

Update of test cases according to the new behavior
This commit is contained in:
msv
2016-09-08 22:57:50 +03:00
committed by bugmaster
parent 4aaadad7bc
commit 14ea8abd0a
13 changed files with 81 additions and 42 deletions

View File

@@ -20,6 +20,7 @@
#include <BRepTopAdaptor_TopolTool.hxx>
#include <ElCLib.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomInt.hxx>
#include <gp.hxx>
#include <gp_Dir.hxx>
#include <gp_Dir2d.hxx>
@@ -2093,39 +2094,24 @@ HLRBRep_Data::Classify (const Standard_Integer E,
IntCurveSurface_TransitionOnCurve Tr;
for (i = 1; i <= nbPoints; i++) {
Standard_Boolean InsideRestriction = Standard_False;
myIntersector.CSPoint(i).Values(PInter,u,v,w,Tr);
if (w < wLim) {
if (PeriodU)
while (u > UMin)
u -= PeriodU;
if (PeriodV)
while (v > VMin)
v -= PeriodV;
// Standard_Real UInit = u;
Standard_Real VInit = v;
Standard_Real aDummyShift;
if (PeriodU > 0.)
GeomInt::AdjustPeriodic(u, UMin, UMax, PeriodU, u, aDummyShift);
if (PeriodV > 0.)
GeomInt::AdjustPeriodic(v, VMin, VMax, PeriodV, v, aDummyShift);
do {
v = VInit;
do {
gp_Pnt2d pnt2d(u,v);
if (myClassifier->Classify(pnt2d,Precision::PConfusion())
!= TopAbs_OUT)
{
InsideRestriction = Standard_True;
state = TopAbs_IN;
Level++;
if (!LevelFlag) {
return state;
}
}
v += PeriodV;
}
while (PeriodV && v < VMax && !InsideRestriction);
u += PeriodU;
}
while (PeriodU && u < UMax && !InsideRestriction);
gp_Pnt2d pnt2d(u, v);
if (myClassifier->Classify(pnt2d, Precision::PConfusion())
!= TopAbs_OUT)
{
state = TopAbs_IN;
Level++;
if (!LevelFlag) {
return state;
}
}
}
}
}
@@ -2444,3 +2430,34 @@ HLRBRep_Data::SameVertex (const Standard_Boolean h1,
}
return SameV;
}
//=======================================================================
//function : IsBadFace
//purpose :
//=======================================================================
Standard_Boolean HLRBRep_Data::IsBadFace() const
{
if (iFaceGeom)
{
// check for garbage data - if periodic then bounds must not exceed period
HLRBRep_Surface *pGeom = (HLRBRep_Surface*)iFaceGeom;
if (pGeom->IsUPeriodic())
{
Standard_Real aPeriod = pGeom->UPeriod();
Standard_Real aMin = pGeom->FirstUParameter();
Standard_Real aMax = pGeom->LastUParameter();
if (aPeriod * 2 < aMax - aMin)
return Standard_True;
}
if (pGeom->IsVPeriodic())
{
Standard_Real aPeriod = pGeom->VPeriod();
Standard_Real aMin = pGeom->FirstVParameter();
Standard_Real aMax = pGeom->LastVParameter();
if (aPeriod * 2 < aMax - aMin)
return Standard_True;
}
}
return Standard_False;
}

View File

@@ -173,7 +173,10 @@ public:
//! Classification of an edge.
Standard_EXPORT TopAbs_State Classify (const Standard_Integer E, const HLRBRep_EdgeData& ED, const Standard_Boolean LevelFlag, Standard_Integer& Level, const Standard_Real param);
//! Returns true if the current face is bad.
Standard_EXPORT Standard_Boolean IsBadFace() const;
Standard_EXPORT void Destroy();
~HLRBRep_Data()
{

View File

@@ -103,6 +103,8 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
myDS->InitEdge(FI,MST);
if (!myDS->MoreEdge()) // there is nothing to do
return; // **********************
if (myDS->IsBadFace())
return;
HLRBRep_EdgeInterferenceTool EIT(myDS); // List of Intersections
HLRBRep_Array1OfEData& myEData = myDS->EDataArray();