diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp
index 06718f41da..370c149796 100644
--- a/pcbnew/dialogs/dialog_drc.cpp
+++ b/pcbnew/dialogs/dialog_drc.cpp
@@ -220,6 +220,7 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
m_cbRefillZones->GetValue(),
m_cbCourtyardOverlap->GetValue(),
m_cbCourtyardMissing->GetValue(),
+ m_cbReportAllTrackErrors->GetValue(),
reportName, make_report );
DelDRCMarkers();
@@ -294,6 +295,7 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event )
m_cbRefillZones->GetValue(),
m_cbCourtyardOverlap->GetValue(),
m_cbCourtyardMissing->GetValue(),
+ m_cbReportAllTrackErrors->GetValue(),
reportName, make_report );
DelDRCMarkers();
diff --git a/pcbnew/dialogs/dialog_drc_base.cpp b/pcbnew/dialogs/dialog_drc_base.cpp
index 5a746642c1..9db5e08362 100644
--- a/pcbnew/dialogs/dialog_drc_base.cpp
+++ b/pcbnew/dialogs/dialog_drc_base.cpp
@@ -1,8 +1,8 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Feb 9 2018)
+// C++ code generated with wxFormBuilder (version Nov 30 2016)
// http://www.wxformbuilder.org/
//
-// PLEASE DO *NOT* EDIT THIS FILE!
+// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_drclistbox.h"
@@ -108,6 +108,11 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerOptSettings->Add( m_cbRefillZones, 0, wxLEFT|wxRIGHT, 5 );
+ m_cbReportAllTrackErrors = new wxCheckBox( this, wxID_ANY, _("Report all errors for tracks (slower)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cbReportAllTrackErrors->SetToolTip( _("If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.\n\nIf unselected, only the first DRC violation will be reported for each track connection.") );
+
+ bSizerOptSettings->Add( m_cbReportAllTrackErrors, 0, wxALL, 5 );
+
m_cbCourtyardOverlap = new wxCheckBox( this, wxID_ANY, _("Check footprint courtyard overlap"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerOptSettings->Add( m_cbCourtyardOverlap, 0, wxLEFT|wxRIGHT, 5 );
diff --git a/pcbnew/dialogs/dialog_drc_base.fbp b/pcbnew/dialogs/dialog_drc_base.fbp
index abb6bc657c..6a0b603924 100644
--- a/pcbnew/dialogs/dialog_drc_base.fbp
+++ b/pcbnew/dialogs/dialog_drc_base.fbp
@@ -14,7 +14,6 @@
dialog_drc_base
1000
none
-
1
dialog_drc_base
@@ -1284,6 +1283,94 @@
+
5
wxLEFT|wxRIGHT
diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h
index 871d8551b5..f5b7ce2c26 100644
--- a/pcbnew/dialogs/dialog_drc_base.h
+++ b/pcbnew/dialogs/dialog_drc_base.h
@@ -1,8 +1,8 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Feb 9 2018)
+// C++ code generated with wxFormBuilder (version Nov 30 2016)
// http://www.wxformbuilder.org/
//
-// PLEASE DO *NOT* EDIT THIS FILE!
+// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_DRC_BASE_H__
@@ -11,6 +11,7 @@
#include
#include
#include
+class DIALOG_SHIM;
class DRCLISTBOX;
#include "dialog_shim.h"
@@ -63,6 +64,7 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM
wxStaticText* m_MicroViaMinTitle;
wxStaticText* m_MicroViaMinUnit;
wxCheckBox* m_cbRefillZones;
+ wxCheckBox* m_cbReportAllTrackErrors;
wxCheckBox* m_cbCourtyardOverlap;
wxCheckBox* m_cbCourtyardMissing;
wxStaticText* m_staticTextRpt;
diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp
index f66e39ce70..c3d618ac06 100644
--- a/pcbnew/drc.cpp
+++ b/pcbnew/drc.cpp
@@ -135,6 +135,7 @@ DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
m_abortDRC = false;
m_drcInProgress = false;
m_refillZones = false; // Only fill zones if requested by user.
+ m_reportAllTrackErrors = false;
m_doCreateRptFile = false;
// m_rptFilename set to empty by its constructor
@@ -165,9 +166,9 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
if( !doTrackDrc( aRefSegm, aList, true ) )
{
- wxASSERT( m_currentMarker );
+ if( m_currentMarker )
+ m_pcbEditorFrame->SetMsgPanel( m_currentMarker );
- m_pcbEditorFrame->SetMsgPanel( m_currentMarker );
return BAD_DRC;
}
@@ -711,9 +712,11 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
if( !doTrackDrc( segm, segm->Next(), true ) )
{
- wxASSERT( m_currentMarker );
- addMarkerToPcb ( m_currentMarker );
- m_currentMarker = nullptr;
+ if( m_currentMarker )
+ {
+ addMarkerToPcb ( m_currentMarker );
+ m_currentMarker = nullptr;
+ }
}
}
diff --git a/pcbnew/drc.h b/pcbnew/drc.h
index 663f2a8de6..0c46aa8730 100644
--- a/pcbnew/drc.h
+++ b/pcbnew/drc.h
@@ -174,6 +174,7 @@ private:
bool m_doFootprintOverlapping;
bool m_doNoCourtyardDefined;
bool m_refillZones;
+ bool m_reportAllTrackErrors;
wxString m_rptFilename;
@@ -501,12 +502,14 @@ public:
* @param aKeepoutTest Tells whether to test keepout areas.
* @param aCourtyardTest Tells whether to test footprint courtyard overlap.
* @param aCourtyardMissingTest Tells whether to test missing courtyard definition in footprint.
+ * @param aReportAllTrackErrors Tells whether or not to stop checking track connections after the first error.
* @param aReportName A string telling the disk file report name entered.
* @param aSaveReport A boolean telling whether to generate disk file report.
*/
void SetSettings( bool aPad2PadTest, bool aUnconnectedTest,
bool aZonesTest, bool aKeepoutTest, bool aRefillZones,
bool aCourtyardTest, bool aCourtyardMissingTest,
+ bool aReportAllTrackErrors,
const wxString& aReportName, bool aSaveReport )
{
m_doPad2PadTest = aPad2PadTest;
@@ -518,6 +521,7 @@ public:
m_doFootprintOverlapping = aCourtyardTest;
m_doNoCourtyardDefined = aCourtyardMissingTest;
m_refillZones = aRefillZones;
+ m_reportAllTrackErrors = aReportAllTrackErrors;
}
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
index 4643065cf8..3f5d531550 100644
--- a/pcbnew/drc_clearance_test_functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -141,6 +141,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
LSET layerMask;
int net_code_ref;
wxPoint shape_pos;
+ bool success = true;
NETCLASSPTR netclass = aRefSeg->GetNetClass();
BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
@@ -165,30 +166,44 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
{
if( refvia->GetWidth() < dsnSettings.m_MicroViasMinSize )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_TOO_SMALL_MICROVIA, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_MICROVIA, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
+
if( refvia->GetDrillValue() < dsnSettings.m_MicroViasMinDrill )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_TOO_SMALL_MICROVIA_DRILL, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_MICROVIA_DRILL, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
else
{
if( refvia->GetWidth() < dsnSettings.m_ViasMinSize )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_TOO_SMALL_VIA, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_VIA, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
+
if( refvia->GetDrillValue() < dsnSettings.m_ViasMinDrill )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_TOO_SMALL_VIA_DRILL, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_VIA_DRILL, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -197,27 +212,36 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// and a default via hole can be bigger than some vias sizes
if( refvia->GetDrillValue() > refvia->GetWidth() )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_VIA_HOLE_BIGGER, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_VIA_HOLE_BIGGER, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
// test if the type of via is allowed due to design rules
if( ( refvia->GetViaType() == VIA_MICROVIA ) &&
( m_pcb->GetDesignSettings().m_MicroViasAllowed == false ) )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_MICRO_VIA_NOT_ALLOWED, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_MICRO_VIA_NOT_ALLOWED, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
// test if the type of via is allowed due to design rules
if( ( refvia->GetViaType() == VIA_BLIND_BURIED ) &&
( m_pcb->GetDesignSettings().m_BlindBuriedViaAllowed == false ) )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_BURIED_VIA_NOT_ALLOWED, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_BURIED_VIA_NOT_ALLOWED, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
// For microvias: test if they are blind vias and only between 2 layers
@@ -242,9 +266,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( err )
{
- m_currentMarker = fillMarker( refvia, NULL,
- DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( refvia, NULL,
+ DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -253,9 +280,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
{
if( aRefSeg->GetWidth() < dsnSettings.m_TrackMinWidth )
{
- m_currentMarker = fillMarker( aRefSeg, NULL,
- DRCE_TOO_SMALL_TRACK_WIDTH, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, NULL,
+ DRCE_TOO_SMALL_TRACK_WIDTH, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -325,9 +355,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(),
netclass->GetClearance() ) )
{
- m_currentMarker = fillMarker( aRefSeg, pad,
- DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, pad,
+ DRCE_TRACK_NEAR_THROUGH_HOLE, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
continue;
@@ -343,11 +376,15 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
shape_pos = pad->ShapePos();
m_padToTestPos = shape_pos - origin;
- if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) )
+ if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(),
+ aRefSeg->GetClearance( pad ) ) )
{
- m_currentMarker = fillMarker( aRefSeg, pad,
- DRCE_TRACK_NEAR_PAD, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, pad,
+ DRCE_TRACK_NEAR_PAD, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
}
@@ -361,6 +398,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// Test the reference segment with other track segments
wxPoint segStartPoint;
wxPoint segEndPoint;
+
for( track = aStart; track; track = track->Next() )
{
// No problem if segments have the same net code:
@@ -394,9 +432,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// Test distance between two vias, i.e. two circles, trivial case
if( EuclideanNorm( segStartPoint ) < w_dist )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_VIA_NEAR_VIA, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_VIA_NEAR_VIA, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
else // test via to segment
@@ -410,9 +451,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
{
- m_currentMarker = fillMarker( track, aRefSeg,
- DRCE_VIA_NEAR_TRACK, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( track, aRefSeg,
+ DRCE_VIA_NEAR_TRACK, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -432,9 +476,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
continue;
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_NEAR_VIA, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_NEAR_VIA, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
/* We have changed axis:
@@ -459,16 +506,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// Fine test : we consider the rounded shape of each end of the track segment:
if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_ENDS1, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS1, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_ENDS2, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS2, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -480,16 +533,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// Fine test : we consider the rounded shape of the ends
if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_ENDS3, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS3, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_ENDS4, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS4, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
@@ -500,9 +559,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// handled)
// X.............X
// O--REF--+
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACK_SEGMENTS_TOO_CLOSE, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACK_SEGMENTS_TOO_CLOSE, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
else if( segStartPoint.x == segEndPoint.x ) // perpendicular segments
@@ -514,25 +576,34 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( segStartPoint.y > segEndPoint.y )
std::swap( segStartPoint.y, segEndPoint.y );
- if( (segStartPoint.y < 0) && (segEndPoint.y > 0) )
+ if( ( segStartPoint.y < 0 ) && ( segEndPoint.y > 0 ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_TRACKS_CROSSING, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_TRACKS_CROSSING, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
// At this point the drc error is due to an end near a reference segm end
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_ENDS_PROBLEM1, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM1, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_ENDS_PROBLEM2, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM2, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
else // segments quelconques entre eux
@@ -558,9 +629,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkLine( segStartPoint, segEndPoint ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_ENDS_PROBLEM3, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM3, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
else // The drc error is due to the starting or the ending point of the reference segment
{
@@ -586,23 +660,29 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_ENDS_PROBLEM4, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM4, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) )
{
- m_currentMarker = fillMarker( aRefSeg, track,
- DRCE_ENDS_PROBLEM5, m_currentMarker );
- return false;
+ addMarkerToPcb( fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM5, nullptr ) );
+ success = false;
+
+ if( !m_reportAllTrackErrors )
+ return false;
}
}
}
}
}
- return true;
+ return success;
}