Enable multi-layer for keepout zones
- Load / save from PCB file correctly - Doesn't display properly yet - Keepout only actually applies to one layer (for now)
This commit is contained in:
parent
28997e7f37
commit
0f6ec7632b
|
@ -563,6 +563,7 @@ LSET FlipLayerMask( LSET aMask, int aCopperLayersCount )
|
|||
|
||||
for( int ii = 0; ii < innerLayerCnt; ii++ )
|
||||
{
|
||||
//TODO there is a problem with this code
|
||||
if( internalMask[innerLayerCnt - ii + In1_Cu] )
|
||||
newMask.set( ii + In1_Cu );
|
||||
else
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
* Function GetLayer
|
||||
* returns the primary layer this item is on.
|
||||
*/
|
||||
PCB_LAYER_ID GetLayer() const { return m_Layer; }
|
||||
virtual PCB_LAYER_ID GetLayer() const { return m_Layer; }
|
||||
|
||||
/**
|
||||
* Function GetLayerSet
|
||||
|
|
|
@ -176,6 +176,70 @@ const wxPoint& ZONE_CONTAINER::GetPosition() const
|
|||
}
|
||||
|
||||
|
||||
PCB_LAYER_ID ZONE_CONTAINER::GetLayer() const
|
||||
{
|
||||
// Testing only
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
std::cout << "GetLayer() called for keepout!" << std::endl;
|
||||
}
|
||||
|
||||
return BOARD_ITEM::GetLayer();
|
||||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::SetLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
SetLayerSet( LSET( aLayer ) );
|
||||
|
||||
m_Layer = aLayer;
|
||||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet )
|
||||
{
|
||||
if( aLayerSet.count() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
// 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
|
||||
m_Layer = aLayerSet.Seq()[0];
|
||||
}
|
||||
|
||||
|
||||
LSET ZONE_CONTAINER::GetLayerSet() const
|
||||
{
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
return m_layerSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LSET( m_Layer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ZONE_CONTAINER::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
return m_layerSet.test( aLayer );
|
||||
}
|
||||
|
||||
return BOARD_ITEM::IsOnLayer( aLayer );
|
||||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
|
||||
const wxPoint& offset )
|
||||
{
|
||||
|
@ -188,10 +252,75 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod
|
|||
|
||||
auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
|
||||
|
||||
auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
|
||||
std::cout << "Drawing zone container" << std::endl;
|
||||
|
||||
PCB_LAYER_ID draw_layer = UNDEFINED_LAYER;
|
||||
|
||||
/* 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:
|
||||
*
|
||||
* 1. If in GR_HIGHLIGHT mode:
|
||||
* a. If zone is on selected layer, use layer color!
|
||||
* b. Else, use grey
|
||||
* 1. Not in GR_HIGHLIGHT mode
|
||||
* a. If zone is on selected layer, use layer color
|
||||
* b. Else, use color of top-most (visible) layer
|
||||
*
|
||||
*/
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
// 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();
|
||||
|
||||
if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
|
||||
return;
|
||||
// Not on any visible layer?
|
||||
if( layers.count() == 0 && !( aDrawMode & GR_HIGHLIGHT ) )
|
||||
{
|
||||
std::cout << "No visible layers found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Is keepout zone present on the selected layer?
|
||||
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 )
|
||||
{
|
||||
draw_layer = layers.Seq()[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_layer = GetLayerSet().Seq()[0];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Non-keepout zones are easier to deal with
|
||||
*/
|
||||
else
|
||||
{
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
|
||||
{
|
||||
std::cout << "Not on visible layer" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
draw_layer = GetLayer();
|
||||
}
|
||||
|
||||
assert( draw_layer != UNDEFINED_LAYER );
|
||||
|
||||
auto color = frame->Settings().Colors().GetLayerColor( draw_layer );
|
||||
|
||||
GRSetDrawMode( DC, aDrawMode );
|
||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
|
||||
|
@ -199,11 +328,15 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod
|
|||
if( displ_opts->m_ContrastModeDisplay )
|
||||
{
|
||||
if( !IsOnLayer( curr_layer ) )
|
||||
{
|
||||
color = COLOR4D( DARKDARKGRAY );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
|
||||
{
|
||||
color.SetToLegacyHighlightColor();
|
||||
}
|
||||
|
||||
color.a = 0.588;
|
||||
|
||||
|
@ -242,6 +375,9 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod
|
|||
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
|
||||
wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
|
||||
{
|
||||
|
||||
std::cout << "DrawFilledArea" << std::endl;
|
||||
|
||||
static std::vector <wxPoint> CornersBuffer;
|
||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
|
||||
|
||||
|
@ -262,9 +398,9 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
|
|||
PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
|
||||
|
||||
auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
|
||||
auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
|
||||
auto color = frame->Settings().Colors().GetLayerColor( GetLayer() );
|
||||
|
||||
if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
|
||||
return;
|
||||
|
||||
GRSetDrawMode( DC, aDrawMode );
|
||||
|
@ -389,7 +525,7 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC,
|
|||
PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
|
||||
|
||||
auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
|
||||
auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
|
||||
auto color = frame->Settings().Colors().GetLayerColor( GetLayer() );
|
||||
|
||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
|
||||
|
||||
|
@ -789,7 +925,15 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
|
|||
{
|
||||
Mirror( aCentre );
|
||||
int copperLayerCount = GetBoard()->GetCopperLayerCount();
|
||||
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
|
||||
|
||||
if( GetIsKeepout() )
|
||||
{
|
||||
SetLayerSet( FlipLayerMask( GetLayerSet(), copperLayerCount ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,10 @@ public:
|
|||
|
||||
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||
|
||||
void SetLayerSet( LSET aLayerSet );
|
||||
|
||||
virtual LSET GetLayerSet() const override;
|
||||
|
||||
/**
|
||||
* Function Draw
|
||||
* Draws the zone outline.
|
||||
|
@ -178,9 +182,16 @@ public:
|
|||
*/
|
||||
bool IsOnCopperLayer() const
|
||||
{
|
||||
//TODO fixme!
|
||||
return IsCopperLayer( GetLayer() );
|
||||
}
|
||||
|
||||
virtual void SetLayer( PCB_LAYER_ID aLayer ) override;
|
||||
|
||||
virtual PCB_LAYER_ID GetLayer() const override;
|
||||
|
||||
virtual bool IsOnLayer( PCB_LAYER_ID ) 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; }
|
||||
|
@ -725,6 +736,8 @@ private:
|
|||
int m_cornerSmoothingType;
|
||||
unsigned int m_cornerRadius;
|
||||
|
||||
LSET m_layerSet;
|
||||
|
||||
/* Priority: when a zone outline is inside and other zone, if its priority is higher
|
||||
* the other zone priority, it will be created inside.
|
||||
* if priorities are equal, a DRC error is set
|
||||
|
|
|
@ -77,7 +77,6 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
|
|||
m_ZoneClearance = aSource.GetZoneClearance();
|
||||
m_ZoneMinThickness = aSource.GetMinThickness();
|
||||
m_NetcodeSelection = aSource.GetNetCode();
|
||||
m_CurrentZone_Layer = aSource.GetLayer();
|
||||
m_Zone_HatchingStyle = aSource.GetHatchStyle();
|
||||
m_ArcToSegmentsCount = aSource.GetArcSegmentCount();
|
||||
m_ThermalReliefGap = aSource.GetThermalReliefGap();
|
||||
|
@ -90,6 +89,9 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
|
|||
m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias();
|
||||
m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks();
|
||||
|
||||
m_CurrentZone_Layer = aSource.GetLayer();
|
||||
m_Layers = aSource.GetLayerSet();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -114,7 +116,16 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
|
|||
{
|
||||
aTarget.SetPriority( m_ZonePriority );
|
||||
aTarget.SetNetCode( m_NetcodeSelection );
|
||||
aTarget.SetLayer( m_CurrentZone_Layer );
|
||||
|
||||
// Keepout zones can have multiple layers
|
||||
if( m_isKeepout )
|
||||
{
|
||||
aTarget.SetLayerSet( m_Layers );
|
||||
}
|
||||
else
|
||||
{
|
||||
aTarget.SetLayer( m_CurrentZone_Layer );
|
||||
}
|
||||
}
|
||||
|
||||
// call SetHatch last, because hatch lines will be rebuilt,
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
int m_ZoneMinThickness; ///< Min thickness value in filled areas
|
||||
int m_NetcodeSelection; ///< Net code selection for the current zone
|
||||
|
||||
LSET m_Layers;
|
||||
|
||||
PCB_LAYER_ID m_CurrentZone_Layer; ///< Layer used to create the current zone
|
||||
|
||||
/// Option to show the zone area (outlines only, short hatches or full hatches
|
||||
|
|
|
@ -89,7 +89,7 @@ private:
|
|||
|
||||
|
||||
#define LAYER_BITMAP_SIZE_X 20
|
||||
#define LAYER_BITMAP_SIZE_Y 10
|
||||
#define LAYER_BITMAP_SIZE_Y 15
|
||||
|
||||
ZONE_EDIT_T InvokeKeepoutAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
|
||||
{
|
||||
|
@ -155,6 +155,7 @@ void DIALOG_KEEPOUT_AREA_PROPERTIES::initDialog()
|
|||
|
||||
// Build copper layer list and append to layer widget
|
||||
LSET show = LSET::AllCuMask( board->GetCopperLayerCount() );
|
||||
|
||||
int imgIdx = 0;
|
||||
|
||||
for( LSEQ cu_stack = show.UIOrder(); cu_stack; ++cu_stack, imgIdx++ )
|
||||
|
@ -173,7 +174,15 @@ void DIALOG_KEEPOUT_AREA_PROPERTIES::initDialog()
|
|||
m_LayerSelectionCtrl->GetItemCount(), msg, imgIdx );
|
||||
|
||||
if( m_zonesettings.m_CurrentZone_Layer == layer )
|
||||
{
|
||||
//m_LayerSelectionCtrl->Select( itemIndex );
|
||||
}
|
||||
|
||||
if( m_zonesettings.m_Layers.test( layer ) )
|
||||
{
|
||||
m_LayerSelectionCtrl->Select( itemIndex );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_LayerSelectionCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE);
|
||||
|
@ -213,6 +222,25 @@ bool DIALOG_KEEPOUT_AREA_PROPERTIES::AcceptOptionsForKeepOut()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Copy the layers across
|
||||
LSET layers;
|
||||
|
||||
for( int ii = 0; ii < m_LayerSelectionCtrl->GetItemCount(); ii++ )
|
||||
{
|
||||
if( m_LayerSelectionCtrl->IsSelected( ii ) )
|
||||
{
|
||||
layers.set( ToLAYER_ID( m_layerId[ii] ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( layers.count() == 0 )
|
||||
{
|
||||
DisplayError( NULL, _( "No layers selected." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_zonesettings.m_Layers = layers;
|
||||
|
||||
// Get the layer selection for this zone
|
||||
int ii = m_LayerSelectionCtrl->GetFirstSelected();
|
||||
|
||||
|
@ -224,6 +252,8 @@ bool DIALOG_KEEPOUT_AREA_PROPERTIES::AcceptOptionsForKeepOut()
|
|||
|
||||
m_zonesettings.m_CurrentZone_Layer = ToLAYER_ID( m_layerId[ii] );
|
||||
|
||||
// Set zone layers
|
||||
|
||||
switch( m_OutlineAppearanceCtrl->GetSelection() )
|
||||
{
|
||||
case 0:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version May 6 2016)
|
||||
// C++ code generated with wxFormBuilder (version Mar 22 2017)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -26,11 +26,11 @@ DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( wxWind
|
|||
wxBoxSizer* m_layersListSizer;
|
||||
m_layersListSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Keepout Zone Layers"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextLayerSelection->Wrap( -1 );
|
||||
m_layersListSizer->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL );
|
||||
m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_HRULES|wxLC_NO_HEADER|wxLC_REPORT );
|
||||
m_layersListSizer->Add( m_LayerSelectionCtrl, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
|
||||
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Layer:</property>
|
||||
<property name="label">Keepout Zone Layers</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -243,7 +243,7 @@
|
|||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL</property>
|
||||
<property name="style">wxLC_ALIGN_LEFT|wxLC_HRULES|wxLC_NO_HEADER|wxLC_REPORT</property>
|
||||
<property name="subclass">wxListView; </property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version May 6 2016)
|
||||
// C++ code generated with wxFormBuilder (version Mar 22 2017)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
|
|
@ -1609,7 +1609,15 @@ 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() );
|
||||
|
||||
formatLayer( aZone );
|
||||
// Keepout zones can exist on multiple layers
|
||||
if( aZone->GetIsKeepout() && aZone->GetLayerSet().count() > 1 )
|
||||
{
|
||||
formatLayers( aZone->GetLayerSet() );
|
||||
}
|
||||
else
|
||||
{
|
||||
formatLayer( aZone );
|
||||
}
|
||||
|
||||
m_out->Print( 0, " (tstamp %lX)", (unsigned long) aZone->GetTimeStamp() );
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ class NETINFO_MAPPING;
|
|||
// // went to 32 Cu layers from 16.
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20160815 // differential pair settings per net class
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20170123 // EDA_TEXT refactor, moved 'hide'
|
||||
#define SEXPR_BOARD_FILE_VERSION 20170920 // long pad names and custom pad shape
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20170920 // long pad names and custom pad shape
|
||||
#define SEXPR_BOARD_FILE_VERSION 20170922 // Keepout zones can exist on multiple layers
|
||||
|
||||
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
|
||||
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)
|
||||
|
|
|
@ -2825,6 +2825,12 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER()
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_layers:
|
||||
// If multiple layers are specified, it is a keepout zone
|
||||
zone->SetIsKeepout( true );
|
||||
zone->SetLayerSet( parseBoardItemLayersAsMask() );
|
||||
break;
|
||||
|
||||
case T_tstamp:
|
||||
zone->SetTimeStamp( parseHex() );
|
||||
NeedRIGHT();
|
||||
|
@ -3075,7 +3081,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER()
|
|||
break;
|
||||
|
||||
default:
|
||||
Expecting( "net, layer, tstamp, hatch, priority, connect_pads, min_thickness, "
|
||||
Expecting( "net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
|
||||
"fill, polygon, filled_polygon, or fill_segments" );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue