From 8c93fc76ae39f8cde3b723fd030bd1d50c9dcd70 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 25 Oct 2020 20:53:24 +0000 Subject: [PATCH] Don't require keepout zones to be named. insideArea() now takes A, B, a UUID or a zone name. (Only the UUID is new.) --- common/kiid.cpp | 3 ++ pcbnew/drc/drc_engine.cpp | 13 +++++---- pcbnew/pcb_expr_evaluator.cpp | 52 ++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/common/kiid.cpp b/common/kiid.cpp index 1334484c20..49977fce65 100644 --- a/common/kiid.cpp +++ b/common/kiid.cpp @@ -111,6 +111,9 @@ bool KIID::SniffTest( const wxString& aCandidate ) if( c >= 'A' && c <= 'F' ) continue; + if( c == '-' ) + continue; + return false; } diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index f4ffc22854..b9de0a3602 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -377,18 +377,21 @@ void DRC_ENGINE::loadImplicitRules() for( ZONE_CONTAINER* zone : keepoutZones ) { - if( zone->GetZoneName().IsEmpty() ) - zone->SetZoneName( KIID().AsString() ); - wxString name = zone->GetZoneName(); - if( KIID::SniffTest( name ) ) // Synthetic name; don't show to user + if( name.IsEmpty() ) + { rule = createImplicitRule( _( "keepout area" ) ); + name = zone->m_Uuid.AsString(); + } else + { rule = createImplicitRule( wxString::Format( _( "keepout area '%s'" ), name ) ); + } rule->m_Condition = new DRC_RULE_CONDITION( wxString::Format( "A.insideArea('%s')", - zone->GetZoneName() ) ); + name ) ); + if( zone->GetDoNotAllowTracks() ) addKeepoutConstraint( DRC_DISALLOW_TRACKS ); diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 2989d26258..36abeefba7 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -305,12 +305,46 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self ) if( insideZone( dynamic_cast( context->GetItem( 1 ) ) ) ) result->Set( 1.0 ); } - else + else if( KIID::SniffTest( arg->AsString() ) ) + { + KIID target( arg->AsString() ); + + for( ZONE_CONTAINER* candidate : item->GetBoard()->Zones() ) + { + // Only a single zone can match the UUID; exit once we find a match whether + // "inside" or not + if( candidate->m_Uuid == target ) + { + if( insideZone( candidate ) ) + result->Set( 1.0 ); + + return; + } + } + + for( MODULE* module : item->GetBoard()->Modules() ) + { + for( ZONE_CONTAINER* candidate : module->Zones() ) + { + // Only a single zone can match the UUID; exit once we find a match whether + // "inside" or not + if( candidate->m_Uuid == target ) + { + if( insideZone( candidate ) ) + result->Set( 1.0 ); + + return; + } + } + } + } + else // Match on zone name { for( ZONE_CONTAINER* candidate : item->GetBoard()->Zones() ) { if( candidate->GetZoneName().Matches( arg->AsString() ) ) { + // Many zones can match the name; exit only when we find an "inside" if( insideZone( candidate ) ) { result->Set( 1.0 ); @@ -318,6 +352,22 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self ) } } } + + for( MODULE* module : item->GetBoard()->Modules() ) + { + for( ZONE_CONTAINER* candidate : module->Zones() ) + { + // Many zones can match the name; exit only when we find an "inside" + if( candidate->GetZoneName().Matches( arg->AsString() ) ) + { + if( insideZone( candidate ) ) + { + result->Set( 1.0 ); + return; + } + } + } + } } }