mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Put the string manipuuation utils in the cpp, and remove string_utils.h from the includes of netinfo.h. This spams that header into about 350 files, not all of which need it. Then go round and tidy up the places (most exporters and dialogs) where CPP files weren't including string_utils.h when they used it, as well as some other order-sensitive include issues that turned up.
450 lines
17 KiB
C++
450 lines
17 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 1992-2017 Jean_Pierre Charras <jp.charras at wanadoo.fr>
|
|
* Copyright The KiCad Developers, see AUTHORS.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
|
|
*/
|
|
|
|
/**
|
|
* @file gendrill_file_writer_base.h
|
|
* @brief helper classes to handle hole info for drill files generators.
|
|
*/
|
|
#ifndef GENDRILL_FILE_WRITER_BASE_H
|
|
#define GENDRILL_FILE_WRITER_BASE_H
|
|
|
|
// holes can have an attribute in Excellon drill files, similar to attributes
|
|
// in Gerber X2 format
|
|
// They are only comments for a better identification of holes (vias, pads...)
|
|
// Set to 1 to add these comments and 0 to not use these comments
|
|
#define USE_ATTRIB_FOR_HOLES 1
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include <layer_ids.h>
|
|
#include <plotters/plotter.h>
|
|
|
|
|
|
class BOARD;
|
|
class BOARD_ITEM;
|
|
class OUTPUTFORMATTER;
|
|
class PAGE_INFO;
|
|
class REPORTER;
|
|
|
|
// hole attribute, mainly to identify vias and pads and add this info as comment
|
|
// in NC drill files
|
|
enum class HOLE_ATTRIBUTE
|
|
{
|
|
HOLE_UNKNOWN, // uninitialized type
|
|
HOLE_VIA_THROUGH, // a via hole (always plated) from top to bottom
|
|
HOLE_VIA_BURIED, // a via hole (always plated) not through hole
|
|
HOLE_PAD, // a plated or not plated pad hole
|
|
HOLE_PAD_CASTELLATED, // a plated castelleted pad hole
|
|
HOLE_PAD_PRESSFIT, // a plated press-fit pad hole
|
|
HOLE_MECHANICAL // a mechanical pad (provided, not used)
|
|
};
|
|
|
|
// Via Protection features according to IPC-4761.
|
|
enum class IPC4761_FEATURES : int
|
|
{
|
|
FILLED,
|
|
CAPPED,
|
|
PLUGGED_FRONT,
|
|
PLUGGED_BACK,
|
|
COVERED_FRONT,
|
|
COVERED_BACK,
|
|
TENTED_FRONT,
|
|
TENTED_BACK
|
|
};
|
|
|
|
// 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
|
|
HOLE_ATTRIBUTE m_HoleAttribute; // Attribute (used in Excellon drill file)
|
|
|
|
public:
|
|
DRILL_TOOL( int aDiameter, bool a_NotPlated )
|
|
{
|
|
m_TotalCount = 0;
|
|
m_OvalCount = 0;
|
|
m_Diameter = aDiameter;
|
|
m_Hole_NotPlated = a_NotPlated;
|
|
m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_UNKNOWN;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* 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:
|
|
HOLE_INFO()
|
|
{
|
|
m_ItemParent = nullptr;
|
|
m_Hole_NotPlated = false;
|
|
m_Hole_Diameter = 0;
|
|
m_Tool_Reference = 0;
|
|
m_Hole_Orient = ANGLE_0;
|
|
m_Hole_Shape = 0;
|
|
m_Hole_Bottom_Layer = B_Cu;
|
|
m_Hole_Top_Layer = F_Cu;
|
|
m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_UNKNOWN;
|
|
m_Hole_Filled = false;
|
|
m_Hole_Capped = false;
|
|
m_Hole_Top_Covered = false;
|
|
m_Hole_Bot_Covered = false;
|
|
m_Hole_Top_Plugged = false;
|
|
m_Hole_Bot_Plugged = false;
|
|
m_Hole_Top_Tented = false;
|
|
m_Hole_Bot_Tented = false;
|
|
}
|
|
|
|
public:
|
|
BOARD_ITEM* m_ItemParent; // The pad or via parent of this hole
|
|
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).
|
|
VECTOR2I m_Hole_Size; // hole size for oblong holes
|
|
EDA_ANGLE m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes
|
|
int m_Hole_Shape; // hole shape: round (0) or oval (1)
|
|
VECTOR2I m_Hole_Pos; // hole position
|
|
PCB_LAYER_ID m_Hole_Bottom_Layer; // hole ending layer (usually back layer)
|
|
PCB_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.
|
|
HOLE_ATTRIBUTE m_HoleAttribute; // Attribute, used in Excellon drill file and to sort holes
|
|
// by type.
|
|
|
|
bool m_Hole_Filled; // hole should be filled
|
|
bool m_Hole_Capped; // hole should be capped
|
|
bool m_Hole_Top_Covered; // hole should be covered on top
|
|
bool m_Hole_Bot_Covered; // hole should be covered on bottom
|
|
bool m_Hole_Top_Plugged; // hole should be plugged on top
|
|
bool m_Hole_Bot_Plugged; // hole should be plugged on bottom
|
|
bool m_Hole_Top_Tented; // hole should be tented on top
|
|
bool m_Hole_Bot_Tented; // hole should be tented on bottom
|
|
};
|
|
|
|
|
|
/**
|
|
* Helper to handle drill precision format in excellon files.
|
|
*/
|
|
class DRILL_PRECISION
|
|
{
|
|
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;
|
|
}
|
|
|
|
int m_Lhs; // Left digit number (integer value of coordinates)
|
|
int m_Rhs; // Right digit number (decimal value of coordinates)
|
|
};
|
|
|
|
|
|
typedef std::pair<PCB_LAYER_ID, PCB_LAYER_ID> DRILL_LAYER_PAIR;
|
|
|
|
/**
|
|
* Create drill maps and drill reports and drill files.
|
|
*
|
|
* Drill files are created by specialized derived classes, depending on the file format.
|
|
*/
|
|
class GENDRILL_WRITER_BASE
|
|
{
|
|
public:
|
|
enum ZEROS_FMT { // Zero format in coordinates
|
|
DECIMAL_FORMAT, // Floating point coordinates
|
|
SUPPRESS_LEADING, // Suppress leading zeros
|
|
SUPPRESS_TRAILING, // Suppress trailing zeros
|
|
KEEP_ZEROS // keep zeros
|
|
};
|
|
|
|
enum TYPE_FILE { // type of holes in file: PTH, NPTH, mixed
|
|
PTH_FILE, // PTH only, this is the default also for blind/buried holes
|
|
NPTH_FILE, // NPTH only
|
|
MIXED_FILE // PHT+NPTH (mixed)
|
|
};
|
|
|
|
virtual ~GENDRILL_WRITER_BASE()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Set the option to make separate drill files for PTH and NPTH.
|
|
*
|
|
* @param aMerge set to true to make only one file containing PTH and NPTH or false to
|
|
* create 2 separate files.
|
|
*/
|
|
void SetMergeOption( bool aMerge ) { m_merge_PTH_NPTH = aMerge; }
|
|
|
|
/**
|
|
* Return the plot offset (usually the position of the drill/place origin).
|
|
*/
|
|
VECTOR2I GetOffset() { return m_offset; }
|
|
|
|
/**
|
|
* Set the page info used to plot drill maps.
|
|
*
|
|
* If NULL, a A4 page format will be used.
|
|
*
|
|
* @param aPageInfo is a reference to the page info, usually used to plot/display the board.
|
|
*/
|
|
void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; }
|
|
|
|
/**
|
|
* Initialize the format for the drill map file.
|
|
*
|
|
* @param aMapFmt a PlotFormat value (one of 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( PLOT_FORMAT aMapFmt )
|
|
{
|
|
m_mapFileFmt = aMapFmt;
|
|
}
|
|
|
|
/**
|
|
* Create the full set of map files for the board, in PS, PDF ... format
|
|
* (use SetMapFileFormat() to select the format).
|
|
*
|
|
* File names are computed from the board name and layer ID.
|
|
*
|
|
* @param aPlotDirectory is the output folder.
|
|
* @param aReporter is a REPORTER to return activity or any message (can be NULL)
|
|
*/
|
|
bool CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr );
|
|
|
|
/**
|
|
* 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 is the name of the file to create.
|
|
* @return true if the file is created.
|
|
*/
|
|
bool GenDrillReportFile( const wxString& aFullFileName );
|
|
|
|
/**
|
|
* Returns the file extension of the drill writer format
|
|
*/
|
|
wxString GetDrillFileExt() const { return m_drillFileExtension; }
|
|
|
|
protected:
|
|
/**
|
|
* Plot a map of drill marks for holes.
|
|
*
|
|
* Hole list must be created before calling this function, by buildHolesList() for the
|
|
* right holes set (PTH, NPTH, buried/blind vias ...) 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 is the full filename of the map file to create.
|
|
* @param aFormat is one of the supported plot formats (see enum PlotFormat ).
|
|
*/
|
|
bool genDrillMapFile( const wxString& aFullFileName, PLOT_FORMAT aFormat );
|
|
|
|
/**
|
|
* 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( DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list );
|
|
|
|
int getHolesCount() const { return m_holeListBuffer.size(); }
|
|
|
|
/**
|
|
* Write the drill marks in PDF, 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 is a PLOTTER instance (PDF, POSTSCRIPT ... plotter).
|
|
*/
|
|
bool plotDrillMarks( PLOTTER* aPlotter );
|
|
|
|
/// Get unique layer pairs by examining the micro and blind_buried vias.
|
|
std::vector<DRILL_LAYER_PAIR> getUniqueLayerPairs() const;
|
|
|
|
/**
|
|
* Print m_toolListBuffer[] tools to aOut and returns total hole count.
|
|
*
|
|
* @param aOut is the current OUTPUTFORMATTER to print summary.
|
|
* @param aSummaryNPTH is true to print summary for NPTH, false for PTH.
|
|
*/
|
|
unsigned printToolSummary( OUTPUTFORMATTER& aOut, bool aSummaryNPTH ) const;
|
|
|
|
/**
|
|
* @return a string from aPair to identify the layer layer pair.
|
|
* string is "<layer1Name>"-"<layer2Name>"
|
|
* used to generate a filename for drill files and drill maps
|
|
*/
|
|
const std::string layerPairName( DRILL_LAYER_PAIR aPair ) const;
|
|
|
|
/**
|
|
* @return a string from aLayer to identify the layer.
|
|
* string are "front" "back" or "in<aLayer>"
|
|
*/
|
|
const std::string layerName( PCB_LAYER_ID aLayer ) const;
|
|
|
|
/**
|
|
* @param aPair is the layer pair.
|
|
* @param aNPTH use true to generate the filename of NPTH holes.
|
|
* @param aMerge_PTH_NPTH use true to generate the filename of a file which containd both
|
|
* NPH and NPTH holes.
|
|
* @return a filename which identify the drill file function.
|
|
* it is the board name with the layer pair names added, and for separate
|
|
* (PTH and NPTH) files, "-NPH" or "-NPTH" added
|
|
*/
|
|
virtual const wxString getDrillFileName( DRILL_LAYER_PAIR aPair, bool aNPTH,
|
|
bool aMerge_PTH_NPTH ) const;
|
|
|
|
|
|
/**
|
|
* @param aPair is the layer pair.
|
|
* @param aFeature Is the protection feature represented by the file
|
|
* @return a filename which identifies the specific protection feature.
|
|
* It is the board file name followed by the feature name and the layer(s) associated with it.
|
|
*/
|
|
virtual const wxString getProtectionFileName( DRILL_LAYER_PAIR aPair,
|
|
IPC4761_FEATURES aFeature ) const;
|
|
|
|
|
|
/**
|
|
* @param aLayerPair is the layer pair (Drill from rom first layer to second layer)
|
|
* @param aHoleType is type of drill file (PTH, NPTH, mixed)
|
|
* @param aCompatNCdrill is true when generating NC (Excellon) compatible drill file
|
|
* @return a wxString containing the .FileFunction attribute.
|
|
* the standard X2 FileFunction for drill files is
|
|
* %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],
|
|
* Drill[Route][Mixed]*%
|
|
* There is no X1 version, as the Gerber drill files uses only X2 format
|
|
* There is a compatible NC drill version.
|
|
*/
|
|
const wxString BuildFileFunctionAttributeString( DRILL_LAYER_PAIR aLayerPair,
|
|
TYPE_FILE aHoleType,
|
|
bool aCompatNCdrill = false ) const;
|
|
|
|
|
|
protected:
|
|
// Use derived classes to build a fully initialized GENDRILL_WRITER_BASE class.
|
|
GENDRILL_WRITER_BASE( BOARD* aPcb )
|
|
{
|
|
m_pcb = aPcb;
|
|
m_conversionUnits = 1.0;
|
|
m_unitsMetric = true;
|
|
m_mapFileFmt = PLOT_FORMAT::PDF;
|
|
m_pageInfo = nullptr;
|
|
m_merge_PTH_NPTH = false;
|
|
m_zeroFormat = DECIMAL_FORMAT;
|
|
}
|
|
|
|
BOARD* m_pcb;
|
|
wxString m_drillFileExtension; // .drl or .gbr, depending on format
|
|
bool m_unitsMetric; // true = mm, 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/Gerber units (i.e
|
|
// inches or mm)
|
|
VECTOR2I 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
|
|
|
|
PLOT_FORMAT 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
|
|
};
|
|
|
|
#endif // #define GENDRILL_FILE_WRITER_BASE_H
|