From 2895030cfae214d606ced7693073589622c81c3b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 22 Sep 2017 15:18:05 +1000 Subject: [PATCH] Add multi-layer zone rendering for GAL Enable multi-layer selection for keepout zones in GAL --- pcbnew/class_zone.cpp | 54 ++++++++++++++++++++++++--------- pcbnew/class_zone.h | 8 ++--- pcbnew/pcb_painter.cpp | 12 ++++++-- pcbnew/pcb_painter.h | 2 +- pcbnew/tools/selection_tool.cpp | 39 ++++++++++++++++++++---- 5 files changed, 85 insertions(+), 30 deletions(-) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 88f2c96fa1..208139039f 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -178,13 +178,20 @@ const wxPoint& ZONE_CONTAINER::GetPosition() const PCB_LAYER_ID ZONE_CONTAINER::GetLayer() const { - // Testing only + return BOARD_ITEM::GetLayer(); +} + + +bool ZONE_CONTAINER::IsOnCopperLayer() const +{ if( GetIsKeepout() ) { - std::cout << "GetLayer() called for keepout!" << std::endl; + return ( m_layerSet & LSET::AllCuMask() ).count() > 0; + } + else + { + return IsCopperLayer( GetLayer() ); } - - return BOARD_ITEM::GetLayer(); } @@ -207,8 +214,6 @@ void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet ) { // Keepouts can only exist on copper layers m_layerSet = aLayerSet & LSET::AllCuMask(); - - std::cout << "Setting layers of keepout: " << aLayerSet.FmtBin() << std::endl; } // Set the single layer to the first selected layer @@ -228,6 +233,26 @@ LSET ZONE_CONTAINER::GetLayerSet() const } } +void ZONE_CONTAINER::ViewGetLayers( int aLayers[], int& aCount ) const +{ + if( GetIsKeepout() ) + { + LSEQ layers = m_layerSet.Seq(); + + for( unsigned int idx = 0; idx < layers.size(); idx++ ) + { + aLayers[idx] = layers[idx]; + } + + aCount = layers.size(); + } + else + { + aLayers[0] = m_Layer; + aCount = 1; + } +} + bool ZONE_CONTAINER::IsOnLayer( PCB_LAYER_ID aLayer ) const { @@ -252,10 +277,16 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod auto frame = static_cast ( panel->GetParent() ); - std::cout << "Drawing zone container" << std::endl; - PCB_LAYER_ID draw_layer = UNDEFINED_LAYER; + LSET layers = GetLayerSet() & brd->GetVisibleLayers(); + + // If there are no visible layers and the zone is not highlighted, return + if( layers.count() == 0 && !( aDrawMode & GR_HIGHLIGHT ) ) + { + return; + } + /* Keepout zones can exist on multiple layers * Thus, determining which color to use to render them is a bit tricky. * In descending order of priority: @@ -279,7 +310,6 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod // Not on any visible layer? if( layers.count() == 0 && !( aDrawMode & GR_HIGHLIGHT ) ) { - std::cout << "No visible layers found" << std::endl; return; } @@ -287,12 +317,9 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod if( layers.test( curr_layer ) ) { draw_layer = curr_layer; - std::cout << "Selecting color of selected layer" << std::endl; } else { - std::cout << "Selecting color of first visible layer"; - // Select the first (top) visible layer if( layers.count() > 0 ) { @@ -311,7 +338,6 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod { if( brd->IsLayerVisible( GetLayer() ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) { - std::cout << "Not on visible layer" << std::endl; return; } @@ -376,8 +402,6 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { - std::cout << "DrawFilledArea" << std::endl; - static std::vector CornersBuffer; DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 1f8f17e99c..7b7915a516 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -180,11 +180,7 @@ public: * Function IsOnCopperLayer * @return true if this zone is on a copper layer, false if on a technical layer */ - bool IsOnCopperLayer() const - { - //TODO fixme! - return IsCopperLayer( GetLayer() ); - } + bool IsOnCopperLayer() const; virtual void SetLayer( PCB_LAYER_ID aLayer ) override; @@ -192,6 +188,8 @@ public: virtual bool IsOnLayer( PCB_LAYER_ID ) const override; + virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; + /// How to fill areas: 0 = use filled polygons, 1 => fill with segments. void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; } int GetFillMode() const { return m_FillMode; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index fa20016d94..dd5ceb6abc 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -301,7 +301,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) break; case PCB_ZONE_AREA_T: - draw( static_cast( item ) ); + draw( static_cast( item ), aLayer ); break; case PCB_DIMENSION_T: @@ -1082,9 +1082,15 @@ void PCB_PAINTER::draw( const MODULE* aModule, int aLayer ) } -void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone ) +void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer ) { - const COLOR4D& color = m_pcbSettings.GetColor( aZone, aZone->GetLayer() ); + + if( !aZone->IsOnLayer( (PCB_LAYER_ID) aLayer ) ) + { + return; + } + + const COLOR4D& color = m_pcbSettings.GetColor( aZone, aLayer ); std::deque corners; PCB_RENDER_SETTINGS::DISPLAY_ZONE_MODE displayMode = m_pcbSettings.m_displayZone; diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index e1cef7bbfa..cb90426926 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -204,7 +204,7 @@ protected: void draw( const TEXTE_PCB* aText, int aLayer ); void draw( const TEXTE_MODULE* aText, int aLayer ); void draw( const MODULE* aModule, int aLayer ); - void draw( const ZONE_CONTAINER* aZone ); + void draw( const ZONE_CONTAINER* aZone, int aLayer ); void draw( const DIMENSION* aDimension, int aLayer ); void draw( const PCB_TARGET* aTarget ); void draw( const MARKER_PCB* aMarker ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 117831c185..4042925915 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -34,6 +34,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include @@ -1388,15 +1389,17 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const // Is high contrast mode enabled? bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast(); + int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count; + + // Filter out items that do not belong to active layers + const std::set& activeLayers = getView()->GetPainter()-> + GetSettings()->GetActiveLayers(); + + aItem->ViewGetLayers( layers, layers_count ); + if( highContrast ) { bool onActive = false; // Is the item on any of active layers? - int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count; - - // Filter out items that do not belong to active layers - const std::set& activeLayers = getView()->GetPainter()-> - GetSettings()->GetActiveLayers(); - aItem->ViewGetLayers( layers, layers_count ); for( int i = 0; i < layers_count; ++i ) { @@ -1408,11 +1411,35 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const } if( !onActive ) // We do not want to select items that are in the background + { return false; + } } switch( aItem->Type() ) { + case PCB_ZONE_AREA_T: + // Keepout zones can exist on multiple layers! + { + auto* zone = static_cast( aItem ); + + if( zone && zone->GetIsKeepout() ) + { + auto zoneLayers = zone->GetLayerSet().Seq(); + + for( unsigned int i = 0; i < zoneLayers.size(); i++ ) + { + if( board()->IsLayerVisible( zoneLayers[i] ) ) + { + return true; + } + } + + // No active layers selected! + return false; + } + } + break; case PCB_VIA_T: { // For vias it is enough if only one of layers is visible