diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index f9e03842c3..3d5915a59c 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -649,7 +649,7 @@ bool PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem, int* aInheritedW bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, - PNS::NET_HANDLE aNet ) + PNS::NET_HANDLE aNet, VECTOR2D aStartPosition ) { BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); PNS::CONSTRAINT constraint; @@ -661,10 +661,23 @@ bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aSizes.SetMinClearance( bds.m_MinClearance ); aSizes.SetClearanceSource( _( "board minimum clearance" ) ); + int startAnchor = 0; + VECTOR2I startPosInt( aStartPosition.x, aStartPosition.y ); + + if( aStartItem && aStartItem->Kind() == PNS::ITEM::SEGMENT_T ) + { + // Find the start anchor which is closest to the start mouse location + double anchor0Distance = startPosInt.Distance( aStartItem->Anchor( 0 ) ); + double anchor1Distance = startPosInt.Distance( aStartItem->Anchor( 1 ) ); + + if( anchor1Distance < anchor0Distance ) + startAnchor = 1; + } + if( aStartItem ) { PNS::SEGMENT dummyTrack; - dummyTrack.SetEnds( aStartItem->Anchor( 0 ), aStartItem->Anchor( 0 ) ); + dummyTrack.SetEnds( aStartItem->Anchor( startAnchor ), aStartItem->Anchor( startAnchor ) ); dummyTrack.SetLayer( ToLAYER_ID( m_startLayer ) ); dummyTrack.SetNet( static_cast( aStartItem->Net() ) ); @@ -694,7 +707,7 @@ bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* if( !found && bds.UseNetClassTrack() && aStartItem ) { PNS::SEGMENT dummyTrack; - dummyTrack.SetEnds( aStartItem->Anchor( 0 ), aStartItem->Anchor( 0 ) ); + dummyTrack.SetEnds( aStartItem->Anchor( startAnchor ), aStartItem->Anchor( startAnchor ) ); dummyTrack.SetLayer( ToLAYER_ID( m_startLayer ) ); dummyTrack.SetNet( static_cast( aStartItem->Net() ) ); diff --git a/pcbnew/router/pns_kicad_iface.h b/pcbnew/router/pns_kicad_iface.h index 36d1d44bf9..0ee9195c31 100644 --- a/pcbnew/router/pns_kicad_iface.h +++ b/pcbnew/router/pns_kicad_iface.h @@ -70,8 +70,8 @@ public: void UpdateItem( PNS::ITEM* aItem ) override; void RemoveItem( PNS::ITEM* aItem ) override; void Commit() override {} - bool ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, - PNS::NET_HANDLE aNet ) override; + bool ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, PNS::NET_HANDLE aNet, + VECTOR2D aStartPosition ) override; int StackupHeight( int aFirstLayer, int aSecondLayer ) const override; int GetNetCode( PNS::NET_HANDLE aNet ) const override { return -1; } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 009a23676b..51652bed10 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -103,7 +103,8 @@ enum DRAG_MODE virtual void DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, NET_HANDLE aNetCode ) = 0; virtual void HideItem( ITEM* aItem ) = 0; virtual void Commit() = 0; - virtual bool ImportSizes( SIZES_SETTINGS& aSizes, ITEM* aStartItem, NET_HANDLE aNet ) = 0; + virtual bool ImportSizes( SIZES_SETTINGS& aSizes, ITEM* aStartItem, NET_HANDLE aNet, + VECTOR2D aStartPosition ) = 0; virtual int StackupHeight( int aFirstLayer, int aSecondLayer ) const = 0; virtual void EraseView() = 0; virtual int GetNetCode( NET_HANDLE aNet ) const = 0; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 940fa9ae2e..6cad160779 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -1210,7 +1210,7 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia ) } -bool ROUTER_TOOL::prepareInteractive() +bool ROUTER_TOOL::prepareInteractive( VECTOR2D aStartPosition ) { PCB_EDIT_FRAME* editFrame = getEditFrame(); int routingLayer = getStartLayer( m_startItem ); @@ -1235,7 +1235,7 @@ bool ROUTER_TOOL::prepareInteractive() m_iface->SetStartLayer( routingLayer ); frame()->GetBoard()->GetDesignSettings().m_TempOverrideTrackWidth = false; - m_iface->ImportSizes( sizes, m_startItem, nullptr ); + m_iface->ImportSizes( sizes, m_startItem, nullptr, aStartPosition ); sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP, frame()->GetScreen()->m_Route_Layer_BOTTOM ); @@ -1303,11 +1303,11 @@ bool ROUTER_TOOL::finishInteractive() } -void ROUTER_TOOL::performRouting() +void ROUTER_TOOL::performRouting( VECTOR2D aStartPosition ) { m_router->ClearViewDecorations(); - if( !prepareInteractive() ) + if( !prepareInteractive( aStartPosition ) ) return; auto setCursor = @@ -1710,7 +1710,7 @@ int ROUTER_TOOL::RouteSelected( const TOOL_EVENT& aEvent ) m_iface->SetCommitFlags( APPEND_UNDO ); // Start interactive routing. Will automatically finish if possible. - performRouting(); + performRouting( VECTOR2D() ); // Route didn't complete automatically, need to a new undo commit // for the next line so those can group as far as they autoroute @@ -1827,7 +1827,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) updateStartItem( *evt ); if( evt->HasPosition() ) - performRouting(); + performRouting( evt->Position() ); } else if( evt->IsAction( &ACT_PlaceThroughVia ) ) { @@ -2610,7 +2610,7 @@ int ROUTER_TOOL::onTrackViaSizeChanged( const TOOL_EVENT& aEvent ) PNS::SIZES_SETTINGS sizes( m_router->Sizes() ); if( !m_router->GetCurrentNets().empty() ) - m_iface->ImportSizes( sizes, m_startItem, m_router->GetCurrentNets()[0] ); + m_iface->ImportSizes( sizes, m_startItem, m_router->GetCurrentNets()[0], VECTOR2D() ); m_router->UpdateSizes( sizes ); diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index 4e6b2ff665..a01a948677 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -70,7 +70,7 @@ public: void UpdateMessagePanel(); private: - void performRouting(); + void performRouting( VECTOR2D aStartPosition ); void performDragging( int aMode = PNS::DM_ANY ); void breakTrack(); @@ -85,7 +85,7 @@ private: int onViaCommand( const TOOL_EVENT& aEvent ); int onTrackViaSizeChanged( const TOOL_EVENT& aEvent ); - bool prepareInteractive(); + bool prepareInteractive( VECTOR2D aStartPosition ); bool finishInteractive(); void saveRouterDebugLog();