diff --git a/pcbnew/router/pns_item.cpp b/pcbnew/router/pns_item.cpp index ededff2dc6..c3f3d69acb 100644 --- a/pcbnew/router/pns_item.cpp +++ b/pcbnew/router/pns_item.cpp @@ -51,6 +51,10 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 ) return false; + // a pad associated with a "free" pin (NIC) doesn't have a net until it has been used + if( aDifferentNetsOnly && ( IsFreePad() || aOther->IsFreePad() ) ) + return false; + // check if we are not on completely different layers first if( !m_layers.Overlaps( aOther->m_layers ) ) return false; diff --git a/pcbnew/router/pns_item.h b/pcbnew/router/pns_item.h index 159eec61fc..6351d7ea36 100644 --- a/pcbnew/router/pns_item.h +++ b/pcbnew/router/pns_item.h @@ -81,6 +81,7 @@ public: m_rank = -1; m_routable = true; m_isVirtual = false; + m_isFreePad = false; m_isCompoundShapePrimitive = false; } @@ -96,6 +97,7 @@ public: m_rank = aOther.m_rank; m_routable = aOther.m_routable; m_isVirtual = aOther.m_isVirtual; + m_isFreePad = aOther.m_isFreePad; m_isCompoundShapePrimitive = aOther.m_isCompoundShapePrimitive; } @@ -232,6 +234,9 @@ public: void SetRoutable( bool aRoutable ) { m_routable = aRoutable; } bool IsRoutable() const { return m_routable; } + void SetIsFreePad( bool aIsFreePad = true ) { m_isFreePad = aIsFreePad; } + bool IsFreePad() const { return m_isFreePad; } + bool IsVirtual() const { return m_isVirtual; @@ -256,6 +261,7 @@ protected: int m_rank; bool m_routable; bool m_isVirtual; + bool m_isFreePad; bool m_isCompoundShapePrimitive; }; diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index cbb17a9dc3..5cc2438392 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -970,6 +970,9 @@ std::unique_ptr PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad ) solid->SetPadToDie( aPad->GetPadToDieLength() ); solid->SetOrientation( aPad->GetOrientation() ); + if( aPad->IsFreePad() ) + solid->SetIsFreePad(); + VECTOR2I wx_c = aPad->ShapePos(); VECTOR2I offset = aPad->GetOffset(); diff --git a/pcbnew/router/pns_tool_base.cpp b/pcbnew/router/pns_tool_base.cpp index 082f58704c..a6dabcd295 100644 --- a/pcbnew/router/pns_tool_base.cpp +++ b/pcbnew/router/pns_tool_base.cpp @@ -133,13 +133,14 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b //if( item->Parent() && !item->Parent()->ViewIsVisible() ) // continue; - if( aNet <= 0 || item->Net() == aNet ) + if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads ) + { + continue; + } + else if( aNet <= 0 || item->Net() == aNet ) { if( item->OfKind( ITEM::VIA_T | ITEM::SOLID_T ) ) { - if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads ) - continue; - SEG::ecoord d = ( item->Shape()->Centre() - aWhere ).SquaredEuclideanNorm(); if( d < dist[2] ) @@ -173,12 +174,18 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b } } } + else if( item->OfKind( ITEM::SOLID_T ) && item->IsFreePad() ) + { + // Allow free pads only when already inside pad + if( item->Shape()->Collide( aWhere ) ) + { + prioritized[0] = item; + dist[0] = 0; + } + } else if ( item->Net() == 0 && m_router->Settings().Mode() == RM_MarkObstacles ) { // Allow unconnected items as last resort in RM_MarkObstacles mode - if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads ) - continue; - if( item->Layers().Overlaps( tl ) ) prioritized[4] = item; }