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() )
|
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::VIA_T:
|
||||||
case ITEM::SOLID_T:
|
case ITEM::SOLID_T:
|
||||||
return aItem->Anchor( 0 );
|
return aItem->Anchor( 0 );
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "pns_routing_settings.h"
|
#include "pns_routing_settings.h"
|
||||||
#include "pns_sizes_settings.h"
|
#include "pns_sizes_settings.h"
|
||||||
#include "pns_item.h"
|
#include "pns_item.h"
|
||||||
|
#include "pns_line.h"
|
||||||
#include "pns_solid.h"
|
#include "pns_solid.h"
|
||||||
#include "pns_segment.h"
|
#include "pns_segment.h"
|
||||||
#include "pns_node.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 )
|
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;
|
return false;
|
||||||
|
|
||||||
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
|
NETINFO_ITEM* netInfo = nullptr;
|
||||||
NETINFO_ITEM* netInfo = cItem->GetNet();
|
|
||||||
|
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 )
|
if( !netInfo )
|
||||||
return false;
|
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
|
// Can't finish something with no connections
|
||||||
if( GetCurrentNets().empty() )
|
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 the user has drawn a line, get the anchor nearest to the line end
|
||||||
if( trace->SegmentCount() > 0 )
|
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
|
// 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 );
|
aOtherEnd = it->Anchor( anchor );
|
||||||
aOtherEndLayers = it->Layers();
|
aOtherEndLayers = it->Layers();
|
||||||
|
aOtherEndItem = it;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -531,19 +534,24 @@ bool ROUTER::Finish()
|
||||||
if( m_state != ROUTE_TRACK )
|
if( m_state != ROUTE_TRACK )
|
||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
// Get our current line and position and nearest ratsnest to them if it exists
|
// Get our current line and position and nearest ratsnest to them if it exists
|
||||||
PNS::LINE current = placer->Trace();
|
|
||||||
VECTOR2I currentEnd = placer->CurrentEnd();
|
VECTOR2I currentEnd = placer->CurrentEnd();
|
||||||
VECTOR2I otherEnd;
|
VECTOR2I otherEnd;
|
||||||
LAYER_RANGE otherEndLayers;
|
LAYER_RANGE otherEndLayers;
|
||||||
|
ITEM* otherEndItem = nullptr;
|
||||||
|
|
||||||
// Get the anchor nearest to the end of the trace the user is routing
|
// 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;
|
return false;
|
||||||
|
|
||||||
// Keep moving until we don't change position or hit the limit
|
// Keep moving until we don't change position or hit the limit
|
||||||
|
@ -553,14 +561,14 @@ bool ROUTER::Finish()
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
moveResultPoint = Placer()->CurrentEnd();
|
moveResultPoint = Placer()->CurrentEnd();
|
||||||
Move( otherEnd, ¤t );
|
Move( otherEnd, otherEndItem );
|
||||||
triesLeft--;
|
triesLeft--;
|
||||||
} while( Placer()->CurrentEnd() != moveResultPoint && triesLeft );
|
} while( Placer()->CurrentEnd() != moveResultPoint && triesLeft );
|
||||||
|
|
||||||
// If we've made it, fix the route and we're done
|
// If we've made it, fix the route and we're done
|
||||||
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
|
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
|
||||||
{
|
{
|
||||||
return FixRoute( otherEnd, ¤t, false );
|
return FixRoute( otherEnd, otherEndItem, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -583,9 +591,10 @@ bool ROUTER::ContinueFromEnd()
|
||||||
VECTOR2I currentEnd = placer->CurrentEnd();
|
VECTOR2I currentEnd = placer->CurrentEnd();
|
||||||
VECTOR2I otherEnd;
|
VECTOR2I otherEnd;
|
||||||
LAYER_RANGE otherEndLayers;
|
LAYER_RANGE otherEndLayers;
|
||||||
|
ITEM* otherEndItem = nullptr;
|
||||||
|
|
||||||
// Get the anchor nearest to the end of the trace the user is routing
|
// 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;
|
return false;
|
||||||
|
|
||||||
CommitRouting();
|
CommitRouting();
|
||||||
|
@ -593,7 +602,7 @@ bool ROUTER::ContinueFromEnd()
|
||||||
// Commit whatever we've fixed and restart routing from the other end
|
// Commit whatever we've fixed and restart routing from the other end
|
||||||
int nextLayer = otherEndLayers.Overlaps( currentLayer ) ? currentLayer : otherEndLayers.Start();
|
int nextLayer = otherEndLayers.Overlaps( currentLayer ) ? currentLayer : otherEndLayers.Start();
|
||||||
|
|
||||||
if( !StartRouting( otherEnd, current, nextLayer ) )
|
if( !StartRouting( otherEnd, otherEndItem, nextLayer ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Attempt to route to our current position
|
// Attempt to route to our current position
|
||||||
|
|
|
@ -228,7 +228,8 @@ private:
|
||||||
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
|
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
|
||||||
bool isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aItem, int aLayer );
|
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:
|
private:
|
||||||
|
|
|
@ -94,7 +94,7 @@ const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( JOINT* aStart )
|
||||||
|
|
||||||
|
|
||||||
bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
|
bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
|
||||||
LAYER_RANGE& aLayers )
|
LAYER_RANGE& aLayers, ITEM*& aItem )
|
||||||
{
|
{
|
||||||
LINE track( *aTrack );
|
LINE track( *aTrack );
|
||||||
VECTOR2I end;
|
VECTOR2I end;
|
||||||
|
@ -115,6 +115,7 @@ bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoi
|
||||||
{
|
{
|
||||||
end = jt->Pos();
|
end = jt->Pos();
|
||||||
aLayers = jt->Layers();
|
aLayers = jt->Layers();
|
||||||
|
aItem = jt->LinkList()[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -128,6 +129,7 @@ bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoi
|
||||||
|
|
||||||
end = it->Anchor( anchor );
|
end = it->Anchor( anchor );
|
||||||
aLayers = it->Layers();
|
aLayers = it->Layers();
|
||||||
|
aItem = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
aPoint = end;
|
aPoint = end;
|
||||||
|
@ -140,8 +142,9 @@ bool TOPOLOGY::LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
|
||||||
VECTOR2I end;
|
VECTOR2I end;
|
||||||
// Ratline doesn't care about the layer
|
// Ratline doesn't care about the layer
|
||||||
LAYER_RANGE layers;
|
LAYER_RANGE layers;
|
||||||
|
ITEM* unusedItem;
|
||||||
|
|
||||||
if( !NearestUnconnectedAnchorPoint( aTrack, end, layers ) )
|
if( !NearestUnconnectedAnchorPoint( aTrack, end, layers, unusedItem ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
aRatLine.Clear();
|
aRatLine.Clear();
|
||||||
|
|
|
@ -50,8 +50,8 @@ public:
|
||||||
ITEM* NearestUnconnectedItem( JOINT* aStart, int* aAnchor = nullptr,
|
ITEM* NearestUnconnectedItem( JOINT* aStart, int* aAnchor = nullptr,
|
||||||
int aKindMask = ITEM::ANY_T );
|
int aKindMask = ITEM::ANY_T );
|
||||||
|
|
||||||
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
|
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint, LAYER_RANGE& aLayers,
|
||||||
LAYER_RANGE& aLayers );
|
ITEM*& aItem );
|
||||||
bool LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
|
bool LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
|
||||||
|
|
||||||
const JOINT_SET ConnectedJoints( JOINT* aStart );
|
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
|
// We want the next router commit to be one undo at the UI layer
|
||||||
m_iface->SetCommitFlags( needsAppend ? APPEND_UNDO : 0 );
|
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 ) )
|
else if( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) || evt->IsAction( &PCB_ACTIONS::routeSingleTrack ) )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue