diff options
Diffstat (limited to 'pcbnew/exporters/gendrill_Excellon_writer.h')
-rw-r--r-- | pcbnew/exporters/gendrill_Excellon_writer.h | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/pcbnew/exporters/gendrill_Excellon_writer.h b/pcbnew/exporters/gendrill_Excellon_writer.h new file mode 100644 index 0000000..9a4d9c1 --- /dev/null +++ b/pcbnew/exporters/gendrill_Excellon_writer.h @@ -0,0 +1,368 @@ +/** + * @file gendrill_Excellon_writer.h + * @brief Classes used in drill files, map files and report files generation. + */ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2015 Jean_Pierre Charras <jp.charras at wanadoo.fr> + * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors. + * + * 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 + */ + +#ifndef _GENDRILL_EXCELLON_WRITER_ +#define _GENDRILL_EXCELLON_WRITER_ + +#include <vector> + + +class BOARD; +class PLOTTER; + + +// the DRILL_TOOL class handles tools used in the excellon drill file: +class DRILL_TOOL +{ +public: + int m_Diameter; // the diameter of the used tool (for oblong, the smaller size) + int m_TotalCount; // how many times it is used (round and oblong) + int m_OvalCount; // oblong count + bool m_Hole_NotPlated; // Is the hole plated or not plated + +public: + DRILL_TOOL( int aDiameter, bool a_NotPlated ) + { + m_TotalCount = 0; + m_OvalCount = 0; + m_Diameter = aDiameter; + m_Hole_NotPlated = a_NotPlated; + } +}; + + +/* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers) + * For buried or micro vias, the hole is not on all layers. + * So we must generate a drill file for each layer pair (adjacent layers) + * Not plated holes are always through holes, and must be output on a specific drill file + * because they are drilled after the Pcb process is finished. + */ +class HOLE_INFO +{ +public: + int m_Hole_Diameter; // hole value, and for oblong: min(hole size x, hole size y) + int m_Tool_Reference; // Tool reference for this hole = 1 ... n (values <=0 must not be used) + wxSize m_Hole_Size; // hole size for oblong holes + double m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes + int m_Hole_Shape; // hole shape: round (0) or oval (1) + wxPoint m_Hole_Pos; // hole position + LAYER_ID m_Hole_Bottom_Layer; // hole ending layer (usually back layer) + LAYER_ID m_Hole_Top_Layer; // hole starting layer (usually front layer): + // m_Hole_Top_Layer < m_Hole_Bottom_Layer + bool m_Hole_NotPlated; // hole not plated. Must be in a specific drill file or section + +public: + HOLE_INFO() + { + m_Hole_NotPlated = false; + m_Hole_Diameter = 0; + m_Tool_Reference = 0; + m_Hole_Orient = 0.0; + m_Hole_Shape = 0; + m_Hole_Bottom_Layer = B_Cu; + m_Hole_Top_Layer = F_Cu; + } +}; + + +/* the DRILL_PRECISION helper class to handle drill precision format in excellon files + */ +class DRILL_PRECISION +{ +public: + int m_lhs; // Left digit number (integer value of coordinates) + int m_rhs; // Right digit number (decimal value of coordinates) + +public: DRILL_PRECISION( int l = 2, int r = 4 ) + { + m_lhs = l; m_rhs = r; + } + + + wxString GetPrecisionString() + { + wxString text; + + text << m_lhs << wxT( ":" ) << m_rhs; + return text; + } +}; + + +typedef std::pair<LAYER_ID, LAYER_ID> LAYER_PAIR; +class OUTPUTFORMATTER; + +/** + * EXCELLON_WRITER is a class mainly used to create Excellon drill files + * However, this class is also used to create drill maps and drill report + */ +class EXCELLON_WRITER +{ +public: + enum ZEROS_FMT { // Zero format in coordinates + DECIMAL_FORMAT, // Floating point coordinates + SUPPRESS_LEADING, // Suppress leading zeros + SUPPRESS_TRAILING, // Suppress trainling zeros + KEEP_ZEROS // keep zeros + }; + + wxPoint m_Offset; // offset coordinates + bool m_ShortHeader; // true to generate the smallest header (strip comments) + +private: + FILE* m_file; // The output file + BOARD* m_pcb; + bool m_minimalHeader; // True to use minimal header + // in excellon file (strip comments) + bool m_unitsDecimal; // true = decimal, false = inches + ZEROS_FMT m_zeroFormat; // the zero format option for output file + DRILL_PRECISION m_precision; // The current coordinate precision (not used in decimal format) + double m_conversionUnits; // scaling factor to convert the board unites to Excellon units + // (i.e inches or mm) + bool m_mirror; + wxPoint m_offset; // Drill offset coordinates + bool m_merge_PTH_NPTH; // True to generate only one drill file + std::vector<HOLE_INFO> m_holeListBuffer; // Buffer containing holes + std::vector<DRILL_TOOL> m_toolListBuffer; // Buffer containing tools + + PlotFormat m_mapFileFmt; // the format of the map drill file, + // if this map is needed + const PAGE_INFO* m_pageInfo; // the page info used to plot drill maps + // If NULL, use a A4 page format + +public: + EXCELLON_WRITER( BOARD* aPcb ); + + ~EXCELLON_WRITER() + { + } + + /** + * Return the plot offset (usually the position + * of the auxiliary axis + */ + const wxPoint GetOffset() { return m_offset; } + + /** + * Function SetFormat + * Initialize internal parameters to match the given format + * @param aMetric = true for metric coordinates, false for imperial units + * @param aZerosFmt = DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS + * @param aLeftDigits = number of digits for integer part of coordinates + * if <= 0 (default), a suitable value will be used, depending on units + * @param aRightDigits = number of digits for mantissa part of coordinates + * if <= 0 (default), a suitable value will be used, depending on units + */ + void SetFormat( bool aMetric, ZEROS_FMT aZerosFmt = DECIMAL_FORMAT, + int aLeftDigits = 0, int aRightDigits = 0 ); + + /** + * Sets the page info used to plot drill maps + * If NULL, a A4 page format will be used + * @param aPageInfo = a reference to the page info, usually used to plot/display the board + */ + void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; } + + /** + * Function SetMapFileFormat + * Initialize the format for the drill map file + * @param SetMapFileFormat = a PlotFormat value (one of + * PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER, + * PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF + * the most useful are PLOT_FORMAT_PDF and PLOT_FORMAT_POST + */ + void SetMapFileFormat( PlotFormat aMapFmt ) { m_mapFileFmt = aMapFmt; } + + + /** + * Function SetOptions + * Initialize internal parameters to match drill options + * @param aMirror = true to create mirrored coordinates (Y coordinates negated) + * @param aMinimalHeader = true to use a minimal header (no comments, no info) + * @param aOffset = drill coordinates offset + */ + void SetOptions( bool aMirror, bool aMinimalHeader, wxPoint aOffset, bool aMerge_PTH_NPTH ) + { + m_mirror = aMirror; + m_offset = aOffset; + m_minimalHeader = aMinimalHeader; + m_merge_PTH_NPTH = aMerge_PTH_NPTH; + } + + /** + * Function BuildHolesList + * Create the list of holes and tools for a given board + * The list is sorted by increasing drill size. + * Only holes included within aLayerPair are listed. + * If aLayerPair identifies with [F_Cu, B_Cu], then + * pad holes are always included also. + * + * @param aLayerPair is an inclusive range of layers. + * @param aGenerateNPTH_list : + * true to create NPTH only list (with no plated holes) + * false to created plated holes list (with no NPTH ) + */ + void BuildHolesList( LAYER_PAIR aLayerPair, + bool aGenerateNPTH_list ); + + int GetHolesCount() const { return m_holeListBuffer.size(); } + + /** + * Function CreateDrillandMapFilesSet + * Creates the full set of Excellon drill file for the board + * filenames are computed from the board name, and layers id + * @param aPlotDirectory = the output folder + * @param aGenDrill = true to generate the EXCELLON drill file + * @param aGenMap = true to generate a drill map file + * @param aReporter = a REPORTER to return activity or any message (can be NULL) + */ + void CreateDrillandMapFilesSet( const wxString& aPlotDirectory, + bool aGenDrill, bool aGenMap, + REPORTER * aReporter = NULL ); + + /** + * Function CreateDrillFile + * Creates an Excellon drill file + * @param aFile = an opened file to write to will be closed by CreateDrillFile + * @return hole count + */ + int CreateDrillFile( FILE * aFile ); + + /** + * Function GenDrillReportFile + * Create a plain text report file giving a list of drill values and drill count + * for through holes, oblong holes, and for buried vias, + * drill values and drill count per layer pair + * there is only one report for all drill files even when buried or blinds vias exist + * + * Here is a sample created by this function: + * Drill report for F:/tmp/interf_u/interf_u.brd + * Created on 04/10/2012 20:48:38 + * Selected Drill Unit: Imperial (inches) + * + * Drill report for plated through holes : + * T1 0,025" 0,64mm (88 holes) + * T2 0,031" 0,79mm (120 holes) + * T3 0,032" 0,81mm (151 holes) (with 1 slot) + * T4 0,040" 1,02mm (43 holes) + * T5 0,079" 2,00mm (1 hole) (with 1 slot) + * T6 0,120" 3,05mm (1 hole) (with 1 slot) + * + * Total plated holes count 404 + * + * + * Drill report for buried and blind vias : + * + * Drill report for holes from layer Soudure to layer Interne1 : + * + * Total plated holes count 0 + * + * + * Drill report for holes from layer Interne1 to layer Interne2 : + * T1 0,025" 0,64mm (3 holes) + * + * Total plated holes count 3 + * + * + * Drill report for holes from layer Interne2 to layer Composant : + * T1 0,025" 0,64mm (1 hole) + * + * Total plated holes count 1 + * + * + * Drill report for unplated through holes : + * T1 0,120" 3,05mm (1 hole) (with 1 slot) + * + * Total unplated holes count 1 + * + * @param aFullFileName : the name of the file to create + * m_unitsDecimal = false to use inches, true to use mm in report file + * + * @return success if the file is created + */ + bool GenDrillReportFile( const wxString& aFullFileName ); + + /** + * Function GenDrillMapFile + * Plot a map of drill marks for holes. + * the paper sheet to use to plot the map is set in m_pageInfo + * ( calls SetPageInfo() to set it ) + * if NULL, A4 format will be used + * @param aFullFileName : the full filename of the map file to create, + * @param aFormat : one of the supported plot formats (see enum PlotFormat ) + */ + bool GenDrillMapFile( const wxString& aFullFileName, PlotFormat aFormat ); + +private: + /* Print the DRILL file header. The full header is: + * M48 + * ;DRILL file {PCBNEW (2007-11-29-b)} date 17/1/2008-21:02:35 + * ;FORMAT={ <precision> / absolute / <units> / <numbers format>} + * FMAT,2 + * INCH,TZ + */ + void WriteEXCELLONHeader(); + + void WriteEXCELLONEndOfFile(); + + /* Created a line like: + * X48000Y19500 + * According to the selected format + */ + void WriteCoordinates( char* aLine, double aCoordX, double aCoordY ); + + /** Helper function. + * Writes the drill marks in HPGL, POSTSCRIPT or other supported formats + * Each hole size has a symbol (circle, cross X, cross + ...) up to + * PLOTTER::MARKER_COUNT different values. + * If more than PLOTTER::MARKER_COUNT different values, + * these other values share the same mark shape + * @param aPlotter = a PLOTTER instance (HPGL, POSTSCRIPT ... plotter). + */ + bool PlotDrillMarks( PLOTTER* aPlotter ); + + /// Get unique layer pairs by examining the micro and blind_buried vias. + std::vector<LAYER_PAIR> getUniqueLayerPairs() const; + + /** + * Function printToolSummary + * prints m_toolListBuffer[] tools to aOut and returns total hole count. + * @param aOut = the current OUTPUTFORMATTER to print summary + * @param aSummaryNPTH = true to print summary for NPTH, false for PTH + */ + unsigned printToolSummary( OUTPUTFORMATTER& aOut, bool aSummaryNPTH ) const; + + const std::string layerPairName( LAYER_PAIR aPair ) const; + + const std::string layerName( LAYER_ID aLayer ) const; + + const wxString drillFileName( LAYER_PAIR aPair, bool aNPTH ) const; +}; + +#endif // #ifndef _GENDRILL_EXCELLON_WRITER_ |