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.

346 lines
13 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2017 Jean_Pierre Charras <jp.charras at wanadoo.fr>
  5. * Copyright (C) 1992-2017 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file gendrill_file_writer_base.h
  26. * @brief helper classes to handle hole info for drill files generators.
  27. */
  28. #ifndef GENDRILL_FILE_WRITER_BASE_H
  29. #define GENDRILL_FILE_WRITER_BASE_H
  30. #include <vector>
  31. class BOARD_ITEM;
  32. // the DRILL_TOOL class handles tools used in the excellon drill file:
  33. class DRILL_TOOL
  34. {
  35. public:
  36. int m_Diameter; // the diameter of the used tool (for oblong, the smaller size)
  37. int m_TotalCount; // how many times it is used (round and oblong)
  38. int m_OvalCount; // oblong count
  39. bool m_Hole_NotPlated; // Is the hole plated or not plated
  40. public:
  41. DRILL_TOOL( int aDiameter, bool a_NotPlated )
  42. {
  43. m_TotalCount = 0;
  44. m_OvalCount = 0;
  45. m_Diameter = aDiameter;
  46. m_Hole_NotPlated = a_NotPlated;
  47. }
  48. };
  49. /* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers)
  50. * For buried or micro vias, the hole is not on all layers.
  51. * So we must generate a drill file for each layer pair (adjacent layers)
  52. * Not plated holes are always through holes, and must be output on a specific drill file
  53. * because they are drilled after the Pcb process is finished.
  54. */
  55. class HOLE_INFO
  56. {
  57. public:
  58. BOARD_ITEM* m_ItemParent; // The pad or via parent of this hole
  59. int m_Hole_Diameter; // hole value, and for oblong: min(hole size x, hole size y)
  60. int m_Tool_Reference; // Tool reference for this hole = 1 ... n (values <=0 must not be used)
  61. wxSize m_Hole_Size; // hole size for oblong holes
  62. double m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes
  63. int m_Hole_Shape; // hole shape: round (0) or oval (1)
  64. wxPoint m_Hole_Pos; // hole position
  65. PCB_LAYER_ID m_Hole_Bottom_Layer; // hole ending layer (usually back layer)
  66. PCB_LAYER_ID m_Hole_Top_Layer; // hole starting layer (usually front layer):
  67. // m_Hole_Top_Layer < m_Hole_Bottom_Layer
  68. bool m_Hole_NotPlated; // hole not plated. Must be in a specific drill file or section
  69. public:
  70. HOLE_INFO()
  71. {
  72. m_ItemParent = nullptr;
  73. m_Hole_NotPlated = false;
  74. m_Hole_Diameter = 0;
  75. m_Tool_Reference = 0;
  76. m_Hole_Orient = 0.0;
  77. m_Hole_Shape = 0;
  78. m_Hole_Bottom_Layer = B_Cu;
  79. m_Hole_Top_Layer = F_Cu;
  80. }
  81. };
  82. /* the DRILL_PRECISION helper class to handle drill precision format in excellon files
  83. */
  84. class DRILL_PRECISION
  85. {
  86. public:
  87. int m_lhs; // Left digit number (integer value of coordinates)
  88. int m_rhs; // Right digit number (decimal value of coordinates)
  89. public:
  90. DRILL_PRECISION( int l = 2, int r = 4 )
  91. {
  92. m_lhs = l; m_rhs = r;
  93. }
  94. wxString GetPrecisionString()
  95. {
  96. wxString text;
  97. text << m_lhs << wxT( ":" ) << m_rhs;
  98. return text;
  99. }
  100. };
  101. typedef std::pair<PCB_LAYER_ID, PCB_LAYER_ID> DRILL_LAYER_PAIR;
  102. /**
  103. * GENDRILL_WRITER_BASE is a class to create drill maps and drill report,
  104. * and a helper class to created drill files.
  105. * drill files are created by specialized derived classes, depenfing on the
  106. * file format.
  107. */
  108. class GENDRILL_WRITER_BASE
  109. {
  110. public:
  111. enum ZEROS_FMT { // Zero format in coordinates
  112. DECIMAL_FORMAT, // Floating point coordinates
  113. SUPPRESS_LEADING, // Suppress leading zeros
  114. SUPPRESS_TRAILING, // Suppress trainling zeros
  115. KEEP_ZEROS // keep zeros
  116. };
  117. protected:
  118. BOARD* m_pcb;
  119. wxString m_drillFileExtension; // .drl or .gbr, depending on format
  120. bool m_unitsMetric; // true = mm, false = inches
  121. ZEROS_FMT m_zeroFormat; // the zero format option for output file
  122. DRILL_PRECISION m_precision; // The current coordinate precision (not used in decimal format)
  123. double m_conversionUnits; // scaling factor to convert the board unites to
  124. // Excellon/Gerber units (i.e inches or mm)
  125. wxPoint m_offset; // Drill offset coordinates
  126. bool m_merge_PTH_NPTH; // True to generate only one drill file
  127. std::vector<HOLE_INFO> m_holeListBuffer; // Buffer containing holes
  128. std::vector<DRILL_TOOL> m_toolListBuffer; // Buffer containing tools
  129. PlotFormat m_mapFileFmt; // the format of the map drill file,
  130. // if this map is needed
  131. const PAGE_INFO* m_pageInfo; // the page info used to plot drill maps
  132. // If NULL, use a A4 page format
  133. // This Ctor is protected.
  134. // Use derived classes to build a fully initialized GENDRILL_WRITER_BASE class.
  135. GENDRILL_WRITER_BASE( BOARD* aPcb )
  136. {
  137. m_pcb = aPcb;
  138. m_conversionUnits = 1.0;
  139. m_unitsMetric = true;
  140. m_mapFileFmt = PLOT_FORMAT_PDF;
  141. m_pageInfo = NULL;
  142. m_merge_PTH_NPTH = false;
  143. m_zeroFormat = DECIMAL_FORMAT;
  144. }
  145. public:
  146. virtual ~GENDRILL_WRITER_BASE()
  147. {
  148. }
  149. /**
  150. * set the option to make separate drill files for PTH and NPTH
  151. * @param aMerge = true to make only one file containing PTH and NPTH
  152. * = false to create 2 separate files
  153. */
  154. void SetMergeOption( bool aMerge ) { m_merge_PTH_NPTH = aMerge; }
  155. /**
  156. * Return the plot offset (usually the position
  157. * of the auxiliary axis
  158. */
  159. const wxPoint GetOffset() { return m_offset; }
  160. /**
  161. * Sets the page info used to plot drill maps
  162. * If NULL, a A4 page format will be used
  163. * @param aPageInfo = a reference to the page info, usually used to plot/display the board
  164. */
  165. void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; }
  166. /**
  167. * Initialize the format for the drill map file
  168. * @param aMapFmt = a PlotFormat value (one of
  169. * PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
  170. * PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
  171. * the most useful are PLOT_FORMAT_PDF and PLOT_FORMAT_POST
  172. */
  173. void SetMapFileFormat( PlotFormat aMapFmt ) { m_mapFileFmt = aMapFmt; }
  174. /**
  175. * Function CreateMapFilesSet
  176. * Creates the full set of map files for the board, in PS, PDF ... format
  177. * (use SetMapFileFormat() to select the format)
  178. * filenames are computed from the board name, and layers id
  179. * @param aPlotDirectory = the output folder
  180. * @param aReporter = a REPORTER to return activity or any message (can be NULL)
  181. */
  182. void CreateMapFilesSet( const wxString& aPlotDirectory,
  183. REPORTER* aReporter = NULL );
  184. /**
  185. * Function GenDrillReportFile
  186. * Create a plain text report file giving a list of drill values and drill count
  187. * for through holes, oblong holes, and for buried vias,
  188. * drill values and drill count per layer pair
  189. * there is only one report for all drill files even when buried or blinds vias exist
  190. *
  191. * Here is a sample created by this function:
  192. * Drill report for F:/tmp/interf_u/interf_u.brd
  193. * Created on 04/10/2012 20:48:38
  194. * Selected Drill Unit: Imperial (inches)
  195. *
  196. * Drill report for plated through holes :
  197. * T1 0,025" 0,64mm (88 holes)
  198. * T2 0,031" 0,79mm (120 holes)
  199. * T3 0,032" 0,81mm (151 holes) (with 1 slot)
  200. * T4 0,040" 1,02mm (43 holes)
  201. * T5 0,079" 2,00mm (1 hole) (with 1 slot)
  202. * T6 0,120" 3,05mm (1 hole) (with 1 slot)
  203. *
  204. * Total plated holes count 404
  205. *
  206. *
  207. * Drill report for buried and blind vias :
  208. *
  209. * Drill report for holes from layer Soudure to layer Interne1 :
  210. *
  211. * Total plated holes count 0
  212. *
  213. *
  214. * Drill report for holes from layer Interne1 to layer Interne2 :
  215. * T1 0,025" 0,64mm (3 holes)
  216. *
  217. * Total plated holes count 3
  218. *
  219. *
  220. * Drill report for holes from layer Interne2 to layer Composant :
  221. * T1 0,025" 0,64mm (1 hole)
  222. *
  223. * Total plated holes count 1
  224. *
  225. *
  226. * Drill report for unplated through holes :
  227. * T1 0,120" 3,05mm (1 hole) (with 1 slot)
  228. *
  229. * Total unplated holes count 1
  230. *
  231. * @param aFullFileName : the name of the file to create
  232. *
  233. * @return true if the file is created
  234. */
  235. bool GenDrillReportFile( const wxString& aFullFileName );
  236. protected:
  237. /**
  238. * Function GenDrillMapFile
  239. * Plot a map of drill marks for holes.
  240. * Hole list must be created before calling this function, by buildHolesList()
  241. * for the right holes set (PTH, NPTH, buried/blind vias ...)
  242. * the paper sheet to use to plot the map is set in m_pageInfo
  243. * ( calls SetPageInfo() to set it )
  244. * if NULL, A4 format will be used
  245. * @param aFullFileName : the full filename of the map file to create,
  246. * @param aFormat : one of the supported plot formats (see enum PlotFormat )
  247. */
  248. bool genDrillMapFile( const wxString& aFullFileName, PlotFormat aFormat );
  249. /**
  250. * Function BuildHolesList
  251. * Create the list of holes and tools for a given board
  252. * The list is sorted by increasing drill size.
  253. * Only holes included within aLayerPair are listed.
  254. * If aLayerPair identifies with [F_Cu, B_Cu], then
  255. * pad holes are always included also.
  256. *
  257. * @param aLayerPair is an inclusive range of layers.
  258. * @param aGenerateNPTH_list :
  259. * true to create NPTH only list (with no plated holes)
  260. * false to created plated holes list (with no NPTH )
  261. */
  262. void buildHolesList( DRILL_LAYER_PAIR aLayerPair,
  263. bool aGenerateNPTH_list );
  264. int getHolesCount() const { return m_holeListBuffer.size(); }
  265. /** Helper function.
  266. * Writes the drill marks in HPGL, POSTSCRIPT or other supported formats
  267. * Each hole size has a symbol (circle, cross X, cross + ...) up to
  268. * PLOTTER::MARKER_COUNT different values.
  269. * If more than PLOTTER::MARKER_COUNT different values,
  270. * these other values share the same mark shape
  271. * @param aPlotter = a PLOTTER instance (HPGL, POSTSCRIPT ... plotter).
  272. */
  273. bool plotDrillMarks( PLOTTER* aPlotter );
  274. /// Get unique layer pairs by examining the micro and blind_buried vias.
  275. std::vector<DRILL_LAYER_PAIR> getUniqueLayerPairs() const;
  276. /**
  277. * Function printToolSummary
  278. * prints m_toolListBuffer[] tools to aOut and returns total hole count.
  279. * @param aOut = the current OUTPUTFORMATTER to print summary
  280. * @param aSummaryNPTH = true to print summary for NPTH, false for PTH
  281. */
  282. unsigned printToolSummary( OUTPUTFORMATTER& aOut, bool aSummaryNPTH ) const;
  283. /**
  284. * minor helper function.
  285. * @return a string from aPair to identify the layer layer pair.
  286. * string is "<layer1Name>"-"<layer2Name>"
  287. * used to generate a filename for drill files and drill maps
  288. */
  289. const std::string layerPairName( DRILL_LAYER_PAIR aPair ) const;
  290. /**
  291. * minor helper function.
  292. * @return a string from aLayer to identify the layer.
  293. * string are "front" "back" or "in<aLayer>"
  294. */
  295. const std::string layerName( PCB_LAYER_ID aLayer ) const;
  296. /**
  297. * @return a filename which identify the drill file function.
  298. * it is the board name with the layer pair names added, and for separate
  299. * (PTH and NPTH) files, "-NPH" or "-NPTH" added
  300. * @param aPair = the layer pair
  301. * @param aNPTH = true to generate the filename of NPTH holes
  302. * @param aMerge_PTH_NPTH = true to generate the filename of a file which containd both
  303. * NPH and NPTH holes
  304. */
  305. virtual const wxString getDrillFileName( DRILL_LAYER_PAIR aPair, bool aNPTH,
  306. bool aMerge_PTH_NPTH ) const;
  307. };
  308. #endif // #define GENDRILL_FILE_WRITER_BASE_H