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 < 4; attempt++ )
 
  321        bool invertTraversal = ( attempt >= 2 );
 
  322        bool clockwise = attempt % 2;
 
  323        int vFirst = -1, vLast = -1;
 
  325        LINE l( aObstacleLine );
 
  332                int      min_dist = std::numeric_limits<int>::max();
 
  335                for( 
int i = 0; i < (int) aHulls.size(); i++ )
 
  338                            aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
 
  345                        dist = ( p - pref ).EuclideanNorm();
 
  347                    if( dist < c_ENDPOINT_ON_HULL_THRESHOLD && dist < min_dist )
 
  355                            minhull = invertTraversal ? aHulls.size() - 1 - i : i;
 
  363            int      minDist0, minDist1, minhull0, minhull1 ;
 
  367            PNS_DBG( 
Dbg(), Message, wxString::Format( 
"mindists : %d %d hulls %d %d\n", minDist0, minDist1, minhull0, minhull1 ) );
 
  369            if( minDist1 < c_ENDPOINT_ON_HULL_THRESHOLD && aPermitAdjustingEnd )
 
  376            if( minDist0 < c_ENDPOINT_ON_HULL_THRESHOLD && aPermitAdjustingStart )
 
  385        bool failWalk = 
false;
 
  387        for( 
int i = 0; i < (int) aHulls.size(); i++ )
 
  389            const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
 
  391            PNS_DBG( 
Dbg(), AddShape, &hull, 
YELLOW, 10000, wxString::Format( 
"hull[%d]", i ) );
 
  397                PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"Fail-Walk %s %s %d\n" ),
 
  413        for( 
int i = 0; i < std::min( 
path.PointCount(), obs.
PointCount() ); i++ )
 
  424        for( 
int i = 
path.PointCount() - 1; i >= 0 && k >= 0; i--, k-- )
 
  433        if( ( vFirst < 0 || vLast < 0 ) && !
path.CompareGeometry( obs ) )
 
  435            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"attempt %d fail vfirst-last" ),
 
  442            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"attempt %d fail vend-start\n" ),
 
  449            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"attempt %d fail direction-check" ),
 
  455        if( 
path.SelfIntersecting() )
 
  457            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"attempt %d fail self-intersect" ),
 
  479            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"attempt %d fail coll-check" ),
 
 
  504    const int cHullFailureExpansionFactor = 1000;
 
  505    int extraHullExpansion = 0;
 
  507    bool voeStart = 
false, voeEnd = 
false;
 
  508    const JOINT* jtStart = 
nullptr;
 
  509    const JOINT* jtEnd = 
nullptr;
 
  518        voeStart = jtStart->
Via() != 
nullptr;
 
  520        voeEnd = jtEnd->
Via() != 
nullptr;
 
  525    LINE obstacleLine( aObstacleLine );
 
  526    std::optional<VIA> obsVia;
 
  530        obsVia = aObstacleLine.
Via();
 
  534    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"shove process-single: voe-cur %d voe-obs %d" ),
 
  549        int      obstacleLineWidth = obstacleLine.
Width();
 
  558        for( 
int attempt = 0; attempt < 3; attempt++ )
 
  562            hulls.reserve( currentLineSegmentCount + 1 );
 
  564            for( 
int i = 0; i < currentLineSegmentCount; i++ )
 
  571                    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"shove add-extra-clearance %d" ),
 
  578                hulls.push_back( hull );
 
  586                int        holeClearance = 
getClearance( viaHole, &obstacleLine );
 
  587                int        layer = aObstacleLine.
Layer();
 
  589                if( holeClearance + 
via.Drill() / 2 > viaClearance + 
via.Diameter( layer ) / 2 )
 
  591                    viaClearance = holeClearance + 
via.Drill() / 2 - 
via.Diameter( layer ) / 2;
 
  594                hulls.push_back( aCurLine.
Via().
Hull( viaClearance, obstacleLineWidth, layer ) );
 
  597            bool permitMovingStart = (attempt >= 2) && !voeStart;
 
  598            bool permitMovingEnd = (attempt >= 2) && !voeEnd;
 
  600            if (
shoveLineToHullSet( aCurLine, obstacleLine, aResultLine, hulls, permitMovingStart, permitMovingEnd ) )
 
  608            extraHullExpansion += cHullFailureExpansionFactor;
 
 
  624    LINE shovedLine( obstacleLine );
 
  629        PNS_DBG(
Dbg(), Message, 
"try walk (locked segments)");
 
  635    const double extensionWalkThreshold = 1.0;
 
  639    double extensionFactor = 0.0;
 
  642        extensionFactor = shovedLen / obsLen - 1.0;
 
  651        PNS_DBG( 
Dbg(), AddItem, aObstacleSeg, 
BLUE, 0, wxT( 
"colliding-segment" ) );
 
  654        PNS_DBG( 
Dbg(), AddItem, &shovedLine, 
BLUE, 10000, wxT( 
"shoved-line" ) );
 
  659        int rank = aCurrent.
Rank();
 
  661        shovedLine.
SetRank( rank - 1 );
 
  666        replaceLine( obstacleLine, shovedLine, 
true, 
false );
 
 
  685    LINE shovedLine( obstacleLine );
 
  686    ARC tmp( *aObstacleArc );
 
  693    const double extensionWalkThreshold = 1.0;
 
  697    double extensionFactor = 0.0;
 
  700        extensionFactor = shovedLen / obsLen - 1.0;
 
  702    if( extensionFactor > extensionWalkThreshold )
 
  708    PNS_DBG( 
Dbg(), AddItem, &aCurrent, 
RED, 10000, wxT( 
"current-line" ) );
 
  709    PNS_DBG( 
Dbg(), AddItem, &obstacleLine, 
GREEN, 10000, wxT( 
"obstacle-line" ) );
 
  710    PNS_DBG( 
Dbg(), AddItem, &shovedLine, 
BLUE, 10000, wxT( 
"shoved-line" ) );
 
  714        int rank = aCurrent.
Rank();
 
  715        shovedLine.
SetRank( rank - 1 );
 
  717        replaceLine( obstacleLine, shovedLine, 
true, 
false );
 
 
  732    LINE shovedLine( aObstacle );
 
  736    PNS_DBG( 
Dbg(), AddItem, &aObstacle, 
RED, 100000, wxT( 
"obstacle-line" ) );
 
  737    PNS_DBG( 
Dbg(), AddItem, &aCurrent, 
GREEN, 150000, wxT( 
"current-line" ) );
 
  738    PNS_DBG( 
Dbg(), AddItem, &shovedLine, 
BLUE, 200000, wxT( 
"shoved-line" ) );
 
  748            m_newHead = shovedLine;
 
  753        shovedLine.
SetRank( aNextRank );
 
 
  770    LINE walkaroundLine( aCurrent );
 
  798    PNS_DBG( 
Dbg(), BeginGroup, 
"walk-cluster", 1 );
 
  801        PNS_DBG( 
Dbg(), AddItem, item, 
RED, 10000, wxT( 
"cl-item" ) );
 
  812    int currentRank = aCurrent.
Rank();
 
  815    bool success = 
false;
 
  817    PNS_DBG( 
Dbg(), AddItem, &aCurrent, 
RED, 10000, wxT( 
"current-line" ) );
 
  819    for( 
int attempt = 0; attempt < 2; attempt++ )
 
  821        if( attempt == 1 || 
Settings().JumpOverObstacles() )
 
  822            nextRank = currentRank - 1;
 
  824            nextRank = currentRank + 10000;
 
  840        PNS_DBG( 
Dbg(), AddItem, &walkaroundLine, 
BLUE, 10000, wxT( 
"walk-line" ) );
 
  850            m_newHead = walkaroundLine;
 
  880    replaceLine( aCurrent, walkaroundLine, 
true, 
false );
 
  881    walkaroundLine.
SetRank( nextRank );
 
 
  895    PNS_DBG( 
Dbg(), Message, wxString::Format(
"prune called" ) );
 
  900    for( 
const ITEM* item : added )
 
 
  959                     wxString::Format( 
"restore-springback-via depth=%d %d %d %d %d ",
 
 
  995                                wxString::Format( 
"push-sp via depth=%d %d %d %d %d ", aNode->
Depth(), vhandle.
pos.
x,
 
 
 1042    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"via force [%d %d]\n" ), aForce.
x, aForce.
y ) );
 
 1045    if ( aForce.
x == 0 && aForce.
y == 0 )
 
 1050        PNS_DBG( 
Dbg(), Message, wxT( 
"weird, can't find the center-of-via joint\n" ) );
 
 1068        p0_pushed += aForce.
Resize( 2 );
 
 1071    std::unique_ptr<VIA> pushedVia = 
Clone( *aVia );
 
 1072    pushedVia->SetPos( p0_pushed );
 
 1073    pushedVia->Mark( aVia->
Marker() );
 
 1085            if( lp.first.HasLockedSegments() )
 
 1088            assert( segIndex == 0 || ( segIndex == ( lp.first.SegmentCount() - 1 ) ) );
 
 1093            lp.second = lp.first;
 
 1094            lp.second.ClearLinks();
 
 1095            lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
 
 1096            lp.second.Line().Simplify2();
 
 1097            draggedLines.push_back( std::move( lp ) );
 
 1101    pushedVia->SetRank( aNewRank );
 
 1102    PNS_DBG( 
Dbg(), Message, wxString::Format(
"via rank %d, fanout %d\n", pushedVia->Rank(), (
int) draggedLines.size() ) );
 
 1107    VIA *
v2 = pushedVia.get();
 
 1109    if( !aDontUnwindStack )
 
 1114    if( draggedLines.empty() ) 
 
 1125        if( !aDontUnwindStack )
 
 1128        PNS_DBG( 
Dbg(), Message, wxString::Format(
"fan %d/%d\n", n, (
int) draggedLines.size() ) );
 
 1131        if( lp.second.SegmentCount() )
 
 1133            lp.second.ClearLinks();
 
 1136            lp.second.LinkVia( 
v2 );
 
 1138            if( !aDontUnwindStack )
 
 1141            lp.second.SetRank( aNewRank );
 
 1144                rootEntry->
newLine = lp.second; 
 
 1147            PNS_DBG( 
Dbg(), Message, wxString::Format(
"PushViaF %p %d eov %d\n", &lp.second, lp.second.SegmentCount(), lp.second.EndsWithVia()?1:0 ) );
 
 
 1171    assert( aObstacleVia );
 
 1177    bool lineCollision = 
false;
 
 1178    bool viaCollision = 
false;
 
 1179    bool solidCollision = 
false;
 
 1180    VECTOR2I mtvLine, mtvVia, mtvSolid;
 
 1182    PNS_DBG( 
Dbg(), BeginGroup, 
"push-via-by-line", 1 );
 
 1186        VIA vtmp ( *aObstacleVia );
 
 1187        int layer = aCurrent->
Layer();
 
 1195        LINE* currentLine = (
LINE*) aCurrent;
 
 1213            const VIA& currentVia = currentLine->
Via();
 
 1230        PNS_DBG( 
Dbg(), Message, wxT(
"collidee-is-solid" ) );
 
 1243    else if ( lineCollision )
 
 1245    else if ( solidCollision )
 
 1251    PNS_DBG( 
Dbg(), Message, wxString::Format(
"push-or-shove-via st %d", st ) );
 
 
 1271        int layer = aCurrent.
Layer();
 
 1272        int dist = (p0 - p1).EuclideanNorm() - aCurrent.
Via().
Diameter( layer ) / 2
 
 1273                   - aObstacleVia->
Diameter( layer ) / 2;
 
 1282        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) );
 
 1284        bool viaCollision = 
false;
 
 1295            return onCollidingVia( &aCurrent, aObstacleVia, aObstacleInfo, aCurrent.
Rank() - 1 );
 
 1299    LINE cur( aCurrent );
 
 1303    LINE shoved( aCurrent );
 
 1349        LINE head( aCurrent );
 
 1367    PNS_DBG( 
Dbg(), AddItem, &aCurrent, 
BLUE, 0, wxT( 
"rr-current-line" ) );
 
 1368    PNS_DBG( 
Dbg(), AddItem, &shoved, 
GREEN, 0, wxT( 
"rr-shoved-line" ) );
 
 1371    int currentRank = aCurrent.
Rank();
 
 1378    shoved.
SetRank( currentRank );
 
 
 1390        if( i->ContainsLink( aSeg ) )
 
 1403                        via = 
static_cast<VIA*
>( l );
 
 
 1446        const LINE* l = 
static_cast<const LINE*
>( aItem );
 
 
 1458        PNS_DBG( 
Dbg(), AddItem, &aL, 
BLUE, 10000, wxT( 
"push line stack failed" ) );
 
 
 1490                     wxString::Format( 
"cur lc %d lnk %p cnt %d", i->LinkCount(), s, aLine.
LinkCount() ) );
 
 1492            if( i->ContainsLink( s ) && !s->OfKind( 
ITEM::VIA_T ) )
 
 
 1518    int layer = aCurrent->
Layer();
 
 1534        for( 
ITEM* link : links )
 
 1539                maxw = std::max( seg->
Width(), maxw );
 
 1543                const ARC* arc = 
static_cast<const ARC*
>( link );
 
 1544                maxw = std::max( arc->
Width(), maxw );
 
 1550        if( maxw > 0 && maxw >= v->
Diameter( layer ) )
 
 1554                     wxString::Format( 
"Fixup via: new-w %d via-w %d", maxw, v->
Diameter( layer ) ) );
 
 1567    int sl = s->
Layer();
 
 1574    for( 
int i = 0; i < 2; i++ )
 
 
 1612    auto viaEnd = jtViaEnd->Via();
 
 1617    bool colliding = 
m_currentNode->CheckColliding( viaEnd ).has_value();
 
 1621    if( viaEnd && !current.
EndsWithVia() && colliding )
 
 
 1644             wxString::Format( wxT( 
"current sc=%d net=%s evia=%d" ),
 
 1677        nearest = 
m_currentNode->NearestObstacle( ¤tLine, opts );
 
 1682            wxString::Format( 
"nearest %p %s rank %d",
 
 1684                                                        nearest->m_item->KindStr(),
 
 1685                                                        nearest->m_item->Rank() ) );
 
 1695        PNS_DBG( 
Dbg(), Message, wxT( 
"no-nearest-item ") );
 
 1701    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"iter %d: via-fixup %d" ), aIter, viaFixup?1:0 ) );
 
 1704    ITEM* ni = nearest->m_item;
 
 1707    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"NI: %s (%s) %p %d" ),
 
 1710                                                            : wxString( wxT( 
"null" ) ),
 
 1720        switch( ni->
Kind() )
 
 1724            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: reverse-collide-via" ), aIter ), 0 );
 
 1731                                             nearest->m_item->Layer() ) )
 
 1733                PNS_DBG( 
Dbg(), AddItem, nearest->m_item, 
YELLOW, 100000, wxT(
"v2v nearesti" ) );
 
 1752            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: reverse-collide-segment" ),
 
 1795            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: reverse-collide-arc " ), aIter ), 0 );
 
 1817        switch( ni->
Kind() )
 
 1820            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: collide-segment " ), aIter ), 0 );
 
 1833            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: collide-arc " ), aIter ), 0 );
 
 1845            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: collide-via (fixup: %d)" ), aIter, 0 ), 0 );
 
 1857            PNS_DBG( 
Dbg(), BeginGroup, wxString::Format( wxT( 
"iter %d: walk-solid " ), aIter ), 0);
 
 
 1885    PNS_DBG( 
Dbg(), Message, wxString::Format( 
"ShoveStart [root: %d jts, current: %d jts]",
 
 1905        PNS_DBG( 
Dbg(), Message, wxString::Format( 
"iter %d: node %p stack %d ", 
m_iter,
 
 1914            PNS_DBG( 
Dbg(), Message, wxString::Format( 
"Fail [time limit expired: %d iter %d iter limit %d",
 
 
 1973            PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"touch [found] uid=%llu type=%s"), link->Uid(), link->KindStr() ) );
 
 1984        PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"touch [create] uid=%llu type=%s"), link->Uid(), link->KindStr() ) );
 
 
 1999        PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"touch [create] uid=%llu"), aItem->
Uid() ) );
 
 2005    PNS_DBG( 
Dbg(), Message, wxString::Format( wxT( 
"touch [create] uid=%llu"), aItem->
Uid() ) );
 
 
 2025        maxWidth = std::max( line.Width(), maxWidth );
 
 2029        area->Inflate( maxWidth );
 
 2079    std::set<const ITEM*> itemsChk;
 
 2083    for( 
int pass = 0; pass < n_passes; pass++ )
 
 2092            LINE* rootLine = 
nullptr;
 
 2097                rootLine = rootEntry->rootLine;
 
 2101                if( rootEntry->isHead )
 
 2106            if( optimizer.
Optimize( &lineToOpt, &optimized, rootLine ) )
 
 2114                replaceLine( lineToOpt, optimized, 
false, aNode );
 
 
 2152        if ( iter->m_node == aNode )
 
 
 2198        if ( iter->m_node == aNode )
 
 2200            iter->m_locked = 
false;
 
 
 2230    rl->policy = aPolicy;
 
 
 2236    rl->policy = aPolicy;
 
 
 2263    for (
auto lnk : head.
Links() )
 
 2265        if( lnk->BelongsTo( aNode ) )
 
 
 2278    for( 
auto& item : added )
 
 2281        if( rootEntry && rootEntry->isHead )
 
 
 2298        if( headEntry.origHead )
 
 2302            PNS_DBG( 
Dbg(), Message, wxString::Format(
"orig LinkC=%d RE=%p", headEntry.origHead->LinkCount(), rootEntry ) );
 
 2304            assert( rootEntry );
 
 2305            assert( rootEntry->rootLine );
 
 2307            if( rootEntry->newLine )
 
 2309                headEntry.newHead = rootEntry->newLine;
 
 2310                headEntry.geometryModified = !rootEntry->newLine->CLine().CompareGeometry( rootEntry->rootLine->CLine() );
 
 2312                wxString msg = wxString::Format(
 
 2313                        "head %d/%d [net %-20s]: root %p, lc-root %d, lc-new %d\n", i, (
int) 
m_headLines.size(),
 
 2314                        iface->GetNetName( rootEntry->rootLine->Net() ).c_str().AsChar(), rootEntry->rootLine, rootEntry->rootLine->LinkCount(), headEntry.newHead->LinkCount() );
 
 2321                wxString msg = wxString::Format(
 
 2322                        "head %d/%d [net %-20s]: unmodified, lc-orig %d\n", i, (
int) 
m_headLines.size(),
 
 2323                        iface->GetNetName( headEntry.origHead->Net() ).c_str().AsChar(),
 
 2324                        headEntry.origHead->LinkCount() );
 
 2332            if( rootEntry->newVia )
 
 2334                headEntry.geometryModified = 
true;
 
 2335                headEntry.theVia = 
VIA_HANDLE( rootEntry->newVia->Pos(), rootEntry->newVia->Layers(), rootEntry->newVia->Net() );
 
 2336                auto chk = 
m_currentNode->FindViaByHandle( *headEntry.theVia );
 
 2337                wxString msg = wxString::Format( 
"[modif] via orig %p chk %p\n", headEntry.draggedVia, chk );
 
 2340                assert( chk != 
nullptr );
 
 2344                headEntry.theVia = 
VIA_HANDLE( rootEntry->oldVia->Pos(), rootEntry->oldVia->Layers(), rootEntry->oldVia->Net() );
 
 2345                auto chk = 
m_currentNode->FindViaByHandle( *headEntry.theVia );
 
 2346                wxString msg = wxString::Format( 
"[unmodif] via orig %p chk %p\n", headEntry.draggedVia, chk );
 
 2348                assert( chk != 
nullptr );
 
 
 2376    PNS_DBG( 
Dbg(), Message, wxString::Format( 
"**** PreshoveCleanup %d -> %d\n", vc_prev, vc_post ) );
 
 2378    if( vc_prev != vc_post )
 
 
 2395    int currentHeadId = 0;
 
 2410            PNS_DBG( 
Dbg(), Message, wxString::Format(
"process head-via [%d %d] node=%p", l.theVia->pos.x, l.theVia->pos.y, 
m_currentNode ) );
 
 2412            assert( realVia != 
nullptr );
 
 2413            headSet.
Add( realVia->Clone() );
 
 2417            headSet.
Add( *l.origHead->Clone() );
 
 2451        if( headLineEntry.theVia )
 
 2462            viaRoot->oldVia = viaToDrag;
 
 2463            headLineEntry.draggedVia = viaToDrag;
 
 2465            st = 
pushOrShoveVia( viaToDrag, ( headLineEntry.viaNewPos - viaToDrag->
Pos() ), 0, 
true );
 
 2473            assert( headLineEntry.origHead->LinkCount() == 0 );
 
 2481                     wxString::Format( 
"touchRoot ohlc %d roots %d re=%p\n",
 
 2482                                       headLineEntry.origHead->LinkCount(),
 
 2487            LINE head( *headLineEntry.origHead );
 
 2514                auto headVia = 
Clone( head.
Via() );
 
 2515                headVia->SetRank( 100000 ); 
 
 2516                headLineEntry.origHead->LinkVia( headVia.get() );
 
 2517                head.
LinkVia( headVia.get() );
 
 2522            headRoot->isHead = 
true;
 
 2523            headRoot->rootLine = 
new PNS::LINE( *headLineEntry.origHead );
 
 2524            headRoot->policy = headLineEntry.policy;
 
 2532                     wxString::Format( 
"headLC %d, rlLC %d oolc %d eov %d\n", head.
LinkCount(),
 
 2533                                       headRoot->rootLine->LinkCount(),
 
 2534                                       headLineEntry.origHead->LinkCount(),
 
 2540                     wxString::Format( 
"Shove heads %d/%d h-lc=%d net=%s Line=%d Policy=%s",
 
 2541                                       currentHeadId, totalHeads, head.
LinkCount(),
 
 2542                                       iface->GetNetName( head.
Net() ), headRoot->newLine ? 1 : 0,
 
 2544                                                : wxString( wxT( 
"default[ne]" ) ) ) );
 
 2565                 wxString::Format( 
"Shove status : %s after %d iterations, heads: %d",
 
 2586            if( headEntry.prevVia )
 
 2590                 wxString::Format( 
"Fail-restore via mod [%d, %d] orig [%d, %d]",
 
 2591                    headEntry.theVia->pos.x,
 
 2592                    headEntry.theVia->pos.y,
 
 2593                    headEntry.prevVia->pos.x,
 
 2594                    headEntry.prevVia->pos.y ) );
 
 2596                headEntry.theVia = headEntry.prevVia;
 
 2597                headEntry.geometryModified = 
true;
 
 
 2624        return wxT( 
"default" );
 
 2629        rv.Append( 
"shove ");
 
 2631        rv.Append( 
"walk-forward ");
 
 2633        rv.Append( 
"walk-back ");
 
 2635        rv.Append( 
"ignore ");
 
 2637        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