Add pad keepout and footprint keepout areas.

Fixes https://gitlab.com/kicad/code/kicad/issues/2365
This commit is contained in:
Jeff Young 2020-05-07 01:30:46 +01:00
parent 3fbc2f9035
commit 0f8c7ffd11
20 changed files with 333 additions and 20 deletions

View File

@ -100,6 +100,7 @@ filled_polygon
filled_areas_thickness
fillet
font
footprints
fp_arc
fp_circle
fp_curve

View File

@ -1155,6 +1155,8 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data(
zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true );
}
else
@ -1346,6 +1348,8 @@ void ALTIUM_PCB::ParseArcs6Data(
zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true );
ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false );
@ -1730,6 +1734,8 @@ void ALTIUM_PCB::ParseTracks6Data(
zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true );
ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false );
@ -2001,6 +2007,8 @@ void ALTIUM_PCB::ParseFills6Data(
zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true );
}

View File

@ -68,6 +68,8 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule )
SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
SetDoNotAllowVias( true ); // has meaning only if m_isKeepout == true
SetDoNotAllowTracks( true ); // has meaning only if m_isKeepout == true
SetDoNotAllowPads( true ); // has meaning only if m_isKeepout == true
SetDoNotAllowFootprints( false ); // has meaning only if m_isKeepout == true
m_cornerRadius = 0;
SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
m_Poly = new SHAPE_POLY_SET(); // Outlines
@ -162,6 +164,8 @@ void ZONE_CONTAINER::initDataFromSrcInCopyCtor( const ZONE_CONTAINER& aZone )
m_doNotAllowCopperPour = aZone.m_doNotAllowCopperPour;
m_doNotAllowVias = aZone.m_doNotAllowVias;
m_doNotAllowTracks = aZone.m_doNotAllowTracks;
m_doNotAllowPads = aZone.m_doNotAllowPads;
m_doNotAllowFootprints = aZone.m_doNotAllowFootprints;
m_cornerSmoothingType = aZone.m_cornerSmoothingType;
m_cornerRadius = aZone.m_cornerRadius;
@ -534,13 +538,19 @@ void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
msg.Empty();
if( GetDoNotAllowVias() )
AccumulateDescription( msg, _( "No via" ) );
AccumulateDescription( msg, _( "No vias" ) );
if( GetDoNotAllowTracks() )
AccumulateDescription( msg, _("No track") );
AccumulateDescription( msg, _("No tracks") );
if( GetDoNotAllowPads() )
AccumulateDescription( msg, _("No pads") );
if( GetDoNotAllowCopperPour() )
AccumulateDescription( msg, _("No copper pour") );
AccumulateDescription( msg, _("No copper pours") );
if( GetDoNotAllowFootprints() )
AccumulateDescription( msg, _("No footpints") );
aList.emplace_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
}

View File

@ -657,11 +657,15 @@ public:
bool GetDoNotAllowCopperPour() const { return m_doNotAllowCopperPour; }
bool GetDoNotAllowVias() const { return m_doNotAllowVias; }
bool GetDoNotAllowTracks() const { return m_doNotAllowTracks; }
bool GetDoNotAllowPads() const { return m_doNotAllowPads; }
bool GetDoNotAllowFootprints() const { return m_doNotAllowFootprints; }
void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_doNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
void SetDoNotAllowPads( bool aEnable ) { m_doNotAllowPads = aEnable; }
void SetDoNotAllowFootprints( bool aEnable ) { m_doNotAllowFootprints = aEnable; }
/**
* Hatch related methods
@ -764,6 +768,8 @@ protected:
bool m_doNotAllowCopperPour;
bool m_doNotAllowVias;
bool m_doNotAllowTracks;
bool m_doNotAllowPads;
bool m_doNotAllowFootprints;
ZONE_CONNECTION m_PadConnection;
int m_ZoneClearance; ///< Clearance value in internal units.

View File

@ -91,6 +91,8 @@ bool DIALOG_KEEPOUT_AREA_PROPERTIES::TransferDataToWindow()
// Init keepout parameters:
m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() );
m_cbViasCtrl->SetValue( m_zonesettings.GetDoNotAllowVias() );
m_cbPadsCtrl->SetValue( m_zonesettings.GetDoNotAllowPads() );
m_cbFootprintsCtrl->SetValue( m_zonesettings.GetDoNotAllowFootprints() );
m_cbCopperPourCtrl->SetValue( m_zonesettings.GetDoNotAllowCopperPour() );
m_cbConstrainCtrl->SetValue( m_zonesettings.m_Zone_45_Only );
@ -146,10 +148,14 @@ bool DIALOG_KEEPOUT_AREA_PROPERTIES::TransferDataFromWindow()
m_zonesettings.SetDoNotAllowTracks( m_cbTracksCtrl->GetValue() );
m_zonesettings.SetDoNotAllowVias( m_cbViasCtrl->GetValue() );
m_zonesettings.SetDoNotAllowCopperPour( m_cbCopperPourCtrl->GetValue() );
m_zonesettings.SetDoNotAllowPads( m_cbPadsCtrl->GetValue() );
m_zonesettings.SetDoNotAllowFootprints( m_cbFootprintsCtrl->GetValue() );
// Test for not allowed items: should have at least one item not allowed:
if( ! m_zonesettings.GetDoNotAllowTracks() &&
! m_zonesettings.GetDoNotAllowVias() &&
! m_zonesettings.GetDoNotAllowPads() &&
! m_zonesettings.GetDoNotAllowFootprints() &&
! m_zonesettings.GetDoNotAllowCopperPour() )
{
DisplayError( NULL, _("Tracks, vias, and pads are allowed. The keepout will have no effect." ) );

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version v3.8.0)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -41,12 +41,21 @@ DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( wxWind
m_cbViasCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out vias"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbViasCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_cbPadsCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out pads"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbPadsCtrl, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_cbCopperPourCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out copper pours"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbCopperPourCtrl, 0, wxALL|wxEXPAND, 5 );
bSizerRight->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_cbFootprintsCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out footprints"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbFootprintsCtrl, 0, wxALL, 5 );
bSizerRight->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_cbConstrainCtrl = new wxCheckBox( this, wxID_ANY, _("Constrain outline to H, V and 45 deg"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbConstrainCtrl, 0, wxALL, 5 );

View File

@ -306,6 +306,70 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Keep out pads</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbPadsCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
@ -380,6 +444,80 @@
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Keep out footprints</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbFootprintsCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version v3.8.0)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -40,7 +40,9 @@ class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE : public DIALOG_SHIM
wxDataViewListCtrl* m_layers;
wxCheckBox* m_cbTracksCtrl;
wxCheckBox* m_cbViasCtrl;
wxCheckBox* m_cbPadsCtrl;
wxCheckBox* m_cbCopperPourCtrl;
wxCheckBox* m_cbFootprintsCtrl;
wxCheckBox* m_cbConstrainCtrl;
wxStaticText* m_staticTextStyle;
wxChoice* m_OutlineAppearanceCtrl;

View File

@ -977,7 +977,7 @@ void DRC::testKeepoutAreas()
if( !area->GetIsKeepout() )
continue;
for( auto segm : m_pcb->Tracks() )
for( TRACK* segm : m_pcb->Tracks() )
{
if( segm->Type() == PCB_TRACE_T )
{
@ -1006,9 +1006,7 @@ void DRC::testKeepoutAreas()
if( ! area->GetDoNotAllowVias() )
continue;
auto viaLayers = segm->GetLayerSet();
if( !area->CommonLayerExists( viaLayers ) )
if( !area->CommonLayerExists( segm->GetLayerSet() ) )
continue;
int widths = segm->GetWidth() / 2;
@ -1025,7 +1023,78 @@ void DRC::testKeepoutAreas()
}
}
}
// Test pads: TODO
if( !area->GetDoNotAllowPads() && !area->GetDoNotAllowFootprints() )
continue;
EDA_RECT areaBBox = area->GetBoundingBox();
bool checkFront = area->CommonLayerExists( LSET::FrontMask() );
bool checkBack = area->CommonLayerExists( LSET::BackMask() );
for( MODULE* fp : m_pcb->Modules() )
{
if( area->GetDoNotAllowFootprints() && ( fp->IsFlipped() ? checkBack : checkFront ) )
{
// Fast test to detect a footprint inside the keepout area bounding box.
if( areaBBox.Intersects( fp->GetBoundingBox() ) )
{
fp->BuildPolyCourtyard();
SHAPE_POLY_SET outline = fp->IsFlipped() ? fp->GetPolyCourtyardBack()
: fp->GetPolyCourtyardFront();
if( outline.OutlineCount() == 0 )
outline = fp->GetBoundingPoly();
// Build the common area between footprint and the keepout area:
outline.BooleanIntersection( *area->Outline(), SHAPE_POLY_SET::PM_FAST );
// If it's not empty then we have a violation
if( outline.OutlineCount() )
{
const VECTOR2I& pt = outline.CVertex( 0, 0, -1 );
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_FOOTPRINT_INSIDE_KEEPOUT );
drcItem->SetItems( fp, area );
MARKER_PCB* marker = new MARKER_PCB( drcItem, (wxPoint) pt );
addMarkerToPcb( marker );
}
}
}
if( area->GetDoNotAllowPads() )
{
for( D_PAD* pad : fp->Pads() )
{
if( !area->CommonLayerExists( pad->GetLayerSet() ) )
continue;
// Fast test to detect a pad inside the keepout area bounding box.
EDA_RECT padBBox( pad->ShapePos(), wxSize() );
padBBox.Inflate( pad->GetBoundingRadius() );
if( areaBBox.Intersects( padBBox ) )
{
SHAPE_POLY_SET outline;
pad->TransformShapeWithClearanceToPolygon( outline, 0 );
// Build the common area between pad and the keepout area:
outline.BooleanIntersection( *area->Outline(), SHAPE_POLY_SET::PM_FAST );
// If it's not empty then we have a violation
if( outline.OutlineCount() )
{
const VECTOR2I& pt = outline.CVertex( 0, 0, -1 );
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_INSIDE_KEEPOUT );
drcItem->SetItems( pad, area );
MARKER_PCB* marker = new MARKER_PCB( drcItem, (wxPoint) pt );
addMarkerToPcb( marker );
}
}
}
}
}
}
}
@ -1059,7 +1128,7 @@ void DRC::testCopperTextAndGraphics()
if( module->IsNetTie() )
continue;
for( auto item : module->GraphicalItems() )
for( BOARD_ITEM* item : module->GraphicalItems() )
{
if( IsCopperLayer( item->GetLayer() ) )
{

View File

@ -68,8 +68,8 @@ enum PCB_DRC_CODE {
DRCE_NETCLASS_uVIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
DRCE_NETCLASS_uVIADRILLSIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
DRCE_VIA_INSIDE_KEEPOUT, ///< Via in inside a keepout area
DRCE_TRACK_INSIDE_KEEPOUT, ///< Track in inside a keepout area
DRCE_PAD_INSIDE_KEEPOUT, ///< Pad in inside a keepout area
DRCE_TRACK_INSIDE_KEEPOUT, ///< Track inside a keepout area
DRCE_PAD_INSIDE_KEEPOUT, ///< Pad inside a keepout area
DRCE_TRACK_NEAR_COPPER, ///< track & copper graphic collide or are too close
DRCE_VIA_NEAR_COPPER, ///< via and copper graphic collide or are too close
DRCE_PAD_NEAR_COPPER, ///< pad and copper graphic collide or are too close
@ -89,8 +89,9 @@ enum PCB_DRC_CODE {
DRCE_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_UNRESOLVED_VARIABLE,
DRCE_FOOTPRINT_INSIDE_KEEPOUT, ///< Footprint inside a keepout area
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE,
DRCE_LAST = DRCE_FOOTPRINT_INSIDE_KEEPOUT,
// These are actually Cleanup Tracks and Vias actions, not DRCE errors
DRCE_SHORT,

View File

@ -122,6 +122,8 @@ wxString DRC_ITEM::GetErrorText( int aCode ) const
return wxString( _( "Track inside keepout area" ) );
case DRCE_PAD_INSIDE_KEEPOUT:
return wxString( _( "Pad inside keepout area" ) );
case DRCE_FOOTPRINT_INSIDE_KEEPOUT:
return wxString( _( "Footprint inside keepout area" ) );
case DRCE_VIA_NEAR_COPPER:
return wxString( _( "Via too close to copper item" ) );

View File

@ -1138,6 +1138,8 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
zone->SetDoNotAllowVias( true );
zone->SetDoNotAllowTracks( true );
zone->SetDoNotAllowCopperPour( true );
zone->SetDoNotAllowPads( true );
zone->SetDoNotAllowFootprints( false );
}
// Get the first vertex and iterate

View File

@ -1834,10 +1834,12 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( aZone->GetIsKeepout() )
{
m_out->Print( aNestLevel+1, "(keepout (tracks %s) (vias %s) (copperpour %s))\n",
m_out->Print( aNestLevel+1, "(keepout (tracks %s) (vias %s) (pads %s ) (copperpour %s) (footprints %s))\n",
aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowCopperPour() ? "not_allowed" : "allowed" );
aZone->GetDoNotAllowPads() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowCopperPour() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowFootprints() ? "not_allowed" : "allowed" );
}
m_out->Print( aNestLevel+1, "(fill" );
@ -1918,10 +1920,12 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)",
FormatInternalUnits( iterator->x ).c_str(), FormatInternalUnits( iterator->y ).c_str() );
FormatInternalUnits( iterator->x ).c_str(),
FormatInternalUnits( iterator->y ).c_str() );
else
m_out->Print( 0, " (xy %s %s)",
FormatInternalUnits( iterator->x ).c_str(), FormatInternalUnits( iterator->y ).c_str() );
FormatInternalUnits( iterator->x ).c_str(),
FormatInternalUnits( iterator->y ).c_str() );
if( newLine < 4 )
{
@ -1978,10 +1982,12 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)",
FormatInternalUnits( it->x ).c_str(), FormatInternalUnits( it->y ).c_str() );
FormatInternalUnits( it->x ).c_str(),
FormatInternalUnits( it->y ).c_str() );
else
m_out->Print( 0, " (xy %s %s)",
FormatInternalUnits( it->x ) .c_str(), FormatInternalUnits( it->y ).c_str() );
FormatInternalUnits( it->x ) .c_str(),
FormatInternalUnits( it->y ).c_str() );
if( newLine < 4 )
{

View File

@ -2529,6 +2529,9 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{
char* token;
zc->SetIsKeepout( true );
zc->SetDoNotAllowPads( false ); // Not supported in legacy
zc->SetDoNotAllowFootprints( false ); // Not supported in legacy
// e.g. "ZKeepout tracks N vias N pads Y"
token = strtok_r( line + SZ( "ZKeepout" ), delims, (char**) &data );

View File

@ -209,13 +209,19 @@ void PCB_POLYGON::AddToBoard()
zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( true );
zone->SetDoNotAllowVias( true );
zone->SetDoNotAllowPads( true );
zone->SetDoNotAllowCopperPour( true );
zone->SetDoNotAllowFootprints( false );
}
else if( m_objType == wxT( 'C' ) )
{
// convert cutouts to keepouts because standalone cutouts are not supported in KiCad
zone->SetIsKeepout( true );
zone->SetDoNotAllowCopperPour( true );
zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
}
//if( m_filled )

View File

@ -3910,6 +3910,10 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
case T_keepout:
zone->SetIsKeepout( true );
// Initialize these two because their tokens won't appear in older files:
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token == T_LEFT )
@ -3941,6 +3945,22 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
zone->SetDoNotAllowCopperPour( token == T_not_allowed );
break;
case T_pads:
token = NextTok();
if( token != T_allowed && token != T_not_allowed )
Expecting( "allowed or not_allowed" );
zone->SetDoNotAllowPads( token == T_not_allowed );
break;
case T_footprints:
token = NextTok();
if( token != T_allowed && token != T_not_allowed )
Expecting( "allowed or not_allowed" );
zone->SetDoNotAllowFootprints( token == T_not_allowed );
break;
default:
Expecting( "tracks, vias or copperpour" );
}

View File

@ -78,6 +78,8 @@ ZONE_SETTINGS::ZONE_SETTINGS()
SetDoNotAllowCopperPour( false );
SetDoNotAllowVias( true );
SetDoNotAllowTracks( true );
SetDoNotAllowPads( true );
SetDoNotAllowFootprints( false );
}
@ -103,6 +105,8 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
m_keepoutDoNotAllowCopperPour = aSource.GetDoNotAllowCopperPour();
m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias();
m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks();
m_keepoutDoNotAllowPads = aSource.GetDoNotAllowPads();
m_keepoutDoNotAllowFootprints = aSource.GetDoNotAllowFootprints();
m_Zone_45_Only = aSource.GetHV45();
m_CurrentZone_Layer = aSource.GetLayer();
@ -131,6 +135,8 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() );
aTarget.SetDoNotAllowVias( GetDoNotAllowVias() );
aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() );
aTarget.SetDoNotAllowPads( GetDoNotAllowPads() );
aTarget.SetDoNotAllowFootprints( GetDoNotAllowFootprints() );
aTarget.SetHV45( m_Zone_45_Only );
if( aFullExport )

View File

@ -111,6 +111,8 @@ private:
bool m_keepoutDoNotAllowCopperPour;
bool m_keepoutDoNotAllowVias;
bool m_keepoutDoNotAllowTracks;
bool m_keepoutDoNotAllowPads;
bool m_keepoutDoNotAllowFootprints;
public:
@ -170,11 +172,15 @@ public:
const bool GetDoNotAllowCopperPour() const { return m_keepoutDoNotAllowCopperPour; }
const bool GetDoNotAllowVias() const { return m_keepoutDoNotAllowVias; }
const bool GetDoNotAllowTracks() const { return m_keepoutDoNotAllowTracks; }
const bool GetDoNotAllowPads() const { return m_keepoutDoNotAllowPads; }
const bool GetDoNotAllowFootprints() const { return m_keepoutDoNotAllowFootprints; }
void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_keepoutDoNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_keepoutDoNotAllowVias = aEnable; }
void SetDoNotAllowTracks( bool aEnable ) { m_keepoutDoNotAllowTracks = aEnable; }
void SetDoNotAllowPads( bool aEnable ) { m_keepoutDoNotAllowPads = aEnable; }
void SetDoNotAllowFootprints( bool aEnable ) { m_keepoutDoNotAllowFootprints = aEnable; }
};

View File

@ -85,6 +85,12 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
if( GetDoNotAllowTracks() != aZoneToCompare.GetDoNotAllowTracks() )
return false;
if( GetDoNotAllowPads() != aZoneToCompare.GetDoNotAllowPads() )
return false;
if( GetDoNotAllowFootprints() != aZoneToCompare.GetDoNotAllowFootprints() )
return false;
}
if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance )

View File

@ -195,6 +195,12 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
if( area_to_test->GetDoNotAllowVias() != area2->GetDoNotAllowVias() )
continue;
if( area_to_test->GetDoNotAllowPads() != area2->GetDoNotAllowPads() )
continue;
if( area_to_test->GetDoNotAllowFootprints() != area2->GetDoNotAllowFootprints() )
continue;
}
// Filled zone specific tests
else