KiCad PCB EDA Suite
EXCELLON_WRITER Class Reference

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. More...

#include <gendrill_Excellon_writer.h>

Public Types

enum  ZEROS_FMT { DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS }
 

Public Member Functions

 EXCELLON_WRITER (BOARD *aPcb)
 
 ~EXCELLON_WRITER ()
 
const wxPoint GetOffset ()
 Return the plot offset (usually the position of the auxiliary axis. More...
 
void SetFormat (bool aMetric, ZEROS_FMT aZerosFmt=DECIMAL_FORMAT, int aLeftDigits=0, int aRightDigits=0)
 Function SetFormat Initialize internal parameters to match the given format. More...
 
void SetPageInfo (const PAGE_INFO *aPageInfo)
 Sets the page info used to plot drill maps If NULL, a A4 page format will be used. More...
 
void SetMapFileFormat (PlotFormat aMapFmt)
 Function SetMapFileFormat Initialize the format for the drill map file. More...
 
void SetOptions (bool aMirror, bool aMinimalHeader, wxPoint aOffset, bool aMerge_PTH_NPTH)
 Function SetOptions Initialize internal parameters to match drill options. More...
 
void CreateDrillandMapFilesSet (const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=NULL)
 Function CreateDrillandMapFilesSet Creates the full set of Excellon drill file for the board filenames are computed from the board name, and layers id. More...
 
bool GenDrillReportFile (const wxString &aFullFileName)
 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. More...
 
bool GenDrillMapFile (const wxString &aFullFileName, PlotFormat aFormat)
 Function GenDrillMapFile Plot a map of drill marks for holes. More...
 

Public Attributes

wxPoint m_Offset
 
bool m_ShortHeader
 

Private Member Functions

int createDrillFile (FILE *aFile)
 Function CreateDrillFile Creates an Excellon drill file. More...
 
void buildHolesList (DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
 Function BuildHolesList Create the list of holes and tools for a given board The list is sorted by increasing drill size. More...
 
int getHolesCount () const
 
void writeEXCELLONHeader ()
 
void writeEXCELLONEndOfFile ()
 
void writeCoordinates (char *aLine, double aCoordX, double aCoordY)
 
bool plotDrillMarks (PLOTTER *aPlotter)
 Helper function. More...
 
std::vector< DRILL_LAYER_PAIRgetUniqueLayerPairs () const
 Get unique layer pairs by examining the micro and blind_buried vias. More...
 
unsigned printToolSummary (OUTPUTFORMATTER &aOut, bool aSummaryNPTH) const
 Function printToolSummary prints m_toolListBuffer[] tools to aOut and returns total hole count. More...
 
const std::string layerPairName (DRILL_LAYER_PAIR aPair) const
 
const std::string layerName (PCB_LAYER_ID aLayer) const
 
const wxString drillFileName (DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
 

Private Attributes

FILE * m_file
 
BOARDm_pcb
 
bool m_minimalHeader
 
bool m_unitsDecimal
 
ZEROS_FMT m_zeroFormat
 
DRILL_PRECISION m_precision
 
double m_conversionUnits
 
bool m_mirror
 
wxPoint m_offset
 
bool m_merge_PTH_NPTH
 
std::vector< HOLE_INFOm_holeListBuffer
 
std::vector< DRILL_TOOLm_toolListBuffer
 
PlotFormat m_mapFileFmt
 
const PAGE_INFOm_pageInfo
 

Detailed Description

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.

Definition at line 126 of file gendrill_Excellon_writer.h.

Member Enumeration Documentation

Enumerator
DECIMAL_FORMAT 
SUPPRESS_LEADING 
SUPPRESS_TRAILING 
KEEP_ZEROS 

Definition at line 129 of file gendrill_Excellon_writer.h.

129  { // Zero format in coordinates
130  DECIMAL_FORMAT, // Floating point coordinates
131  SUPPRESS_LEADING, // Suppress leading zeros
132  SUPPRESS_TRAILING, // Suppress trainling zeros
133  KEEP_ZEROS // keep zeros
134  };

Constructor & Destructor Documentation

EXCELLON_WRITER::EXCELLON_WRITER ( BOARD aPcb)
See also
for EXCELLON format, see: http://www.excellon.com/manuals/program.htm and the CNC-7 manual.

Definition at line 66 of file gendrill_Excellon_writer.cpp.

References DECIMAL_FORMAT, m_conversionUnits, m_file, m_mapFileFmt, m_merge_PTH_NPTH, m_minimalHeader, m_mirror, m_pageInfo, m_pcb, m_ShortHeader, m_unitsDecimal, m_zeroFormat, and PLOT_FORMAT_PDF.

EXCELLON_WRITER::~EXCELLON_WRITER ( )
inline

Definition at line 163 of file gendrill_Excellon_writer.h.

164  {
165  }

Member Function Documentation

void EXCELLON_WRITER::buildHolesList ( DRILL_LAYER_PAIR  aLayerPair,
bool  aGenerateNPTH_list 
)
private

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.

Parameters
aLayerPairis an inclusive range of layers.
aGenerateNPTH_list: true to create NPTH only list (with no plated holes) false to created plated holes list (with no NPTH )

Definition at line 557 of file gendrill_Excellon_writer.cpp.

References B_Cu, CmpHoleSettings(), F_Cu, GetFirstVia(), DRILL_TOOL::m_Diameter, HOLE_INFO::m_Hole_Bottom_Layer, HOLE_INFO::m_Hole_Diameter, DRILL_TOOL::m_Hole_NotPlated, HOLE_INFO::m_Hole_NotPlated, HOLE_INFO::m_Hole_Orient, HOLE_INFO::m_Hole_Pos, HOLE_INFO::m_Hole_Shape, HOLE_INFO::m_Hole_Size, HOLE_INFO::m_Hole_Top_Layer, m_holeListBuffer, m_merge_PTH_NPTH, BOARD::m_Modules, m_pcb, HOLE_INFO::m_Tool_Reference, m_toolListBuffer, BOARD::m_Track, min, MODULE::Next(), D_PAD::Next(), PAD_ATTRIB_HOLE_NOT_PLATED, and PAD_DRILL_SHAPE_CIRCLE.

Referenced by CreateDrillandMapFilesSet(), and GenDrillReportFile().

559 {
560  HOLE_INFO new_hole;
561 
562  m_holeListBuffer.clear();
563  m_toolListBuffer.clear();
564 
565  wxASSERT( aLayerPair.first < aLayerPair.second ); // fix the caller
566 
567  // build hole list for vias
568  if( ! aGenerateNPTH_list ) // vias are always plated !
569  {
570  for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; via = GetFirstVia( via->Next() ) )
571  {
572  int hole_sz = via->GetDrillValue();
573 
574  if( hole_sz == 0 ) // Should not occur.
575  continue;
576 
577  new_hole.m_Tool_Reference = -1; // Flag value for Not initialized
578  new_hole.m_Hole_Orient = 0;
579  new_hole.m_Hole_Diameter = hole_sz;
580  new_hole.m_Hole_NotPlated = false;
581  new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
582 
583  new_hole.m_Hole_Shape = 0; // hole shape: round
584  new_hole.m_Hole_Pos = via->GetStart();
585 
586  via->LayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
587 
588  // LayerPair() returns params with m_Hole_Bottom_Layer > m_Hole_Top_Layer
589  // Remember: top layer = 0 and bottom layer = 31 for through hole vias
590  // Any captured via should be from aLayerPair.first to aLayerPair.second exactly.
591  if( new_hole.m_Hole_Top_Layer != aLayerPair.first ||
592  new_hole.m_Hole_Bottom_Layer != aLayerPair.second )
593  continue;
594 
595  m_holeListBuffer.push_back( new_hole );
596  }
597  }
598 
599  if( aLayerPair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
600  {
601  // add holes for thru hole pads
602  for( MODULE* module = m_pcb->m_Modules; module; module = module->Next() )
603  {
604  for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
605  {
606  if( !m_merge_PTH_NPTH )
607  {
608  if( !aGenerateNPTH_list && pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
609  continue;
610 
611  if( aGenerateNPTH_list && pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
612  continue;
613  }
614 
615  if( pad->GetDrillSize().x == 0 )
616  continue;
617 
618  new_hole.m_Hole_NotPlated = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED);
619  new_hole.m_Tool_Reference = -1; // Flag is: Not initialized
620  new_hole.m_Hole_Orient = pad->GetOrientation();
621  new_hole.m_Hole_Shape = 0; // hole shape: round
622  new_hole.m_Hole_Diameter = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y );
623  new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
624 
625  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
626  new_hole.m_Hole_Shape = 1; // oval flag set
627 
628  new_hole.m_Hole_Size = pad->GetDrillSize();
629  new_hole.m_Hole_Pos = pad->GetPosition(); // hole position
630  new_hole.m_Hole_Bottom_Layer = B_Cu;
631  new_hole.m_Hole_Top_Layer = F_Cu; // pad holes are through holes
632  m_holeListBuffer.push_back( new_hole );
633  }
634  }
635  }
636 
637  // Sort holes per increasing diameter value
638  sort( m_holeListBuffer.begin(), m_holeListBuffer.end(), CmpHoleSettings );
639 
640  // build the tool list
641  int last_hole = -1; // Set to not initialized (this is a value not used
642  // for m_holeListBuffer[ii].m_Hole_Diameter)
643  bool last_notplated_opt = false;
644 
645  DRILL_TOOL new_tool( 0, false );
646  unsigned jj;
647 
648  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
649  {
650  if( m_holeListBuffer[ii].m_Hole_Diameter != last_hole ||
651  m_holeListBuffer[ii].m_Hole_NotPlated != last_notplated_opt )
652  {
653  new_tool.m_Diameter = m_holeListBuffer[ii].m_Hole_Diameter;
654  new_tool.m_Hole_NotPlated = m_holeListBuffer[ii].m_Hole_NotPlated;
655  m_toolListBuffer.push_back( new_tool );
656  last_hole = new_tool.m_Diameter;
657  last_notplated_opt = new_tool.m_Hole_NotPlated;
658  }
659 
660  jj = m_toolListBuffer.size();
661 
662  if( jj == 0 )
663  continue; // Should not occurs
664 
665  m_holeListBuffer[ii].m_Tool_Reference = jj; // Tool value Initialized (value >= 1)
666 
667  m_toolListBuffer.back().m_TotalCount++;
668 
669  if( m_holeListBuffer[ii].m_Hole_Shape )
670  m_toolListBuffer.back().m_OvalCount++;
671  }
672 }
static bool CmpHoleSettings(const HOLE_INFO &a, const HOLE_INFO &b)
std::vector< DRILL_TOOL > m_toolListBuffer
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
MODULE * Next() const
Definition: class_module.h:100
D_PAD * Next() const
Definition: class_pad.h:106
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
PCB_LAYER_ID m_Hole_Bottom_Layer
PCB_LAYER_ID m_Hole_Top_Layer
std::vector< HOLE_INFO > m_holeListBuffer
DLIST< MODULE > m_Modules
Definition: class_board.h:243
DLIST< TRACK > m_Track
Definition: class_board.h:244
#define min(a, b)
Definition: auxiliary.h:85
VIA * GetFirstVia(TRACK *aTrk, const TRACK *aStopPoint=NULL)
Scan a track list for the first VIA o NULL if not found (or NULL passed)
Definition: class_track.h:497
void EXCELLON_WRITER::CreateDrillandMapFilesSet ( const wxString &  aPlotDirectory,
bool  aGenDrill,
bool  aGenMap,
REPORTER aReporter = NULL 
)

Function CreateDrillandMapFilesSet Creates the full set of Excellon drill file for the board filenames are computed from the board name, and layers id.

Parameters
aPlotDirectory= the output folder
aGenDrill= true to generate the EXCELLON drill file
aGenMap= true to generate a drill map file
aReporter= a REPORTER to return activity or any message (can be NULL)

Definition at line 82 of file gendrill_Excellon_writer.cpp.

References B_Cu, buildHolesList(), createDrillFile(), drillFileName(), F_Cu, GenDrillMapFile(), GetChars(), GetDefaultPlotExtension(), getHolesCount(), getUniqueLayerPairs(), m_mapFileFmt, m_merge_PTH_NPTH, and REPORTER::Report().

85 {
86  wxFileName fn;
87  wxString msg;
88 
89  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
90 
91  // append a pair representing the NPTH set of holes, for separate drill files.
92  if( !m_merge_PTH_NPTH )
93  hole_sets.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) );
94 
95  for( std::vector<DRILL_LAYER_PAIR>::const_iterator it = hole_sets.begin();
96  it != hole_sets.end(); ++it )
97  {
98  DRILL_LAYER_PAIR pair = *it;
99  // For separate drill files, the last layer pair is the NPTH drill file.
100  bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 );
101 
102  buildHolesList( pair, doing_npth );
103 
104  // The file is created if it has holes, or if it is the non plated drill file
105  // to be sure the NPTH file is up to date in separate files mode.
106  if( getHolesCount() > 0 || doing_npth )
107  {
108  fn = drillFileName( pair, doing_npth, m_merge_PTH_NPTH );
109  fn.SetPath( aPlotDirectory );
110 
111  if( aGenDrill )
112  {
113  wxString fullFilename = fn.GetFullPath();
114 
115  FILE* file = wxFopen( fullFilename, wxT( "w" ) );
116 
117  if( file == NULL )
118  {
119  if( aReporter )
120  {
121  msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) );
122  aReporter->Report( msg );
123  }
124  break;
125  }
126  else
127  {
128  if( aReporter )
129  {
130  msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
131  aReporter->Report( msg );
132  }
133  }
134 
135  createDrillFile( file );
136  }
137 
138  if( aGenMap )
139  {
140  fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
141  wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
142  fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );
143 
144  bool success = GenDrillMapFile( fullfilename, m_mapFileFmt );
145 
146  if( ! success )
147  {
148  if( aReporter )
149  {
150  msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
151  aReporter->Report( msg );
152  }
153 
154  return;
155  }
156  else
157  {
158  if( aReporter )
159  {
160  msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
161  aReporter->Report( msg );
162  }
163  }
164  }
165  }
166  }
167 }
wxString GetDefaultPlotExtension(PlotFormat aFormat)
Returns the default plot extension for a format.
const wxString drillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
void buildHolesList(DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
Function BuildHolesList Create the list of holes and tools for a given board The list is sorted by in...
int createDrillFile(FILE *aFile)
Function CreateDrillFile Creates an Excellon drill file.
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
bool GenDrillMapFile(const wxString &aFullFileName, PlotFormat aFormat)
Function GenDrillMapFile Plot a map of drill marks for holes.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
int EXCELLON_WRITER::createDrillFile ( FILE *  aFile)
private

Function CreateDrillFile Creates an Excellon drill file.

Parameters
aFile= an opened file to write to will be closed by CreateDrillFile
Returns
hole count

Definition at line 170 of file gendrill_Excellon_writer.cpp.

References delta, dummy(), m_conversionUnits, DRILL_TOOL::m_Diameter, m_file, DRILL_TOOL::m_Hole_NotPlated, HOLE_INFO::m_Hole_Orient, HOLE_INFO::m_Hole_Pos, HOLE_INFO::m_Hole_Shape, HOLE_INFO::m_Hole_Size, m_holeListBuffer, m_merge_PTH_NPTH, m_minimalHeader, m_mirror, m_offset, HOLE_INFO::m_Tool_Reference, m_toolListBuffer, m_unitsDecimal, min, RotatePoint(), writeCoordinates(), writeEXCELLONEndOfFile(), writeEXCELLONHeader(), wxPoint::x, and wxPoint::y.

Referenced by CreateDrillandMapFilesSet().

171 {
172  m_file = aFile;
173 
174  int diam, holes_count;
175  int x0, y0, xf, yf, xc, yc;
176  double xt, yt;
177  char line[1024];
178 
179  LOCALE_IO dummy; // Use the standard notation for double numbers
180 
182 
183  holes_count = 0;
184 
185 #ifdef WRITE_PTH_NPTH_COMMENT
186  // if PTH_ and NPTH are merged write a comment in drill file at the
187  // beginning of NPTH section
188  bool writePTHcomment = m_merge_PTH_NPTH;
189  bool writeNPTHcomment = m_merge_PTH_NPTH;
190 #endif
191 
192  /* Write the tool list */
193  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
194  {
195  DRILL_TOOL& tool_descr = m_toolListBuffer[ii];
196 
197 #ifdef WRITE_PTH_NPTH_COMMENT
198  if( writePTHcomment && !tool_descr.m_Hole_NotPlated )
199  {
200  writePTHcomment = false;
201  fprintf( m_file, ";TYPE=PLATED\n" );
202  }
203 
204  if( writeNPTHcomment && tool_descr.m_Hole_NotPlated )
205  {
206  writeNPTHcomment = false;
207  fprintf( m_file, ";TYPE=NON_PLATED\n" );
208  }
209 #endif
210 
211  fprintf( m_file, "T%dC%.3f\n", ii + 1, tool_descr.m_Diameter * m_conversionUnits );
212  }
213 
214  fputs( "%\n", m_file ); // End of header info
215  fputs( "G90\n", m_file ); // Absolute mode
216  fputs( "G05\n", m_file ); // Drill mode
217 
218  // Units :
219  if( !m_minimalHeader )
220  {
221  if( m_unitsDecimal )
222  fputs( "M71\n", m_file ); /* M71 = metric mode */
223  else
224  fputs( "M72\n", m_file ); /* M72 = inch mode */
225  }
226 
227  /* Read the hole file and generate lines for normal holes (oblong
228  * holes will be created later) */
229  int tool_reference = -2;
230 
231  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
232  {
233  HOLE_INFO& hole_descr = m_holeListBuffer[ii];
234 
235  if( hole_descr.m_Hole_Shape )
236  continue; // oblong holes will be created later
237 
238  if( tool_reference != hole_descr.m_Tool_Reference )
239  {
240  tool_reference = hole_descr.m_Tool_Reference;
241  fprintf( m_file, "T%d\n", tool_reference );
242  }
243 
244  x0 = hole_descr.m_Hole_Pos.x - m_offset.x;
245  y0 = hole_descr.m_Hole_Pos.y - m_offset.y;
246 
247  if( !m_mirror )
248  y0 *= -1;
249 
250  xt = x0 * m_conversionUnits;
251  yt = y0 * m_conversionUnits;
252  writeCoordinates( line, xt, yt );
253 
254  fputs( line, m_file );
255  holes_count++;
256  }
257 
258  /* Read the hole file and generate lines for normal holes (oblong holes
259  * will be created later) */
260  tool_reference = -2; // set to a value not used for
261  // m_holeListBuffer[ii].m_Tool_Reference
262  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
263  {
264  HOLE_INFO& hole_descr = m_holeListBuffer[ii];
265 
266  if( hole_descr.m_Hole_Shape == 0 )
267  continue; // wait for oblong holes
268 
269  if( tool_reference != hole_descr.m_Tool_Reference )
270  {
271  tool_reference = hole_descr.m_Tool_Reference;
272  fprintf( m_file, "T%d\n", tool_reference );
273  }
274 
275  diam = std::min( hole_descr.m_Hole_Size.x, hole_descr.m_Hole_Size.y );
276 
277  if( diam == 0 )
278  continue;
279 
280  /* Compute the hole coordinates: */
281  xc = x0 = xf = hole_descr.m_Hole_Pos.x - m_offset.x;
282  yc = y0 = yf = hole_descr.m_Hole_Pos.y - m_offset.y;
283 
284  /* Compute the start and end coordinates for the shape */
285  if( hole_descr.m_Hole_Size.x < hole_descr.m_Hole_Size.y )
286  {
287  int delta = ( hole_descr.m_Hole_Size.y - hole_descr.m_Hole_Size.x ) / 2;
288  y0 -= delta;
289  yf += delta;
290  }
291  else
292  {
293  int delta = ( hole_descr.m_Hole_Size.x - hole_descr.m_Hole_Size.y ) / 2;
294  x0 -= delta;
295  xf += delta;
296  }
297 
298  RotatePoint( &x0, &y0, xc, yc, hole_descr.m_Hole_Orient );
299  RotatePoint( &xf, &yf, xc, yc, hole_descr.m_Hole_Orient );
300 
301  if( !m_mirror )
302  {
303  y0 *= -1;
304  yf *= -1;
305  }
306 
307  xt = x0 * m_conversionUnits;
308  yt = y0 * m_conversionUnits;
309  writeCoordinates( line, xt, yt );
310 
311  /* remove the '\n' from end of line, because we must add the "G85"
312  * command to the line: */
313  for( int kk = 0; line[kk] != 0; kk++ )
314  {
315  if( line[kk] == '\n' || line[kk] =='\r' )
316  line[kk] = 0;
317  }
318 
319  fputs( line, m_file );
320  fputs( "G85", m_file ); // add the "G85" command
321 
322  xt = xf * m_conversionUnits;
323  yt = yf * m_conversionUnits;
324  writeCoordinates( line, xt, yt );
325 
326  fputs( line, m_file );
327  fputs( "G05\n", m_file );
328  holes_count++;
329  }
330 
332 
333  return holes_count;
334 }
std::vector< DRILL_TOOL > m_toolListBuffer
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
static const int delta[8][2]
Definition: solve.cpp:112
void writeCoordinates(char *aLine, double aCoordX, double aCoordY)
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
std::vector< HOLE_INFO > m_holeListBuffer
#define min(a, b)
Definition: auxiliary.h:85
const wxString EXCELLON_WRITER::drillFileName ( DRILL_LAYER_PAIR  aPair,
bool  aNPTH,
bool  aMerge_PTH_NPTH 
) const
private
Returns
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
Parameters
aPair= the layer pair
aNPTH= true to generate the filename of NPTH holes
aMerge_PTH_NPTH= true to generate the filename of a file which containd both NPH and NPTH holes

Definition at line 742 of file gendrill_Excellon_writer.cpp.

References B_Cu, DrillFileExtension, F_Cu, BOARD::GetFileName(), layerPairName(), and m_pcb.

Referenced by CreateDrillandMapFilesSet(), and GenDrillReportFile().

744 {
745  wxASSERT( m_pcb );
746 
747  wxString extend;
748 
749  if( aNPTH )
750  extend = "-NPTH";
751  else if( aPair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
752  {
753  if( !aMerge_PTH_NPTH )
754  extend = "-PTH";
755  // if merged, extend with nothing
756  }
757  else
758  {
759  extend += '-';
760  extend += layerPairName( aPair );
761  }
762 
763  wxFileName fn = m_pcb->GetFileName();
764 
765  fn.SetName( fn.GetName() + extend );
766  fn.SetExt( DrillFileExtension );
767 
768  wxString ret = fn.GetFullName(); // show me in debugger
769 
770  return ret;
771 }
const wxString DrillFileExtension
const wxString & GetFileName() const
Definition: class_board.h:237
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
const std::string layerPairName(DRILL_LAYER_PAIR aPair) const
bool EXCELLON_WRITER::GenDrillMapFile ( const wxString &  aFullFileName,
PlotFormat  aFormat 
)

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

Parameters
aFullFileName: the full filename of the map file to create,
aFormat: one of the supported plot formats (see enum PlotFormat )

Definition at line 58 of file gen_drill_report_files.cpp.

References PAGE_INFO::A4, EDA_RECT::Centre(), diameter_in_inches(), diameter_in_mm(), dummy(), Edge_Cuts, PLOTTER::EndPlot(), FROM_UTF8(), BOARD::GetBoardEdgesBoundingBox(), EDA_RECT::GetBottom(), EDA_RECT::GetHeight(), PCB_PLOT_PARAMS::GetHPGLPenNum(), PCB_PLOT_PARAMS::GetHPGLPenSpeed(), GetOffset(), EDA_RECT::GetWidth(), EDA_RECT::GetX(), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, KiROUND(), DRILL_TOOL::m_Diameter, BOARD::m_Drawings, DRILL_TOOL::m_Hole_NotPlated, DRILL_TOOL::m_OvalCount, m_pageInfo, m_pcb, m_toolListBuffer, DRILL_TOOL::m_TotalCount, PLOTTER::Marker(), min, BOARD_ITEM::Next(), PLOTTER::OpenFile(), PCB_DIMENSION_T, PCB_LINE_T, PCB_MARKER_T, PCB_TARGET_T, PCB_TEXT_T, PLOT_FORMAT_DXF, PLOT_FORMAT_GERBER, PLOT_FORMAT_HPGL, PLOT_FORMAT_PDF, PLOT_FORMAT_POST, PLOT_FORMAT_SVG, BRDITEMS_PLOTTER::PlotDrawSegment(), plotDrillMarks(), BRDITEMS_PLOTTER::PlotTextePcb(), scale, PLOTTER::SetColorMode(), PLOTTER::SetCreator(), PLOTTER::SetCurrentLineWidth(), PLOTTER::SetDefaultLineWidth(), PLOTTER::SetGerberCoordinatesFormat(), BRDITEMS_PLOTTER::SetLayerSet(), PLOTTER::SetPageSettings(), HPGL_PLOTTER::SetPenNumber(), HPGL_PLOTTER::SetPenSpeed(), PLOTTER::SetViewport(), PLOTTER::StartPlot(), PLOTTER::Text(), wxPoint::x, and wxPoint::y.

Referenced by CreateDrillandMapFilesSet().

60 {
61  double scale = 1.0;
62  wxPoint offset;
63  PLOTTER* plotter = NULL;
64  PAGE_INFO dummy( PAGE_INFO::A4, false );
65 
66  PCB_PLOT_PARAMS plot_opts; // starts plotting with default options
67 
68  LOCALE_IO toggle; // use standard C notation for float numbers
69 
70  const PAGE_INFO& page_info = m_pageInfo ? *m_pageInfo : dummy;
71 
72  // Calculate dimensions and center of PCB
74 
75  // Calculate the scale for the format type, scale 1 in HPGL, drawing on
76  // an A4 sheet in PS, + text description of symbols
77  switch( aFormat )
78  {
79  case PLOT_FORMAT_GERBER:
80  offset = GetOffset();
81  plotter = new GERBER_PLOTTER();
82  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
83  plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm
84  break;
85 
86  case PLOT_FORMAT_HPGL: // Scale for HPGL format.
87  {
88  HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER;
89  plotter = hpgl_plotter;
90  hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
91  hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
92  plotter->SetPageSettings( page_info );
93  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
94  }
95  break;
96 
97 
98  default:
99  wxASSERT( false );
100  // fall through
101  case PLOT_FORMAT_PDF:
102  case PLOT_FORMAT_POST:
103  {
104  PAGE_INFO pageA4( wxT( "A4" ) );
105  wxSize pageSizeIU = pageA4.GetSizeIU();
106 
107  // Reserve a margin around the page.
108  int margin = KiROUND( 20 * IU_PER_MM );
109 
110  // Calculate a scaling factor to print the board on the sheet
111  double Xscale = double( pageSizeIU.x - ( 2 * margin ) ) / bbbox.GetWidth();
112 
113  // We should print the list of drill sizes, so reserve room for it
114  // 60% height for board 40% height for list
115  int ypagesize_for_board = KiROUND( pageSizeIU.y * 0.6 );
116  double Yscale = double( ypagesize_for_board - margin ) / bbbox.GetHeight();
117 
118  scale = std::min( Xscale, Yscale );
119 
120  // Experience shows the scale should not to large, because texts
121  // create problem (can be to big or too small).
122  // So the scale is clipped at 3.0;
123  scale = std::min( scale, 3.0 );
124 
125  offset.x = KiROUND( double( bbbox.Centre().x ) -
126  ( pageSizeIU.x / 2.0 ) / scale );
127  offset.y = KiROUND( double( bbbox.Centre().y ) -
128  ( ypagesize_for_board / 2.0 ) / scale );
129 
130  if( aFormat == PLOT_FORMAT_PDF )
131  plotter = new PDF_PLOTTER;
132  else
133  plotter = new PS_PLOTTER;
134 
135  plotter->SetPageSettings( pageA4 );
136  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
137  }
138  break;
139 
140  case PLOT_FORMAT_DXF:
141  {
142  DXF_PLOTTER* dxf_plotter = new DXF_PLOTTER;
143  plotter = dxf_plotter;
144  plotter->SetPageSettings( page_info );
145  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
146  }
147  break;
148 
149  case PLOT_FORMAT_SVG:
150  {
151  SVG_PLOTTER* svg_plotter = new SVG_PLOTTER;
152  plotter = svg_plotter;
153  plotter->SetPageSettings( page_info );
154  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
155  }
156  break;
157  }
158 
159  plotter->SetCreator( wxT( "PCBNEW" ) );
160  plotter->SetDefaultLineWidth( 5 * IU_PER_MILS );
161  plotter->SetColorMode( false );
162 
163  if( ! plotter->OpenFile( aFullFileName ) )
164  {
165  delete plotter;
166  return false;
167  }
168 
169  plotter->StartPlot();
170 
171  // Draw items on edge layer (not all, only items useful for drill map
172  BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
173  itemplotter.SetLayerSet( Edge_Cuts );
174 
175  for( EDA_ITEM* PtStruct = m_pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
176  {
177  switch( PtStruct->Type() )
178  {
179  case PCB_LINE_T:
180  itemplotter.PlotDrawSegment( (DRAWSEGMENT*) PtStruct );
181  break;
182 
183  case PCB_TEXT_T:
184  itemplotter.PlotTextePcb( (TEXTE_PCB*) PtStruct );
185  break;
186 
187  case PCB_DIMENSION_T:
188  case PCB_TARGET_T:
189  case PCB_MARKER_T: // do not draw
190  default:
191  break;
192  }
193  }
194 
195  int x, y;
196  int plotX, plotY, TextWidth;
197  int intervalle = 0;
198  char line[1024];
199  wxString msg;
200  int textmarginaftersymbol = KiROUND( 2 * IU_PER_MM );
201 
202  // Set Drill Symbols width
203  plotter->SetDefaultLineWidth( 0.2 * IU_PER_MM / scale );
204  plotter->SetCurrentLineWidth( -1 );
205 
206  // Plot board outlines and drill map
207  plotDrillMarks( plotter );
208 
209  // Print a list of symbols used.
210  int charSize = 3 * IU_PER_MM; // text size in IUs
211  double charScale = 1.0 / scale; // real scale will be 1/scale,
212  // because the global plot scale is scale
213  TextWidth = KiROUND( (charSize * charScale) / 10.0 ); // Set text width (thickness)
214  intervalle = KiROUND( charSize * charScale ) + TextWidth;
215 
216  // Trace information.
217  plotX = KiROUND( bbbox.GetX() + textmarginaftersymbol * charScale );
218  plotY = bbbox.GetBottom() + intervalle;
219 
220  // Plot title "Info"
221  wxString Text = wxT( "Drill Map:" );
222  plotter->Text( wxPoint( plotX, plotY ), COLOR4D::UNSPECIFIED, Text, 0,
223  wxSize( KiROUND( charSize * charScale ),
224  KiROUND( charSize * charScale ) ),
226  TextWidth, false, false );
227 
228  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
229  {
230  DRILL_TOOL& tool = m_toolListBuffer[ii];
231 
232  if( tool.m_TotalCount == 0 )
233  continue;
234 
235  plotY += intervalle;
236 
237  int plot_diam = KiROUND( tool.m_Diameter );
238  x = KiROUND( plotX - textmarginaftersymbol * charScale - plot_diam / 2.0 );
239  y = KiROUND( plotY + charSize * charScale );
240  plotter->Marker( wxPoint( x, y ), plot_diam, ii );
241 
242  // List the diameter of each drill in mm and inches.
243  sprintf( line, "%2.2fmm / %2.3f\" ",
244  diameter_in_mm( tool.m_Diameter ),
245  diameter_in_inches( tool.m_Diameter ) );
246 
247  msg = FROM_UTF8( line );
248 
249  // Now list how many holes and ovals are associated with each drill.
250  if( ( tool.m_TotalCount == 1 )
251  && ( tool.m_OvalCount == 0 ) )
252  sprintf( line, "(1 hole)" );
253  else if( tool.m_TotalCount == 1 ) // && ( toolm_OvalCount == 1 )
254  sprintf( line, "(1 slot)" );
255  else if( tool.m_OvalCount == 0 )
256  sprintf( line, "(%d holes)", tool.m_TotalCount );
257  else if( tool.m_OvalCount == 1 )
258  sprintf( line, "(%d holes + 1 slot)", tool.m_TotalCount - 1 );
259  else // if ( toolm_OvalCount > 1 )
260  sprintf( line, "(%d holes + %d slots)",
261  tool.m_TotalCount - tool.m_OvalCount,
262  tool.m_OvalCount );
263 
264  msg += FROM_UTF8( line );
265 
266  if( tool.m_Hole_NotPlated )
267  msg += wxT( " (not plated)" );
268 
269  plotter->Text( wxPoint( plotX, y ), COLOR4D::UNSPECIFIED, msg, 0,
270  wxSize( KiROUND( charSize * charScale ),
271  KiROUND( charSize * charScale ) ),
273  TextWidth, false, false );
274 
275  intervalle = KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 );
276 
277  if( intervalle < ( plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth ) )
278  intervalle = plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth;
279  }
280 
281  plotter->EndPlot();
282  delete plotter;
283 
284  return true;
285 }
double diameter_in_inches(double ius)
std::vector< DRILL_TOOL > m_toolListBuffer
double diameter_in_mm(double ius)
virtual void SetCreator(const wxString &aCreator)
Definition: plot_common.h:151
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
virtual bool StartPlot()=0
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
int GetHeight() const
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
virtual void SetGerberCoordinatesFormat(int aResolution, bool aUseInches=false)
Definition: plot_common.h:415
virtual void Text(const wxPoint &aPos, const COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, void *aData=NULL)
Draws text with the plotter.
Definition: drawtxt.cpp:227
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:839
BOARD_ITEM * Next() const
virtual bool EndPlot()=0
int GetHPGLPenNum() const
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
virtual void SetPenSpeed(int speed)
Definition: plot_common.h:586
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
static const wxChar A4[]
int GetBottom() const
wxPoint Centre() const
bool plotDrillMarks(PLOTTER *aPlotter)
Helper function.
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
const PAGE_INFO * m_pageInfo
virtual void SetViewport(const wxPoint &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord x0, y0.
virtual void SetDefaultLineWidth(int width)=0
Set the default line width.
Base plotter engine class.
Definition: plot_common.h:86
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:111
const int scale
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
virtual void SetPenNumber(int number)
Definition: plot_common.h:591
int GetHPGLPenSpeed() const
Class EDA_RECT handles the component boundary box.
int GetX() const
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
int GetWidth() const
const wxPoint GetOffset()
Return the plot offset (usually the position of the auxiliary axis.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
virtual void SetColorMode(bool _color_mode)
Definition: plot_common.h:116
#define min(a, b)
Definition: auxiliary.h:85
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
bool EXCELLON_WRITER::GenDrillReportFile ( const wxString &  aFullFileName)

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

Parameters
aFullFileName: the name of the file to create m_unitsDecimal = false to use inches, true to use mm in report file
Returns
success if the file is created

Definition at line 288 of file gen_drill_report_files.cpp.

References LSET::AllCuMask(), B_Cu, buildHolesList(), cu, DateAndTime(), drillFileName(), F_Cu, BOARD::GetEnabledLayers(), BOARD::GetFileName(), BOARD::GetLayerName(), getUniqueLayerPairs(), layerName(), m_merge_PTH_NPTH, m_pcb, OUTPUTFORMATTER::Print(), printToolSummary(), LSET::Seq(), TO_UTF8, and ToLAYER_ID().

289 {
290  FILE_OUTPUTFORMATTER out( aFullFileName );
291 
292  static const char separator[] =
293  " =============================================================\n";
294 
295  wxASSERT( m_pcb );
296 
297  unsigned totalHoleCount;
298  wxString brdFilename = m_pcb->GetFileName();
299 
300  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
301 
302  out.Print( 0, "Drill report for %s\n", TO_UTF8( brdFilename ) );
303  out.Print( 0, "Created on %s\n\n", TO_UTF8( DateAndTime() ) );
304 
305  // Output the cu layer stackup, so layer name references make sense.
306  out.Print( 0, "Copper Layer Stackup:\n" );
307  out.Print( 0, separator );
308 
310 
311  int conventional_layer_num = 1;
312  for( LSEQ seq = cu.Seq(); seq; ++seq, ++conventional_layer_num )
313  {
314  out.Print( 0, " L%-2d: %-25s %s\n",
315  conventional_layer_num,
316  TO_UTF8( m_pcb->GetLayerName( *seq ) ),
317  layerName( *seq ).c_str() // generic layer name
318  );
319  }
320 
321  out.Print( 0, "\n\n" );
322 
323  /* output hole lists:
324  * 1 - through holes
325  * 2 - for partial holes only: by layer starting and ending pair
326  * 3 - Non Plated through holes
327  */
328 
329  bool buildNPTHlist = false;
330 
331  // in this loop are plated only:
332  for( unsigned pair_ndx = 0; pair_ndx < hole_sets.size(); ++pair_ndx )
333  {
334  DRILL_LAYER_PAIR pair = hole_sets[pair_ndx];
335 
336  buildHolesList( pair, buildNPTHlist );
337 
338  if( pair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
339  {
340  out.Print( 0, "Drill file '%s' contains\n",
341  TO_UTF8( drillFileName( pair, false, m_merge_PTH_NPTH ) ) );
342 
343  out.Print( 0, " plated through holes:\n" );
344  out.Print( 0, separator );
345  totalHoleCount = printToolSummary( out, false );
346  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
347  }
348  else // blind/buried
349  {
350  out.Print( 0, "Drill file '%s' contains\n",
351  TO_UTF8( drillFileName( pair, false, m_merge_PTH_NPTH ) ) );
352 
353  out.Print( 0, " holes connecting layer pair: '%s and %s' (%s vias):\n",
354  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.first ) ) ),
355  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.second ) ) ),
356  pair.first == F_Cu || pair.second == B_Cu ? "blind" : "buried"
357  );
358 
359  out.Print( 0, separator );
360  totalHoleCount = printToolSummary( out, false );
361  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
362  }
363 
364  out.Print( 0, "\n\n" );
365  }
366 
367  // NPTHoles. Generate the full list (pads+vias) if PTH and NPTH are merged,
368  // or only the NPTH list (which never has vias)
369  if( !m_merge_PTH_NPTH )
370  buildNPTHlist = true;
371 
372  buildHolesList( DRILL_LAYER_PAIR( F_Cu, B_Cu ), buildNPTHlist );
373 
374  // nothing wrong with an empty NPTH file in report.
375  if( m_merge_PTH_NPTH )
376  out.Print( 0, "Not plated through holes are merged with plated holes\n" );
377  else
378  out.Print( 0, "Drill file '%s' contains\n",
380  true, m_merge_PTH_NPTH ) ) );
381 
382  out.Print( 0, " unplated through holes:\n" );
383  out.Print( 0, separator );
384  totalHoleCount = printToolSummary( out, true );
385  out.Print( 0, " Total unplated holes count %u\n", totalHoleCount );
386 
387  return true;
388 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:639
const wxString drillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
void buildHolesList(DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
Function BuildHolesList Create the list of holes and tools for a given board The list is sorted by in...
#define cu(a)
Definition: auxiliary.h:88
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
unsigned printToolSummary(OUTPUTFORMATTER &aOut, bool aSummaryNPTH) const
Function printToolSummary prints m_toolListBuffer[] tools to aOut and returns total hole count...
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:337
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
Class LSET is a set of PCB_LAYER_IDs.
const wxString & GetFileName() const
Definition: class_board.h:237
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
const std::string layerName(PCB_LAYER_ID aLayer) const
wxString DateAndTime()
Function DateAndTime.
Definition: string.cpp:229
int EXCELLON_WRITER::getHolesCount ( ) const
inlineprivate

Definition at line 322 of file gendrill_Excellon_writer.h.

Referenced by CreateDrillandMapFilesSet().

322 { return m_holeListBuffer.size(); }
std::vector< HOLE_INFO > m_holeListBuffer
const wxPoint EXCELLON_WRITER::GetOffset ( )
inline

Return the plot offset (usually the position of the auxiliary axis.

Definition at line 171 of file gendrill_Excellon_writer.h.

References m_offset.

Referenced by GenDrillMapFile().

171 { return m_offset; }
std::vector< DRILL_LAYER_PAIR > EXCELLON_WRITER::getUniqueLayerPairs ( ) const
private

Get unique layer pairs by examining the micro and blind_buried vias.

Definition at line 675 of file gendrill_Excellon_writer.cpp.

References B_Cu, PCB_TYPE_COLLECTOR::Collect(), EOT, F_Cu, COLLECTOR::GetCount(), VIA::LayerPair(), m_pcb, and PCB_VIA_T.

Referenced by CreateDrillandMapFilesSet(), and GenDrillReportFile().

676 {
677  wxASSERT( m_pcb );
678 
679  static const KICAD_T interesting_stuff_to_collect[] = {
680  PCB_VIA_T,
681  EOT
682  };
683 
684  PCB_TYPE_COLLECTOR vias;
685 
686  vias.Collect( m_pcb, interesting_stuff_to_collect );
687 
688  std::set< DRILL_LAYER_PAIR > unique;
689 
690  DRILL_LAYER_PAIR layer_pair;
691 
692  for( int i = 0; i < vias.GetCount(); ++i )
693  {
694  VIA* v = (VIA*) vias[i];
695 
696  v->LayerPair( &layer_pair.first, &layer_pair.second );
697 
698  // only make note of blind buried.
699  // thru hole is placed unconditionally as first in fetched list.
700  if( layer_pair != DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
701  {
702  unique.insert( layer_pair );
703  }
704  }
705 
706  std::vector<DRILL_LAYER_PAIR> ret;
707 
708  ret.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) ); // always first in returned list
709 
710  for( std::set< DRILL_LAYER_PAIR >::const_iterator it = unique.begin(); it != unique.end(); ++it )
711  ret.push_back( *it );
712 
713  return ret;
714 }
int GetCount() const
Function GetCount returns the number of objects in the list.
search types array terminator (End Of Types)
Definition: typeinfo.h:94
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Function Collect scans a BOARD_ITEM using this class's Inspector method, which does the collection...
Definition: collectors.cpp:488
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
Class PCB_TYPE_COLLECTOR merely gathers up all BOARD_ITEMs of a given set of KICAD_T type(s)...
Definition: collectors.h:593
const std::string EXCELLON_WRITER::layerName ( PCB_LAYER_ID  aLayer) const
private

Definition at line 717 of file gendrill_Excellon_writer.cpp.

References B_Cu, F_Cu, and StrPrintf().

Referenced by GenDrillReportFile(), and layerPairName().

718 {
719  // Generic names here.
720  switch( aLayer )
721  {
722  case F_Cu:
723  return "front";
724  case B_Cu:
725  return "back";
726  default:
727  return StrPrintf( "inner%d", aLayer );
728  }
729 }
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
const std::string EXCELLON_WRITER::layerPairName ( DRILL_LAYER_PAIR  aPair) const
private

Definition at line 732 of file gendrill_Excellon_writer.cpp.

References layerName().

Referenced by drillFileName().

733 {
734  std::string ret = layerName( aPair.first );
735  ret += '-';
736  ret += layerName( aPair.second );
737 
738  return ret;
739 }
const std::string layerName(PCB_LAYER_ID aLayer) const
bool EXCELLON_WRITER::plotDrillMarks ( PLOTTER aPlotter)
private

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

Parameters
aPlotter= a PLOTTER instance (HPGL, POSTSCRIPT ... plotter).

Definition at line 391 of file gen_drill_report_files.cpp.

References PLOTTER::FlashPadOval(), HOLE_INFO::m_Hole_Diameter, HOLE_INFO::m_Hole_Orient, HOLE_INFO::m_Hole_Pos, HOLE_INFO::m_Hole_Shape, HOLE_INFO::m_Hole_Size, m_holeListBuffer, HOLE_INFO::m_Tool_Reference, PLOTTER::Marker(), and SKETCH.

Referenced by GenDrillMapFile().

392 {
393  // Plot the drill map:
394  wxPoint pos;
395 
396  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
397  {
398  const HOLE_INFO& hole = m_holeListBuffer[ii];
399  pos = hole.m_Hole_Pos;
400 
401  // Always plot the drill symbol (for slots identifies the needed cutter!
402  aPlotter->Marker( pos, hole.m_Hole_Diameter, hole.m_Tool_Reference - 1 );
403 
404  if( hole.m_Hole_Shape != 0 )
405  {
406  wxSize oblong_size = hole.m_Hole_Size;
407  aPlotter->FlashPadOval( pos, oblong_size, hole.m_Hole_Orient, SKETCH, NULL );
408  }
409  }
410 
411  return true;
412 }
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord x0, y0.
std::vector< HOLE_INFO > m_holeListBuffer
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
unsigned EXCELLON_WRITER::printToolSummary ( OUTPUTFORMATTER aOut,
bool  aSummaryNPTH 
) const
private

Function printToolSummary prints m_toolListBuffer[] tools to aOut and returns total hole count.

Parameters
aOut= the current OUTPUTFORMATTER to print summary
aSummaryNPTH= true to print summary for NPTH, false for PTH

Definition at line 415 of file gen_drill_report_files.cpp.

References diameter_in_inches(), diameter_in_mm(), DRILL_TOOL::m_Diameter, DRILL_TOOL::m_Hole_NotPlated, DRILL_TOOL::m_OvalCount, m_toolListBuffer, DRILL_TOOL::m_TotalCount, and OUTPUTFORMATTER::Print().

Referenced by GenDrillReportFile().

416 {
417  unsigned totalHoleCount = 0;
418 
419  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
420  {
421  const DRILL_TOOL& tool = m_toolListBuffer[ii];
422 
423  if( aSummaryNPTH && !tool.m_Hole_NotPlated )
424  continue;
425 
426  if( !aSummaryNPTH && tool.m_Hole_NotPlated )
427  continue;
428 
429  // List the tool number assigned to each drill,
430  // in mm then in inches.
431  int tool_number = ii+1;
432  out.Print( 0, " T%d %2.2fmm %2.3f\" ", tool_number,
433  diameter_in_mm( tool.m_Diameter ),
434  diameter_in_inches( tool.m_Diameter ) );
435 
436  // Now list how many holes and ovals are associated with each drill.
437  if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
438  out.Print( 0, "(1 hole)\n" );
439  else if( tool.m_TotalCount == 1 )
440  out.Print( 0, "(1 hole) (with 1 slot)\n" );
441  else if( tool.m_OvalCount == 0 )
442  out.Print( 0, "(%d holes)\n", tool.m_TotalCount );
443  else if( tool.m_OvalCount == 1 )
444  out.Print( 0, "(%d holes) (with 1 slot)\n", tool.m_TotalCount );
445  else // tool.m_OvalCount > 1
446  out.Print( 0, "(%d holes) (with %d slots)\n",
447  tool.m_TotalCount, tool.m_OvalCount );
448 
449  totalHoleCount += tool.m_TotalCount;
450  }
451 
452  out.Print( 0, "\n" );
453 
454  return totalHoleCount;
455 }
double diameter_in_inches(double ius)
std::vector< DRILL_TOOL > m_toolListBuffer
double diameter_in_mm(double ius)
void EXCELLON_WRITER::SetFormat ( bool  aMetric,
ZEROS_FMT  aZerosFmt = DECIMAL_FORMAT,
int  aLeftDigits = 0,
int  aRightDigits = 0 
)

Function SetFormat Initialize internal parameters to match the given format.

Parameters
aMetric= true for metric coordinates, false for imperial units
aZerosFmt= DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS
aLeftDigits= number of digits for integer part of coordinates if <= 0 (default), a suitable value will be used, depending on units
aRightDigits= number of digits for mantissa part of coordinates if <= 0 (default), a suitable value will be used, depending on units

Definition at line 337 of file gendrill_Excellon_writer.cpp.

References m_conversionUnits, DRILL_PRECISION::m_lhs, m_precision, DRILL_PRECISION::m_rhs, m_unitsDecimal, and m_zeroFormat.

Referenced by DIALOG_GENDRILL::GenDrillAndMapFiles(), and DIALOG_GENDRILL::OnGenReportFile().

341 {
342  m_unitsDecimal = aMetric;
343  m_zeroFormat = aZerosFmt;
344 
345  /* Set conversion scale depending on drill file units */
346  if( m_unitsDecimal )
347  m_conversionUnits = 1.0 / IU_PER_MM; // EXCELLON units = mm
348  else
349  m_conversionUnits = 0.001 / IU_PER_MILS; // EXCELLON units = INCHES
350 
351  // Set the zero counts. if aZerosFmt == DECIMAL_FORMAT, these values
352  // will be set, but not used.
353  if( aLeftDigits <= 0 )
354  aLeftDigits = m_unitsDecimal ? 3 : 2;
355 
356  if( aRightDigits <= 0 )
357  aRightDigits = m_unitsDecimal ? 3 : 4;
358 
359  m_precision.m_lhs = aLeftDigits;
360  m_precision.m_rhs = aRightDigits;
361 }
DRILL_PRECISION m_precision
void EXCELLON_WRITER::SetMapFileFormat ( PlotFormat  aMapFmt)
inline

Function SetMapFileFormat Initialize the format for the drill map file.

Parameters
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

Definition at line 201 of file gendrill_Excellon_writer.h.

201 { m_mapFileFmt = aMapFmt; }
void EXCELLON_WRITER::SetOptions ( bool  aMirror,
bool  aMinimalHeader,
wxPoint  aOffset,
bool  aMerge_PTH_NPTH 
)
inline

Function SetOptions Initialize internal parameters to match drill options.

Parameters
aMirror= true to create mirrored coordinates (Y coordinates negated)
aMinimalHeader= true to use a minimal header (no comments, no info)
aOffset= drill coordinates offset

Definition at line 211 of file gendrill_Excellon_writer.h.

212  {
213  m_mirror = aMirror;
214  m_offset = aOffset;
215  m_minimalHeader = aMinimalHeader;
216  m_merge_PTH_NPTH = aMerge_PTH_NPTH;
217  }
void EXCELLON_WRITER::SetPageInfo ( const PAGE_INFO aPageInfo)
inline

Sets the page info used to plot drill maps If NULL, a A4 page format will be used.

Parameters
aPageInfo= a reference to the page info, usually used to plot/display the board

Definition at line 191 of file gendrill_Excellon_writer.h.

191 { m_pageInfo = aPageInfo; }
const PAGE_INFO * m_pageInfo
void EXCELLON_WRITER::writeCoordinates ( char *  aLine,
double  aCoordX,
double  aCoordY 
)
private

Definition at line 364 of file gendrill_Excellon_writer.cpp.

References DECIMAL_FORMAT, KEEP_ZEROS, KiROUND(), DRILL_PRECISION::m_lhs, m_precision, DRILL_PRECISION::m_rhs, m_unitsDecimal, m_zeroFormat, SUPPRESS_LEADING, SUPPRESS_TRAILING, and TO_UTF8.

Referenced by createDrillFile().

365 {
366  wxString xs, ys;
367  int xpad = m_precision.m_lhs + m_precision.m_rhs;
368  int ypad = xpad;
369 
370  switch( m_zeroFormat )
371  {
372  default:
373  case DECIMAL_FORMAT:
374  /* In Excellon files, resolution is 1/1000 mm or 1/10000 inch (0.1 mil)
375  * Although in decimal format, Excellon specifications do not specify
376  * clearly the resolution. However it seems to be 1/1000mm or 0.1 mil
377  * like in non decimal formats, so we trunk coordinates to 3 or 4 digits in mantissa
378  * Decimal format just prohibit useless leading 0:
379  * 0.45 or .45 is right, but 00.54 is incorrect.
380  */
381  if( m_unitsDecimal )
382  {
383  // resolution is 1/1000 mm
384  xs.Printf( wxT( "%.3f" ), aCoordX );
385  ys.Printf( wxT( "%.3f" ), aCoordY );
386  }
387  else
388  {
389  // resolution is 1/10000 inch
390  xs.Printf( wxT( "%.4f" ), aCoordX );
391  ys.Printf( wxT( "%.4f" ), aCoordY );
392  }
393 
394  //Remove useless trailing 0
395  while( xs.Last() == '0' )
396  xs.RemoveLast();
397 
398  while( ys.Last() == '0' )
399  ys.RemoveLast();
400 
401  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
402  break;
403 
404  case SUPPRESS_LEADING:
405  for( int i = 0; i< m_precision.m_rhs; i++ )
406  {
407  aCoordX *= 10; aCoordY *= 10;
408  }
409 
410  sprintf( aLine, "X%dY%d\n", KiROUND( aCoordX ), KiROUND( aCoordY ) );
411  break;
412 
413  case SUPPRESS_TRAILING:
414  {
415  for( int i = 0; i < m_precision.m_rhs; i++ )
416  {
417  aCoordX *= 10;
418  aCoordY *= 10;
419  }
420 
421  if( aCoordX < 0 )
422  xpad++;
423 
424  if( aCoordY < 0 )
425  ypad++;
426 
427  xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
428  ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
429 
430  size_t j = xs.Len() - 1;
431 
432  while( xs[j] == '0' && j )
433  xs.Truncate( j-- );
434 
435  j = ys.Len() - 1;
436 
437  while( ys[j] == '0' && j )
438  ys.Truncate( j-- );
439 
440  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
441  break;
442  }
443 
444  case KEEP_ZEROS:
445  for( int i = 0; i< m_precision.m_rhs; i++ )
446  {
447  aCoordX *= 10; aCoordY *= 10;
448  }
449 
450  if( aCoordX < 0 )
451  xpad++;
452 
453  if( aCoordY < 0 )
454  ypad++;
455 
456  xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
457  ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
458  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
459  break;
460  }
461 }
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
DRILL_PRECISION m_precision
void EXCELLON_WRITER::writeEXCELLONEndOfFile ( )
private

Definition at line 529 of file gendrill_Excellon_writer.cpp.

References m_file.

Referenced by createDrillFile().

530 {
531  //add if minimal here
532  fputs( "T0\nM30\n", m_file );
533  fclose( m_file );
534 }
void EXCELLON_WRITER::writeEXCELLONHeader ( )
private

Definition at line 464 of file gendrill_Excellon_writer.cpp.

References DateAndTime(), DECIMAL_FORMAT, GetBuildVersion(), DRILL_PRECISION::GetPrecisionString(), KEEP_ZEROS, m_file, m_minimalHeader, m_precision, m_unitsDecimal, m_zeroFormat, SUPPRESS_LEADING, SUPPRESS_TRAILING, and TO_UTF8.

Referenced by createDrillFile().

465 {
466  fputs( "M48\n", m_file ); // The beginning of a header
467 
468  if( !m_minimalHeader )
469  {
470  // The next 2 lines in EXCELLON files are comments:
471  wxString msg;
472  msg << wxT("KiCad") << wxT( " " ) << GetBuildVersion();
473 
474  fprintf( m_file, ";DRILL file {%s} date %s\n", TO_UTF8( msg ), TO_UTF8( DateAndTime() ) );
475  msg = wxT( ";FORMAT={" );
476 
477  // Print precision:
480  else
481  msg << wxT( "-:-" ); // in decimal format the precision is irrelevant
482 
483  msg << wxT( "/ absolute / " );
484  msg << ( m_unitsDecimal ? wxT( "metric" ) : wxT( "inch" ) );
485 
486  /* Adding numbers notation format.
487  * this is same as m_Choice_Zeros_Format strings, but NOT translated
488  * because some EXCELLON parsers do not like non ASCII values
489  * so we use ONLY English (ASCII) strings.
490  * if new options are added in m_Choice_Zeros_Format, they must also
491  * be added here
492  */
493  msg << wxT( " / " );
494 
495  const wxString zero_fmt[4] =
496  {
497  wxT( "decimal" ),
498  wxT( "suppress leading zeros" ),
499  wxT( "suppress trailing zeros" ),
500  wxT( "keep zeros" )
501  };
502 
503  msg << zero_fmt[m_zeroFormat];
504  msg << wxT( "}\n" );
505  fputs( TO_UTF8( msg ), m_file );
506  fputs( "FMAT,2\n", m_file ); // Use Format 2 commands (version used since 1979)
507  }
508 
509  fputs( m_unitsDecimal ? "METRIC" : "INCH", m_file );
510 
511  switch( m_zeroFormat )
512  {
513  case SUPPRESS_LEADING:
514  case DECIMAL_FORMAT:
515  fputs( ",TZ\n", m_file );
516  break;
517 
518  case SUPPRESS_TRAILING:
519  fputs( ",LZ\n", m_file );
520  break;
521 
522  case KEEP_ZEROS:
523  fputs( ",TZ\n", m_file ); // TZ is acceptable when all zeros are kept
524  break;
525  }
526 }
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
DRILL_PRECISION m_precision
wxString DateAndTime()
Function DateAndTime.
Definition: string.cpp:229

Member Data Documentation

double EXCELLON_WRITER::m_conversionUnits
private

Definition at line 147 of file gendrill_Excellon_writer.h.

Referenced by createDrillFile(), EXCELLON_WRITER(), and SetFormat().

FILE* EXCELLON_WRITER::m_file
private
std::vector<HOLE_INFO> EXCELLON_WRITER::m_holeListBuffer
private

Definition at line 152 of file gendrill_Excellon_writer.h.

Referenced by buildHolesList(), createDrillFile(), and plotDrillMarks().

PlotFormat EXCELLON_WRITER::m_mapFileFmt
private

Definition at line 155 of file gendrill_Excellon_writer.h.

Referenced by CreateDrillandMapFilesSet(), and EXCELLON_WRITER().

bool EXCELLON_WRITER::m_merge_PTH_NPTH
private
bool EXCELLON_WRITER::m_minimalHeader
private
bool EXCELLON_WRITER::m_mirror
private

Definition at line 149 of file gendrill_Excellon_writer.h.

Referenced by createDrillFile(), and EXCELLON_WRITER().

wxPoint EXCELLON_WRITER::m_Offset

Definition at line 136 of file gendrill_Excellon_writer.h.

wxPoint EXCELLON_WRITER::m_offset
private

Definition at line 150 of file gendrill_Excellon_writer.h.

Referenced by createDrillFile(), and GetOffset().

const PAGE_INFO* EXCELLON_WRITER::m_pageInfo
private

Definition at line 157 of file gendrill_Excellon_writer.h.

Referenced by EXCELLON_WRITER(), and GenDrillMapFile().

BOARD* EXCELLON_WRITER::m_pcb
private
DRILL_PRECISION EXCELLON_WRITER::m_precision
private

Definition at line 146 of file gendrill_Excellon_writer.h.

Referenced by SetFormat(), writeCoordinates(), and writeEXCELLONHeader().

bool EXCELLON_WRITER::m_ShortHeader

Definition at line 137 of file gendrill_Excellon_writer.h.

Referenced by EXCELLON_WRITER().

std::vector<DRILL_TOOL> EXCELLON_WRITER::m_toolListBuffer
private
bool EXCELLON_WRITER::m_unitsDecimal
private
ZEROS_FMT EXCELLON_WRITER::m_zeroFormat
private

The documentation for this class was generated from the following files: