You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
21 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
15 years ago
18 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /**
  2. * @file drc_stuff.h
  3. */
  4. /*
  5. * This program source code file is part of KiCad, a free EDA CAD application.
  6. *
  7. * Copyright (C) 2007-2016 Dick Hollenbeck, dick@softplc.com
  8. * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #ifndef _DRC_STUFF_H
  28. #define _DRC_STUFF_H
  29. #include <vector>
  30. #include <memory>
  31. #define OK_DRC 0
  32. #define BAD_DRC 1
  33. /// DRC error codes:
  34. #define DRCE_ 1 // not used yet
  35. #define DRCE_UNCONNECTED_PADS 2 ///< pads are unconnected
  36. #define DRCE_TRACK_NEAR_THROUGH_HOLE 3 ///< thru hole is too close to track
  37. #define DRCE_TRACK_NEAR_PAD 4 ///< pad too close to track
  38. #define DRCE_TRACK_NEAR_VIA 5 ///< track too close to via
  39. #define DRCE_VIA_NEAR_VIA 6 ///< via too close to via
  40. #define DRCE_VIA_NEAR_TRACK 7 ///< via too close to track
  41. #define DRCE_TRACK_ENDS1 8 ///< 2 parallel track segments too close: fine start point test
  42. #define DRCE_TRACK_ENDS2 9 ///< 2 parallel track segments too close: fine start point test
  43. #define DRCE_TRACK_ENDS3 10 ///< 2 parallel track segments too close: fine end point test
  44. #define DRCE_TRACK_ENDS4 11 ///< 2 parallel track segments too close: fine end point test
  45. #define DRCE_TRACK_SEGMENTS_TOO_CLOSE 12 ///< 2 parallel track segments too close: segm ends between segref ends
  46. #define DRCE_TRACKS_CROSSING 13 ///< tracks are crossing
  47. #define DRCE_ENDS_PROBLEM1 14 ///< track ends are too close
  48. #define DRCE_ENDS_PROBLEM2 15 ///< track ends are too close
  49. #define DRCE_ENDS_PROBLEM3 16 ///< track ends are too close
  50. #define DRCE_ENDS_PROBLEM4 17 ///< track ends are too close
  51. #define DRCE_ENDS_PROBLEM5 18 ///< track ends are too close
  52. #define DRCE_PAD_NEAR_PAD1 19 ///< pad too close to pad
  53. #define DRCE_VIA_HOLE_BIGGER 20 ///< via's hole is bigger than its diameter
  54. #define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent)
  55. #define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
  56. #define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close
  57. #define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE 24 ///< copper area has a net but no pads in nets, which is suspicious
  58. #define DRCE_HOLE_NEAR_PAD 25 ///< hole too close to pad
  59. #define DRCE_HOLE_NEAR_TRACK 26 ///< hole too close to track
  60. #define DRCE_TOO_SMALL_TRACK_WIDTH 27 ///< Too small track width
  61. #define DRCE_TOO_SMALL_VIA 28 ///< Too small via size
  62. #define DRCE_TOO_SMALL_MICROVIA 29 ///< Too small micro via size
  63. #define DRCE_TOO_SMALL_VIA_DRILL 30 ///< Too small via drill
  64. #define DRCE_TOO_SMALL_MICROVIA_DRILL 31 ///< Too small micro via drill
  65. #define DRCE_NETCLASS_TRACKWIDTH 32 ///< netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
  66. #define DRCE_NETCLASS_CLEARANCE 33 ///< netclass has Clearance < board.m_designSettings->m_TrackClearance
  67. #define DRCE_NETCLASS_VIASIZE 34 ///< netclass has ViaSize < board.m_designSettings->m_ViasMinSize
  68. #define DRCE_NETCLASS_VIADRILLSIZE 35 ///< netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
  69. #define DRCE_NETCLASS_uVIASIZE 36 ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
  70. #define DRCE_NETCLASS_uVIADRILLSIZE 37 ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
  71. #define DRCE_VIA_INSIDE_KEEPOUT 38 ///< Via in inside a keepout area
  72. #define DRCE_TRACK_INSIDE_KEEPOUT 39 ///< Track in inside a keepout area
  73. #define DRCE_PAD_INSIDE_KEEPOUT 40 ///< Pad in inside a keepout area
  74. #define DRCE_VIA_INSIDE_TEXT 41 ///< Via in inside a text area
  75. #define DRCE_TRACK_INSIDE_TEXT 42 ///< Track in inside a text area
  76. #define DRCE_PAD_INSIDE_TEXT 43 ///< Pad in inside a text area
  77. class EDA_DRAW_PANEL;
  78. class PCB_EDIT_FRAME;
  79. class DIALOG_DRC_CONTROL;
  80. class BOARD_ITEM;
  81. class BOARD;
  82. class D_PAD;
  83. class ZONE_CONTAINER;
  84. class TRACK;
  85. class MARKER_PCB;
  86. class DRC_ITEM;
  87. class NETCLASS;
  88. /**
  89. * Class DRC_ITEM_LIST
  90. * provides an abstract interface of a DRC_ITEM* list manager. The details
  91. * of the actual list architecture are hidden from the caller. Any class
  92. * that implements this interface can then be used by a DRCLISTBOX class without
  93. * it knowing the actual architecture of the list.
  94. */
  95. class DRC_ITEM_LIST
  96. {
  97. public:
  98. /**
  99. * Function DeleteAllItems
  100. * removes and deletes all the items in the list.
  101. */
  102. virtual void DeleteAllItems() = 0;
  103. /**
  104. * Function GetItem
  105. * retrieves a DRC_ITEM by pointer. The actual item remains owned by the
  106. * list container.
  107. * @param aIndex The 0 based index into the list of the desired item.
  108. * @return const DRC_ITEM* - the desired item or NULL if aIndex is out of range.
  109. */
  110. virtual const DRC_ITEM* GetItem( int aIndex ) = 0;
  111. /**
  112. * Function DeleteAllItems
  113. * removes and deletes desired item from the list.
  114. * @param aIndex The 0 based index into the list of the desired item which
  115. * is to be deleted.
  116. */
  117. virtual void DeleteItem( int aIndex ) = 0;
  118. /**
  119. * Function GetCount
  120. * returns the number of items in the list.
  121. */
  122. virtual int GetCount() = 0;
  123. virtual ~DRC_ITEM_LIST() { }
  124. };
  125. typedef std::vector<DRC_ITEM*> DRC_LIST;
  126. /**
  127. * Class DRC
  128. * is the Design Rule Checker, and performs all the DRC tests. The output of
  129. * the checking goes to the BOARD file in the form of two MARKER lists. Those
  130. * two lists are displayable in the drc dialog box. And they can optionally
  131. * be sent to a text file on disk.
  132. * This class is given access to the windows and the BOARD
  133. * that it needs via its constructor or public access functions.
  134. */
  135. class DRC
  136. {
  137. friend class DIALOG_DRC_CONTROL;
  138. private:
  139. // protected or private functions() are lowercase first character.
  140. bool m_doPad2PadTest;
  141. bool m_doUnconnectedTest;
  142. bool m_doZonesTest;
  143. bool m_doKeepoutTest;
  144. bool m_doCreateRptFile;
  145. wxString m_rptFilename;
  146. MARKER_PCB* m_currentMarker;
  147. bool m_abortDRC;
  148. bool m_drcInProgress;
  149. /* In DRC functions, many calculations are using coordinates relative
  150. * to the position of the segment under test (segm to segm DRC, segm to pad DRC
  151. * Next variables store coordinates relative to the start point of this segment
  152. */
  153. wxPoint m_padToTestPos; // Position of the pad to compare in drc test segm to pad or pad to pad
  154. wxPoint m_segmEnd; // End point of the reference segment (start point = (0,0) )
  155. /* Some functions are comparing the ref segm to pads or others segments using
  156. * coordinates relative to the ref segment considered as the X axis
  157. * so we store the ref segment length (the end point relative to these axis)
  158. * and the segment orientation (used to rotate other coordinates)
  159. */
  160. double m_segmAngle; // Ref segm orientation in 0,1 degre
  161. int m_segmLength; // length of the reference segment
  162. /* variables used in checkLine to test DRC segm to segm:
  163. * define the area relative to the ref segment that does not contains any other segment
  164. */
  165. int m_xcliplo;
  166. int m_ycliplo;
  167. int m_xcliphi;
  168. int m_ycliphi;
  169. PCB_EDIT_FRAME* m_pcbEditorFrame; ///< The pcb frame editor which owns the board
  170. BOARD* m_pcb;
  171. DIALOG_DRC_CONTROL* m_drcDialog;
  172. DRC_LIST m_unconnected; ///< list of unconnected pads, as DRC_ITEMs
  173. /**
  174. * Function updatePointers
  175. * is a private helper function used to update needed pointers from the
  176. * one pointer which is known not to change, m_pcbEditorFrame.
  177. */
  178. void updatePointers();
  179. /**
  180. * Function fillMarker
  181. * optionally creates a marker and fills it in with information,
  182. * but does not add it to the BOARD. Use this to report any kind of
  183. * DRC problem, or unconnected pad problem.
  184. *
  185. * @param aTrack The reference track.
  186. * @param aItem Another item on the BOARD, such as a VIA, SEGZONE,
  187. * or TRACK.
  188. * @param aErrorCode A categorizing identifier for the particular type
  189. * of error that is being reported.
  190. * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to
  191. * first be allocated, then filled.
  192. */
  193. MARKER_PCB* fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe );
  194. MARKER_PCB* fillMarker( D_PAD* aPad, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe );
  195. MARKER_PCB* fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe );
  196. /**
  197. * Function fillMarker
  198. * optionally creates a marker and fills it in with information,
  199. * but does not add it to the BOARD. Use this to report any kind of
  200. * DRC problem, or unconnected pad problem.
  201. *
  202. * @param aArea The zone to test
  203. * @param aPos position of error
  204. * @param aErrorCode Type of error
  205. * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to
  206. * first be allocated, then filled.
  207. */
  208. MARKER_PCB* fillMarker( const ZONE_CONTAINER* aArea,
  209. const wxPoint& aPos,
  210. int aErrorCode,
  211. MARKER_PCB* fillMe );
  212. /**
  213. * Function fillMarker
  214. * fills a MARKER which will report on a generic problem with the board which is
  215. * not geographically locatable.
  216. */
  217. MARKER_PCB* fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe );
  218. //-----<categorical group tests>-----------------------------------------
  219. /**
  220. * Function testNetClasses
  221. * goes through each NETCLASS and verifies that its clearance, via size,
  222. * track width, and track clearance are larger than those in board.m_designSettings.
  223. * This is necessary because the actual DRC checks are run against the NETCLASS
  224. * limits, so in order enforce global limits, we first check the NETCLASSes against
  225. * the global limits.
  226. * @return bool - true if succes, else false but only after
  227. * reporting _all_ NETCLASS violations.
  228. */
  229. bool testNetClasses();
  230. /**
  231. * Function testTracks
  232. * performs the DRC on all tracks.
  233. * because this test can take a while, a progress bar can be displayed
  234. * @param aActiveWindow = the active window ued as parent for the progress bar
  235. * @param aShowProgressBar = true to show a progress bar
  236. * (Note: it is shown only if there are many tracks)
  237. */
  238. void testTracks( wxWindow * aActiveWindow, bool aShowProgressBar );
  239. void testPad2Pad();
  240. void testUnconnected();
  241. void testZones();
  242. void testKeepoutAreas();
  243. void testTexts();
  244. //-----<single "item" tests>-----------------------------------------
  245. bool doNetClass( std::shared_ptr<NETCLASS> aNetClass, wxString& msg );
  246. /**
  247. * Function doPadToPadsDrc
  248. * tests the clearance between aRefPad and other pads.
  249. * The pad list must be sorted by x coordinate.
  250. * @param aRefPad The pad to test
  251. * @param aStart The start of the pad list to test against
  252. * @param aEnd Marks the end of the list and is not included
  253. * @param x_limit is used to stop the test (when the any pad's X coord exceeds this)
  254. */
  255. bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
  256. /**
  257. * Function DoTrackDrc
  258. * tests the current segment.
  259. * @param aRefSeg The segment to test
  260. * @param aStart The head of a list of tracks to test against (usually BOARD::m_Track)
  261. * @param doPads true if should do pads test
  262. * @return bool - true if no poblems, else false and m_currentMarker is
  263. * filled in with the problem information.
  264. */
  265. bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool doPads = true );
  266. /**
  267. * Function doTrackKeepoutDrc
  268. * tests the current segment or via.
  269. * @param aRefSeg The segment to test
  270. * @return bool - true if no poblems, else false and m_currentMarker is
  271. * filled in with the problem information.
  272. */
  273. bool doTrackKeepoutDrc( TRACK* aRefSeg );
  274. /**
  275. * Function doEdgeZoneDrc
  276. * tests a segment in ZONE_CONTAINER * aArea:
  277. * Test Edge inside other areas
  278. * Test Edge too close other areas
  279. * @param aArea The current area.
  280. * @param aCornerIndex The first corner of the segment to test.
  281. * @return bool - false if DRC error or true if OK
  282. */
  283. bool doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex );
  284. //-----<single tests>----------------------------------------------
  285. /**
  286. * Function checkClearancePadToPad
  287. * @param aRefPad The reference pad to check
  288. * @param aPad Another pad to check against
  289. * @return bool - true if clearance between aRefPad and aPad is >= dist_min, else false
  290. */
  291. bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad );
  292. /**
  293. * Function checkClearanceSegmToPad
  294. * check the distance from a pad to segment. This function uses several
  295. * instance variable not passed in:
  296. * m_segmLength = length of the segment being tested
  297. * m_segmAngle = angle of the segment with the X axis;
  298. * m_segmEnd = end coordinate of the segment
  299. * m_padToTestPos = position of pad relative to the origin of segment
  300. * @param aPad Is the pad involved in the check
  301. * @param aSegmentWidth width of the segment to test
  302. * @param aMinDist Is the minimum clearance needed
  303. *
  304. * @return true distance >= dist_min,
  305. * false if distance < dist_min
  306. */
  307. bool checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist );
  308. /**
  309. * Helper function checkMarginToCircle
  310. * Check the distance from a point to a segment.
  311. * The segment is expected starting at 0,0, and on the X axis
  312. * (used to test DRC between a segment and a round pad, via or round end of a track
  313. * @param aCentre The coordinate of the circle's center
  314. * @param aRadius A "keep out" radius centered over the circle
  315. * @param aLength The length of the segment (i.e. coordinate of end, because it is on
  316. * the X axis)
  317. * @return bool - true if distance >= radius, else
  318. * false when distance < aRadius
  319. */
  320. static bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
  321. /**
  322. * Function checkLine
  323. * (helper function used in drc calculations to see if one track is in contact with
  324. * another track).
  325. * Test if a line intersects a bounding box (a rectangle)
  326. * The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
  327. * return true if the line from aSegStart to aSegEnd is outside the bounding box
  328. */
  329. bool checkLine( wxPoint aSegStart, wxPoint aSegEnd );
  330. //-----</single tests>---------------------------------------------
  331. public:
  332. DRC( PCB_EDIT_FRAME* aPcbWindow );
  333. ~DRC();
  334. /**
  335. * Function Drc
  336. * tests the current segment and returns the result and displays the error
  337. * in the status panel only if one exists.
  338. * @param aRefSeg The current segment to test.
  339. * @param aList The track list to test (usually m_Pcb->m_Track)
  340. * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
  341. */
  342. int Drc( TRACK* aRefSeg, TRACK* aList );
  343. /**
  344. * Function Drc
  345. * tests the outline segment starting at CornerIndex and returns the result and displays
  346. * the error in the status panel only if one exists.
  347. * Test Edge inside other areas
  348. * Test Edge too close other areas
  349. * @param aArea The areaparent which contains the corner.
  350. * @param aCornerIndex The starting point of the segment to test.
  351. * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
  352. */
  353. int Drc( ZONE_CONTAINER* aArea, int aCornerIndex );
  354. /**
  355. * Function DrcBlind
  356. * tests the current segment and returns the result. Any error is not
  357. * displayed in the status panel.
  358. * @param aRefSeg The current segment to test.
  359. * @param aList The track list to test (usually m_Pcb->m_Track)
  360. * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
  361. */
  362. int DrcBlind( TRACK* aRefSeg, TRACK* aList )
  363. {
  364. updatePointers();
  365. if( ! doTrackDrc( aRefSeg, aList ) )
  366. return BAD_DRC;
  367. return doTrackKeepoutDrc( aRefSeg ) ? OK_DRC : BAD_DRC;
  368. }
  369. /**
  370. * Function ShowDRCDialog
  371. * opens a dialog and prompts the user, then if a test run button is
  372. * clicked, runs the test(s) and creates the MARKERS. The dialog is only
  373. * created if it is not already in existence.
  374. * @param aParent is the parent window for wxWidgets. Usually the PCB editor frame
  375. * but can be an other dialog
  376. * if aParent == NULL (default), the parent will be the PCB editor frame
  377. * and the dialog will be not modal (just float on parent
  378. * if aParent is specified, the dialog will be modal.
  379. * The modal mode is mandatory if the dialog is created from an other dialog, not
  380. * from the PCB editor frame
  381. */
  382. void ShowDRCDialog( wxWindow* aParent = NULL );
  383. /**
  384. * Function DestroyDRCDialog
  385. * deletes this ui dialog box and zeros out its pointer to remember
  386. * the state of the dialog's existence.
  387. * @param aReason Indication of which button was clicked to cause the destruction.
  388. * if aReason == wxID_OK, design parameters values which can be entered from the dialog will bbe saved
  389. * in design parameters list
  390. */
  391. void DestroyDRCDialog( int aReason );
  392. /**
  393. * Function SetSettings
  394. * saves all the UI or test settings and may be called before running the tests.
  395. * @param aPad2PadTest Tells whether to test pad to pad distances.
  396. * @param aUnconnectedTest Tells whether to list unconnected pads.
  397. * @param aZonesTest Tells whether to test zones.
  398. * @param aKeepoutTest Tells whether to test keepout areas.
  399. * @param aReportName A string telling the disk file report name entered.
  400. * @param aSaveReport A boolean telling whether to generate disk file report.
  401. */
  402. void SetSettings( bool aPad2PadTest, bool aUnconnectedTest,
  403. bool aZonesTest, bool aKeepoutTest,
  404. const wxString& aReportName, bool aSaveReport )
  405. {
  406. m_doPad2PadTest = aPad2PadTest;
  407. m_doUnconnectedTest = aUnconnectedTest;
  408. m_doZonesTest = aZonesTest;
  409. m_doKeepoutTest = aKeepoutTest;
  410. m_rptFilename = aReportName;
  411. m_doCreateRptFile = aSaveReport;
  412. }
  413. /**
  414. * Function RunTests
  415. * will actually run all the tests specified with a previous call to
  416. * SetSettings()
  417. * @param aMessages = a wxTextControl where to display some activity messages. Can be NULL
  418. */
  419. void RunTests( wxTextCtrl* aMessages = NULL );
  420. /**
  421. * Function ListUnconnectedPad
  422. * gathers a list of all the unconnected pads and shows them in the
  423. * dialog, and optionally prints a report of such.
  424. */
  425. void ListUnconnectedPads();
  426. /**
  427. * @return a pointer to the current marker (last created marker
  428. */
  429. MARKER_PCB* GetCurrentMarker( )
  430. {
  431. return m_currentMarker;
  432. }
  433. };
  434. #endif // _DRC_STUFF_H
  435. //EOF