summaryrefslogtreecommitdiff
path: root/pcbnew/exporters/gendrill_Excellon_writer.h
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/exporters/gendrill_Excellon_writer.h')
-rw-r--r--pcbnew/exporters/gendrill_Excellon_writer.h368
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_