diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index 924310b8fb..af2d14ccea 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1069,6 +1069,23 @@ bool PNS_KICAD_IFACE::IsAnyLayerVisible( const LAYER_RANGE& aLayer ) } +bool PNS_KICAD_IFACE::IsItemVisible( const PNS::ITEM* aItem ) +{ + if( !m_view ) + return false; + + auto item = aItem->Parent(); + auto activeLayers = m_view->GetPainter()->GetSettings()->GetActiveLayers(); + bool isHighContrast = m_view->GetPainter()->GetSettings()->GetHighContrast(); + + if( m_view->IsVisible( item ) && ( !isHighContrast || activeLayers.count( item->GetLayer() ) ) + && item->ViewGetLOD( item->GetLayer(), m_view ) < m_view->GetScale() ) + return true; + + return false; +} + + void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld ) { int worstPadClearance = 0; diff --git a/pcbnew/router/pns_kicad_iface.h b/pcbnew/router/pns_kicad_iface.h index 69e6c5d052..2c48de3569 100644 --- a/pcbnew/router/pns_kicad_iface.h +++ b/pcbnew/router/pns_kicad_iface.h @@ -53,6 +53,7 @@ public: void SyncWorld( PNS::NODE* aWorld ) override; void EraseView() override; bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) override; + bool IsItemVisible( const PNS::ITEM* aItem ) override; void HideItem( PNS::ITEM* aItem ) override; void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override; void AddItem( PNS::ITEM* aItem ) override; diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 49e4edb664..e41b4a54d0 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -95,6 +95,7 @@ enum DRAG_MODE virtual void AddItem( ITEM* aItem ) = 0; virtual void RemoveItem( ITEM* aItem ) = 0; virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) = 0; + virtual bool IsItemVisible( const PNS::ITEM* aItem ) = 0; virtual void DisplayItem( const ITEM* aItem, int aColor = -1, int aClearance = -1, bool aEdit = false ) = 0; virtual void HideItem( ITEM* aItem ) = 0; virtual void Commit() = 0; diff --git a/pcbnew/router/pns_tool_base.cpp b/pcbnew/router/pns_tool_base.cpp index 7780086dc1..3e08ede4a6 100644 --- a/pcbnew/router/pns_tool_base.cpp +++ b/pcbnew/router/pns_tool_base.cpp @@ -382,7 +382,7 @@ const VECTOR2I TOOL_BASE::snapToItem( bool aEnabled, ITEM* aItem, VECTOR2I aP) { VECTOR2I anchor; - if( !aItem || !aEnabled ) + if( !aItem || !aEnabled || !m_iface->IsItemVisible( aItem ) ) { return m_gridHelper->Align( aP ); } diff --git a/pcbnew/tools/grid_helper.cpp b/pcbnew/tools/grid_helper.cpp index 152aea7673..7799df4faa 100644 --- a/pcbnew/tools/grid_helper.cpp +++ b/pcbnew/tools/grid_helper.cpp @@ -35,12 +35,12 @@ using namespace std::placeholders; #include #include +#include +#include +#include #include #include #include -#include - -#include #include "grid_helper.h" @@ -51,6 +51,7 @@ GRID_HELPER::GRID_HELPER( PCB_BASE_FRAME* aFrame ) : m_enableSnap = true; m_enableGrid = true; m_snapSize = 100; + m_snapItem = nullptr; KIGFX::VIEW* view = m_frame->GetCanvas()->GetView(); m_viewAxis.SetSize( 20000 ); @@ -228,7 +229,8 @@ std::set GRID_HELPER::queryVisible( const BOX2I& aArea, BOARD_ITEM* item = static_cast( it.first ); // The item must be visible and on an active layer - if( view->IsVisible( item ) && ( !isHighContrast || activeLayers.count( it.second ) ) ) + if( view->IsVisible( item ) && ( !isHighContrast || activeLayers.count( it.second ) ) + && item->ViewGetLOD( it.second, view ) < view->GetScale() ) items.insert ( item ); } @@ -310,6 +312,9 @@ BOARD_ITEM* GRID_HELPER::GetSnapped( void ) const void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom ) { VECTOR2I origin; + auto view = m_frame->GetCanvas()->GetView(); + auto activeLayers = view->GetPainter()->GetSettings()->GetActiveLayers(); + bool isHighContrast = view->GetPainter()->GetSettings()->GetHighContrast(); switch( aItem->Type() ) { @@ -319,8 +324,12 @@ void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bo for( auto pad : mod->Pads() ) { + // Getting pads from the module requires re-checking that the pad is shown if( ( aFrom || m_frame->Settings().m_MagneticPads == CAPTURE_ALWAYS ) - && pad->GetBoundingBox().Contains( wxPoint( aRefPos.x, aRefPos.y ) ) ) + && pad->GetBoundingBox().Contains( wxPoint( aRefPos.x, aRefPos.y ) ) + && view->IsVisible( pad ) + && ( !isHighContrast || activeLayers.count( pad->GetLayer() ) ) + && pad->ViewGetLOD( pad->GetLayer(), view ) < view->GetScale() ) { addAnchor( pad->GetPosition(), CORNER | SNAPPABLE, pad ); break;