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 filled_areas_thickness
fillet fillet
font font
footprints
fp_arc fp_arc
fp_circle fp_circle
fp_curve fp_curve

View File

@ -1155,6 +1155,8 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data(
zone->SetIsKeepout( true ); zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false ); zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false ); zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true ); zone->SetDoNotAllowCopperPour( true );
} }
else else
@ -1346,6 +1348,8 @@ void ALTIUM_PCB::ParseArcs6Data(
zone->SetIsKeepout( true ); zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false ); zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false ); zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true ); zone->SetDoNotAllowCopperPour( true );
ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false ); ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false );
@ -1730,6 +1734,8 @@ void ALTIUM_PCB::ParseTracks6Data(
zone->SetIsKeepout( true ); zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false ); zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false ); zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true ); zone->SetDoNotAllowCopperPour( true );
ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false ); ds.TransformShapeWithClearanceToPolygon( *zone->Outline(), 0, ARC_HIGH_DEF, false );
@ -2001,6 +2007,8 @@ void ALTIUM_PCB::ParseFills6Data(
zone->SetIsKeepout( true ); zone->SetIsKeepout( true );
zone->SetDoNotAllowTracks( false ); zone->SetDoNotAllowTracks( false );
zone->SetDoNotAllowVias( false ); zone->SetDoNotAllowVias( false );
zone->SetDoNotAllowPads( false );
zone->SetDoNotAllowFootprints( false );
zone->SetDoNotAllowCopperPour( true ); 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 SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
SetDoNotAllowVias( true ); // 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 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; m_cornerRadius = 0;
SetLocalFlags( 0 ); // flags tempoarry used in zone calculations SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
m_Poly = new SHAPE_POLY_SET(); // Outlines 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_doNotAllowCopperPour = aZone.m_doNotAllowCopperPour;
m_doNotAllowVias = aZone.m_doNotAllowVias; m_doNotAllowVias = aZone.m_doNotAllowVias;
m_doNotAllowTracks = aZone.m_doNotAllowTracks; m_doNotAllowTracks = aZone.m_doNotAllowTracks;
m_doNotAllowPads = aZone.m_doNotAllowPads;
m_doNotAllowFootprints = aZone.m_doNotAllowFootprints;
m_cornerSmoothingType = aZone.m_cornerSmoothingType; m_cornerSmoothingType = aZone.m_cornerSmoothingType;
m_cornerRadius = aZone.m_cornerRadius; m_cornerRadius = aZone.m_cornerRadius;
@ -534,13 +538,19 @@ void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
msg.Empty(); msg.Empty();
if( GetDoNotAllowVias() ) if( GetDoNotAllowVias() )
AccumulateDescription( msg, _( "No via" ) ); AccumulateDescription( msg, _( "No vias" ) );
if( GetDoNotAllowTracks() ) if( GetDoNotAllowTracks() )
AccumulateDescription( msg, _("No track") ); AccumulateDescription( msg, _("No tracks") );
if( GetDoNotAllowPads() )
AccumulateDescription( msg, _("No pads") );
if( GetDoNotAllowCopperPour() ) 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 ) ); aList.emplace_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
} }

View File

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

View File

@ -91,6 +91,8 @@ bool DIALOG_KEEPOUT_AREA_PROPERTIES::TransferDataToWindow()
// Init keepout parameters: // Init keepout parameters:
m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() ); m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() );
m_cbViasCtrl->SetValue( m_zonesettings.GetDoNotAllowVias() ); 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_cbCopperPourCtrl->SetValue( m_zonesettings.GetDoNotAllowCopperPour() );
m_cbConstrainCtrl->SetValue( m_zonesettings.m_Zone_45_Only ); 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.SetDoNotAllowTracks( m_cbTracksCtrl->GetValue() );
m_zonesettings.SetDoNotAllowVias( m_cbViasCtrl->GetValue() ); m_zonesettings.SetDoNotAllowVias( m_cbViasCtrl->GetValue() );
m_zonesettings.SetDoNotAllowCopperPour( m_cbCopperPourCtrl->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: // Test for not allowed items: should have at least one item not allowed:
if( ! m_zonesettings.GetDoNotAllowTracks() && if( ! m_zonesettings.GetDoNotAllowTracks() &&
! m_zonesettings.GetDoNotAllowVias() && ! m_zonesettings.GetDoNotAllowVias() &&
! m_zonesettings.GetDoNotAllowPads() &&
! m_zonesettings.GetDoNotAllowFootprints() &&
! m_zonesettings.GetDoNotAllowCopperPour() ) ! m_zonesettings.GetDoNotAllowCopperPour() )
{ {
DisplayError( NULL, _("Tracks, vias, and pads are allowed. The keepout will have no effect." ) ); 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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // 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 ); m_cbViasCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out vias"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbViasCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 ); 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 ); m_cbCopperPourCtrl = new wxCheckBox( this, wxID_ANY, _("Keep out copper pours"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_cbCopperPourCtrl, 0, wxALL|wxEXPAND, 5 ); bSizerRight->Add( m_cbCopperPourCtrl, 0, wxALL|wxEXPAND, 5 );
bSizerRight->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 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 ); 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 ); bSizerRight->Add( m_cbConstrainCtrl, 0, wxALL, 5 );

View File

@ -306,6 +306,70 @@
<property name="window_style"></property> <property name="window_style"></property>
</object> </object>
</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"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
@ -380,6 +444,80 @@
<property name="width">0</property> <property name="width">0</property>
</object> </object>
</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"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL</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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -40,7 +40,9 @@ class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE : public DIALOG_SHIM
wxDataViewListCtrl* m_layers; wxDataViewListCtrl* m_layers;
wxCheckBox* m_cbTracksCtrl; wxCheckBox* m_cbTracksCtrl;
wxCheckBox* m_cbViasCtrl; wxCheckBox* m_cbViasCtrl;
wxCheckBox* m_cbPadsCtrl;
wxCheckBox* m_cbCopperPourCtrl; wxCheckBox* m_cbCopperPourCtrl;
wxCheckBox* m_cbFootprintsCtrl;
wxCheckBox* m_cbConstrainCtrl; wxCheckBox* m_cbConstrainCtrl;
wxStaticText* m_staticTextStyle; wxStaticText* m_staticTextStyle;
wxChoice* m_OutlineAppearanceCtrl; wxChoice* m_OutlineAppearanceCtrl;

View File

@ -977,7 +977,7 @@ void DRC::testKeepoutAreas()
if( !area->GetIsKeepout() ) if( !area->GetIsKeepout() )
continue; continue;
for( auto segm : m_pcb->Tracks() ) for( TRACK* segm : m_pcb->Tracks() )
{ {
if( segm->Type() == PCB_TRACE_T ) if( segm->Type() == PCB_TRACE_T )
{ {
@ -1006,9 +1006,7 @@ void DRC::testKeepoutAreas()
if( ! area->GetDoNotAllowVias() ) if( ! area->GetDoNotAllowVias() )
continue; continue;
auto viaLayers = segm->GetLayerSet(); if( !area->CommonLayerExists( segm->GetLayerSet() ) )
if( !area->CommonLayerExists( viaLayers ) )
continue; continue;
int widths = segm->GetWidth() / 2; 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() ) if( module->IsNetTie() )
continue; continue;
for( auto item : module->GraphicalItems() ) for( BOARD_ITEM* item : module->GraphicalItems() )
{ {
if( IsCopperLayer( item->GetLayer() ) ) 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_uVIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
DRCE_NETCLASS_uVIADRILLSIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill DRCE_NETCLASS_uVIADRILLSIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
DRCE_VIA_INSIDE_KEEPOUT, ///< Via in inside a keepout area DRCE_VIA_INSIDE_KEEPOUT, ///< Via in inside a keepout area
DRCE_TRACK_INSIDE_KEEPOUT, ///< Track in inside a keepout area DRCE_TRACK_INSIDE_KEEPOUT, ///< Track inside a keepout area
DRCE_PAD_INSIDE_KEEPOUT, ///< Pad in 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_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_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 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_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_UNRESOLVED_VARIABLE, 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 // These are actually Cleanup Tracks and Vias actions, not DRCE errors
DRCE_SHORT, DRCE_SHORT,

View File

@ -122,6 +122,8 @@ wxString DRC_ITEM::GetErrorText( int aCode ) const
return wxString( _( "Track inside keepout area" ) ); return wxString( _( "Track inside keepout area" ) );
case DRCE_PAD_INSIDE_KEEPOUT: case DRCE_PAD_INSIDE_KEEPOUT:
return wxString( _( "Pad inside keepout area" ) ); return wxString( _( "Pad inside keepout area" ) );
case DRCE_FOOTPRINT_INSIDE_KEEPOUT:
return wxString( _( "Footprint inside keepout area" ) );
case DRCE_VIA_NEAR_COPPER: case DRCE_VIA_NEAR_COPPER:
return wxString( _( "Via too close to copper item" ) ); 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->SetDoNotAllowVias( true );
zone->SetDoNotAllowTracks( true ); zone->SetDoNotAllowTracks( true );
zone->SetDoNotAllowCopperPour( true ); zone->SetDoNotAllowCopperPour( true );
zone->SetDoNotAllowPads( true );
zone->SetDoNotAllowFootprints( false );
} }
// Get the first vertex and iterate // 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() ) 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->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowVias() ? "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" ); m_out->Print( aNestLevel+1, "(fill" );
@ -1918,10 +1920,12 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( newLine == 0 ) if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)", 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 else
m_out->Print( 0, " (xy %s %s)", 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 ) if( newLine < 4 )
{ {
@ -1978,10 +1982,12 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( newLine == 0 ) if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)", 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 else
m_out->Print( 0, " (xy %s %s)", 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 ) if( newLine < 4 )
{ {

View File

@ -2529,6 +2529,9 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{ {
char* token; char* token;
zc->SetIsKeepout( true ); 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" // e.g. "ZKeepout tracks N vias N pads Y"
token = strtok_r( line + SZ( "ZKeepout" ), delims, (char**) &data ); token = strtok_r( line + SZ( "ZKeepout" ), delims, (char**) &data );

View File

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

View File

@ -3910,6 +3910,10 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
case T_keepout: case T_keepout:
zone->SetIsKeepout( true ); 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() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
if( token == T_LEFT ) if( token == T_LEFT )
@ -3941,6 +3945,22 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
zone->SetDoNotAllowCopperPour( token == T_not_allowed ); zone->SetDoNotAllowCopperPour( token == T_not_allowed );
break; 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: default:
Expecting( "tracks, vias or copperpour" ); Expecting( "tracks, vias or copperpour" );
} }

View File

@ -78,6 +78,8 @@ ZONE_SETTINGS::ZONE_SETTINGS()
SetDoNotAllowCopperPour( false ); SetDoNotAllowCopperPour( false );
SetDoNotAllowVias( true ); SetDoNotAllowVias( true );
SetDoNotAllowTracks( 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_keepoutDoNotAllowCopperPour = aSource.GetDoNotAllowCopperPour();
m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias(); m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias();
m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks(); m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks();
m_keepoutDoNotAllowPads = aSource.GetDoNotAllowPads();
m_keepoutDoNotAllowFootprints = aSource.GetDoNotAllowFootprints();
m_Zone_45_Only = aSource.GetHV45(); m_Zone_45_Only = aSource.GetHV45();
m_CurrentZone_Layer = aSource.GetLayer(); m_CurrentZone_Layer = aSource.GetLayer();
@ -131,6 +135,8 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() ); aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() );
aTarget.SetDoNotAllowVias( GetDoNotAllowVias() ); aTarget.SetDoNotAllowVias( GetDoNotAllowVias() );
aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() ); aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() );
aTarget.SetDoNotAllowPads( GetDoNotAllowPads() );
aTarget.SetDoNotAllowFootprints( GetDoNotAllowFootprints() );
aTarget.SetHV45( m_Zone_45_Only ); aTarget.SetHV45( m_Zone_45_Only );
if( aFullExport ) if( aFullExport )

View File

@ -111,6 +111,8 @@ private:
bool m_keepoutDoNotAllowCopperPour; bool m_keepoutDoNotAllowCopperPour;
bool m_keepoutDoNotAllowVias; bool m_keepoutDoNotAllowVias;
bool m_keepoutDoNotAllowTracks; bool m_keepoutDoNotAllowTracks;
bool m_keepoutDoNotAllowPads;
bool m_keepoutDoNotAllowFootprints;
public: public:
@ -170,11 +172,15 @@ public:
const bool GetDoNotAllowCopperPour() const { return m_keepoutDoNotAllowCopperPour; } const bool GetDoNotAllowCopperPour() const { return m_keepoutDoNotAllowCopperPour; }
const bool GetDoNotAllowVias() const { return m_keepoutDoNotAllowVias; } const bool GetDoNotAllowVias() const { return m_keepoutDoNotAllowVias; }
const bool GetDoNotAllowTracks() const { return m_keepoutDoNotAllowTracks; } 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 SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_keepoutDoNotAllowCopperPour = aEnable; } void SetDoNotAllowCopperPour( bool aEnable ) { m_keepoutDoNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_keepoutDoNotAllowVias = aEnable; } void SetDoNotAllowVias( bool aEnable ) { m_keepoutDoNotAllowVias = aEnable; }
void SetDoNotAllowTracks( bool aEnable ) { m_keepoutDoNotAllowTracks = 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() ) if( GetDoNotAllowTracks() != aZoneToCompare.GetDoNotAllowTracks() )
return false; return false;
if( GetDoNotAllowPads() != aZoneToCompare.GetDoNotAllowPads() )
return false;
if( GetDoNotAllowFootprints() != aZoneToCompare.GetDoNotAllowFootprints() )
return false;
} }
if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance ) 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() ) if( area_to_test->GetDoNotAllowVias() != area2->GetDoNotAllowVias() )
continue; continue;
if( area_to_test->GetDoNotAllowPads() != area2->GetDoNotAllowPads() )
continue;
if( area_to_test->GetDoNotAllowFootprints() != area2->GetDoNotAllowFootprints() )
continue;
} }
// Filled zone specific tests // Filled zone specific tests
else else