Skip to content

Commit 65a01c2

Browse files
Modelling - Fix infinite loop in IntWalk_IWalking::ComputeOpenLine()
Infinite loop occurred in IntWalk_IWalking::ComputeOpenLine() inside 'while (!Arrive)' loop. Fixed by checking for degenerate case after very large amount of iterations have passed.
1 parent 1db8025 commit 65a01c2

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

src/ModelingAlgorithms/TKGeomAlgo/IntWalk/IntWalk_IWalking.gxx

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
OSD_Chronometer Chronrsnld;
3232
#endif
3333

34+
namespace
35+
{
36+
static const double CosRef3D = 0.98; // rule by tests in U4
37+
// correspond to 11.478 d
38+
static const double CosRef2D = 0.88; // correspond to 25 d
39+
static const int MaxDivision = 60; // max number of step division
40+
// because the angle is too great in 2d (U4)
41+
} // namespace
42+
3443
//==================================================================================
3544
// function : IsTangentExtCheck
3645
// purpose : Additional check if the point (theU, theV) in parametric surface
@@ -1557,8 +1566,9 @@ void IntWalk_IWalking::ComputeOpenLine(const NCollection_Sequence<double>& Umult
15571566
// modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000
15581567
int IndexOfPathPointDoNotCheck = 0;
15591568
int aNbIter = 10;
1569+
int aNbBadRootIter = 0; // consecutive iterations where Root > Tolerance
15601570
while (!Arrive)
1561-
{ // as one of stop tests is not checked
1571+
{
15621572
Cadre = Cadrage(BornInf, BornSup, UVap, PasC, StepSign);
15631573
// Border?
15641574

@@ -1586,8 +1596,11 @@ void IntWalk_IWalking::ComputeOpenLine(const NCollection_Sequence<double>& Umult
15861596
PasC = PasC / 2.0;
15871597
PasCu = std::abs(PasC * previousd2d.X());
15881598
PasCv = std::abs(PasC * previousd2d.Y());
1589-
if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
1599+
++aNbBadRootIter;
1600+
if ((PasCu <= tolerance(1) && PasCv <= tolerance(2)) || aNbBadRootIter > MaxDivision)
15901601
{
1602+
// Step collapsed below tolerance, or Cadrage keeps resetting
1603+
// the step (preventing convergence) after too many attempts.
15911604
if (CurrentLine->NbPoints() == 1)
15921605
break;
15931606
Arrive = true;
@@ -1600,6 +1613,7 @@ void IntWalk_IWalking::ComputeOpenLine(const NCollection_Sequence<double>& Umult
16001613
}
16011614
else
16021615
{ // test stop
1616+
aNbBadRootIter = 0;
16031617
Rsnld.Root(UVap);
16041618
Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
16051619
if (Arrive)
@@ -2143,11 +2157,12 @@ void IntWalk_IWalking::ComputeCloseLine(const NCollection_Sequence<double>& Umul
21432157

21442158
PasSav = PasC;
21452159

2146-
Arrive = false;
2147-
ArretAjout = false;
2148-
NbDivision = 0;
2149-
StatusPrecedent = IntWalk_OK;
2150-
int aNbIter = 10;
2160+
Arrive = false;
2161+
ArretAjout = false;
2162+
NbDivision = 0;
2163+
StatusPrecedent = IntWalk_OK;
2164+
int aNbIter = 10;
2165+
int aNbBadRootIter = 0; // consecutive iterations where Root > Tolerance
21512166
while (!Arrive)
21522167
{ // as no test of stop is passed
21532168
Cadre = Cadrage(BornInf, BornSup, Uvap, PasC, StepSign); // border?
@@ -2176,8 +2191,9 @@ void IntWalk_IWalking::ComputeCloseLine(const NCollection_Sequence<double>& Umul
21762191
PasC = PasC / 2.;
21772192
PasCu = std::abs(PasC * previousd2d.X());
21782193
PasCv = std::abs(PasC * previousd2d.Y());
2194+
++aNbBadRootIter;
21792195

2180-
if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
2196+
if ((PasCu <= tolerance(1) && PasCv <= tolerance(2)) || aNbBadRootIter > MaxDivision)
21812197
{
21822198
if (CurrentLine->NbPoints() == 1)
21832199
{
@@ -2219,6 +2235,7 @@ void IntWalk_IWalking::ComputeCloseLine(const NCollection_Sequence<double>& Umul
22192235
}
22202236
else
22212237
{ // there is a solution
2238+
aNbBadRootIter = 0;
22222239
Rsnld.Root(Uvap);
22232240

22242241
// Avoid uninitialized memory access.
@@ -2604,15 +2621,6 @@ void IntWalk_IWalking::ComputeCloseLine(const NCollection_Sequence<double>& Umul
26042621

26052622
//-- IntWalk_IWalking_5.gxx
26062623

2607-
namespace
2608-
{
2609-
static const double CosRef3D = 0.98; // rule by tests in U4
2610-
// correspond to 11.478 d
2611-
static const double CosRef2D = 0.88; // correspond to 25 d
2612-
static const int MaxDivision = 60; // max number of step division
2613-
// because the angle is too great in 2d (U4)
2614-
} // namespace
2615-
26162624
IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection(
26172625
TheIWFunction& sp,
26182626
const bool Finished,

0 commit comments

Comments
 (0)