From c977c88a108045ba803bf57c6f1e013d461d1b38 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 26 Sep 2017 19:40:00 +1000 Subject: [PATCH] Zone keepout exclusion now works on multiple layers! Bug fixes for keepout layers - Changed LSET::size() -> LSET::count() - Save/load functions no longer depend on zone being a keepout --- pcbnew/class_zone.cpp | 13 +++++++------ pcbnew/class_zone.h | 3 +++ pcbnew/kicad_plugin.cpp | 4 ++-- pcbnew/pcb_parser.cpp | 2 -- pcbnew/tools/pcb_editor_control.cpp | 17 +++++++++++++---- pcbnew/zones_by_polygon_fill_functions.cpp | 2 ++ ...convert_brd_items_to_polygons_with_Boost.cpp | 3 ++- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 5308264428..410eb9fa00 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -197,9 +197,9 @@ bool ZONE_CONTAINER::IsOnCopperLayer() const bool ZONE_CONTAINER::CommonLayerExists( const LSET aLayerSet ) const { - auto common = GetLayerSet() & aLayerSet; + LSET common = GetLayerSet() & aLayerSet; - return common.size() > 0; + return common.count() > 0; } @@ -221,9 +221,11 @@ void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet ) if( GetIsKeepout() ) { // Keepouts can only exist on copper layers - m_layerSet = aLayerSet & LSET::AllCuMask(); + aLayerSet &= LSET::AllCuMask(); } + m_layerSet = aLayerSet; + // Set the single layer to the first selected layer m_Layer = aLayerSet.Seq()[0]; } @@ -231,6 +233,8 @@ void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet ) LSET ZONE_CONTAINER::GetLayerSet() const { + // TODO - Enable multi-layer zones for all zone types + // not just keepout zones if( GetIsKeepout() ) { return m_layerSet; @@ -312,9 +316,6 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod // At least one layer must be provided! assert( GetLayerSet().count() > 0 ); - // If none of the keepout layers are actually visible, return - LSET layers = GetLayerSet() & brd->GetVisibleLayers(); - // Not on any visible layer? if( layers.count() == 0 && !( aDrawMode & GR_HIGHLIGHT ) ) { diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index b80c0c07ce..a99359c027 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -594,6 +594,9 @@ public: * returns a reference to the list of filled polygons. * @return Reference to the list of filled polygons. */ + + //TODO - This should be called for each layer on which the zone exists + const SHAPE_POLY_SET& GetFilledPolysList() const { return m_FilledPolysList; diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 8309a54468..bdc632d184 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1609,8 +1609,8 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNetCode() ), m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() ); - // Keepout zones can exist on multiple layers - if( aZone->GetIsKeepout() && aZone->GetLayerSet().count() > 1 ) + // If a zone exists on multiple layers, format accordingly + if( aZone->GetLayerSet().count() > 1 ) { formatLayers( aZone->GetLayerSet() ); } diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index a7b4b4b8d1..b867490440 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2826,8 +2826,6 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() break; case T_layers: - // If multiple layers are specified, it is a keepout zone - zone->SetIsKeepout( true ); zone->SetLayerSet( parseBoardItemLayersAsMask() ); break; diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index a91a548144..438d52135e 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -912,11 +912,20 @@ int PCB_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent ) // If the new zone is on the same layer as the the initial zone, // do nothing - if( success && ( oldZone->GetLayer() == zoneSettings.m_CurrentZone_Layer ) ) + if( success ) { - DisplayError( m_frame, - _( "The duplicated zone cannot be on the same layer as the original zone." ) ); - success = false; + if( oldZone->GetIsKeepout() && ( oldZone->GetLayerSet() == zoneSettings.m_Layers ) ) + { + DisplayError( + m_frame, _( "The duplicated keepout zone cannot be on the same layers as the original zone." ) ); + success = false; + } + else if( !oldZone->GetIsKeepout() && ( oldZone->GetLayer() == zoneSettings.m_CurrentZone_Layer ) ) + { + DisplayError( + m_frame, _( "The duplicated zone cannot be on the same layer as the original zone." ) ); + success = false; + } } // duplicate the zone diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 32a4458017..632702af80 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -160,6 +160,8 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) for( ii = 0; ii < areaCount; ii++ ) { ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii ); + + // Keepout zones are not filled if( zoneContainer->GetIsKeepout() ) continue; diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 91ee93bb57..3c0ea70944 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -363,7 +363,8 @@ void ZONE_CONTAINER::buildFeatureHoleList( BOARD* aPcb, SHAPE_POLY_SET& aFeature { ZONE_CONTAINER* zone = GetBoard()->GetArea( ii ); - if( zone->GetLayer() != GetLayer() ) + // If the zones share no common layers + if( !CommonLayerExists( zone->GetLayerSet() ) ) continue; if( !zone->GetIsKeepout() && zone->GetPriority() <= GetPriority() )