Router: fix Continue From End/ Attempt Finish work for diff pairs

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/13772
This commit is contained in:
Mike Williams 2023-03-06 14:48:42 -05:00
parent 8d3e1eb52a
commit 74a9d79a8d
7 changed files with 52 additions and 18 deletions

View File

@ -435,6 +435,15 @@ OPT_VECTOR2I getDanglingAnchor( NODE* aNode, ITEM* aItem )
{
switch( aItem->Kind() )
{
case ITEM::LINE_T:
{
LINE* l = static_cast<LINE*>( aItem );
if( !l->PointCount() )
return OPT_VECTOR2I();
else
return l->CPoint( 0 );
}
case ITEM::VIA_T:
case ITEM::SOLID_T:
return aItem->Anchor( 0 );

View File

@ -63,6 +63,7 @@
#include "pns_routing_settings.h"
#include "pns_sizes_settings.h"
#include "pns_item.h"
#include "pns_line.h"
#include "pns_solid.h"
#include "pns_segment.h"
#include "pns_node.h"
@ -862,11 +863,18 @@ int PNS_PCBNEW_RULE_RESOLVER::DpNetPolarity( int aNet )
bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN )
{
if( !aItem || !aItem->Parent() || !aItem->Parent()->IsConnected() )
if( !aItem )
return false;
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
NETINFO_ITEM* netInfo = cItem->GetNet();
NETINFO_ITEM* netInfo = nullptr;
if( aItem->Parent() && aItem->Parent()->IsConnected() )
{
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
netInfo = cItem->GetNet();
}
else
netInfo = m_board->FindNet( aItem->Net() );
if( !netInfo )
return false;

View File

@ -480,7 +480,8 @@ bool ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
}
bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers )
bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers,
ITEM*& aOtherEndItem )
{
// Can't finish something with no connections
if( GetCurrentNets().empty() )
@ -501,7 +502,8 @@ bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEn
// If the user has drawn a line, get the anchor nearest to the line end
if( trace->SegmentCount() > 0 )
return topo.NearestUnconnectedAnchorPoint( trace, aOtherEnd, aOtherEndLayers );
return topo.NearestUnconnectedAnchorPoint( trace, aOtherEnd, aOtherEndLayers,
aOtherEndItem );
// Otherwise, find the closest anchor to our start point
@ -521,6 +523,7 @@ bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEn
aOtherEnd = it->Anchor( anchor );
aOtherEndLayers = it->Layers();
aOtherEndItem = it;
return true;
}
@ -531,19 +534,24 @@ bool ROUTER::Finish()
if( m_state != ROUTE_TRACK )
return false;
LINE_PLACER* placer = dynamic_cast<LINE_PLACER*>( Placer() );
PLACEMENT_ALGO* placer = Placer();
if( placer == nullptr )
if( placer == nullptr || placer->Traces().Size() == 0 )
return false;
LINE* current = dynamic_cast<LINE*>( placer->Traces()[0] );
if( current == nullptr )
return false;
// Get our current line and position and nearest ratsnest to them if it exists
PNS::LINE current = placer->Trace();
VECTOR2I currentEnd = placer->CurrentEnd();
VECTOR2I otherEnd;
LAYER_RANGE otherEndLayers;
ITEM* otherEndItem = nullptr;
// Get the anchor nearest to the end of the trace the user is routing
if( !getNearestRatnestAnchor( otherEnd, otherEndLayers ) )
if( !getNearestRatnestAnchor( otherEnd, otherEndLayers, otherEndItem ) )
return false;
// Keep moving until we don't change position or hit the limit
@ -553,14 +561,14 @@ bool ROUTER::Finish()
do
{
moveResultPoint = Placer()->CurrentEnd();
Move( otherEnd, &current );
Move( otherEnd, otherEndItem );
triesLeft--;
} while( Placer()->CurrentEnd() != moveResultPoint && triesLeft );
// If we've made it, fix the route and we're done
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
{
return FixRoute( otherEnd, &current, false );
return FixRoute( otherEnd, otherEndItem, false );
}
return false;
@ -583,9 +591,10 @@ bool ROUTER::ContinueFromEnd()
VECTOR2I currentEnd = placer->CurrentEnd();
VECTOR2I otherEnd;
LAYER_RANGE otherEndLayers;
ITEM* otherEndItem = nullptr;
// Get the anchor nearest to the end of the trace the user is routing
if( !getNearestRatnestAnchor( otherEnd, otherEndLayers ) )
if( !getNearestRatnestAnchor( otherEnd, otherEndLayers, otherEndItem ) )
return false;
CommitRouting();
@ -593,7 +602,7 @@ bool ROUTER::ContinueFromEnd()
// Commit whatever we've fixed and restart routing from the other end
int nextLayer = otherEndLayers.Overlaps( currentLayer ) ? currentLayer : otherEndLayers.Start();
if( !StartRouting( otherEnd, current, nextLayer ) )
if( !StartRouting( otherEnd, otherEndItem, nextLayer ) )
return false;
// Attempt to route to our current position

View File

@ -228,7 +228,8 @@ private:
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
bool isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aItem, int aLayer );
bool getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers );
bool getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers,
ITEM*& aOtherEndItem );
private:

View File

@ -94,7 +94,7 @@ const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( JOINT* aStart )
bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
LAYER_RANGE& aLayers )
LAYER_RANGE& aLayers, ITEM*& aItem )
{
LINE track( *aTrack );
VECTOR2I end;
@ -115,6 +115,7 @@ bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoi
{
end = jt->Pos();
aLayers = jt->Layers();
aItem = jt->LinkList()[0];
}
else
{
@ -128,6 +129,7 @@ bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoi
end = it->Anchor( anchor );
aLayers = it->Layers();
aItem = it;
}
aPoint = end;
@ -140,8 +142,9 @@ bool TOPOLOGY::LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
VECTOR2I end;
// Ratline doesn't care about the layer
LAYER_RANGE layers;
ITEM* unusedItem;
if( !NearestUnconnectedAnchorPoint( aTrack, end, layers ) )
if( !NearestUnconnectedAnchorPoint( aTrack, end, layers, unusedItem ) )
return false;
aRatLine.Clear();

View File

@ -50,8 +50,8 @@ public:
ITEM* NearestUnconnectedItem( JOINT* aStart, int* aAnchor = nullptr,
int aKindMask = ITEM::ANY_T );
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
LAYER_RANGE& aLayers );
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint, LAYER_RANGE& aLayers,
ITEM*& aItem );
bool LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
const JOINT_SET ConnectedJoints( JOINT* aStart );

View File

@ -1369,6 +1369,10 @@ void ROUTER_TOOL::performRouting()
// We want the next router commit to be one undo at the UI layer
m_iface->SetCommitFlags( needsAppend ? APPEND_UNDO : 0 );
}
else
{
frame()->ShowInfoBarError( m_router->FailureReason(), true );
}
}
else if( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) || evt->IsAction( &PCB_ACTIONS::routeSingleTrack ) )
{