Respect the "report all errors" checkbox

When we have objects spanning multiple layers, the user doesn't need to
see every layer/hole combination violation if they do not request it
This commit is contained in:
Seth Hillbrand 2022-12-12 10:53:44 -08:00
parent bd9c37aa5f
commit c07043e762
1 changed files with 52 additions and 14 deletions

View File

@ -83,6 +83,14 @@ public:
int GetNumPhases() const override;
private:
/**
* Checks for track/via/hole <-> clearance
* @param track Track to text
* @param trackShape Primitive track shape
* @param layer Which layer to test (in case of vias this can be multiple
* @param other item against which to test the track item
* @return false if there is a clearance violation reported, true if there is none
*/
bool testTrackAgainstItem( PCB_TRACK* track, SHAPE* trackShape, PCB_LAYER_ID layer,
BOARD_ITEM* other );
@ -96,6 +104,18 @@ private:
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
typedef struct checked
{
checked()
: layers(), has_error( false ) {}
checked( PCB_LAYER_ID aLayer )
: layers( aLayer ), has_error( false ) {}
LSET layers;
bool has_error;
} layers_checked;
private:
DRC_RTREE m_copperTree;
int m_drcEpsilon;
@ -267,6 +287,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
int clearance = -1;
int actual;
VECTOR2I pos;
bool has_error = false;
std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
@ -300,7 +321,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
reportViolation( drcItem, (wxPoint) intersection.get() );
return m_drcEngine->GetReportAllTrackErrors();
return false;
}
}
@ -319,6 +340,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
has_error = true;
if( !m_drcEngine->GetReportAllTrackErrors() )
return false;
@ -331,9 +353,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
std::array<BOARD_ITEM*, 2> b{ other, track };
std::array<SHAPE*, 2> a_shape{ trackShape, otherShape.get() };
bool has_error = false;
for( size_t ii = 0; ii < 2 && !has_error; ++ii )
for( size_t ii = 0; ii < 2; ++ii )
{
std::unique_ptr<SHAPE_SEGMENT> holeShape;
@ -385,16 +405,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
has_error = true;
if( !m_drcEngine->GetReportAllTrackErrors() )
return false;
return false;
}
}
}
}
return true;
return !has_error;
}
@ -532,8 +549,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
reportAux( wxT( "Testing %d tracks & vias..." ), m_board->Tracks().size() );
std::map<BOARD_ITEM*, int> freePadsUsageMap;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, LSET> checkedPairs;
std::map<BOARD_ITEM*, int> freePadsUsageMap;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, layers_checked> checkedPairs;
for( PCB_TRACK* track : m_board->Tracks() )
{
@ -568,13 +585,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end() && it->second.test( layer ) )
if( it != checkedPairs.end() && ( it->second.layers.test( layer )
|| ( it->second.has_error && !m_drcEngine->GetReportAllTrackErrors() ) ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].set( layer );
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
@ -599,7 +617,27 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
}
}
return testTrackAgainstItem( track, trackShape.get(), layer, other );
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<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
auto it = checkedPairs.find( { a, b } );
// If we get an error, mark the pair as having a clearance error already
// Only continue if we are reporting all track errors
if( !testTrackAgainstItem( track, trackShape.get(), layer, other ) )
{
if( it != checkedPairs.end() )
it->second.has_error = true;
return m_drcEngine->GetReportAllTrackErrors();
}
return true;
},
m_largestClearance );