117        PNS_DBG( 
Dbg(), AddItem, &line, 
WHITE, 10000, wxString::Format( 
"current (policy %d, stat %d)", i, status ) );
 
  128            PNS_DBG( 
Dbg(), Message,  wxString::Format( 
"no-more-colls pol %d st %d", i, status ) );
 
  134        pendingClusters[ i ] = topo.
AssembleCluster( obstacle->m_item, line.Layer(), 0.0, line.Net() );
 
  135        PNS_DBG( 
Dbg(), AddItem, obstacle->m_item, 
BLUE, 10000, wxString::Format( 
"col-item owner-depth %d cl-items=%d", 
static_cast<const NODE*
>( obstacle->m_item->Owner() )->
Depth(), (
int) pendingClusters[i].
m_items.size() ) );
 
  143        using namespace std::chrono;
 
  144        auto start_time = steady_clock::now();
 
  148        PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( 
"cluster-details [cw %d]", aCw?1:0 ), 1 );
 
  150        for( 
auto& clItem : aCluster.
m_items )
 
  156            auto now = steady_clock::now();
 
  157            auto elapsed = duration_cast<milliseconds>( now - start_time ).count();
 
  159            if( elapsed > timeout_ms )
 
  161                PNS_DBG( 
Dbg(), Message, wxString::Format( 
"processCluster timeout after %d ms", timeout_ms ) );
 
  181            bool stat = aLine.Walkaround( hull, tmp.
Line(), aCw );
 
  183            PNS_DBG( 
Dbg(), AddShape, &hull, 
YELLOW, 10000, wxString::Format( 
"hull stat %d", stat?1:0 ) );
 
  184            PNS_DBG( 
Dbg(), AddItem, &tmp, 
RED, 10000, wxString::Format( 
"walk stat %d", stat?1:0 ) );
 
  185            PNS_DBG( 
Dbg(), AddItem, clItem, 
WHITE, 10000, wxString::Format( 
"item stat %d", stat?1:0 ) );
 
  193            aLine.SetShape( tmp.
CLine() );
 
  218        LINE  path_cw( line ), path_ccw( line );
 
  220        auto st_cw = processCluster( pendingClusters[
WP_SHORTEST], path_cw, 
true );
 
  221        auto st_ccw = processCluster( pendingClusters[
WP_SHORTEST], path_ccw, 
false );
 
  223        bool cw_coll = st_cw ? 
m_world->CheckColliding( &path_cw ).has_value() : 
false;
 
  224        bool ccw_coll = st_ccw ? 
m_world->CheckColliding( &path_ccw ).has_value() : 
false;
 
  226        double lengthFactorCw = (double) path_cw.CLine().Length() / (double) 
m_initialLength;
 
  229        PNS_DBG( 
Dbg(), AddItem, &path_cw, 
RED, 10000, wxString::Format( 
"shortest-cw stat %d lf %.1f", st_cw?1:0, lengthFactorCw ) );
 
  230        PNS_DBG( 
Dbg(), AddItem, &path_ccw, 
BLUE, 10000, wxString::Format( 
"shortest-ccw stat %d lf %.1f", st_ccw?1:0, lengthFactorCcw ) );
 
  233        std::optional<LINE> shortest;
 
  234        std::optional<LINE> shortest_alt;
 
  237        if( st_cw && st_ccw )
 
  239            if( !cw_coll && !ccw_coll || ( cw_coll && ccw_coll) )
 
  241                if( path_cw.CLine().Length() > path_ccw.
CLine().
Length() )
 
  244                    shortest_alt = path_cw;
 
  249                    shortest_alt = path_ccw;
 
  263        bool anyColliding = 
false;
 
  269                if( shortest->Collide( item, 
m_world, shortest->Layer() ) )
 
  281            shortest = std::move( shortest_alt );
 
 
  322    start( aInitialPath );
 
  324    PNS_DBG( 
Dbg(), AddItem, &aInitialPath, 
WHITE, 10000, wxT( 
"initial-path" ) );
 
  330        bool stillInProgress = 
false;
 
  339            double lengthFactor = (double) ln.CLine().Length() / (double) aInitialPath.
CLine().
Length();
 
  350            PNS_DBG( 
Dbg(), Message, wxString::Format( 
"check-wp iter %d st %d i %d lf %.1f", 
m_iteration, st, pol, lengthFactor ) );
 
  353                stillInProgress = 
true;
 
  357        if( !stillInProgress )
 
  373        if( ln.SegmentCount() < 1 || ln.CPoint( 0 ) != aInitialPath.
CPoint( 0 ) )
 
  378        if( ln.PointCount() > 0 && ln.CLastPoint() != aInitialPath.
CLastPoint() )
 
  383        PNS_DBG( 
Dbg(), Message, wxString::Format( 
"stat=%d", st ) );
 
 
wxString result
Test unit parsing edge cases and error handling.