From c9bc45f7ed8680dfe8f054033711a3d381f09d66 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 6 Jun 2021 16:03:03 -0400 Subject: [PATCH] PNS: Limit the maximum walkaround distance factor The constant chosen is somewhat arbitrary and may need further tuning or a more complex algorithm, but in general this will prevent churning when solutions can't be found or a solution can be found but it is unrealistic (going around the entire board) Fixes https://gitlab.com/kicad/code/kicad/-/issues/8558 --- pcbnew/router/pns_walkaround.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pcbnew/router/pns_walkaround.cpp b/pcbnew/router/pns_walkaround.cpp index 3fc6745337..6b5817e756 100644 --- a/pcbnew/router/pns_walkaround.cpp +++ b/pcbnew/router/pns_walkaround.cpp @@ -127,6 +127,13 @@ const WALKAROUND::RESULT WALKAROUND::Route( const LINE& aInitialPath ) m_forceSingleDirection = false; } + // In some situations, there isn't a trivial path (or even a path at all). Hitting the + // iteration limit causes lag, so we can exit out early if the walkaround path gets very long + // compared with the initial path. If the length exceeds the initial length times this factor, + // fail out. + const int maxWalkDistFactor = 10; + long long lengthLimit = aInitialPath.CLine().Length() * maxWalkDistFactor; + while( m_iteration < m_iterationLimit ) { if( s_cw != STUCK && s_cw != ALMOST_DONE ) @@ -150,6 +157,10 @@ const WALKAROUND::RESULT WALKAROUND::Route( const LINE& aInitialPath ) if( s_cw != IN_PROGRESS && s_ccw != IN_PROGRESS ) break; + // Safety valve + if( path_cw.Line().Length() > lengthLimit && path_ccw.Line().Length() > lengthLimit ) + break; + m_iteration++; }