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:
parent
8d3e1eb52a
commit
74a9d79a8d
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
NETINFO_ITEM* netInfo = nullptr;
|
||||
|
||||
if( aItem->Parent() && aItem->Parent()->IsConnected() )
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
|
||||
NETINFO_ITEM* netInfo = cItem->GetNet();
|
||||
netInfo = cItem->GetNet();
|
||||
}
|
||||
else
|
||||
netInfo = m_board->FindNet( aItem->Net() );
|
||||
|
||||
if( !netInfo )
|
||||
return false;
|
||||
|
|
|
@ -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, ¤t );
|
||||
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, ¤t, 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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 ) )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue