From 41fd8293e8a1c0f8883533b7b317f7f7eaea85fa Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 22 Oct 2020 14:45:12 +0100 Subject: [PATCH] Don't apply clearance to keepout zones. Also improves the clearance and keepout reporting. Fixes https://gitlab.com/kicad/code/kicad/issues/6118 --- common/common.cpp | 25 ++++++++++++++ include/common.h | 2 ++ pcbnew/drc/drc_engine.cpp | 73 +++++++++++++++++++++++++++++---------- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/common/common.cpp b/common/common.cpp index b9c292ced2..c6cfab0cc9 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -110,6 +110,31 @@ KIID::KIID( const wxString& aString ) : } +bool KIID::SniffTest( const wxString& aCandidate ) +{ + static wxString niluuidStr = niluuid.AsString(); + + if( aCandidate.Length() != niluuidStr.Length() ) + return false; + + for( wxChar c : aCandidate ) + { + if( c >= '0' && c <= '9' ) + continue; + + if( c >= 'a' && c <= 'f' ) + continue; + + if( c >= 'A' && c <= 'F' ) + continue; + + return false; + } + + return true; +} + + KIID::KIID( timestamp_t aTimestamp ) { m_cached_timestamp = aTimestamp; diff --git a/include/common.h b/include/common.h index e1c7eadbba..f15c34066b 100644 --- a/include/common.h +++ b/include/common.h @@ -85,6 +85,8 @@ public: wxString AsString() const; wxString AsLegacyTimestampString() const; + static bool SniffTest( const wxString& aCandidate ); + /** * Change an existing time stamp based UUID into a true UUID. * diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index c36bdc75f9..a41d125978 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -73,6 +73,23 @@ DRC_ENGINE::~DRC_ENGINE() } +static bool isKeepoutZone( const BOARD_ITEM* aItem ) +{ + if( aItem && ( aItem->Type() == PCB_ZONE_AREA_T || aItem->Type() == PCB_FP_ZONE_AREA_T ) ) + { + const ZONE_CONTAINER* zone = static_cast( aItem ); + + return zone->GetIsRuleArea() && ( zone->GetDoNotAllowTracks() + || zone->GetDoNotAllowVias() + || zone->GetDoNotAllowPads() + || zone->GetDoNotAllowCopperPour() + || zone->GetDoNotAllowFootprints() ); + } + + return false; +} + + DRC_RULE* DRC_ENGINE::createImplicitRule( const wxString& name ) { DRC_RULE *rule = new DRC_RULE; @@ -330,16 +347,6 @@ void DRC_ENGINE::loadImplicitRules() rule->AddConstraint( disallowConstraint ); }; - auto isKeepoutZone = - []( ZONE_CONTAINER* aZone ) - { - return aZone->GetIsRuleArea() && ( aZone->GetDoNotAllowTracks() - || aZone->GetDoNotAllowVias() - || aZone->GetDoNotAllowPads() - || aZone->GetDoNotAllowCopperPour() - || aZone->GetDoNotAllowFootprints() ); - }; - std::vector keepoutZones; for( ZONE_CONTAINER* zone : m_board->Zones() ) @@ -362,7 +369,13 @@ void DRC_ENGINE::loadImplicitRules() if( zone->GetZoneName().IsEmpty() ) zone->SetZoneName( KIID().AsString() ); - rule = createImplicitRule( _( "keepout area" ) ); + wxString name = zone->GetZoneName(); + + if( KIID::SniffTest( name ) ) // Synthetic name; don't show to user + rule = createImplicitRule( _( "keepout area" ) ); + else + rule = createImplicitRule( wxString::Format( _( "keepout area '%s'" ), name ) ); + rule->m_Condition = new DRC_RULE_CONDITION( wxString::Format( "A.insideArea('%s')", zone->GetZoneName() ) ); if( zone->GetDoNotAllowTracks() ) @@ -707,7 +720,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI } auto processConstraint = - [&]( const CONSTRAINT_WITH_CONDITIONS* c ) + [&]( const CONSTRAINT_WITH_CONDITIONS* c ) -> bool { implicit = c->parentRule && c->parentRule->m_Implicit; @@ -748,6 +761,19 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI c->constraint.GetName(), MessageTextFromValue( UNITS, clearance ) ) ) } + else + { + REPORT( wxString::Format( _( "Checking %s." ), c->constraint.GetName() ) ) + } + + if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE ) + { + if( implicit && ( isKeepoutZone( a ) || isKeepoutZone( b ) ) ) + { + REPORT( _( "Board and netclass clearances not applied to keepout zones" ) ); + return true; + } + } else if( aConstraintId == DRC_CONSTRAINT_TYPE_DISALLOW ) { int mask; @@ -785,12 +811,23 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI } if( ( c->constraint.m_DisallowFlags & mask ) == 0 ) - return false; - } - else - { - REPORT( wxString::Format( _( "Checking %s." ), - c->constraint.GetName() ) ) + { + if( implicit ) + { + REPORT( _( "Keepout constraint not met." ) ) + + // Keepout areas unioned in classic system + return false; + } + else + { + REPORT( _( "Disallow constraint not met." ) ) + + // First matching rule wins in rule system + REPORT( "Item allowed." ); + return true; + } + } } if( aLayer != UNDEFINED_LAYER && !c->layerTest.test( aLayer ) )