diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 0f5dd96cc3..974d3e9663 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -359,6 +359,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances() reportAux( "Testing %d tracks & vias...", m_board->Tracks().size() ); + std::map< std::pair, int> checkedPairs; + for( TRACK* track : m_board->Tracks() ) { if( !reportProgress( ii++, m_board->Tracks().size(), delta ) ) @@ -380,7 +382,23 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances() if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() ) return false; - return true; + BOARD_ITEM* a = track; + BOARD_ITEM* b = other; + + // store canonical order so we don't collide in both directions + // (a:b and b:a) + if( static_cast( a ) > static_cast( b ) ) + std::swap( a, b ); + + if( checkedPairs.count( { a, b } ) ) + { + return false; + } + else + { + checkedPairs[ { a, b } ] = 1; + return true; + } }, // Visitor: [&]( BOARD_ITEM* other ) -> bool @@ -519,6 +537,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( ) reportAux( "Testing %d pads...", count ); int ii = 0; + std::map< std::pair, int> checkedPairs; for( FOOTPRINT* footprint : m_board->Footprints() ) { @@ -538,7 +557,23 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( ) if( other->HasFlag( SKIP_STRUCT ) ) return false; - return true; + BOARD_ITEM* a = pad; + BOARD_ITEM* b = other; + + // store canonical order so we don't collide in both directions + // (a:b and b:a) + if( static_cast( a ) > static_cast( b ) ) + std::swap( a, b ); + + if( checkedPairs.count( { a, b } ) ) + { + return false; + } + else + { + checkedPairs[ { a, b } ] = 1; + return true; + } }, // Visitor [&]( BOARD_ITEM* other ) -> bool diff --git a/pcbnew/drc/drc_test_provider_hole_clearance.cpp b/pcbnew/drc/drc_test_provider_hole_clearance.cpp index abeccbedf3..2e10e9ecab 100644 --- a/pcbnew/drc/drc_test_provider_hole_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_hole_clearance.cpp @@ -165,6 +165,8 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() forEachGeometryItem( { PCB_PAD_T, PCB_VIA_T }, LSET::AllLayersMask(), addToHoleTree ); + std::map< std::pair, int> checkedPairs; + for( TRACK* track : m_board->Tracks() ) { if( track->Type() != PCB_VIA_T ) @@ -184,7 +186,23 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() if( other->HasFlag( SKIP_STRUCT ) ) return false; - return true; + BOARD_ITEM* a = via; + BOARD_ITEM* b = other; + + // store canonical order so we don't collide in both directions + // (a:b and b:a) + if( static_cast( a ) > static_cast( b ) ) + std::swap( a, b ); + + if( checkedPairs.count( { a, b } ) ) + { + return false; + } + else + { + checkedPairs[ { a, b } ] = 1; + return true; + } }, // Visitor: [&]( BOARD_ITEM* other ) -> bool @@ -196,6 +214,8 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() via->SetFlags( SKIP_STRUCT ); } + checkedPairs.clear(); + for( FOOTPRINT* footprint : m_board->Footprints() ) { for( PAD* pad : footprint->Pads() ) @@ -212,7 +232,23 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() if( other->HasFlag( SKIP_STRUCT ) ) return false; - return true; + BOARD_ITEM* a = pad; + BOARD_ITEM* b = other; + + // store canonical order so we don't collide in both directions + // (a:b and b:a) + if( static_cast( a ) > static_cast( b ) ) + std::swap( a, b ); + + if( checkedPairs.count( { a, b } ) ) + { + return false; + } + else + { + checkedPairs[ { a, b } ] = 1; + return true; + } }, // Visitor: [&]( BOARD_ITEM* other ) -> bool