61 VIA* vold =
static_cast<VIA*
>( aOld );
62 VIA* vnew =
static_cast<VIA*
>( aNew.get() );
65 newId =
static_cast<VIA*
>( aNew.get() )->
Uid();
68 wxString::Format(
"replace-via node=%p vold=%p [%d %d]-> vnew=%p [%d %d] nid %llu",
m_currentNode, aOld,
70 vnew->
Pos().
y, newId ) );
82 if( aIncludeInChangedArea )
89 PNS_DBG(
Dbg(), AddShape, &r,
BLUE, 0, wxT(
"shove-changed-area" ) );
114 bool foundPredecessor =
false;
130 rootEntry = oldLineIter->second;
131 foundPredecessor =
true;
137 if( !foundPredecessor )
152 aNode->
Replace( aOld, aNew, aAllowRedundantSegments );
154 m_currentNode->Replace( aOld, aNew, aAllowRedundantSegments );
243 const LINE& aShovedLine )
const
267 int obstacleLineWidth = aObstacleLine.
Width();
271 int holeClearance =
getClearance( viaHole, &aObstacleLine );
280 if( ! aObstacleLine.
Walkaround( hull, path_cw,
true ) )
283 if( ! aObstacleLine.
Walkaround( hull, path_ccw,
false ) )
310 const HULL_SET& aHulls,
bool aPermitAdjustingStart,
311 bool aPermitAdjustingEnd )
313 const int c_ENDPOINT_ON_HULL_THRESHOLD = 1000;
315 bool permitAdjustingEndpoints = aPermitAdjustingStart || aPermitAdjustingEnd;
317 PNS_DBG(
Dbg(), BeginGroup,
"shove-details", 1 );
319 for( attempt = 0; attempt < 2; attempt++ )
321 bool invertTraversal = ( attempt >= 1 );
322 int vFirst = -1, vLast = -1;
324 LINE l_base( aObstacleLine );
327 if( permitAdjustingEndpoints && l_base.
SegmentCount() >= 1 )
331 int min_dist = std::numeric_limits<int>::max();
334 for(
int i = 0; i < (int) aHulls.size(); i++ )
337 aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
344 dist = ( p - pref ).EuclideanNorm();
346 if( dist < c_ENDPOINT_ON_HULL_THRESHOLD && dist < min_dist )
354 minhull = invertTraversal ? aHulls.size() - 1 - i : i;
362 int minDist0, minDist1, minhull0, minhull1;
367 wxString::Format(
"mindists : %d %d hulls %d %d\n", minDist0, minDist1,
368 minhull0, minhull1 ) );
370 if( minDist1 < c_ENDPOINT_ON_HULL_THRESHOLD && aPermitAdjustingEnd )
373 obs = l_base.
CLine();
374 path_base = l_base.
CLine();
377 if( minDist0 < c_ENDPOINT_ON_HULL_THRESHOLD && aPermitAdjustingStart )
380 obs = l_base.
CLine();
381 path_base = l_base.
CLine();
388 long long minLength = std::numeric_limits<long long>::max();
392 for(
int cw = 0;
cw <= 1;
cw++ )
396 bool failWalk =
false;
398 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"Trying cw %d" ),
cw ) );
400 for(
int i = 0; i < (int) aHulls.size(); i++ )
402 const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
404 PNS_DBG(
Dbg(), AddShape, &hull,
YELLOW, 10000, wxString::Format(
"hull[%d]", i ) );
406 wxString::Format(
"line[%d]", i ) );
411 wxString::Format( wxT(
"Fail-Walk cw %d %s %s" ),
cw,
423 wxString::Format(
"path[%d]", i ) );
429 for(
int i = 0; i < std::min(
path.PointCount(), obs.
PointCount() ); i++ )
440 for(
int i =
path.PointCount() - 1; i >= 0 && k >= 0; i--, k-- )
449 if( ( vFirst < 0 || vLast < 0 ) && !
path.CompareGeometry( obs ) )
452 wxString::Format( wxT(
"attempt %d fail vfirst-last" ), attempt ) );
458 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"attempt %d fail vend-start\n" ),
463 if(
path.SelfIntersecting() )
466 wxString::Format( wxT(
"attempt %d fail self-intersect" ), attempt ) );
488 wxString::Format( wxT(
"attempt %d fail coll-check" ), attempt ) );
493 PNS_DBG(
Dbg(), Message, wxString::Format(
"cw %d length %lld",
cw, len ) );
496 if( len <= minLength )
503 if( minLength == std::numeric_limits<long long>::max() )
524 const int cHullFailureExpansionFactor = 1000;
525 int extraHullExpansion = 0;
527 bool voeStart =
false, voeEnd =
false;
528 const JOINT* jtStart =
nullptr;
529 const JOINT* jtEnd =
nullptr;
538 voeStart = jtStart->
Via() !=
nullptr;
540 voeEnd = jtEnd->
Via() !=
nullptr;
545 LINE obstacleLine( aObstacleLine );
546 std::optional<VIA> obsVia;
550 obsVia = aObstacleLine.
Via();
554 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"shove process-single: voe-cur %d voe-obs %d" ),
569 int obstacleLineWidth = obstacleLine.
Width();
578 for(
int attempt = 0; attempt < 3; attempt++ )
582 hulls.reserve( currentLineSegmentCount + 1 );
584 for(
int i = 0; i < currentLineSegmentCount; i++ )
591 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"shove add-extra-clearance %d" ),
598 hulls.push_back( hull );
606 int holeClearance =
getClearance( viaHole, &obstacleLine );
607 int layer = aObstacleLine.
Layer();
609 if( holeClearance +
via.Drill() / 2 > viaClearance +
via.Diameter( layer ) / 2 )
611 viaClearance = holeClearance +
via.Drill() / 2 -
via.Diameter( layer ) / 2;
614 hulls.push_back( aCurLine.
Via().
Hull( viaClearance, obstacleLineWidth, layer ) );
617 bool permitMovingStart = (attempt >= 2) && !voeStart;
618 bool permitMovingEnd = (attempt >= 2) && !voeEnd;
620 if (
shoveLineToHullSet( aCurLine, obstacleLine, aResultLine, hulls, permitMovingStart, permitMovingEnd ) )
628 extraHullExpansion += cHullFailureExpansionFactor;
644 LINE shovedLine( obstacleLine );
649 PNS_DBG(
Dbg(), Message,
"try walk (locked segments)");
655 const double extensionWalkThreshold = 1.0;
659 double extensionFactor = 0.0;
662 extensionFactor = shovedLen / obsLen - 1.0;
671 PNS_DBG(
Dbg(), AddItem, aObstacleSeg,
BLUE, 0, wxT(
"colliding-segment" ) );
674 PNS_DBG(
Dbg(), AddItem, &shovedLine,
BLUE, 10000, wxT(
"shoved-line" ) );
679 int rank = aCurrent.
Rank();
681 shovedLine.
SetRank( rank - 1 );
686 replaceLine( obstacleLine, shovedLine,
true,
false );
705 LINE shovedLine( obstacleLine );
706 ARC tmp( *aObstacleArc );
713 const double extensionWalkThreshold = 1.0;
717 double extensionFactor = 0.0;
720 extensionFactor = shovedLen / obsLen - 1.0;
722 if( extensionFactor > extensionWalkThreshold )
728 PNS_DBG(
Dbg(), AddItem, &aCurrent,
RED, 10000, wxT(
"current-line" ) );
729 PNS_DBG(
Dbg(), AddItem, &obstacleLine,
GREEN, 10000, wxT(
"obstacle-line" ) );
730 PNS_DBG(
Dbg(), AddItem, &shovedLine,
BLUE, 10000, wxT(
"shoved-line" ) );
734 int rank = aCurrent.
Rank();
735 shovedLine.
SetRank( rank - 1 );
737 replaceLine( obstacleLine, shovedLine,
true,
false );
752 LINE shovedLine( aObstacle );
756 PNS_DBG(
Dbg(), AddItem, &aObstacle,
RED, 100000, wxT(
"obstacle-line" ) );
757 PNS_DBG(
Dbg(), AddItem, &aCurrent,
GREEN, 150000, wxT(
"current-line" ) );
758 PNS_DBG(
Dbg(), AddItem, &shovedLine,
BLUE, 200000, wxT(
"shoved-line" ) );
768 m_newHead = shovedLine;
773 shovedLine.
SetRank( aNextRank );
790 LINE walkaroundLine( aCurrent );
818 PNS_DBG(
Dbg(), BeginGroup,
"walk-cluster", 1 );
821 PNS_DBG(
Dbg(), AddItem, item,
RED, 10000, wxT(
"cl-item" ) );
832 int currentRank = aCurrent.
Rank();
835 bool success =
false;
837 PNS_DBG(
Dbg(), AddItem, &aCurrent,
RED, 10000, wxT(
"current-line" ) );
839 for(
int attempt = 0; attempt < 2; attempt++ )
841 if( attempt == 1 ||
Settings().JumpOverObstacles() )
842 nextRank = currentRank - 1;
844 nextRank = currentRank + 10000;
860 PNS_DBG(
Dbg(), AddItem, &walkaroundLine,
BLUE, 10000, wxT(
"walk-line" ) );
870 m_newHead = walkaroundLine;
900 replaceLine( aCurrent, walkaroundLine,
true,
false );
901 walkaroundLine.
SetRank( nextRank );
915 PNS_DBG(
Dbg(), Message, wxString::Format(
"prune called" ) );
920 for(
const ITEM* item : added )
979 wxString::Format(
"restore-springback-via depth=%d %d %d %d %d ",
1015 wxString::Format(
"push-sp via depth=%d %d %d %d %d ", aNode->
Depth(), vhandle.
pos.
x,
1062 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"via force [%d %d]\n" ), aForce.
x, aForce.
y ) );
1065 if ( aForce.
x == 0 && aForce.
y == 0 )
1070 PNS_DBG(
Dbg(), Message, wxT(
"weird, can't find the center-of-via joint\n" ) );
1088 p0_pushed += aForce.
Resize( 2 );
1091 std::unique_ptr<VIA> pushedVia =
Clone( *aVia );
1092 pushedVia->SetPos( p0_pushed );
1093 pushedVia->Mark( aVia->
Marker() );
1105 if( lp.first.HasLockedSegments() )
1108 assert( segIndex == 0 || ( segIndex == ( lp.first.SegmentCount() - 1 ) ) );
1113 lp.second = lp.first;
1114 lp.second.ClearLinks();
1115 lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
1116 lp.second.Line().Simplify2();
1117 draggedLines.push_back( std::move( lp ) );
1121 pushedVia->SetRank( aNewRank );
1122 PNS_DBG(
Dbg(), Message, wxString::Format(
"via rank %d, fanout %d\n", pushedVia->Rank(), (
int) draggedLines.size() ) );
1127 VIA *
v2 = pushedVia.get();
1129 if( !aDontUnwindStack )
1134 if( draggedLines.empty() )
1145 if( !aDontUnwindStack )
1148 PNS_DBG(
Dbg(), Message, wxString::Format(
"fan %d/%d\n", n, (
int) draggedLines.size() ) );
1151 if( lp.second.SegmentCount() )
1153 lp.second.ClearLinks();
1156 lp.second.LinkVia(
v2 );
1158 if( !aDontUnwindStack )
1161 lp.second.SetRank( aNewRank );
1164 rootEntry->
newLine = lp.second;
1167 PNS_DBG(
Dbg(), Message, wxString::Format(
"PushViaF %p %d eov %d\n", &lp.second, lp.second.SegmentCount(), lp.second.EndsWithVia()?1:0 ) );
1191 assert( aObstacleVia );
1197 bool lineCollision =
false;
1198 bool viaCollision =
false;
1199 bool solidCollision =
false;
1200 VECTOR2I mtvLine, mtvVia, mtvSolid;
1202 PNS_DBG(
Dbg(), BeginGroup,
"push-via-by-line", 1 );
1206 VIA vtmp ( *aObstacleVia );
1207 int layer = aCurrent->
Layer();
1215 LINE* currentLine = (
LINE*) aCurrent;
1233 const VIA& currentVia = currentLine->
Via();
1250 PNS_DBG(
Dbg(), Message, wxT(
"collidee-is-solid" ) );
1263 else if ( lineCollision )
1265 else if ( solidCollision )
1271 PNS_DBG(
Dbg(), Message, wxString::Format(
"push-or-shove-via st %d", st ) );
1291 int layer = aCurrent.
Layer();
1292 int dist = (p0 - p1).EuclideanNorm() - aCurrent.
Via().
Diameter( layer ) / 2
1293 - aObstacleVia->
Diameter( layer ) / 2;
1303 PNS_DBG(
Dbg(), Message, wxString::Format(
"via2via coll check dist %d cl %d delta %d pi %d\n", dist,
clearance, dist -
clearance, epInsideHull ? 1 : 0) );
1305 bool viaCollision =
false;
1316 return onCollidingVia( &aCurrent, aObstacleVia, aObstacleInfo, aCurrent.
Rank() - 1 );
1320 LINE cur( aCurrent );
1324 LINE shoved( aCurrent );
1370 LINE head( aCurrent );
1388 PNS_DBG(
Dbg(), AddItem, &aCurrent,
BLUE, 0, wxT(
"rr-current-line" ) );
1389 PNS_DBG(
Dbg(), AddItem, &shoved,
GREEN, 0, wxT(
"rr-shoved-line" ) );
1392 int currentRank = aCurrent.
Rank();
1399 shoved.
SetRank( currentRank );
1411 if( i->ContainsLink( aSeg ) )
1424 via =
static_cast<VIA*
>( l );
1467 const LINE* l =
static_cast<const LINE*
>( aItem );
1479 PNS_DBG(
Dbg(), AddItem, &aL,
BLUE, 10000, wxT(
"push line stack failed" ) );
1511 wxString::Format(
"cur lc %d lnk %p cnt %d", i->LinkCount(), s, aLine.
LinkCount() ) );
1513 if( i->ContainsLink( s ) && !s->OfKind(
ITEM::VIA_T ) )
1539 int layer = aCurrent->
Layer();
1555 for(
ITEM* link : links )
1560 maxw = std::max( seg->
Width(), maxw );
1564 const ARC* arc =
static_cast<const ARC*
>( link );
1565 maxw = std::max( arc->
Width(), maxw );
1571 if( maxw > 0 && maxw >= v->
Diameter( layer ) )
1575 wxString::Format(
"Fixup via: new-w %d via-w %d", maxw, v->
Diameter( layer ) ) );
1588 int sl = s->
Layer();
1595 for(
int i = 0; i < 2; i++ )
1633 auto viaEnd = jtViaEnd->Via();
1638 bool colliding =
m_currentNode->CheckColliding( viaEnd ).has_value();
1642 if( viaEnd && !current.
EndsWithVia() && colliding )
1665 wxString::Format( wxT(
"current sc=%d net=%s evia=%d" ),
1698 nearest =
m_currentNode->NearestObstacle( ¤tLine, opts );
1703 wxString::Format(
"nearest %p %s rank %d",
1705 nearest->m_item->KindStr(),
1706 nearest->m_item->Rank() ) );
1716 PNS_DBG(
Dbg(), Message, wxT(
"no-nearest-item ") );
1722 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"iter %d: via-fixup %d" ), aIter, viaFixup?1:0 ) );
1725 ITEM* ni = nearest->m_item;
1728 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"NI: %s (%s) %p %d" ),
1731 : wxString( wxT(
"null" ) ),
1741 switch( ni->
Kind() )
1745 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: reverse-collide-via" ), aIter ), 0 );
1752 nearest->m_item->Layer() ) )
1754 PNS_DBG(
Dbg(), AddItem, nearest->m_item,
YELLOW, 100000, wxT(
"v2v nearesti" ) );
1773 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: reverse-collide-segment" ),
1816 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: reverse-collide-arc " ), aIter ), 0 );
1838 switch( ni->
Kind() )
1841 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: collide-segment " ), aIter ), 0 );
1854 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: collide-arc " ), aIter ), 0 );
1866 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: collide-via (fixup: %d)" ), aIter, 0 ), 0 );
1878 PNS_DBG(
Dbg(), BeginGroup, wxString::Format( wxT(
"iter %d: walk-solid " ), aIter ), 0);
1906 PNS_DBG(
Dbg(), Message, wxString::Format(
"ShoveStart [root: %d jts, current: %d jts]",
1926 PNS_DBG(
Dbg(), Message, wxString::Format(
"iter %d: node %p stack %d ",
m_iter,
1935 PNS_DBG(
Dbg(), Message, wxString::Format(
"Fail [time limit expired: %d iter %d iter limit %d",
1994 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"touch [found] uid=%llu type=%s"), link->Uid(), link->KindStr() ) );
2005 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"touch [create] uid=%llu type=%s"), link->Uid(), link->KindStr() ) );
2020 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"touch [create] uid=%llu"), aItem->
Uid() ) );
2026 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"touch [create] uid=%llu"), aItem->
Uid() ) );
2046 maxWidth = std::max( line.Width(), maxWidth );
2050 area->Inflate( maxWidth );
2100 std::set<const ITEM*> itemsChk;
2104 for(
int pass = 0; pass < n_passes; pass++ )
2113 LINE* rootLine =
nullptr;
2118 rootLine = rootEntry->rootLine;
2122 if( rootEntry->isHead )
2127 if( optimizer.
Optimize( &lineToOpt, &optimized, rootLine ) )
2135 replaceLine( lineToOpt, optimized,
false, aNode );
2173 if ( iter->m_node == aNode )
2219 if ( iter->m_node == aNode )
2221 iter->m_locked =
false;
2251 rl->policy = aPolicy;
2257 rl->policy = aPolicy;
2284 for (
auto lnk : head.
Links() )
2286 if( lnk->BelongsTo( aNode ) )
2299 for(
auto& item : added )
2302 if( rootEntry && rootEntry->isHead )
2319 if( headEntry.origHead )
2323 PNS_DBG(
Dbg(), Message, wxString::Format(
"orig LinkC=%d RE=%p", headEntry.origHead->LinkCount(), rootEntry ) );
2325 assert( rootEntry );
2326 assert( rootEntry->rootLine );
2328 if( rootEntry->newLine )
2330 headEntry.newHead = rootEntry->newLine;
2331 headEntry.geometryModified = !rootEntry->newLine->CLine().CompareGeometry( rootEntry->rootLine->CLine() );
2333 wxString msg = wxString::Format(
2334 "head %d/%d [net %-20s]: root %p, lc-root %d, lc-new %d\n", i, (
int)
m_headLines.size(),
2335 iface->GetNetName( rootEntry->rootLine->Net() ).c_str().AsChar(), rootEntry->rootLine, rootEntry->rootLine->LinkCount(), headEntry.newHead->LinkCount() );
2342 wxString msg = wxString::Format(
2343 "head %d/%d [net %-20s]: unmodified, lc-orig %d\n", i, (
int)
m_headLines.size(),
2344 iface->GetNetName( headEntry.origHead->Net() ).c_str().AsChar(),
2345 headEntry.origHead->LinkCount() );
2353 if( rootEntry->newVia )
2355 headEntry.geometryModified =
true;
2356 headEntry.theVia =
VIA_HANDLE( rootEntry->newVia->Pos(), rootEntry->newVia->Layers(), rootEntry->newVia->Net() );
2357 auto chk =
m_currentNode->FindViaByHandle( *headEntry.theVia );
2358 wxString msg = wxString::Format(
"[modif] via orig %p chk %p\n", headEntry.draggedVia, chk );
2361 assert( chk !=
nullptr );
2365 headEntry.theVia =
VIA_HANDLE( rootEntry->oldVia->Pos(), rootEntry->oldVia->Layers(), rootEntry->oldVia->Net() );
2366 auto chk =
m_currentNode->FindViaByHandle( *headEntry.theVia );
2367 wxString msg = wxString::Format(
"[unmodif] via orig %p chk %p\n", headEntry.draggedVia, chk );
2369 assert( chk !=
nullptr );
2397 PNS_DBG(
Dbg(), Message, wxString::Format(
"**** PreshoveCleanup %d -> %d\n", vc_prev, vc_post ) );
2399 if( vc_prev != vc_post )
2416 int currentHeadId = 0;
2431 PNS_DBG(
Dbg(), Message, wxString::Format(
"process head-via [%d %d] node=%p", l.theVia->pos.x, l.theVia->pos.y,
m_currentNode ) );
2433 assert( realVia !=
nullptr );
2434 headSet.
Add( realVia->Clone() );
2438 headSet.
Add( *l.origHead->Clone() );
2472 if( headLineEntry.theVia )
2483 viaRoot->oldVia = viaToDrag;
2484 headLineEntry.draggedVia = viaToDrag;
2486 st =
pushOrShoveVia( viaToDrag, ( headLineEntry.viaNewPos - viaToDrag->
Pos() ), 0,
true );
2494 assert( headLineEntry.origHead->LinkCount() == 0 );
2502 wxString::Format(
"touchRoot ohlc %d roots %d re=%p\n",
2503 headLineEntry.origHead->LinkCount(),
2508 LINE head( *headLineEntry.origHead );
2535 auto headVia =
Clone( head.
Via() );
2536 headVia->SetRank( 100000 );
2537 headLineEntry.origHead->LinkVia( headVia.get() );
2538 head.
LinkVia( headVia.get() );
2543 headRoot->isHead =
true;
2544 headRoot->rootLine =
new PNS::LINE( *headLineEntry.origHead );
2545 headRoot->policy = headLineEntry.policy;
2553 wxString::Format(
"headLC %d, rlLC %d oolc %d eov %d\n", head.
LinkCount(),
2554 headRoot->rootLine->LinkCount(),
2555 headLineEntry.origHead->LinkCount(),
2561 wxString::Format(
"Shove heads %d/%d h-lc=%d net=%s Line=%d Policy=%s",
2562 currentHeadId, totalHeads, head.
LinkCount(),
2563 iface->GetNetName( head.
Net() ), headRoot->newLine ? 1 : 0,
2565 : wxString( wxT(
"default[ne]" ) ) ) );
2586 wxString::Format(
"Shove status : %s after %d iterations, heads: %d",
2607 if( headEntry.prevVia )
2611 wxString::Format(
"Fail-restore via mod [%d, %d] orig [%d, %d]",
2612 headEntry.theVia->pos.x,
2613 headEntry.theVia->pos.y,
2614 headEntry.prevVia->pos.x,
2615 headEntry.prevVia->pos.y ) );
2617 headEntry.theVia = headEntry.prevVia;
2618 headEntry.geometryModified =
true;
2645 return wxT(
"default" );
2650 rv.Append(
"shove ");
2652 rv.Append(
"walk-forward ");
2654 rv.Append(
"walk-back ");
2656 rv.Append(
"ignore ");
2658 rv.Append(
"dont-optimize ");
constexpr EDA_IU_SCALE pcbIUScale
std::optional< BOX2I > OPT_BOX2I
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
@ ROUNDED_45
H/V/45 with filleted corners.
@ MITERED_45
H/V/45 with mitered corners (default)
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
const BOX2I & VisibleViewArea() const
void SetDebugDecorator(DEBUG_DECORATOR *aDecorator)
Assign a debug decorator allowing this algo to draw extra graphics for visual debugging.
ROUTER * Router() const
Return current router settings.
ALGO_BASE(ROUTER *aRouter)
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
DEBUG_DECORATOR * Dbg() const
int Width() const override
virtual void SetIteration(int iter)
void Add(const LINE &aLine)
Base class for PNS router board items.
BOARD_ITEM * Parent() const
virtual const std::string Format() const
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
std::set< int > RelevantShapeLayers(const ITEM *aOther) const
Returns the set of layers on which either this or the other item can have a unique shape.
virtual int Layer() const
PnsKind
< Supported item types
bool Collide(const ITEM *aHead, const NODE *aNode, int aLayer, COLLISION_SEARCH_CONTEXT *aCtx=nullptr) const
Check for a collision (clearance violation) with between us and item aOther.
virtual const NODE * OwningNode() const
bool OfKind(int aKindMask) const
bool LayersOverlap(const ITEM *aOther) const
Return true if the set of layers spanned by aOther overlaps our layers.
virtual HOLE * Hole() const
virtual bool HasHole() const
virtual int Marker() const
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
const std::vector< ITEM * > & LinkList() const
const ITEM_SET & CLinks() const
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
const VECTOR2I & CPoint(int aIdx) const
bool HasLockedSegments() const
int Rank() const override
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Return the shape of the line.
virtual void Mark(int aMarker) const override
const SHAPE_LINE_CHAIN & CLine() const
const VECTOR2I & CLastPoint() const
void SetRank(int aRank) override
SHAPE_LINE_CHAIN & Line()
const SHAPE * Shape(int aLayer) const override
Modifiable accessor to the underlying shape.
virtual int Marker() const override
void AppendVia(const VIA &aVia)
virtual void Unmark(int aMarker=-1) const override
bool Walkaround(SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle).
const SEG CSegment(int aIdx) const
Set line width.
virtual LINE * Clone() const override
Return a deep copy of the item.
int Width() const
Return true if the line is geometrically identical as line aOther.
void Unlink(const LINKED_ITEM *aLink)
Return the list of links from the owning node that constitute this line (or NULL if the line is not l...
bool IsLinked() const
Check if the segment aLink is a part of the line.
std::vector< LINKED_ITEM * > & Links()
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
Keep the router "world" - i.e.
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
std::vector< ITEM * > ITEM_VECTOR
void Replace(ITEM *aOldItem, std::unique_ptr< ITEM > aNewItem)
Replace an item with another one.
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
std::optional< OBSTACLE > OPT_OBSTACLE
void Remove(ARC *aArc)
Remove an item from this branch.
Perform various optimizations of the lines being routed, attempting to make the lines shorter and les...
void SetRestrictArea(const BOX2I &aArea, bool aStrict=true)
void SetCollisionMask(int aMask)
void SetEffortLevel(int aEffort)
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
@ LIMIT_CORNER_COUNT
Do not attempt to optimize if the resulting line's corner count is outside the predefined range.
@ SMART_PADS
Reroute pad exits.
@ MERGE_SEGMENTS
Reduce corner cost iteratively.
@ MERGE_OBTUSE
Reduce corner cost by merging obtuse segments.
virtual wxString GetNetName(PNS::NET_HANDLE aNet) const =0
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
ROUTER_IFACE * GetInterface() const
TIME_LIMIT ShoveTimeLimit() const
PNS_OPTIMIZATION_EFFORT OptimizerEffort() const
Set the optimizer effort. Bigger means cleaner traces, but slower routing.
int ShoveIterationLimit() const
DIRECTION_45::CORNER_MODE GetCornerMode() const
int Width() const override
const SHAPE_LINE_CHAIN Hull(int aClearance, int aWalkaroundThickness, int aLayer=-1) const override
void SetSpringbackDoNotTouchNode(const NODE *aNode)
SHOVE_STATUS shoveIteration(int aIter)
SHOVE_STATUS shoveMainLoop()
std::vector< SHAPE_LINE_CHAIN > HULL_SET
void reconstructHeads(bool aShoveFailed)
std::pair< LINE, LINE > LINE_PAIR
SHOVE_STATUS pushOrShoveVia(VIA *aVia, const VECTOR2I &aForce, int aNextRank, bool aDontUnwindStack=false)
SHOVE_STATUS onReverseCollidingVia(LINE &aCurrent, VIA *aObstacleVia, OBSTACLE &aObstacleInfo)
std::vector< LINE > m_lineStack
ROOT_LINE_ENTRY * findRootLine(const LINE &aLine)
std::vector< SPRINGBACK_TAG > m_nodeStack
@ SHP_DONT_LOCK_ENDPOINTS
bool patchTadpoleVia(ITEM *nearest, LINE ¤t)
SHOVE_STATUS onCollidingArc(LINE &aCurrent, ARC *aObstacleArc)
bool shoveLineToHullSet(const LINE &aCurLine, const LINE &aObstacleLine, LINE &aResultLine, const HULL_SET &aHulls, bool aPermitAdjustingStart=false, bool aPermitAdjustingEnd=false)
LINE assembleLine(const LINKED_ITEM *aSeg, int *aIndex=nullptr, bool aPreCleanup=false)
bool checkShoveDirection(const LINE &aCurLine, const LINE &aObstacleLine, const LINE &aShovedLine) const
SHOVE_STATUS onCollidingSegment(LINE &aCurrent, SEGMENT *aObstacleSeg)
SHOVE(NODE *aWorld, ROUTER *aRouter)
void DisablePostShoveOptimizations(int aMask)
bool RewindSpringbackTo(NODE *aNode)
bool pushLineStack(const LINE &aL, bool aKeepCurrentOnTop=false)
OPT_BOX2I totalAffectedArea() const
bool RewindToLastLockedNode()
std::deque< HEAD_LINE_ENTRY > m_headLines
const wxString formatPolicy(int aPolicy)
bool ShoveObstacleLine(const LINE &aCurLine, const LINE &aObstacleLine, LINE &aResultLine)
SHOVE_STATUS onCollidingVia(ITEM *aCurrent, VIA *aObstacleVia, OBSTACLE &aObstacleInfo, int aNextRank)
void sanityCheck(LINE *aOld, LINE *aNew)
int m_restrictSpringbackTagId
void runOptimizer(NODE *aNode)
ROOT_LINE_ENTRY * touchRootLine(const LINE &aLine)
const PNS::LINE GetModifiedHead(int aIndex) const
bool HeadsModified(int aIndex=-1) const
void UnlockSpringbackNode(NODE *aNode)
NODE * reduceSpringback(const ITEM_SET &aHeadSet)
bool AddLockedSpringbackNode(NODE *aNode)
void SetDefaultShovePolicy(int aPolicy)
void AddHeads(const LINE &aHead, int aPolicy=SHP_DEFAULT)
void SetShovePolicy(const LINKED_ITEM *aItem, int aPolicy)
void unwindLineStack(const LINKED_ITEM *aSeg)
bool preShoveCleanup(LINE *aOld, LINE *aNew)
int getClearance(const ITEM *aA, const ITEM *aB) const
std::vector< LINE > m_optimizerQueue
SHOVE_STATUS onCollidingSolid(LINE &aCurrent, ITEM *aObstacle, OBSTACLE &aObstacleInfo)
bool pushSpringback(NODE *aNode, const OPT_BOX2I &aAffectedArea)
SHOVE_STATUS onCollidingLine(LINE &aCurrent, LINE &aObstacle, int aNextRank)
bool fixupViaCollisions(const LINE *aCurrent, OBSTACLE &obs)
bool pruneLineFromOptimizerQueue(const LINE &aLine)
void replaceItems(ITEM *aOld, std::unique_ptr< ITEM > aNew)
bool shoveLineFromLoneVia(const LINE &aCurLine, const LINE &aObstacleLine, LINE &aResultLine)
const NODE * m_springbackDoNotTouchNode
std::unordered_map< LINKED_ITEM::UNIQ_ID, ROOT_LINE_ENTRY * > m_rootLineHistory
void pruneRootLines(NODE *aRemovedNode)
const VIA_HANDLE GetModifiedHeadVia(int aIndex) const
ROOT_LINE_ENTRY * replaceLine(LINE &aOld, LINE &aNew, bool aIncludeInChangedArea=true, bool aAllowRedundantSegments=true, NODE *aNode=nullptr)
std::vector< LINE_PAIR > LINE_PAIR_VEC
const CLUSTER AssembleCluster(ITEM *aStart, int aLayer, double aAreaExpansionLimit=0.0, NET_HANDLE aExcludedNet=nullptr)
int Diameter(int aLayer) const
void SetDiameter(int aLayer, int aDiameter)
const VECTOR2I & Pos() const
const SHAPE * Shape(int aLayer) const override
Return the geometrical shape of the item.
const SHAPE_LINE_CHAIN Hull(int aClearance=0, int aWalkaroundThickness=0, int aLayer=-1) const override
VIA * Clone() const override
Return a deep copy of the item.
void SetIterationLimit(const int aIterLimit)
void RestrictToCluster(bool aEnabled, const TOPOLOGY::CLUSTER &aCluster)
void SetSolidsOnly(bool aSolidsOnly)
STATUS Route(const LINE &aInitialPath, LINE &aWalkPath, bool aOptimize=true)
void SetAllowedPolicies(std::vector< WALK_POLICY > aPolicies)
static int DefaultAccuracyForPCB()
A dynamic state checking if a point lies within polygon with a dynamically built outline ( with each ...
void AddPolyline(const SHAPE_LINE_CHAIN &aPolyline)
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Clear()
Remove all points from the line chain.
SHAPE_LINE_CHAIN & Simplify2(bool aRemoveColinear=true)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
const std::string Format(bool aCplusPlus=true) const override
bool IsArcSegment(size_t aSegment) const
void Insert(size_t aVertex, const VECTOR2I &aP)
long long int Length() const
Return length of the line chain in Euclidean metric.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
VECTOR2_TRAITS< int32_t >::extended_type extended_type
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Push and Shove diff pair dimensions (gap) settings dialog.
OPT_BOX2I ChangedArea(const ITEM *aItemA, const ITEM *aItemB)
void removeHead(NODE *aNode, LINE &head)
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
#define PNS_DBG(dbg, method,...)
#define PNS_DBGN(dbg, method)
VECTOR2I::extended_type ecoord
std::vector< FAB_LAYER_COLOR > dummy
std::function< bool(const ITEM *)> m_filter
Hold an object colliding with another object, along with some useful data about the collision.
int m_maxFanoutWidth
worst case (largest) width of the tracks connected to the item
ITEM * m_item
Item found to be colliding with m_head.
std::optional< VIA_HANDLE > theVia
std::optional< VIA_HANDLE > prevVia
std::optional< LINE > newLine
std::vector< VIA_HANDLE > m_draggedVias
std::set< ITEM * > m_items
LINE lines[MaxWalkPolicies]
STATUS status[MaxWalkPolicies]
VECTOR2< int32_t > VECTOR2I