← Back to team overview

kicad-developers team mailing list archive

[PATCH] DRC: Add an optional mode to report all track errors

 

I'd like some eyes on this before I push it, since it's a rather
significant change.

I have added a (disabled by default) option to report all DRC issues on
each tested track.  The current behavior is to stop at the first error,
which means that the only way to get a full DRC report is to fix errors one
by one.

See: https://bugs.launchpad.net/kicad/+bug/1754442

I tried to make this change as minimal as possible because I know the DRC
code is a target for refactoring after 5.0.  The performance of the current
system is not great, and I can think of several optimizations that would
help a lot, but I think they would touch too much to be a part of 5.0.
Fortunately there is progress reporting on this step, so at least users
will have feedback.

-Jon
From af6e43b9f0ca47b1d52adfd3b1ae227e5b0a9a37 Mon Sep 17 00:00:00 2001
From: Jon Evans <jon@xxxxxxxxxxxxx>
Date: Mon, 19 Mar 2018 22:54:16 -0400
Subject: [PATCH] DRC: Add an optional mode to report all track errors

Fixes: lp:1754442
* https://bugs.launchpad.net/kicad/+bug/1754442
---
 pcbnew/dialogs/dialog_drc.cpp           |   2 +
 pcbnew/dialogs/dialog_drc_base.cpp      |   9 +-
 pcbnew/dialogs/dialog_drc_base.fbp      |  89 +++++++++++-
 pcbnew/dialogs/dialog_drc_base.h        |   6 +-
 pcbnew/drc.cpp                          |  13 +-
 pcbnew/drc.h                            |   4 +
 pcbnew/drc_clearance_test_functions.cpp | 236 +++++++++++++++++++++-----------
 7 files changed, 271 insertions(+), 88 deletions(-)

diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp
index 06718f41d..370c14979 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 5a746642c..9db5e0836 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 abb6bc657..6a0b60392 100644
--- a/pcbnew/dialogs/dialog_drc_base.fbp
+++ b/pcbnew/dialogs/dialog_drc_base.fbp
@@ -14,7 +14,6 @@
         <property name="file">dialog_drc_base</property>
         <property name="first_id">1000</property>
         <property name="help_provider">none</property>
-        <property name="indent_with_spaces"></property>
         <property name="internationalize">1</property>
         <property name="name">dialog_drc_base</property>
         <property name="namespace"></property>
@@ -1284,6 +1283,94 @@
                                                         <event name="OnUpdateUI"></event>
                                                     </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">Report all errors for tracks (slower)</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_cbReportAllTrackErrors</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">If selected, all DRC violations for tracks will be reported.  This can be slow for complicated designs.&#x0A;&#x0A;If unselected, only the first DRC violation will be reported for each track connection.</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>
+                                                        <event name="OnChar"></event>
+                                                        <event name="OnCheckBox"></event>
+                                                        <event name="OnEnterWindow"></event>
+                                                        <event name="OnEraseBackground"></event>
+                                                        <event name="OnKeyDown"></event>
+                                                        <event name="OnKeyUp"></event>
+                                                        <event name="OnKillFocus"></event>
+                                                        <event name="OnLeaveWindow"></event>
+                                                        <event name="OnLeftDClick"></event>
+                                                        <event name="OnLeftDown"></event>
+                                                        <event name="OnLeftUp"></event>
+                                                        <event name="OnMiddleDClick"></event>
+                                                        <event name="OnMiddleDown"></event>
+                                                        <event name="OnMiddleUp"></event>
+                                                        <event name="OnMotion"></event>
+                                                        <event name="OnMouseEvents"></event>
+                                                        <event name="OnMouseWheel"></event>
+                                                        <event name="OnPaint"></event>
+                                                        <event name="OnRightDClick"></event>
+                                                        <event name="OnRightDown"></event>
+                                                        <event name="OnRightUp"></event>
+                                                        <event name="OnSetFocus"></event>
+                                                        <event name="OnSize"></event>
+                                                        <event name="OnUpdateUI"></event>
+                                                    </object>
+                                                </object>
                                                 <object class="sizeritem" expanded="1">
                                                     <property name="border">5</property>
                                                     <property name="flag">wxLEFT|wxRIGHT</property>
diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h
index 871d8551b..f5b7ce2c2 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 <wx/artprov.h>
 #include <wx/xrc/xmlres.h>
 #include <wx/intl.h>
+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 f66e39ce7..c3d618ac0 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 663f2a8de..0c46aa873 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 2288cd30d..f54bc685b 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;
 }
 
 
-- 
2.14.1


Follow ups