kicad/pcbnew/drc/drc.h

296 lines
12 KiB
C
Raw Normal View History

2007-11-27 01:34:35 +00:00
/*
* This program source code file is part of KiCad, a free EDA CAD application.
2007-11-27 01:34:35 +00:00
*
* Copyright (C) 2007-2016 Dick Hollenbeck, dick@softplc.com
2019-06-04 10:45:43 +00:00
* Copyright (C) 2017-2019 KiCad Developers, see change_log.txt for contributors.
2007-11-27 01:34:35 +00:00
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
2018-01-28 21:02:31 +00:00
#ifndef DRC_H
#define DRC_H
2007-11-27 01:34:35 +00:00
2020-05-18 00:20:16 +00:00
#include <board_commit.h>
2019-05-31 02:30:28 +00:00
#include <class_board.h>
#include <class_track.h>
#include <class_marker_pcb.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
2019-05-31 02:30:28 +00:00
#include <memory>
#include <vector>
#include <tools/pcb_tool_base.h>
2007-12-01 03:42:52 +00:00
/// DRC error codes:
enum PCB_DRC_CODE {
DRCE_FIRST = 1,
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected
DRCE_SHORTING_ITEMS, ///< items short two nets but are not a net tie
DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used
DRCE_CLEARANCE, ///< items are too close together
DRCE_TRACKS_CROSSING, ///< tracks are crossing
DRCE_COPPER_EDGE_CLEARANCE, ///< a copper item is too close to the board edge
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
DRCE_ZONE_HAS_EMPTY_NET, ///< copper area has a net but no pads in nets, which is suspicious
DRCE_DANGLING_VIA, ///< via which isn't connected to anything
DRCE_DANGLING_TRACK, ///< track with at least one end not connected to anything
DRCE_DRILLED_HOLES_TOO_CLOSE, ///< overlapping drilled holes break drill bits
DRCE_TRACK_WIDTH, ///< Track width is too small or too large
DRCE_TOO_SMALL_VIA, ///< Too small via size
DRCE_VIA_ANNULUS, ///< Via size and drill leave annulus too small or too large
DRCE_TOO_SMALL_DRILL, ///< Too small via or pad drill
DRCE_VIA_HOLE_BIGGER, ///< via's hole is bigger than its diameter
DRCE_PADSTACK, ///< something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size
DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill
DRCE_KEEPOUT, ///< A disallowed object is inside a keepout
DRCE_OVERLAPPING_FOOTPRINTS, ///< footprint courtyards overlap
DRCE_MISSING_COURTYARD, ///< footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, ///< footprint has a courtyard but malformed
///< (not convertible to a closed polygon with holes)
DRCE_PTH_IN_COURTYARD,
DRCE_NPTH_IN_COURTYARD,
DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
DRCE_INVALID_OUTLINE, ///< invalid board outline
DRCE_MISSING_FOOTPRINT, ///< footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, ///< more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_NET_CONFLICT, ///< pad net doesn't match netlist
DRCE_UNRESOLVED_VARIABLE,
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE
};
2007-11-27 01:34:35 +00:00
class PCB_EDIT_FRAME;
class DIALOG_DRC;
class BOARD_ITEM;
class BOARD;
class D_PAD;
class ZONE_CONTAINER;
class TRACK;
class MARKER_PCB;
class DRC_ITEM;
class NETCLASS;
class EDA_TEXT;
class DRAWSEGMENT;
class NETLIST;
class wxWindow;
class wxString;
class wxTextCtrl;
2007-11-27 01:34:35 +00:00
2007-12-03 05:14:51 +00:00
2007-11-27 01:34:35 +00:00
/**
* Design Rule Checker object that performs all the DRC tests. The output of
2007-12-01 03:42:52 +00:00
* the checking goes to the BOARD file in the form of two MARKER lists. Those
* two lists are displayable in the drc dialog box. And they can optionally
* be sent to a text file on disk.
* This class is given access to the windows and the BOARD
* that it needs via its constructor or public access functions.
*/
class DRC : public PCB_TOOL_BASE
2007-11-27 01:34:35 +00:00
{
friend class DIALOG_DRC;
public:
DRC();
~DRC();
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
2007-12-01 03:42:52 +00:00
private:
bool m_doUnconnectedTest; // enable unconnected tests
bool m_testTracksAgainstZones; // enable zone to items clearance tests
bool m_doKeepoutTest; // enable keepout areas to items clearance tests
bool m_refillZones; // refill zones if requested (by user).
bool m_reportAllTrackErrors; // Report all tracks errors (or only 4 first errors)
bool m_testFootprints; // Test footprints against schematic
PCB_EDIT_FRAME* m_editFrame; // The pcb frame editor which owns the board
BOARD* m_pcb;
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
bool m_board_outline_valid;
DIALOG_DRC* m_drcDialog;
2020-08-11 13:33:16 +00:00
std::vector<std::shared_ptr<DRC_ITEM> > m_unconnected; // list of unconnected pads
std::vector<std::shared_ptr<DRC_ITEM> > m_footprints; // list of footprint warnings
bool m_drcRun; // indicates DRC has been run at least once
bool m_footprintsTested; // indicates footprints were tested in last run
std::vector<DRC_RULE*> m_rules;
// Temp variables for performance during a single DRC run
//
2020-05-18 00:20:16 +00:00
// wxString's c'tor is surprisingly expensive, and in the world of DRC everything matters
//
wxString m_msg;
wxString m_clearanceSource;
int m_largestClearance;
2020-05-18 00:20:16 +00:00
private:
///> Sets up handlers for various events.
void setTransitions() override;
/**
* Update needed pointers from the one pointer which is known not to change.
2007-12-01 03:42:52 +00:00
*/
void updatePointers();
EDA_UNITS userUnits() const { return m_editFrame->GetUserUnits(); }
/**
* Adds a DRC marker to the PCB through the COMMIT mechanism.
*/
2020-05-18 00:20:16 +00:00
void addMarkerToPcb( BOARD_COMMIT& aCommit, MARKER_PCB* aMarker );
//-----<categorical group tests>-----------------------------------------
/**
* Perform the DRC on all tracks.
*
* This test can take a while, a progress bar can be displayed
* @param aActiveWindow = the active window ued as parent for the progress bar
* @param aShowProgressBar = true to show a progress bar
* (Note: it is shown only if there are many tracks)
*/
2020-05-18 00:20:16 +00:00
void testTracks( BOARD_COMMIT& aCommit, wxWindow * aActiveWindow, bool aShowProgressBar );
void testPadClearances( BOARD_COMMIT& aCommit );
void testUnconnected();
2007-12-01 03:42:52 +00:00
2020-05-18 00:20:16 +00:00
void testZones( BOARD_COMMIT& aCommit );
2020-05-18 00:20:16 +00:00
void testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aDrawing );
2020-05-18 00:20:16 +00:00
void testCopperTextAndGraphics( BOARD_COMMIT& aCommit );
// Tests for items placed on disabled layers (causing false connections).
2020-05-18 00:20:16 +00:00
void testDisabledLayers( BOARD_COMMIT& aCommit );
/**
* Test that the board outline is contiguous and composed of valid elements
*/
2020-05-18 00:20:16 +00:00
void testOutline( BOARD_COMMIT& aCommit );
//-----<single "item" tests>-----------------------------------------
2007-12-01 03:42:52 +00:00
/**
* Test the clearance between aRefPad and other pads.
*
2007-12-01 03:42:52 +00:00
* The pad list must be sorted by x coordinate.
*
* @param aRefPad is the pad to test
* @param aStart is the first pad of the list to test against aRefPad
* @param aEnd is the end of the list and is not included
* @param x_limit is used to stop the test
* (i.e. when the current pad pos X in list exceeds this limit, because the list
* is sorted by X coordinate)
2007-12-01 03:42:52 +00:00
*/
2020-05-18 00:20:16 +00:00
bool doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd,
int x_limit );
2007-12-01 03:42:52 +00:00
/**
* Test the current segment.
*
2007-12-01 03:42:52 +00:00
* @param aRefSeg The segment to test
2019-05-31 02:30:28 +00:00
* @param aStartIt the iterator to the first track to test
* @param aEndIt the marker for the iterator end
* @param aTestZones true if should do copper zones test. This can be very time consumming
* @param aLayer sets the layer to test against
* @return bool - true if no problems, else false and m_currentMarker is
2007-12-01 03:42:52 +00:00
* filled in with the problem information.
*/
2020-05-18 00:20:16 +00:00
void doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aStartIt,
TRACKS::iterator aEndIt, bool aTestZones, PCB_LAYER_ID aLayer );
/**
* Test a single via for DRC errors
*
* @param aCommit The board commit to add DRC errors
* @param aRefVia The via to test against design settings
*/
void doSingleViaDRC( BOARD_COMMIT& aCommit, VIA* aRefVia );
/**
* Test a single track segment for DRC errors
*
* @param aCommit The board commit to add DRC errors
* @param aRefSeg The track to test against design settings
*/
void doSingleTrackDRC( BOARD_COMMIT& aCommit, TRACK* aRefSeg );
2007-11-27 01:34:35 +00:00
public:
/**
* Load the DRC rules. Must be called after the netclasses have been read.
*/
bool LoadRules();
2020-05-18 00:20:16 +00:00
/**
* Fetches a reasonable point for marking a violoation between two non-point objects.
*/
Clean up arc/circle polygonization. 1) For a while now we've been using a calculated seg count from a given maxError, and a correction factor to push the radius out so that all the error is outside the arc/circle. However, the second calculation (which pre-dates the first) is pretty much just the inverse of the first (and yields nothing more than maxError back). This is particularly sub-optimal given the cost of trig functions. 2) There are a lot of old optimizations to reduce segcounts in certain situations, someting that our error-based calculation compensates for anyway. (Smaller radii need fewer segments to meet the maxError condition.) But perhaps more importantly we now surface maxError in the UI and we don't really want to call it "Max deviation except when it's not". 3) We were also clamping the segCount twice: once in the calculation routine and once in most of it's callers. Furthermore, the caller clamping was inconsistent (both in being done and in the clamping value). We now clamp only in the calculation routine. 4) There's no reason to use the correction factors in the 3Dviewer; it's just a visualization and whether the polygonization error is inside or outside the shape isn't really material. 5) The arc-correction-disabling stuff (used for solder mask layer) was somewhat fragile in that it depended on the caller to turn it back on afterwards. It's now only exposed as a RAII object which automatically cleans up when it goes out of scope. 6) There were also bugs in a couple of the polygonization routines where we'd accumulate round-off error in adding up the segments and end up with an overly long last segment (which of course would voilate the error max). This was the cause of the linked bug and also some issues with vias that we had fudged in the past with extra clearance. Fixes https://gitlab.com/kicad/code/kicad/issues/5567
2020-09-10 23:05:20 +00:00
static wxPoint GetLocation( PCB_LAYER_ID aLayer, TRACK* aTrack, ZONE_CONTAINER* aZone );
static wxPoint GetLocation( TRACK* aTrack, const SEG& aSeg );
2020-05-18 00:20:16 +00:00
2007-12-01 03:42:52 +00:00
/**
* Open a dialog and prompts the user, then if a test run button is
2007-12-03 05:14:51 +00:00
* clicked, runs the test(s) and creates the MARKERS. The dialog is only
* created if it is not already in existence.
*
* @param aParent is the parent window for wxWidgets. Usually the PCB editor frame
2018-04-08 10:28:59 +00:00
* but can be another dialog
* if aParent == NULL (default), the parent will be the PCB editor frame
* and the dialog will be not modal (just float on parent
* if aParent is specified, the dialog will be modal.
2018-04-08 10:28:59 +00:00
* The modal mode is mandatory if the dialog is created from another dialog, not
* from the PCB editor frame
2007-12-01 03:42:52 +00:00
*/
void ShowDRCDialog( wxWindow* aParent );
int ShowDRCDialog( const TOOL_EVENT& aEvent );
2007-12-03 05:14:51 +00:00
/**
* Check to see if the DRC dialog is currently shown
*
* @return true if the dialog is shown
*/
bool IsDRCDialogShown();
2007-12-03 05:14:51 +00:00
/**
* Deletes this ui dialog box and zeros out its pointer to remember
2007-12-04 18:23:38 +00:00
* the state of the dialog's existence.
*
2007-12-04 18:23:38 +00:00
* @param aReason Indication of which button was clicked to cause the destruction.
* if aReason == wxID_OK, design parameters values which can be entered from the dialog
* will bbe saved in design parameters list
2007-12-03 05:14:51 +00:00
*/
void DestroyDRCDialog( int aReason );
2007-12-01 05:37:44 +00:00
/**
* Run all the tests specified with a previous call to
2007-12-01 05:37:44 +00:00
* SetSettings()
* @param aMessages = a wxTextControl where to display some activity messages. Can be NULL
2007-12-01 05:37:44 +00:00
*/
void RunTests( wxTextCtrl* aMessages = NULL );
2007-11-27 01:34:35 +00:00
};
2018-01-28 21:02:31 +00:00
#endif // DRC_H