PNS/Router Tool: Refactor Finish Route
This commit is contained in:
parent
b1f2273bc6
commit
1be0deb58f
|
@ -462,6 +462,86 @@ bool ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers )
|
||||||
|
{
|
||||||
|
// Can't finish something with no connections
|
||||||
|
if( GetCurrentNets().empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PNS::LINE_PLACER* placer = dynamic_cast<PNS::LINE_PLACER*>( Placer() );
|
||||||
|
|
||||||
|
if( placer == nullptr )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PNS::LINE trace = placer->Trace();
|
||||||
|
PNS::NODE* lastNode = placer->CurrentNode( true );
|
||||||
|
PNS::TOPOLOGY topo( lastNode );
|
||||||
|
|
||||||
|
// 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 );
|
||||||
|
|
||||||
|
// Otherwise, find the closest anchor to our start point
|
||||||
|
|
||||||
|
// Get joint from placer start item
|
||||||
|
JOINT* jt = lastNode->FindJoint( placer->CurrentStart(), placer->CurrentLayer(),
|
||||||
|
placer->CurrentNets()[0] );
|
||||||
|
|
||||||
|
if( !jt )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get unconnected item from joint
|
||||||
|
int anchor;
|
||||||
|
PNS::ITEM* it = topo.NearestUnconnectedItem( jt, &anchor );
|
||||||
|
|
||||||
|
if( !it )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aOtherEnd = it->Anchor( anchor );
|
||||||
|
aOtherEndLayers = it->Layers();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ROUTER::Finish()
|
||||||
|
{
|
||||||
|
if( m_state != ROUTE_TRACK )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LINE_PLACER* placer = dynamic_cast<LINE_PLACER*>( Placer() );
|
||||||
|
|
||||||
|
if( placer == 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;
|
||||||
|
|
||||||
|
// Get the anchor nearest to the end of the trace the user is routing
|
||||||
|
if( !getNearestRatnestAnchor( otherEnd, otherEndLayers ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Keep moving until we don't change position
|
||||||
|
VECTOR2I moveResultPoint;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
moveResultPoint = Placer()->CurrentEnd();
|
||||||
|
Move( otherEnd, ¤t );
|
||||||
|
} while( Placer()->CurrentEnd() != moveResultPoint );
|
||||||
|
|
||||||
|
// If we've made it, fix the route and we're done
|
||||||
|
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
|
||||||
|
{
|
||||||
|
return FixRoute( otherEnd, ¤t, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ROUTER::moveDragging( const VECTOR2I& aP, ITEM* aEndItem )
|
bool ROUTER::moveDragging( const VECTOR2I& aP, ITEM* aEndItem )
|
||||||
{
|
{
|
||||||
m_iface->EraseView();
|
m_iface->EraseView();
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
bool RoutingInProgress() const;
|
bool RoutingInProgress() const;
|
||||||
bool StartRouting( const VECTOR2I& aP, ITEM* aItem, int aLayer );
|
bool StartRouting( const VECTOR2I& aP, ITEM* aItem, int aLayer );
|
||||||
bool Move( const VECTOR2I& aP, ITEM* aItem );
|
bool Move( const VECTOR2I& aP, ITEM* aItem );
|
||||||
|
bool Finish();
|
||||||
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false );
|
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false );
|
||||||
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
||||||
|
|
||||||
|
@ -221,6 +222,9 @@ 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 );
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOX2I m_visibleViewArea;
|
BOX2I m_visibleViewArea;
|
||||||
RouterState m_state;
|
RouterState m_state;
|
||||||
|
|
|
@ -1263,8 +1263,35 @@ void ROUTER_TOOL::performRouting()
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
m_router->Move( m_endSnapPoint, m_endItem );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::routerAttemptFinish )
|
else if( evt->IsAction( &PCB_ACTIONS::routerAttemptFinish ) )
|
||||||
|| evt->IsAction( &PCB_ACTIONS::routerContinueFromEnd ) )
|
{
|
||||||
|
bool* autoRouted = evt->Parameter<bool*>();
|
||||||
|
|
||||||
|
if( m_router->Finish() )
|
||||||
|
{
|
||||||
|
// When we're routing a group of signals automatically we want
|
||||||
|
// to break up the undo stack every time we have to manually route
|
||||||
|
// so the user gets nice checkpoints. Remove the APPEND_UNDO flag.
|
||||||
|
if( autoRouted != nullptr )
|
||||||
|
*autoRouted = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This acts as check if we were called by the autorouter; we don't want
|
||||||
|
// to reset APPEND_UNDO if we're auto finishing after route-other-end
|
||||||
|
if( autoRouted != nullptr )
|
||||||
|
{
|
||||||
|
*autoRouted = false;
|
||||||
|
m_iface->SetCommitFlags( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warp the mouse so the user is at the point we managed to route to
|
||||||
|
controls()->WarpMouseCursor( m_router->Placer()->CurrentEnd(), true, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &PCB_ACTIONS::routerContinueFromEnd ) )
|
||||||
{
|
{
|
||||||
PNS::LINE_PLACER* placer = dynamic_cast<PNS::LINE_PLACER*>( m_router->Placer() );
|
PNS::LINE_PLACER* placer = dynamic_cast<PNS::LINE_PLACER*>( m_router->Placer() );
|
||||||
|
|
||||||
|
@ -1311,49 +1338,6 @@ void ROUTER_TOOL::performRouting()
|
||||||
// Warp the mouse to wherever we actually ended up routing to
|
// Warp the mouse to wherever we actually ended up routing to
|
||||||
controls()->WarpMouseCursor( currentEnd, true, true );
|
controls()->WarpMouseCursor( currentEnd, true, true );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
VECTOR2I moveResultPoint;
|
|
||||||
bool* autoRouted = evt->Parameter<bool*>();
|
|
||||||
|
|
||||||
if( autoRouted != nullptr )
|
|
||||||
*autoRouted = false;
|
|
||||||
|
|
||||||
// Keep moving until we don't change position
|
|
||||||
do
|
|
||||||
{
|
|
||||||
moveResultPoint = m_router->Placer()->CurrentEnd();
|
|
||||||
m_router->Move( otherEnd, ¤t );
|
|
||||||
} while( m_router->Placer()->CurrentEnd() != moveResultPoint );
|
|
||||||
|
|
||||||
// Fix the route and end routing if we made it to the destination
|
|
||||||
if( moveResultPoint == otherEnd
|
|
||||||
&& otherEndLayers.Overlaps( m_router->GetCurrentLayer() ) )
|
|
||||||
{
|
|
||||||
if( m_router->FixRoute( otherEnd, ¤t, false ) )
|
|
||||||
{
|
|
||||||
// When we're routing a group of signals automatically we want
|
|
||||||
// to break up the undo stack every time we have to manually route
|
|
||||||
// so the user gets nice checkpoints. Remove the APPEND_UNDO flag.
|
|
||||||
if( autoRouted != nullptr )
|
|
||||||
{
|
|
||||||
*autoRouted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// This acts as check if we were called by the autorouter; we don't want
|
|
||||||
// to reset APPEND_UNDO if we're auto finishing after route-other-end
|
|
||||||
else if( autoRouted != nullptr )
|
|
||||||
m_iface->SetCommitFlags( 0 );
|
|
||||||
}
|
|
||||||
// Otherwise warp the mouse so the user is at the point we managed to route to
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_iface->SetCommitFlags( 0 );
|
|
||||||
controls()->WarpMouseCursor( moveResultPoint, true, 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