diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 881849e0f3..4a8b9427a5 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -414,6 +414,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances() reportAux( wxT( "Testing %d tracks & vias..." ), m_board->Tracks().size() ); + std::map freePadsUsageMap; std::unordered_map checkedPairs; for( PCB_TRACK* track : m_board->Tracks() ) @@ -457,6 +458,24 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances() // Visitor: [&]( BOARD_ITEM* other ) -> bool { + if( other->Type() == PCB_PAD_T && static_cast( other )->IsFreePad() ) + { + if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) ) + { + auto it = freePadsUsageMap.find( other ); + + if( it == freePadsUsageMap.end() ) + { + freePadsUsageMap[ other ] = track->GetNetCode(); + return false; + } + else if( it->second == track->GetNetCode() ) + { + return false; + } + } + } + return testTrackAgainstItem( track, trackShape.get(), layer, other ); }, m_board->m_DRCMaxClearance ); diff --git a/pcbnew/drc/drc_test_provider_solder_mask.cpp b/pcbnew/drc/drc_test_provider_solder_mask.cpp index 1a0873c357..40a2c6d435 100644 --- a/pcbnew/drc/drc_test_provider_solder_mask.cpp +++ b/pcbnew/drc/drc_test_provider_solder_mask.cpp @@ -296,17 +296,6 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testSilkToMaskClearance() } -bool isMaskAperture( BOARD_ITEM* aItem ) -{ - static const LSET saved( 2, F_Mask, B_Mask ); - - LSET maskLayers = aItem->GetLayerSet() & saved; - LSET otherLayers = aItem->GetLayerSet() & ~saved; - - return maskLayers.count() > 0 && otherLayers.count() == 0; -} - - bool isNullAperture( BOARD_ITEM* aItem ) { if( aItem->Type() == PCB_PAD_T ) @@ -329,6 +318,21 @@ bool isNullAperture( BOARD_ITEM* aItem ) // Simple mask apertures aren't associated with copper items, so they only constitute a bridge // when they expose other copper items having at least two distinct nets. We use a map to record // the first net exposed by each mask aperture (on each copper layer). +// +// Note that this algorithm is also used for free pads. + +bool isMaskAperture( BOARD_ITEM* aItem ) +{ + if( aItem->Type() == PCB_PAD_T && static_cast( aItem )->IsFreePad() ) + return true; + + static const LSET saved( 2, F_Mask, B_Mask ); + + LSET maskLayers = aItem->GetLayerSet() & saved; + LSET otherLayers = aItem->GetLayerSet() & ~saved; + + return maskLayers.count() > 0 && otherLayers.count() == 0; +} bool DRC_TEST_PROVIDER_SOLDER_MASK::checkMaskAperture( BOARD_ITEM* aMaskItem, BOARD_ITEM* aTestItem, PCB_LAYER_ID aTestLayer, int aTestNet,