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.

399 lines
15 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 The KiCad Developers, see AUTHORS.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. // holes can have an attribute in Excellon drill files, similar to attributes
  31. // in Gerber X2 format
  32. // They are only comments for a better identification of holes (vias, pads...)
  33. // Set to 1 to add these comments and 0 to not use these comments
  34. #define USE_ATTRIB_FOR_HOLES 1
  35. #include <vector>
  36. class BOARD_ITEM;
  37. // hole attribute, mainly to identify vias and pads and add this info as comment
  38. // in NC drill files
  39. enum class HOLE_ATTRIBUTE
  40. {
  41. HOLE_UNKNOWN, // uninitialized type
  42. HOLE_VIA_THROUGH, // a via hole (always plated) from top to bottom
  43. HOLE_VIA_BURIED, // a via hole (always plated) not through hole
  44. HOLE_PAD, // a plated or not plated pad hole
  45. HOLE_MECHANICAL // a mechanical pad (provided, not used)
  46. };
  47. // the DRILL_TOOL class handles tools used in the excellon drill file:
  48. class DRILL_TOOL
  49. {
  50. public:
  51. int m_Diameter; // the diameter of the used tool
  52. // (for oblong, the smaller size)
  53. int m_TotalCount; // how many times it is used (round and oblong)
  54. int m_OvalCount; // oblong count
  55. bool m_Hole_NotPlated; // Is the hole plated or not plated
  56. HOLE_ATTRIBUTE m_HoleAttribute; // Attribute (used in Excellon drill file)
  57. public:
  58. DRILL_TOOL( int aDiameter, bool a_NotPlated )
  59. {
  60. m_TotalCount = 0;
  61. m_OvalCount = 0;
  62. m_Diameter = aDiameter;
  63. m_Hole_NotPlated = a_NotPlated;
  64. m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_UNKNOWN;
  65. }
  66. };
  67. /**
  68. * Handle hole which must be drilled (diameter, position and layers).
  69. *
  70. * For buried or micro vias, the hole is not on all layers. So we must generate a drill file
  71. * for each layer pair (adjacent layers). Not plated holes are always through holes, and must
  72. * be output on a specific drill file because they are drilled after the PCB process is finished.
  73. */
  74. class HOLE_INFO
  75. {
  76. public:
  77. HOLE_INFO()
  78. {
  79. m_ItemParent = nullptr;
  80. m_Hole_NotPlated = false;
  81. m_Hole_Diameter = 0;
  82. m_Tool_Reference = 0;
  83. m_Hole_Orient = ANGLE_0;
  84. m_Hole_Shape = 0;
  85. m_Hole_Bottom_Layer = B_Cu;
  86. m_Hole_Top_Layer = F_Cu;
  87. m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_UNKNOWN;
  88. }
  89. public:
  90. BOARD_ITEM* m_ItemParent; // The pad or via parent of this hole
  91. int m_Hole_Diameter; // hole value, and for oblong: min(hole size x, hole
  92. // size y).
  93. int m_Tool_Reference; // Tool reference for this hole = 1 ... n (values <=0
  94. // must not be used).
  95. VECTOR2I m_Hole_Size; // hole size for oblong holes
  96. EDA_ANGLE m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes
  97. int m_Hole_Shape; // hole shape: round (0) or oval (1)
  98. VECTOR2I m_Hole_Pos; // hole position
  99. PCB_LAYER_ID m_Hole_Bottom_Layer; // hole ending layer (usually back layer)
  100. PCB_LAYER_ID m_Hole_Top_Layer; // hole starting layer (usually front layer):
  101. // m_Hole_Top_Layer < m_Hole_Bottom_Layer
  102. bool m_Hole_NotPlated; // hole not plated. Must be in a specific drill file or
  103. // section.
  104. HOLE_ATTRIBUTE m_HoleAttribute; // Attribute, used in Excellon drill file and to sort holes
  105. // by type.
  106. };
  107. /**
  108. * Helper to handle drill precision format in excellon files.
  109. */
  110. class DRILL_PRECISION
  111. {
  112. public:
  113. DRILL_PRECISION( int l = 2, int r = 4 )
  114. {
  115. m_Lhs = l; m_Rhs = r;
  116. }
  117. wxString GetPrecisionString()
  118. {
  119. wxString text;
  120. text << m_Lhs << wxT( ":" ) << m_Rhs;
  121. return text;
  122. }
  123. int m_Lhs; // Left digit number (integer value of coordinates)
  124. int m_Rhs; // Right digit number (decimal value of coordinates)
  125. };
  126. typedef std::pair<PCB_LAYER_ID, PCB_LAYER_ID> DRILL_LAYER_PAIR;
  127. /**
  128. * Create drill maps and drill reports and drill files.
  129. *
  130. * Drill files are created by specialized derived classes, depending on the file format.
  131. */
  132. class GENDRILL_WRITER_BASE
  133. {
  134. public:
  135. enum ZEROS_FMT { // Zero format in coordinates
  136. DECIMAL_FORMAT, // Floating point coordinates
  137. SUPPRESS_LEADING, // Suppress leading zeros
  138. SUPPRESS_TRAILING, // Suppress trailing zeros
  139. KEEP_ZEROS // keep zeros
  140. };
  141. enum TYPE_FILE { // type of holes in file: PTH, NPTH, mixed
  142. PTH_FILE, // PTH only, this is the default also for blind/buried holes
  143. NPTH_FILE, // NPTH only
  144. MIXED_FILE // PHT+NPTH (mixed)
  145. };
  146. virtual ~GENDRILL_WRITER_BASE()
  147. {
  148. }
  149. /**
  150. * Set the option to make separate drill files for PTH and NPTH.
  151. *
  152. * @param aMerge set to true to make only one file containing PTH and NPTH or false to
  153. * create 2 separate files.
  154. */
  155. void SetMergeOption( bool aMerge ) { m_merge_PTH_NPTH = aMerge; }
  156. /**
  157. * Return the plot offset (usually the position of the drill/place origin).
  158. */
  159. VECTOR2I GetOffset() { return m_offset; }
  160. /**
  161. * Set the page info used to plot drill maps.
  162. *
  163. * If NULL, a A4 page format will be used.
  164. *
  165. * @param aPageInfo is a reference to the page info, usually used to plot/display the board.
  166. */
  167. void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; }
  168. /**
  169. * Initialize the format for the drill map file.
  170. *
  171. * @param aMapFmt a PlotFormat value (one of PLOT_FORMAT_HPGL, PLOT_FORMAT_POST,
  172. * PLOT_FORMAT_GERBER, PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
  173. * the most useful are PLOT_FORMAT_PDF and PLOT_FORMAT_POST.
  174. */
  175. void SetMapFileFormat( PLOT_FORMAT aMapFmt )
  176. {
  177. m_mapFileFmt = aMapFmt;
  178. }
  179. /**
  180. * Create the full set of map files for the board, in PS, PDF ... format
  181. * (use SetMapFileFormat() to select the format).
  182. *
  183. * File names are computed from the board name and layer ID.
  184. *
  185. * @param aPlotDirectory is the output folder.
  186. * @param aReporter is a REPORTER to return activity or any message (can be NULL)
  187. */
  188. bool CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr );
  189. /**
  190. * Create a plain text report file giving a list of drill values and drill count for through
  191. * holes, oblong holes, and for buried vias, drill values and drill count per layer pair
  192. * there is only one report for all drill files even when buried or blinds vias exist.
  193. *
  194. * Here is a sample created by this function:
  195. * Drill report for F:/tmp/interf_u/interf_u.brd
  196. * Created on 04/10/2012 20:48:38
  197. * Selected Drill Unit: Imperial (inches)
  198. *
  199. * Drill report for plated through holes :
  200. * T1 0,025" 0,64mm (88 holes)
  201. * T2 0,031" 0,79mm (120 holes)
  202. * T3 0,032" 0,81mm (151 holes) (with 1 slot)
  203. * T4 0,040" 1,02mm (43 holes)
  204. * T5 0,079" 2,00mm (1 hole) (with 1 slot)
  205. * T6 0,120" 3,05mm (1 hole) (with 1 slot)
  206. *
  207. * Total plated holes count 404
  208. *
  209. *
  210. * Drill report for buried and blind vias :
  211. *
  212. * Drill report for holes from layer Soudure to layer Interne1 :
  213. *
  214. * Total plated holes count 0
  215. *
  216. *
  217. * Drill report for holes from layer Interne1 to layer Interne2 :
  218. * T1 0,025" 0,64mm (3 holes)
  219. *
  220. * Total plated holes count 3
  221. *
  222. *
  223. * Drill report for holes from layer Interne2 to layer Composant :
  224. * T1 0,025" 0,64mm (1 hole)
  225. *
  226. * Total plated holes count 1
  227. *
  228. *
  229. * Drill report for unplated through holes :
  230. * T1 0,120" 3,05mm (1 hole) (with 1 slot)
  231. *
  232. * Total unplated holes count 1
  233. *
  234. * @param aFullFileName is the name of the file to create.
  235. * @return true if the file is created.
  236. */
  237. bool GenDrillReportFile( const wxString& aFullFileName );
  238. /**
  239. * Returns the file extension of the drill writer format
  240. */
  241. wxString GetDrillFileExt() const { return m_drillFileExtension; }
  242. protected:
  243. /**
  244. * Plot a map of drill marks for holes.
  245. *
  246. * Hole list must be created before calling this function, by buildHolesList() for the
  247. * right holes set (PTH, NPTH, buried/blind vias ...) the paper sheet to use to plot the
  248. * map is set in m_pageInfo ( calls SetPageInfo() to set it ). If NULL, A4 format will
  249. * be used.
  250. *
  251. * @param aFullFileName is the full filename of the map file to create.
  252. * @param aFormat is one of the supported plot formats (see enum PlotFormat ).
  253. */
  254. bool genDrillMapFile( const wxString& aFullFileName, PLOT_FORMAT aFormat );
  255. /**
  256. * Create the list of holes and tools for a given board.
  257. *
  258. * The list is sorted by increasing drill size. Only holes included within aLayerPair
  259. * are listed. If aLayerPair identifies with [F_Cu, B_Cu], then pad holes are always
  260. * included also.
  261. *
  262. * @param aLayerPair is an inclusive range of layers.
  263. * @param aGenerateNPTH_list :
  264. * true to create NPTH only list (with no plated holes)
  265. * false to created plated holes list (with no NPTH )
  266. */
  267. void buildHolesList( DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list );
  268. int getHolesCount() const { return m_holeListBuffer.size(); }
  269. /**
  270. * Write the drill marks in HPGL, POSTSCRIPT or other supported formats/
  271. *
  272. * Each hole size has a symbol (circle, cross X, cross + ...) up to PLOTTER::MARKER_COUNT
  273. * different values. If more than PLOTTER::MARKER_COUNT different values, these other
  274. * values share the same mark shape.
  275. *
  276. * @param aPlotter is a PLOTTER instance (HPGL, POSTSCRIPT ... plotter).
  277. */
  278. bool plotDrillMarks( PLOTTER* aPlotter );
  279. /// Get unique layer pairs by examining the micro and blind_buried vias.
  280. std::vector<DRILL_LAYER_PAIR> getUniqueLayerPairs() const;
  281. /**
  282. * Print m_toolListBuffer[] tools to aOut and returns total hole count.
  283. *
  284. * @param aOut is the current OUTPUTFORMATTER to print summary.
  285. * @param aSummaryNPTH is true to print summary for NPTH, false for PTH.
  286. */
  287. unsigned printToolSummary( OUTPUTFORMATTER& aOut, bool aSummaryNPTH ) const;
  288. /**
  289. * @return a string from aPair to identify the layer layer pair.
  290. * string is "<layer1Name>"-"<layer2Name>"
  291. * used to generate a filename for drill files and drill maps
  292. */
  293. const std::string layerPairName( DRILL_LAYER_PAIR aPair ) const;
  294. /**
  295. * @return a string from aLayer to identify the layer.
  296. * string are "front" "back" or "in<aLayer>"
  297. */
  298. const std::string layerName( PCB_LAYER_ID aLayer ) const;
  299. /**
  300. * @param aPair is the layer pair.
  301. * @param aNPTH use true to generate the filename of NPTH holes.
  302. * @param aMerge_PTH_NPTH use true to generate the filename of a file which containd both
  303. * NPH and NPTH holes.
  304. * @return a filename which identify the drill file function.
  305. * it is the board name with the layer pair names added, and for separate
  306. * (PTH and NPTH) files, "-NPH" or "-NPTH" added
  307. */
  308. virtual const wxString getDrillFileName( DRILL_LAYER_PAIR aPair, bool aNPTH,
  309. bool aMerge_PTH_NPTH ) const;
  310. /**
  311. * @param aLayerPair is the layer pair (Drill from rom first layer to second layer)
  312. * @param aHoleType is type of drill file (PTH, NPTH, mixed)
  313. * @param aCompatNCdrill is true when generating NC (Excellon) compatible drill file
  314. * @return a wxString containing the .FileFunction attribute.
  315. * the standard X2 FileFunction for drill files is
  316. * %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],
  317. * Drill[Route][Mixed]*%
  318. * There is no X1 version, as the Gerber drill files uses only X2 format
  319. * There is a compatible NC drill version.
  320. */
  321. const wxString BuildFileFunctionAttributeString( DRILL_LAYER_PAIR aLayerPair,
  322. TYPE_FILE aHoleType,
  323. bool aCompatNCdrill = false ) const;
  324. protected:
  325. // Use derived classes to build a fully initialized GENDRILL_WRITER_BASE class.
  326. GENDRILL_WRITER_BASE( BOARD* aPcb )
  327. {
  328. m_pcb = aPcb;
  329. m_conversionUnits = 1.0;
  330. m_unitsMetric = true;
  331. m_mapFileFmt = PLOT_FORMAT::PDF;
  332. m_pageInfo = nullptr;
  333. m_merge_PTH_NPTH = false;
  334. m_zeroFormat = DECIMAL_FORMAT;
  335. }
  336. BOARD* m_pcb;
  337. wxString m_drillFileExtension; // .drl or .gbr, depending on format
  338. bool m_unitsMetric; // true = mm, false = inches
  339. ZEROS_FMT m_zeroFormat; // the zero format option for output file
  340. DRILL_PRECISION m_precision; // The current coordinate precision (not
  341. // used in decimal format).
  342. double m_conversionUnits; // scaling factor to convert the board
  343. // unites to Excellon/Gerber units (i.e
  344. // inches or mm)
  345. VECTOR2I m_offset; // Drill offset coordinates
  346. bool m_merge_PTH_NPTH; // True to generate only one drill file
  347. std::vector<HOLE_INFO> m_holeListBuffer; // Buffer containing holes
  348. std::vector<DRILL_TOOL> m_toolListBuffer; // Buffer containing tools
  349. PLOT_FORMAT m_mapFileFmt; // the format of the map drill file,
  350. // if this map is needed
  351. const PAGE_INFO* m_pageInfo; // the page info used to plot drill maps
  352. // If NULL, use a A4 page format
  353. };
  354. #endif // #define GENDRILL_FILE_WRITER_BASE_H