130 PNS_DBG(
Dbg(), AddItem, &line,
WHITE, 10000, wxString::Format(
"current (policy %d, stat %d)", i, status ) );
141 PNS_DBG(
Dbg(), Message, wxString::Format(
"no-more-colls pol %d st %d", i, status ) );
147 int clusterMargin = 2 * obstacle->m_clearance + line.Width() ;
149 pendingClusters[ i ] = topo.
AssembleCluster( obstacle->m_item, line.Layer(), 0.0, line.Net(), clusterMargin );
150 PNS_DBG(
Dbg(), AddItem, obstacle->m_item,
BLUE, 10000, wxString::Format(
"col-item owner-depth %d cl-items=%d cl-margin=%d",
static_cast<const NODE*
>( obstacle->m_item->Owner() )->
Depth(), (
int) pendingClusters[i].
m_items.size(), clusterMargin ) );
158 using namespace std::chrono;
159 auto start_time = steady_clock::now();
163 PNS_DBG(
Dbg(), BeginGroup, wxString::Format(
"cluster-details [cw %d]", aCw?1:0 ), 1 );
165 for(
auto& clItem : aCluster.
m_items )
171 auto now = steady_clock::now();
172 auto elapsed = duration_cast<milliseconds>( now - start_time ).count();
174 if( elapsed > timeout_ms )
176 PNS_DBG(
Dbg(), Message, wxString::Format(
"processCluster timeout after %d ms", timeout_ms ) );
183 clItem,
clearance, aLine.Width(), aLine.Layer() );
202 aLine.Line().Simplify2();
204 bool stat = aLine.Walkaround( hull, tmp.
Line(), aCw );
206 PNS_DBG(
Dbg(), AddShape, &hull,
YELLOW, 10000, wxString::Format(
"hull stat %d", stat?1:0 ) );
207 PNS_DBG(
Dbg(), AddItem, &tmp,
RED, 10000, wxString::Format(
"walk stat %d", stat?1:0 ) );
208 PNS_DBG(
Dbg(), AddItem, clItem,
WHITE, 10000, wxString::Format(
"item stat %d", stat?1:0 ) );
216 aLine.SetShape( tmp.
CLine() );
242 LINE path_cw( line ), path_ccw( line );
244 auto st_cw = processCluster( pendingClusters[
WP_SHORTEST], path_cw,
true );
245 auto st_ccw = processCluster( pendingClusters[
WP_SHORTEST], path_ccw,
false );
249 bool cw_coll = st_cw ?
m_world->CheckColliding( &path_cw, opts ).has_value() :
false;
250 bool ccw_coll = st_ccw ?
m_world->CheckColliding( &path_ccw, opts ).has_value() :
false;
252 double lengthFactorCw = (double) path_cw.CLine().Length() / (double)
m_initialLength;
255 PNS_DBG(
Dbg(), AddItem, &path_cw,
RED, 10000, wxString::Format(
"shortest-cw stat %d lf %.1f", st_cw?1:0, lengthFactorCw ) );
256 PNS_DBG(
Dbg(), AddItem, &path_ccw,
BLUE, 10000, wxString::Format(
"shortest-ccw stat %d lf %.1f", st_ccw?1:0, lengthFactorCcw ) );
259 std::optional<LINE> shortest;
260 std::optional<LINE> shortest_alt;
263 if( st_cw && st_ccw )
265 if( ( !cw_coll && !ccw_coll ) || ( cw_coll && ccw_coll ) )
267 if( path_cw.CLine().Length() > path_ccw.
CLine().
Length() )
270 shortest_alt = path_cw;
275 shortest_alt = path_ccw;
289 bool anyColliding =
false;
291 if( shortest.has_value() )
293 PNS_DBG(
Dbg(), AddItem, &shortest.value(),
RED, 10000, wxString::Format(
"shortest-l" ) );
297 std::set<PNS::OBSTACLE> obstacles;
299 if( shortest->Collide( item,
m_world, shortest->Layer(), &ctx ) )
306 PNS_DBG(
Dbg(), Message, wxString::Format(
"check-back cc %d items %d coll %d", (
int) pendingClusters[
WP_SHORTEST ].m_items.size(), (
int)
m_processedItems.size(), anyColliding ? 1: 0 ) );
311 shortest = std::move( shortest_alt );
323 for(
auto item : pendingClusters[
WP_SHORTEST ].m_items )
353 start( aInitialPath );
357 PNS_DBG(
Dbg(), AddItem, &aInitialPath,
WHITE, 10000, wxT(
"initial-path" ) );
363 bool stillInProgress =
false;
372 double lengthFactor = (double) ln.CLine().Length() / (double) aInitialPath.
CLine().
Length();
383 PNS_DBG(
Dbg(), Message, wxString::Format(
"check-wp iter %d st %d i %d lf %.1f",
m_iteration, st, pol, lengthFactor ) );
386 stillInProgress =
true;
390 if( !stillInProgress )
406 if( ln.SegmentCount() < 1 || ln.CPoint( 0 ) != aInitialPath.
CPoint( 0 ) )
411 if( ln.PointCount() > 0 && ln.CLastPoint() != aInitialPath.
CLastPoint() )
416 PNS_DBG(
Dbg(), Message, wxString::Format(
"stat=%d", st ) );
wxString result
Test unit parsing edge cases and error handling.