Browse Source

Always report all track keepout violations.

(Regardless of report-all-errors-per-track setting.
There's no clear rule here, but to do otherwise just
feels wrong.  Keepout areas are distinct, it's not
like tracks too close together reporting lots of
clearance errors.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13219
revert-0c36e162
Jeff Young 9 months ago
parent
commit
e7652685f0
  1. 85
      pcbnew/drc/drc_test_provider_disallow.cpp
  2. 4
      pcbnew/grid_layer_box_helpers.cpp
  3. 4
      pcbnew/zone.cpp

85
pcbnew/drc/drc_test_provider_disallow.cpp

@ -33,6 +33,7 @@
#include <progress_reporter.h>
#include <thread_pool.h>
#include <zone.h>
#include <pcb_track.h>
#include <mutex>
@ -84,17 +85,22 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
std::vector<std::pair<ZONE*, ZONE*>> toCache;
std::atomic<size_t> done( 1 );
int totalCount = 0;
std::unique_ptr<DRC_RTREE> antiTrackKeepouts = std::make_unique<DRC_RTREE>();
forEachGeometryItem( {}, LSET::AllLayersMask(),
[&]( BOARD_ITEM* item ) -> bool
{
ZONE* zone = dynamic_cast<ZONE*>( item );
if( zone && zone->GetIsRuleArea() && zone->HasKeepoutParametersSet()
&& zone->GetDoNotAllowCopperPour() )
if( zone && zone->GetIsRuleArea() && zone->GetDoNotAllowCopperPour() )
{
antiCopperKeepouts.push_back( zone );
}
else if( zone && zone->GetIsRuleArea() && zone->GetDoNotAllowTracks() )
{
for( PCB_LAYER_ID layer : zone->GetLayerSet() )
antiTrackKeepouts->Insert( zone, layer );
}
else if( zone && zone->IsOnCopperLayer() )
{
copperZones.push_back( zone );
@ -204,7 +210,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
auto checkTextOnEdgeCuts =
[&]( BOARD_ITEM* item )
{
if( item->Type() == PCB_FIELD_T || item->Type() == PCB_TEXT_T || item->Type() == PCB_TEXTBOX_T
if( item->Type() == PCB_FIELD_T
|| item->Type() == PCB_TEXT_T
|| item->Type() == PCB_TEXTBOX_T
|| BaseType( item->Type() ) == PCB_DIMENSION_T )
{
if( item->GetLayer() == Edge_Cuts )
@ -216,6 +224,23 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
}
};
auto checkAntiTrackKeepout =
[&]( PCB_TRACK* track, ZONE* keepout )
{
std::shared_ptr<SHAPE> shape = track->GetEffectiveShape();
int dummyActual;
VECTOR2I pos;
if( keepout->Outline()->Collide( shape.get(), board->m_DRCMaxClearance,
&dummyActual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
drcItem->SetItems( track );
reportViolation( drcItem, pos, track->GetLayerSet().ExtractLayer() );
}
};
auto checkDisallow =
[&]( BOARD_ITEM* item )
{
@ -225,33 +250,20 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
DRC_RULE* rule = constraint.GetParentRule();
VECTOR2I pos = item->GetPosition();
PCB_LAYER_ID layer = item->GetLayerSet().ExtractLayer();
wxString msg;
// Implicit rules reported in checkAntiTrackKeepout
if( constraint.GetParentRule()->m_Implicit )
return;
msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( rule );
drcItem->SetViolatingRule( constraint.GetParentRule() );
if( rule->m_Implicit )
{
// Provide a better location for keepout area collisions.
BOARD_ITEM* ruleItem = board->GetItem( rule->m_ImplicitItemId );
if( ZONE* keepout = dynamic_cast<ZONE*>( ruleItem ) )
{
std::shared_ptr<SHAPE> shape = item->GetEffectiveShape( layer );
int dummyActual;
keepout->Outline()->Collide( shape.get(), board->m_DRCMaxClearance,
&dummyActual, &pos );
}
}
reportViolation( drcItem, pos, layer );
reportViolation( drcItem, item->GetPosition(), layer );
}
};
@ -263,13 +275,34 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
{
ZONE* zone = dynamic_cast<ZONE*>( item );
if( zone && zone->GetIsRuleArea() && zone->HasKeepoutParametersSet() )
return true;
if( ZONE* zone = dynamic_cast<ZONE*>( item ) )
{
if( zone->GetIsRuleArea() && zone->HasKeepoutParametersSet() )
return true;
}
item->ClearFlags( HOLE_PROXY ); // Just in case
if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
{
PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
PCB_LAYER_ID layer = track->GetLayer();
antiTrackKeepouts->QueryColliding( track, layer, layer,
// Filter:
[&]( BOARD_ITEM* other ) -> bool
{
return true;
},
// Visitor:
[&]( BOARD_ITEM* other ) -> bool
{
checkAntiTrackKeepout( track, static_cast<ZONE*>( other ) );
return !m_drcEngine->IsCancelled();
},
board->m_DRCMaxPhysicalClearance );
}
checkDisallow( item );
if( item->HasHole() )

4
pcbnew/grid_layer_box_helpers.cpp

@ -75,7 +75,11 @@ void GRID_CELL_LAYER_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC&
}
// draw the swatch
#ifdef __WXMAC__
int size = 14;
#else
int size = KiROUND( 14 * aDC.GetContentScaleFactor() );
#endif
wxBitmap bitmap( size, size );
LAYER_PRESENTATION::DrawColorSwatch( bitmap,

4
pcbnew/zone.cpp

@ -1588,7 +1588,9 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aBuffer, int aClea
std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
if( m_FilledPolysList.find( aLayer ) == m_FilledPolysList.end() )
if( GetIsRuleArea() )
return std::make_shared<SHAPE_POLY_SET>( *Outline() );
else if( m_FilledPolysList.find( aLayer ) == m_FilledPolysList.end() )
return std::make_shared<SHAPE_NULL>();
else
return m_FilledPolysList.at( aLayer );

Loading…
Cancel
Save