diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp
index e0d3a72ec6..313b470400 100644
--- a/3d-viewer/3d_canvas/create_layer_items.cpp
+++ b/3d-viewer/3d_canvas/create_layer_items.cpp
@@ -690,7 +690,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
switch( item->Type() )
{
- case PCB_LINE_T: // should not exist on copper layers
+ case PCB_LINE_T:
{
AddShapeWithClearanceToContainer( (DRAWSEGMENT*)item,
layerContainer,
diff --git a/include/board_design_settings.h b/include/board_design_settings.h
index 58cc0d0413..38060c5a48 100644
--- a/include/board_design_settings.h
+++ b/include/board_design_settings.h
@@ -66,6 +66,10 @@
#define DEFAULT_MICROVIASMINDRILL 0.1 // micro vias (not vias) min drill diameter
#define DEFAULT_HOLETOHOLEMIN 0.25 // separation between drilled hole edges
+#define DEFAULT_COPPEREDGECLEARANCE 0.01 // clearance between copper items and edge cuts
+#define LEGACY_COPPEREDGECLEARANCE -0.01 // A flag to indicate the legacy method (based
+ // on edge cut line thicknesses) should be used.
+
/**
* Struct VIA_DIMENSION
* is a small helper container to handle a stock of specific vias each with
@@ -189,6 +193,7 @@ public:
int m_ViasMinDrill; ///< vias (not micro vias) min drill diameter
int m_MicroViasMinSize; ///< micro vias (not vias) min diameter
int m_MicroViasMinDrill; ///< micro vias (not vias) min drill diameter
+ int m_CopperEdgeClearance;
// Global mask margins:
int m_SolderMaskMargin; ///< Solder mask margin
@@ -631,6 +636,12 @@ public:
*/
void SetMinHoleSeparation( int aDistance );
+ /**
+ * Function SetCopperEdgeClearance
+ * @param aValue The minimum distance between copper items and board edges.
+ */
+ void SetCopperEdgeClearance( int aDistance );
+
/**
* Function SetRequireCourtyardDefinitions
* @param aRequire Set to true to generate DRC violations from missing courtyards.
diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp
index d9512d854c..732eef8244 100644
--- a/pcbnew/board_design_settings.cpp
+++ b/pcbnew/board_design_settings.cpp
@@ -489,11 +489,12 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
m_customDiffPair.m_Gap = Millimeter2iu( DEFAULT_CUSTOMDPAIRGAP );
m_customDiffPair.m_ViaGap = Millimeter2iu( DEFAULT_CUSTOMDPAIRVIAGAP );
- m_TrackMinWidth = Millimeter2iu( DEFAULT_TRACKMINWIDTH );
- m_ViasMinSize = Millimeter2iu( DEFAULT_VIASMINSIZE );
- m_ViasMinDrill = Millimeter2iu( DEFAULT_VIASMINDRILL );
- m_MicroViasMinSize = Millimeter2iu( DEFAULT_MICROVIASMINSIZE );
- m_MicroViasMinDrill = Millimeter2iu( DEFAULT_MICROVIASMINDRILL );
+ m_TrackMinWidth = Millimeter2iu( DEFAULT_TRACKMINWIDTH );
+ m_ViasMinSize = Millimeter2iu( DEFAULT_VIASMINSIZE );
+ m_ViasMinDrill = Millimeter2iu( DEFAULT_VIASMINDRILL );
+ m_MicroViasMinSize = Millimeter2iu( DEFAULT_MICROVIASMINSIZE );
+ m_MicroViasMinDrill = Millimeter2iu( DEFAULT_MICROVIASMINDRILL );
+ m_CopperEdgeClearance = Millimeter2iu( DEFAULT_COPPEREDGECLEARANCE );
// Global mask margins:
m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE );
@@ -564,7 +565,14 @@ void BOARD_DESIGN_SETTINGS::AppendConfigs( BOARD* aBoard, PARAM_CFG_ARRAY* aResu
aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinHoleToHole" ),
&m_HoleToHoleMin,
- Millimeter2iu( DEFAULT_HOLETOHOLEMIN ), 0, Millimeter2iu( 10.0 ),
+ Millimeter2iu( DEFAULT_HOLETOHOLEMIN ), Millimeter2iu( 0.0 ), Millimeter2iu( 10.0 ),
+ nullptr, MM_PER_IU ) );
+
+ // Note: a clearance of -0.01 is a flag indicating we should use the legacy (pre-6.0) method
+ // based on the edge cut thicknesses.
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CopperEdgeClearance" ),
+ &m_CopperEdgeClearance,
+ Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ), Millimeter2iu( -0.01 ), Millimeter2iu( 25.0 ),
nullptr, MM_PER_IU ) );
aResult->push_back( new PARAM_CFG_TRACKWIDTHS( &m_TrackWidthList ) );
@@ -850,6 +858,12 @@ void BOARD_DESIGN_SETTINGS::SetMinHoleSeparation( int aDistance )
}
+void BOARD_DESIGN_SETTINGS::SetCopperEdgeClearance( int aDistance )
+{
+ m_CopperEdgeClearance = aDistance;
+}
+
+
void BOARD_DESIGN_SETTINGS::SetRequireCourtyardDefinitions( bool aRequire )
{
m_RequireCourtyards = aRequire;
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
index ec9de9285b..695dc93a00 100644
--- a/pcbnew/board_items_to_polygon_shape_transform.cpp
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -123,7 +123,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
switch( item->Type() )
{
- case PCB_LINE_T: // should not exist on copper layers
+ case PCB_LINE_T:
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
aOutlines, 0, segcountforcircle, correctionFactor );
break;
diff --git a/pcbnew/dialogs/panel_setup_feature_constraints.cpp b/pcbnew/dialogs/panel_setup_feature_constraints.cpp
index a949a3592d..6074e98be8 100644
--- a/pcbnew/dialogs/panel_setup_feature_constraints.cpp
+++ b/pcbnew/dialogs/panel_setup_feature_constraints.cpp
@@ -37,7 +37,8 @@ PANEL_SETUP_FEATURE_CONSTRAINTS::PANEL_SETUP_FEATURE_CONSTRAINTS( PAGED_DIALOG*
m_viaMinDrill( aFrame, m_ViaMinDrillTitle, m_SetViasMinDrillCtrl, m_ViaMinDrillUnits, true ),
m_uviaMinSize( aFrame, m_uviaMinSizeLabel, m_uviaMinSizeCtrl, m_uviaMinSizeUnits, true ),
m_uviaMinDrill( aFrame, m_uviaMinDrillLabel, m_uviaMinDrillCtrl, m_uviaMinDrillUnits, true ),
- m_holeToHoleMin( aFrame, m_HoleToHoleTitle, m_SetHoleToHoleCtrl, m_HoleToHoleUnits, true )
+ m_holeToHoleMin( aFrame, m_HoleToHoleTitle, m_SetHoleToHoleCtrl, m_HoleToHoleUnits, true ),
+ m_edgeClearance( aFrame, m_EdgeClearanceLabel, m_EdgeClearanceCtrl, m_EdgeClearanceUnits, true )
{
m_Frame = aFrame;
m_BrdSettings = &m_Frame->GetBoard()->GetDesignSettings();
@@ -58,6 +59,8 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::TransferDataToWindow()
m_holeToHoleMin.SetValue( m_BrdSettings->m_HoleToHoleMin );
+ m_edgeClearance.SetValue( m_BrdSettings->m_CopperEdgeClearance );
+
m_OptRequireCourtyards->SetValue( m_BrdSettings->m_RequireCourtyards );
m_OptOverlappingCourtyards->SetValue( m_BrdSettings->m_ProhibitOverlappingCourtyards );
@@ -83,6 +86,8 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::TransferDataFromWindow()
m_BrdSettings->SetMinHoleSeparation( m_holeToHoleMin.GetValue() );
+ m_BrdSettings->SetCopperEdgeClearance( m_edgeClearance.GetValue() );
+
m_BrdSettings->SetRequireCourtyardDefinitions( m_OptRequireCourtyards->GetValue() );
m_BrdSettings->SetProhibitOverlappingCourtyards( m_OptOverlappingCourtyards->GetValue() );
diff --git a/pcbnew/dialogs/panel_setup_feature_constraints.h b/pcbnew/dialogs/panel_setup_feature_constraints.h
index 5c17315d1e..cb52de17da 100644
--- a/pcbnew/dialogs/panel_setup_feature_constraints.h
+++ b/pcbnew/dialogs/panel_setup_feature_constraints.h
@@ -47,6 +47,7 @@ public:
UNIT_BINDER m_uviaMinSize;
UNIT_BINDER m_uviaMinDrill;
UNIT_BINDER m_holeToHoleMin;
+ UNIT_BINDER m_edgeClearance;
public:
PANEL_SETUP_FEATURE_CONSTRAINTS( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame );
diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp
index 2408dd134b..f5573a8121 100644
--- a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp
+++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2018)
+// C++ code generated with wxFormBuilder (version Dec 30 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -143,6 +143,26 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgFeatureConstraints->Add( m_HoleToHoleUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
+ fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_EdgeClearanceLabel = new wxStaticText( this, wxID_ANY, _("Copper edge clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EdgeClearanceLabel->Wrap( -1 );
+ fgFeatureConstraints->Add( m_EdgeClearanceLabel, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_EdgeClearanceCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgFeatureConstraints->Add( m_EdgeClearanceCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_EdgeClearanceUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EdgeClearanceUnits->Wrap( -1 );
+ fgFeatureConstraints->Add( m_EdgeClearanceUnits, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+
sbFeatureConstraints->Add( fgFeatureConstraints, 1, wxEXPAND|wxTOP|wxLEFT, 5 );
diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp
index 95329ccec1..fe2bc0f2c5 100644
--- a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp
+++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp
@@ -14,7 +14,6 @@
panel_setup_feature_constraints_base
1000
none
-
1
panel_setup_feature_constraints_base
@@ -2124,6 +2123,293 @@
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 0
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 0
+
+
+
+ 5
+ wxTOP|wxBOTTOM|wxRIGHT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Copper edge clearance:
+
+ 0
+
+
+ 0
+
+ 1
+ m_EdgeClearanceLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+ wxALL|wxEXPAND
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+
+ 0
+
+ 1
+ m_EdgeClearanceCtrl
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+ wxTOP|wxBOTTOM|wxRIGHT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ mm
+
+ 0
+
+
+ 0
+
+ 1
+ m_EdgeClearanceUnits
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.h b/pcbnew/dialogs/panel_setup_feature_constraints_base.h
index ce42aba445..ea21254f1e 100644
--- a/pcbnew/dialogs/panel_setup_feature_constraints_base.h
+++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2018)
+// C++ code generated with wxFormBuilder (version Dec 30 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -55,6 +55,9 @@ class PANEL_SETUP_FEATURE_CONSTRAINTS_BASE : public wxPanel
wxStaticText* m_HoleToHoleTitle;
wxTextCtrl* m_SetHoleToHoleCtrl;
wxStaticText* m_HoleToHoleUnits;
+ wxStaticText* m_EdgeClearanceLabel;
+ wxTextCtrl* m_EdgeClearanceCtrl;
+ wxStaticText* m_EdgeClearanceUnits;
public:
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
index e8e7a60b1f..678bb844b9 100644
--- a/pcbnew/drc_clearance_test_functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -737,10 +737,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool aTestPads, bool aTestZ
{
SEG test_seg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
- // the minimum distance = clearance plus half the reference track
- // width. Board edges do not have width or clearance values, so we
- // look for simple crossing.
- SEG::ecoord w_dist = aRefSeg->GetClearance() + aRefSeg->GetWidth() / 2;
+ int clearance = std::max( aRefSeg->GetClearance(), dsnSettings.m_CopperEdgeClearance );
+
+ // the minimum distance = clearance plus half the reference track width
+ SEG::ecoord w_dist = clearance + aRefSeg->GetWidth() / 2;
w_dist *= w_dist;
for( auto it = m_board_outlines.IterateSegmentsWithHoles(); it; it++ )
diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp
index 939fe4830d..1dc1f587ca 100644
--- a/pcbnew/files.cpp
+++ b/pcbnew/files.cpp
@@ -384,6 +384,48 @@ IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
}
+int PCB_EDIT_FRAME::inferLegacyEdgeClearance( BOARD* aBoard )
+{
+ PCB_LAYER_COLLECTOR collector;
+
+ collector.SetLayerId( Edge_Cuts );
+ collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
+
+ int edgeWidth = -1;
+ bool mixed = false;
+
+ for( int i = 0; i < collector.GetCount(); i++ )
+ {
+ if( collector[i]->Type() == PCB_LINE_T )
+ {
+ int itemWidth = static_cast( collector[i] )->GetWidth();
+
+ if( edgeWidth != -1 && edgeWidth != itemWidth )
+ {
+ mixed = true;
+ edgeWidth = std::max( edgeWidth, itemWidth );
+ }
+ else
+ {
+ edgeWidth = itemWidth;
+ }
+ }
+ }
+
+ if( mixed )
+ {
+ // If they had different widths then we can't ensure that fills will be the same.
+ wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance\n"
+ "setting will be used (see Board Setup > Design Rules). This may\n"
+ "result in different fills from previous Kicad versions which used\n"
+ "the line thickness of the board boundary on the Edge Cuts layer." ),
+ _( "Edge Clearance Warning" ), wxOK|wxICON_WARNING, this );
+ }
+
+ return std::max( 0, edgeWidth / 2 );
+}
+
+
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, int aCtl )
{
// This is for python:
@@ -518,6 +560,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in
std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic );
std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright );
bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList;
+ bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance;
bds.SetElementVisibility( LAYER_GRID, configBds.IsElementVisible( LAYER_GRID ) );
bds.SetElementVisibility( LAYER_RATSNEST, configBds.IsElementVisible( LAYER_RATSNEST ) );
@@ -528,6 +571,11 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in
loadedBoard->BuildListOfNets();
loadedBoard->SynchronizeNetsAndNetClasses();
+ // If this is a legacy board then we set the copper edge clearance to 1/2 the edge-cut
+ // line width (which was a legacy kludge for implementing edge clearances).
+ if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) )
+ bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) );
+
GetScreen()->ClrModify();
if( pluginType == IO_MGR::LEGACY &&
diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h
index a916893b27..13d0c0ff6a 100644
--- a/pcbnew/pcb_edit_frame.h
+++ b/pcbnew/pcb_edit_frame.h
@@ -264,6 +264,11 @@ protected:
*/
bool importFile( const wxString& aFileName, int aFileType );
+ /**
+ * Use the existing edge_cut line thicknesses to infer the edge clearace.
+ */
+ int inferLegacyEdgeClearance( BOARD* aBoard );
+
/**
* Rematch orphaned zones and vias to schematic nets.
*/
diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp
index c7bf8308ac..1ae0c2d05c 100644
--- a/pcbnew/zone_filler.cpp
+++ b/pcbnew/zone_filler.cpp
@@ -332,15 +332,15 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
aFeatures.RemoveAllContours();
- int outline_half_thickness = aZone->GetMinThickness() / 2;
+ int zone_clearance = aZone->GetClearance();
+ int edgeClearance = m_board->GetDesignSettings().m_CopperEdgeClearance;
+ int zone_to_edgecut_clearance = std::max( aZone->GetZoneClearance(), edgeClearance );
// When removing holes, the holes must be expanded by outline_half_thickness
// to take in account the thickness of the zone outlines
- int zone_clearance = aZone->GetClearance() + outline_half_thickness;
-
- // When holes are created by non copper items (edge cut items), use only
- // the m_ZoneClearance parameter (zone clearance with no netclass clearance)
- int zone_to_edgecut_clearance = aZone->GetZoneClearance() + outline_half_thickness;
+ int outline_half_thickness = aZone->GetMinThickness() / 2;
+ zone_clearance += outline_half_thickness;
+ zone_to_edgecut_clearance += outline_half_thickness;
/* store holes (i.e. tracks and pads areas as polygons outlines)
* in a polygon list
@@ -531,12 +531,8 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
// the netclass value, because we do not have a copper item
zclearance = zone_to_edgecut_clearance;
-#if 0
-// 6.0 TODO: we're leaving this off for 5.1 so that people can continue to use the board
-// edge width as a hack for edge clearance.
// edge cuts by definition don't have a width
ignoreLineWidth = true;
-#endif
}
switch( aItem->Type() )
diff --git a/template/kicad.pro b/template/kicad.pro
index 152769cb72..5cd098305b 100644
--- a/template/kicad.pro
+++ b/template/kicad.pro
@@ -1,4 +1,4 @@
-update=22/05/2015 07:44:53
+update=05/04/2019 20:44:53
version=1
last_client=kicad
[general]
@@ -24,6 +24,7 @@ SolderMaskMinWidth=0.000000000000
DrawSegmentWidth=0.200000000000
BoardOutlineThickness=0.100000000000
ModuleOutlineThickness=0.150000000000
+CopperEdgeClearance=0.000000000000
[cvpcb]
version=1
NetIExt=net