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>

Inheritance diagram for EXCELLON_WRITER:
GENDRILL_WRITER_BASE

Public Types

enum  ZEROS_FMT { DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS }
 

Public Member Functions

 EXCELLON_WRITER (BOARD *aPcb)
 
virtual ~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 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...
 
void SetMergeOption (bool aMerge)
 set the option to make separate drill files for PTH and NPTH 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)
 Initialize the format for the drill map file. More...
 
void CreateMapFilesSet (const wxString &aPlotDirectory, REPORTER *aReporter=NULL)
 Function CreateMapFilesSet Creates the full set of map files for the board, in PS, PDF ... 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...
 

Protected Member Functions

bool genDrillMapFile (const wxString &aFullFileName, PlotFormat aFormat)
 Function GenDrillMapFile Plot a map of drill marks for holes. 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
 
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
 minor helper function. More...
 
const std::string layerName (PCB_LAYER_ID aLayer) const
 minor helper function. More...
 
virtual const wxString getDrillFileName (DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
 
const wxString BuildFileFunctionAttributeString (DRILL_LAYER_PAIR aLayerPair, bool aIsNpth, bool aCompatNCdrill=false) const
 

Protected Attributes

BOARDm_pcb
 
wxString m_drillFileExtension
 
bool m_unitsMetric
 
ZEROS_FMT m_zeroFormat
 
DRILL_PRECISION m_precision
 
double m_conversionUnits
 
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
 

Private Member Functions

int createDrillFile (FILE *aFile, DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
 Function CreateDrillFile Creates an Excellon drill file. More...
 
void writeEXCELLONHeader (DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
 
void writeEXCELLONEndOfFile ()
 
void writeCoordinates (char *aLine, double aCoordX, double aCoordY)
 

Private Attributes

FILE * m_file
 
bool m_minimalHeader
 
bool m_mirror
 

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 44 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_file_writer_base.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)

Definition at line 65 of file gendrill_Excellon_writer.cpp.

References GENDRILL_WRITER_BASE::DECIMAL_FORMAT, DrillFileExtension, GENDRILL_WRITER_BASE::m_conversionUnits, GENDRILL_WRITER_BASE::m_drillFileExtension, m_file, GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, m_minimalHeader, m_mirror, and GENDRILL_WRITER_BASE::m_zeroFormat.

virtual EXCELLON_WRITER::~EXCELLON_WRITER ( )
inlinevirtual

Definition at line 54 of file gendrill_Excellon_writer.h.

55  {
56  }

Member Function Documentation

const wxString GENDRILL_WRITER_BASE::BuildFileFunctionAttributeString ( DRILL_LAYER_PAIR  aLayerPair,
bool  aIsNpth,
bool  aCompatNCdrill = false 
) const
protectedinherited
Returns
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.
Parameters
aLayerPairis the layer pair (Drill from rom first layer to second layer)
aIsNpthis true when generating NPTH drill file
aCompatNCdrillis true when generating NC (Excellon) compatible drill file

Definition at line 347 of file gendrill_file_writer_base.cpp.

References B_Cu, BOARD::GetCopperLayerCount(), HOLE_INFO::m_Hole_Shape, GENDRILL_WRITER_BASE::m_holeListBuffer, and GENDRILL_WRITER_BASE::m_pcb.

Referenced by GERBER_WRITER::createDrillFile(), and writeEXCELLONHeader().

349 {
350 // Build a wxString containing the .FileFunction attribute for drill files.
351 // %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],Drill[Route][Mixed]*%
352  wxString text;
353 
354  if( aCompatNCdrill )
355  text = "; #@! ";
356  else
357  text = "%";
358 
359  text << "TF.FileFunction,";
360 
361  if( aIsNpth )
362  text << "NonPlated,";
363  else
364  text << "Plated,";
365 
366  int layer1 = aLayerPair.first;
367  int layer2 = aLayerPair.second;
368  // In Gerber files, layers num are 1 to copper layer count instead of F_Cu to B_Cu
369  // (0 to copper layer count-1)
370  // Note also for a n copper layers board, gerber layers num are 1 ... n
371  layer1 += 1;
372 
373  if( layer2 == B_Cu )
374  layer2 = m_pcb->GetCopperLayerCount();
375  else
376  layer2 += 1;
377 
378  text << layer1 << ",";
379  text << layer2 << ",";
380 
381  // Now add PTH or NPTH or Blind or Buried attribute
382  int toplayer = 1;
383  int bottomlayer = m_pcb->GetCopperLayerCount();
384 
385  if( aIsNpth )
386  text << "NPTH";
387  else if( layer1 == toplayer && layer2 == bottomlayer )
388  text << "PTH";
389  else if( layer1 == toplayer || layer2 == bottomlayer )
390  text << "Blind";
391  else
392  text << "Buried";
393 
394  // In NC drill file, these previous parameters should be enough:
395  if( aCompatNCdrill )
396  return text;
397 
398 
399  // Now add Drill or Route or Mixed:
400  // file containing only round holes have Drill attribute
401  // file containing only oblong holes have Routed attribute
402  // file containing both holes have Mixed attribute
403  bool hasOblong = false;
404  bool hasDrill = false;
405 
406  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
407  {
408  const HOLE_INFO& hole_descr = m_holeListBuffer[ii];
409 
410  if( hole_descr.m_Hole_Shape ) // m_Hole_Shape not 0 is an oblong hole)
411  hasOblong = true;
412  else
413  hasDrill = true;
414  }
415 
416  if( hasOblong && hasDrill )
417  text << ",Mixed";
418  else if( hasDrill )
419  text << ",Drill";
420  else if( hasOblong )
421  text << ",Route";
422 
423  // else: empty file.
424 
425  // End of .FileFunction attribute:
426  text << "*%";
427 
428  return text;
429 }
int GetCopperLayerCount() const
Function GetCopperLayerCount.
std::vector< HOLE_INFO > m_holeListBuffer
void GENDRILL_WRITER_BASE::buildHolesList ( DRILL_LAYER_PAIR  aLayerPair,
bool  aGenerateNPTH_list 
)
protectedinherited

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 72 of file gendrill_file_writer_base.cpp.

References B_Cu, CmpHoleSorting(), 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, GENDRILL_WRITER_BASE::m_holeListBuffer, HOLE_INFO::m_ItemParent, GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, BOARD::m_Modules, GENDRILL_WRITER_BASE::m_pcb, HOLE_INFO::m_Tool_Reference, GENDRILL_WRITER_BASE::m_toolListBuffer, BOARD::m_Track, min, MODULE::Next(), PAD_ATTRIB_HOLE_NOT_PLATED, and PAD_DRILL_SHAPE_CIRCLE.

Referenced by GERBER_WRITER::CreateDrillandMapFilesSet(), CreateDrillandMapFilesSet(), GENDRILL_WRITER_BASE::CreateMapFilesSet(), and GENDRILL_WRITER_BASE::GenDrillReportFile().

74 {
75  HOLE_INFO new_hole;
76 
77  m_holeListBuffer.clear();
78  m_toolListBuffer.clear();
79 
80  wxASSERT( aLayerPair.first < aLayerPair.second ); // fix the caller
81 
82  // build hole list for vias
83  if( ! aGenerateNPTH_list ) // vias are always plated !
84  {
85  for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; via = GetFirstVia( via->Next() ) )
86  {
87  int hole_sz = via->GetDrillValue();
88 
89  if( hole_sz == 0 ) // Should not occur.
90  continue;
91 
92  new_hole.m_ItemParent = via;
93  new_hole.m_Tool_Reference = -1; // Flag value for Not initialized
94  new_hole.m_Hole_Orient = 0;
95  new_hole.m_Hole_Diameter = hole_sz;
96  new_hole.m_Hole_NotPlated = false;
97  new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
98 
99  new_hole.m_Hole_Shape = 0; // hole shape: round
100  new_hole.m_Hole_Pos = via->GetStart();
101 
102  via->LayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
103 
104  // LayerPair() returns params with m_Hole_Bottom_Layer > m_Hole_Top_Layer
105  // Remember: top layer = 0 and bottom layer = 31 for through hole vias
106  // Any captured via should be from aLayerPair.first to aLayerPair.second exactly.
107  if( new_hole.m_Hole_Top_Layer != aLayerPair.first ||
108  new_hole.m_Hole_Bottom_Layer != aLayerPair.second )
109  continue;
110 
111  m_holeListBuffer.push_back( new_hole );
112  }
113  }
114 
115  if( aLayerPair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
116  {
117  // add holes for thru hole pads
118  for( MODULE* module = m_pcb->m_Modules; module; module = module->Next() )
119  {
120  for( auto& pad : module->Pads() )
121  {
122  if( !m_merge_PTH_NPTH )
123  {
124  if( !aGenerateNPTH_list && pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
125  continue;
126 
127  if( aGenerateNPTH_list && pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
128  continue;
129  }
130 
131  if( pad->GetDrillSize().x == 0 )
132  continue;
133 
134  new_hole.m_ItemParent = pad;
135  new_hole.m_Hole_NotPlated = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED);
136  new_hole.m_Tool_Reference = -1; // Flag is: Not initialized
137  new_hole.m_Hole_Orient = pad->GetOrientation();
138  new_hole.m_Hole_Shape = 0; // hole shape: round
139  new_hole.m_Hole_Diameter = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y );
140  new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
141 
142  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
143  new_hole.m_Hole_Shape = 1; // oval flag set
144 
145  new_hole.m_Hole_Size = pad->GetDrillSize();
146  new_hole.m_Hole_Pos = pad->GetPosition(); // hole position
147  new_hole.m_Hole_Bottom_Layer = B_Cu;
148  new_hole.m_Hole_Top_Layer = F_Cu; // pad holes are through holes
149  m_holeListBuffer.push_back( new_hole );
150  }
151  }
152  }
153 
154  // Sort holes per increasing diameter value
155  sort( m_holeListBuffer.begin(), m_holeListBuffer.end(), CmpHoleSorting );
156 
157  // build the tool list
158  int last_hole = -1; // Set to not initialized (this is a value not used
159  // for m_holeListBuffer[ii].m_Hole_Diameter)
160  bool last_notplated_opt = false;
161 
162  DRILL_TOOL new_tool( 0, false );
163  unsigned jj;
164 
165  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
166  {
167  if( m_holeListBuffer[ii].m_Hole_Diameter != last_hole ||
168  m_holeListBuffer[ii].m_Hole_NotPlated != last_notplated_opt )
169  {
170  new_tool.m_Diameter = m_holeListBuffer[ii].m_Hole_Diameter;
171  new_tool.m_Hole_NotPlated = m_holeListBuffer[ii].m_Hole_NotPlated;
172  m_toolListBuffer.push_back( new_tool );
173  last_hole = new_tool.m_Diameter;
174  last_notplated_opt = new_tool.m_Hole_NotPlated;
175  }
176 
177  jj = m_toolListBuffer.size();
178 
179  if( jj == 0 )
180  continue; // Should not occurs
181 
182  m_holeListBuffer[ii].m_Tool_Reference = jj; // Tool value Initialized (value >= 1)
183 
184  m_toolListBuffer.back().m_TotalCount++;
185 
186  if( m_holeListBuffer[ii].m_Hole_Shape )
187  m_toolListBuffer.back().m_OvalCount++;
188  }
189 }
BOARD_ITEM * m_ItemParent
static bool CmpHoleSorting(const HOLE_INFO &a, const HOLE_INFO &b)
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
MODULE * Next() const
Definition: class_module.h:122
std::vector< DRILL_TOOL > m_toolListBuffer
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
DLIST< MODULE > m_Modules
Definition: class_board.h:249
DLIST< TRACK > m_Track
Definition: class_board.h:250
std::vector< HOLE_INFO > m_holeListBuffer
#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:514
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 78 of file gendrill_Excellon_writer.cpp.

References B_Cu, GENDRILL_WRITER_BASE::buildHolesList(), createDrillFile(), GENDRILL_WRITER_BASE::CreateMapFilesSet(), F_Cu, GetChars(), GENDRILL_WRITER_BASE::getDrillFileName(), GENDRILL_WRITER_BASE::getHolesCount(), GENDRILL_WRITER_BASE::getUniqueLayerPairs(), GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, and REPORTER::Report().

Referenced by SetOptions().

81 {
82  wxFileName fn;
83  wxString msg;
84 
85  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
86 
87  // append a pair representing the NPTH set of holes, for separate drill files.
88  if( !m_merge_PTH_NPTH )
89  hole_sets.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) );
90 
91  for( std::vector<DRILL_LAYER_PAIR>::const_iterator it = hole_sets.begin();
92  it != hole_sets.end(); ++it )
93  {
94  DRILL_LAYER_PAIR pair = *it;
95  // For separate drill files, the last layer pair is the NPTH drill file.
96  bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 );
97 
98  buildHolesList( pair, doing_npth );
99 
100  // The file is created if it has holes, or if it is the non plated drill file
101  // to be sure the NPTH file is up to date in separate files mode.
102  if( getHolesCount() > 0 || doing_npth )
103  {
104  fn = getDrillFileName( pair, doing_npth, m_merge_PTH_NPTH );
105  fn.SetPath( aPlotDirectory );
106 
107  if( aGenDrill )
108  {
109  wxString fullFilename = fn.GetFullPath();
110 
111  FILE* file = wxFopen( fullFilename, wxT( "w" ) );
112 
113  if( file == NULL )
114  {
115  if( aReporter )
116  {
117  msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) );
118  aReporter->Report( msg );
119  }
120  break;
121  }
122  else
123  {
124  if( aReporter )
125  {
126  msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
127  aReporter->Report( msg );
128  }
129  }
130 
131  createDrillFile( file, pair, doing_npth );
132  }
133  }
134  }
135 
136  if( aGenMap )
137  CreateMapFilesSet( aPlotDirectory, aReporter );
138 }
virtual const wxString getDrillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
int createDrillFile(FILE *aFile, DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
Function CreateDrillFile Creates an Excellon drill file.
void CreateMapFilesSet(const wxString &aPlotDirectory, REPORTER *aReporter=NULL)
Function CreateMapFilesSet Creates the full set of map files for the board, in PS, PDF ...
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
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...
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
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,
DRILL_LAYER_PAIR  aLayerPair,
bool  aGenerateNPTH_list 
)
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 141 of file gendrill_Excellon_writer.cpp.

References delta, dummy(), GENDRILL_WRITER_BASE::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, GENDRILL_WRITER_BASE::m_holeListBuffer, GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, m_mirror, GENDRILL_WRITER_BASE::m_offset, HOLE_INFO::m_Tool_Reference, GENDRILL_WRITER_BASE::m_toolListBuffer, GENDRILL_WRITER_BASE::m_unitsMetric, min, RotatePoint(), writeCoordinates(), writeEXCELLONEndOfFile(), and writeEXCELLONHeader().

Referenced by CreateDrillandMapFilesSet(), and SetOptions().

143 {
144  m_file = aFile;
145 
146  int diam, holes_count;
147  int x0, y0, xf, yf, xc, yc;
148  double xt, yt;
149  char line[1024];
150 
151  LOCALE_IO dummy; // Use the standard notation for double numbers
152 
153  writeEXCELLONHeader( aLayerPair, aGenerateNPTH_list );
154 
155  holes_count = 0;
156 
157 #ifdef WRITE_PTH_NPTH_COMMENT
158  // if PTH_ and NPTH are merged write a comment in drill file at the
159  // beginning of NPTH section
160  bool writePTHcomment = m_merge_PTH_NPTH;
161  bool writeNPTHcomment = m_merge_PTH_NPTH;
162 #endif
163 
164  /* Write the tool list */
165  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
166  {
167  DRILL_TOOL& tool_descr = m_toolListBuffer[ii];
168 
169 #ifdef WRITE_PTH_NPTH_COMMENT
170  if( writePTHcomment && !tool_descr.m_Hole_NotPlated )
171  {
172  writePTHcomment = false;
173  fprintf( m_file, ";TYPE=PLATED\n" );
174  }
175 
176  if( writeNPTHcomment && tool_descr.m_Hole_NotPlated )
177  {
178  writeNPTHcomment = false;
179  fprintf( m_file, ";TYPE=NON_PLATED\n" );
180  }
181 #endif
182 
183  if( m_unitsMetric ) // if units are mm, the resolution is 0.001 mm (3 digits in mantissa)
184  fprintf( m_file, "T%dC%.3f\n", ii + 1, tool_descr.m_Diameter * m_conversionUnits );
185  else // if units are inches, the resolution is 0.1 mil (4 digits in mantissa)
186  fprintf( m_file, "T%dC%.4f\n", ii + 1, tool_descr.m_Diameter * m_conversionUnits );
187  }
188 
189  fputs( "%\n", m_file ); // End of header info
190  fputs( "G90\n", m_file ); // Absolute mode
191  fputs( "G05\n", m_file ); // Drill mode
192 
193  /* Read the hole file and generate lines for normal holes (oblong
194  * holes will be created later) */
195  int tool_reference = -2;
196 
197  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
198  {
199  HOLE_INFO& hole_descr = m_holeListBuffer[ii];
200 
201  if( hole_descr.m_Hole_Shape )
202  continue; // oblong holes will be created later
203 
204  if( tool_reference != hole_descr.m_Tool_Reference )
205  {
206  tool_reference = hole_descr.m_Tool_Reference;
207  fprintf( m_file, "T%d\n", tool_reference );
208  }
209 
210  x0 = hole_descr.m_Hole_Pos.x - m_offset.x;
211  y0 = hole_descr.m_Hole_Pos.y - m_offset.y;
212 
213  if( !m_mirror )
214  y0 *= -1;
215 
216  xt = x0 * m_conversionUnits;
217  yt = y0 * m_conversionUnits;
218  writeCoordinates( line, xt, yt );
219 
220  fputs( line, m_file );
221  holes_count++;
222  }
223 
224  /* Read the hole file and generate lines for normal holes (oblong holes
225  * will be created later) */
226  tool_reference = -2; // set to a value not used for
227  // m_holeListBuffer[ii].m_Tool_Reference
228  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
229  {
230  HOLE_INFO& hole_descr = m_holeListBuffer[ii];
231 
232  if( hole_descr.m_Hole_Shape == 0 )
233  continue; // wait for oblong holes
234 
235  if( tool_reference != hole_descr.m_Tool_Reference )
236  {
237  tool_reference = hole_descr.m_Tool_Reference;
238  fprintf( m_file, "T%d\n", tool_reference );
239  }
240 
241  diam = std::min( hole_descr.m_Hole_Size.x, hole_descr.m_Hole_Size.y );
242 
243  if( diam == 0 )
244  continue;
245 
246  /* Compute the hole coordinates: */
247  xc = x0 = xf = hole_descr.m_Hole_Pos.x - m_offset.x;
248  yc = y0 = yf = hole_descr.m_Hole_Pos.y - m_offset.y;
249 
250  /* Compute the start and end coordinates for the shape */
251  if( hole_descr.m_Hole_Size.x < hole_descr.m_Hole_Size.y )
252  {
253  int delta = ( hole_descr.m_Hole_Size.y - hole_descr.m_Hole_Size.x ) / 2;
254  y0 -= delta;
255  yf += delta;
256  }
257  else
258  {
259  int delta = ( hole_descr.m_Hole_Size.x - hole_descr.m_Hole_Size.y ) / 2;
260  x0 -= delta;
261  xf += delta;
262  }
263 
264  RotatePoint( &x0, &y0, xc, yc, hole_descr.m_Hole_Orient );
265  RotatePoint( &xf, &yf, xc, yc, hole_descr.m_Hole_Orient );
266 
267  if( !m_mirror )
268  {
269  y0 *= -1;
270  yf *= -1;
271  }
272 
273  xt = x0 * m_conversionUnits;
274  yt = y0 * m_conversionUnits;
275 #ifdef USE_ROUTING_MODE_FOR_OBLONG_HOLE
276  fputs( "G00", m_file ); // Select the routing mode
277 #endif
278  writeCoordinates( line, xt, yt );
279 
280 #ifndef USE_ROUTING_MODE_FOR_OBLONG_HOLE
281  /* remove the '\n' from end of line, because we must add the "G85"
282  * command to the line: */
283  for( int kk = 0; line[kk] != 0; kk++ )
284  {
285  if( line[kk] < ' ' )
286  line[kk] = 0;
287  }
288 
289  fputs( line, m_file );
290  fputs( "G85", m_file ); // add the "G85" command
291 #else
292  fputs( line, m_file );
293  fputs( "M15\nG01", m_file ); // tool down and linear routing from last coordinates
294 #endif
295  xt = xf * m_conversionUnits;
296  yt = yf * m_conversionUnits;
297  writeCoordinates( line, xt, yt );
298 
299  fputs( line, m_file );
300 #ifdef USE_ROUTING_MODE_FOR_OBLONG_HOLE
301  fputs( "M16\n", m_file ); // Tool up (end routing)
302 #endif
303  fputs( "G05\n", m_file ); // Select drill mode
304  holes_count++;
305  }
306 
308 
309  return holes_count;
310 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown...
Definition: common.h:180
void writeEXCELLONHeader(DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
static const int delta[8][2]
Definition: solve.cpp:112
std::vector< DRILL_TOOL > m_toolListBuffer
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
void GENDRILL_WRITER_BASE::CreateMapFilesSet ( const wxString &  aPlotDirectory,
REPORTER aReporter = NULL 
)
inherited

Function CreateMapFilesSet Creates the full set of map files for the board, in PS, PDF ...

format (use SetMapFileFormat() to select the format) filenames are computed from the board name, and layers id

Parameters
aPlotDirectory= the output folder
aReporter= a REPORTER to return activity or any message (can be NULL)

Definition at line 290 of file gendrill_file_writer_base.cpp.

References B_Cu, GENDRILL_WRITER_BASE::buildHolesList(), F_Cu, GENDRILL_WRITER_BASE::genDrillMapFile(), GetChars(), GetDefaultPlotExtension(), GENDRILL_WRITER_BASE::getDrillFileName(), GENDRILL_WRITER_BASE::getHolesCount(), GENDRILL_WRITER_BASE::getUniqueLayerPairs(), GENDRILL_WRITER_BASE::m_mapFileFmt, GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, and REPORTER::Report().

Referenced by GERBER_WRITER::CreateDrillandMapFilesSet(), and CreateDrillandMapFilesSet().

292 {
293  wxFileName fn;
294  wxString msg;
295 
296  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
297 
298  // append a pair representing the NPTH set of holes, for separate drill files.
299  if( !m_merge_PTH_NPTH )
300  hole_sets.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) );
301 
302  for( std::vector<DRILL_LAYER_PAIR>::const_iterator it = hole_sets.begin();
303  it != hole_sets.end(); ++it )
304  {
305  DRILL_LAYER_PAIR pair = *it;
306  // For separate drill files, the last layer pair is the NPTH drill file.
307  bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 );
308 
309  buildHolesList( pair, doing_npth );
310 
311  // The file is created if it has holes, or if it is the non plated drill file
312  // to be sure the NPTH file is up to date in separate files mode.
313  if( getHolesCount() > 0 || doing_npth )
314  {
315  fn = getDrillFileName( pair, doing_npth, m_merge_PTH_NPTH );
316  fn.SetPath( aPlotDirectory );
317 
318  fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
319  wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
320  fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );
321 
322  bool success = genDrillMapFile( fullfilename, m_mapFileFmt );
323 
324  if( ! success )
325  {
326  if( aReporter )
327  {
328  msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
329  aReporter->Report( msg );
330  }
331 
332  return;
333  }
334  else
335  {
336  if( aReporter )
337  {
338  msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
339  aReporter->Report( msg );
340  }
341  }
342  }
343  }
344 }
bool genDrillMapFile(const wxString &aFullFileName, PlotFormat aFormat)
Function GenDrillMapFile Plot a map of drill marks for holes.
virtual const wxString getDrillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
wxString GetDefaultPlotExtension(PlotFormat aFormat)
Returns the default plot extension for a format.
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
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...
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
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
bool GENDRILL_WRITER_BASE::genDrillMapFile ( const wxString &  aFullFileName,
PlotFormat  aFormat 
)
protectedinherited

Function GenDrillMapFile 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

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(), BOARD::Drawings(), dummy(), Edge_Cuts, PLOTTER::EndPlot(), FROM_UTF8(), BOARD::GetBoardEdgesBoundingBox(), EDA_RECT::GetBottom(), EDA_RECT::GetHeight(), PCB_PLOT_PARAMS::GetHPGLPenNum(), PCB_PLOT_PARAMS::GetHPGLPenSpeed(), GENDRILL_WRITER_BASE::GetOffset(), EDA_RECT::GetWidth(), EDA_RECT::GetX(), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, IU_PER_MILS, KiROUND(), DRILL_TOOL::m_Diameter, DRILL_TOOL::m_Hole_NotPlated, DRILL_TOOL::m_OvalCount, GENDRILL_WRITER_BASE::m_pageInfo, GENDRILL_WRITER_BASE::m_pcb, GENDRILL_WRITER_BASE::m_toolListBuffer, DRILL_TOOL::m_TotalCount, PLOTTER::Marker(), min, 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(), GENDRILL_WRITER_BASE::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(), and PLOTTER::Text().

Referenced by GENDRILL_WRITER_BASE::CreateMapFilesSet().

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

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
Returns
true if the file is created

Definition at line 292 of file gen_drill_report_files.cpp.

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

Referenced by DIALOG_GENDRILL::OnGenReportFile().

293 {
294  FILE_OUTPUTFORMATTER out( aFullFileName );
295 
296  static const char separator[] =
297  " =============================================================\n";
298 
299  wxASSERT( m_pcb );
300 
301  unsigned totalHoleCount;
302  wxString brdFilename = m_pcb->GetFileName();
303 
304  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
305 
306  out.Print( 0, "Drill report for %s\n", TO_UTF8( brdFilename ) );
307  out.Print( 0, "Created on %s\n\n", TO_UTF8( DateAndTime() ) );
308 
309  // Output the cu layer stackup, so layer name references make sense.
310  out.Print( 0, "Copper Layer Stackup:\n" );
311  out.Print( 0, separator );
312 
314 
315  int conventional_layer_num = 1;
316 
317  for( LSEQ seq = cu.Seq(); seq; ++seq, ++conventional_layer_num )
318  {
319  out.Print( 0, " L%-2d: %-25s %s\n",
320  conventional_layer_num,
321  TO_UTF8( m_pcb->GetLayerName( *seq ) ),
322  layerName( *seq ).c_str() // generic layer name
323  );
324  }
325 
326  out.Print( 0, "\n\n" );
327 
328  /* output hole lists:
329  * 1 - through holes
330  * 2 - for partial holes only: by layer starting and ending pair
331  * 3 - Non Plated through holes
332  */
333 
334  bool buildNPTHlist = false; // First pass: build PTH list only
335 
336  // in this loop are plated only:
337  for( unsigned pair_ndx = 0; pair_ndx < hole_sets.size(); ++pair_ndx )
338  {
339  DRILL_LAYER_PAIR pair = hole_sets[pair_ndx];
340 
341  buildHolesList( pair, buildNPTHlist );
342 
343  if( pair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
344  {
345  out.Print( 0, "Drill file '%s' contains\n",
346  TO_UTF8( getDrillFileName( pair, false, m_merge_PTH_NPTH ) ) );
347 
348  out.Print( 0, " plated through holes:\n" );
349  out.Print( 0, separator );
350  totalHoleCount = printToolSummary( out, false );
351  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
352  }
353  else // blind/buried
354  {
355  out.Print( 0, "Drill file '%s' contains\n",
356  TO_UTF8( getDrillFileName( pair, false, m_merge_PTH_NPTH ) ) );
357 
358  out.Print( 0, " holes connecting layer pair: '%s and %s' (%s vias):\n",
359  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.first ) ) ),
360  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.second ) ) ),
361  pair.first == F_Cu || pair.second == B_Cu ? "blind" : "buried"
362  );
363 
364  out.Print( 0, separator );
365  totalHoleCount = printToolSummary( out, false );
366  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
367  }
368 
369  out.Print( 0, "\n\n" );
370  }
371 
372  // NPTHoles. Generate the full list (pads+vias) if PTH and NPTH are merged,
373  // or only the NPTH list (which never has vias)
374  if( !m_merge_PTH_NPTH )
375  buildNPTHlist = true;
376 
377  buildHolesList( DRILL_LAYER_PAIR( F_Cu, B_Cu ), buildNPTHlist );
378 
379  // nothing wrong with an empty NPTH file in report.
380  if( m_merge_PTH_NPTH )
381  out.Print( 0, "Not plated through holes are merged with plated holes\n" );
382  else
383  out.Print( 0, "Drill file '%s' contains\n",
385  true, m_merge_PTH_NPTH ) ) );
386 
387  out.Print( 0, " unplated through holes:\n" );
388  out.Print( 0, separator );
389  totalHoleCount = printToolSummary( out, true );
390  out.Print( 0, " Total unplated holes count %u\n", totalHoleCount );
391 
392  return true;
393 }
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:676
virtual const wxString getDrillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
const std::string layerName(PCB_LAYER_ID aLayer) const
minor helper function.
#define cu(a)
Definition: auxiliary.h:88
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
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:367
#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.
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
const wxString & GetFileName() const
Definition: class_board.h:238
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.
unsigned printToolSummary(OUTPUTFORMATTER &aOut, bool aSummaryNPTH) const
Function printToolSummary prints m_toolListBuffer[] tools to aOut and returns total hole count...
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...
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:813
wxString DateAndTime()
Function DateAndTime.
Definition: string.cpp:306
const wxString GENDRILL_WRITER_BASE::getDrillFileName ( DRILL_LAYER_PAIR  aPair,
bool  aNPTH,
bool  aMerge_PTH_NPTH 
) const
protectedvirtualinherited
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

Reimplemented in GERBER_WRITER.

Definition at line 259 of file gendrill_file_writer_base.cpp.

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

Referenced by CreateDrillandMapFilesSet(), GENDRILL_WRITER_BASE::CreateMapFilesSet(), GENDRILL_WRITER_BASE::GenDrillReportFile(), and GERBER_WRITER::getDrillFileName().

261 {
262  wxASSERT( m_pcb );
263 
264  wxString extend;
265 
266  if( aNPTH )
267  extend = "-NPTH";
268  else if( aPair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
269  {
270  if( !aMerge_PTH_NPTH )
271  extend = "-PTH";
272  // if merged, extend with nothing
273  }
274  else
275  {
276  extend += '-';
277  extend += layerPairName( aPair );
278  }
279 
280  wxFileName fn = m_pcb->GetFileName();
281 
282  fn.SetName( fn.GetName() + extend );
283  fn.SetExt( m_drillFileExtension );
284 
285  wxString ret = fn.GetFullName();
286 
287  return ret;
288 }
const wxString & GetFileName() const
Definition: class_board.h:238
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
const std::string layerPairName(DRILL_LAYER_PAIR aPair) const
minor helper function.
int GENDRILL_WRITER_BASE::getHolesCount ( ) const
inlineprotectedinherited
const wxPoint EXCELLON_WRITER::GetOffset ( )
inline

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

Definition at line 62 of file gendrill_Excellon_writer.h.

References GENDRILL_WRITER_BASE::DECIMAL_FORMAT, GENDRILL_WRITER_BASE::m_offset, and SetFormat().

62 { return m_offset; }
std::vector< DRILL_LAYER_PAIR > GENDRILL_WRITER_BASE::getUniqueLayerPairs ( ) const
protectedinherited

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

Definition at line 192 of file gendrill_file_writer_base.cpp.

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

Referenced by GERBER_WRITER::CreateDrillandMapFilesSet(), CreateDrillandMapFilesSet(), GENDRILL_WRITER_BASE::CreateMapFilesSet(), and GENDRILL_WRITER_BASE::GenDrillReportFile().

193 {
194  wxASSERT( m_pcb );
195 
196  static const KICAD_T interesting_stuff_to_collect[] = {
197  PCB_VIA_T,
198  EOT
199  };
200 
201  PCB_TYPE_COLLECTOR vias;
202 
203  vias.Collect( m_pcb, interesting_stuff_to_collect );
204 
205  std::set< DRILL_LAYER_PAIR > unique;
206 
207  DRILL_LAYER_PAIR layer_pair;
208 
209  for( int i = 0; i < vias.GetCount(); ++i )
210  {
211  VIA* v = (VIA*) vias[i];
212 
213  v->LayerPair( &layer_pair.first, &layer_pair.second );
214 
215  // only make note of blind buried.
216  // thru hole is placed unconditionally as first in fetched list.
217  if( layer_pair != DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
218  {
219  unique.insert( layer_pair );
220  }
221  }
222 
223  std::vector<DRILL_LAYER_PAIR> ret;
224 
225  ret.push_back( DRILL_LAYER_PAIR( F_Cu, B_Cu ) ); // always first in returned list
226 
227  for( std::set< DRILL_LAYER_PAIR >::const_iterator it = unique.begin(); it != unique.end(); ++it )
228  ret.push_back( *it );
229 
230  return ret;
231 }
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Collect BOARD_ITEM objects using this class&#39;s Inspector method, which does the collection.
Definition: collectors.cpp:522
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...
size_t i
Definition: json11.cpp:597
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:627
const std::string GENDRILL_WRITER_BASE::layerName ( PCB_LAYER_ID  aLayer) const
protectedinherited

minor helper function.

Returns
a string from aLayer to identify the layer. string are "front" "back" or "in<aLayer>"

Definition at line 234 of file gendrill_file_writer_base.cpp.

References B_Cu, F_Cu, and numEval::StrPrintf().

Referenced by GENDRILL_WRITER_BASE::GenDrillReportFile(), and GENDRILL_WRITER_BASE::layerPairName().

235 {
236  // Generic names here.
237  switch( aLayer )
238  {
239  case F_Cu:
240  return "front";
241  case B_Cu:
242  return "back";
243  default:
244  return StrPrintf( "in%d", aLayer );
245  }
246 }
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
const std::string GENDRILL_WRITER_BASE::layerPairName ( DRILL_LAYER_PAIR  aPair) const
protectedinherited

minor helper function.

Returns
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

Definition at line 249 of file gendrill_file_writer_base.cpp.

References GENDRILL_WRITER_BASE::layerName().

Referenced by GENDRILL_WRITER_BASE::getDrillFileName().

250 {
251  std::string ret = layerName( aPair.first );
252  ret += '-';
253  ret += layerName( aPair.second );
254 
255  return ret;
256 }
const std::string layerName(PCB_LAYER_ID aLayer) const
minor helper function.
bool GENDRILL_WRITER_BASE::plotDrillMarks ( PLOTTER aPlotter)
protectedinherited

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 396 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, GENDRILL_WRITER_BASE::m_holeListBuffer, HOLE_INFO::m_Tool_Reference, PLOTTER::Marker(), and SKETCH.

Referenced by GENDRILL_WRITER_BASE::genDrillMapFile().

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

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 420 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, GENDRILL_WRITER_BASE::m_toolListBuffer, DRILL_TOOL::m_TotalCount, and OUTPUTFORMATTER::Print().

Referenced by GENDRILL_WRITER_BASE::GenDrillReportFile().

421 {
422  unsigned totalHoleCount = 0;
423 
424  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
425  {
426  const DRILL_TOOL& tool = m_toolListBuffer[ii];
427 
428  if( aSummaryNPTH && !tool.m_Hole_NotPlated )
429  continue;
430 
431  if( !aSummaryNPTH && tool.m_Hole_NotPlated )
432  continue;
433 
434  // List the tool number assigned to each drill,
435  // in mm then in inches.
436  int tool_number = ii+1;
437  out.Print( 0, " T%d %2.2fmm %2.3f\" ", tool_number,
438  diameter_in_mm( tool.m_Diameter ),
439  diameter_in_inches( tool.m_Diameter ) );
440 
441  // Now list how many holes and ovals are associated with each drill.
442  if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
443  out.Print( 0, "(1 hole)\n" );
444  else if( tool.m_TotalCount == 1 )
445  out.Print( 0, "(1 hole) (with 1 slot)\n" );
446  else if( tool.m_OvalCount == 0 )
447  out.Print( 0, "(%d holes)\n", tool.m_TotalCount );
448  else if( tool.m_OvalCount == 1 )
449  out.Print( 0, "(%d holes) (with 1 slot)\n", tool.m_TotalCount );
450  else // tool.m_OvalCount > 1
451  out.Print( 0, "(%d holes) (with %d slots)\n",
452  tool.m_TotalCount, tool.m_OvalCount );
453 
454  totalHoleCount += tool.m_TotalCount;
455  }
456 
457  out.Print( 0, "\n" );
458 
459  return totalHoleCount;
460 }
double diameter_in_inches(double ius)
double diameter_in_mm(double ius)
std::vector< DRILL_TOOL > m_toolListBuffer
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 313 of file gendrill_Excellon_writer.cpp.

References IU_PER_MILS, GENDRILL_WRITER_BASE::m_conversionUnits, DRILL_PRECISION::m_lhs, GENDRILL_WRITER_BASE::m_precision, DRILL_PRECISION::m_rhs, GENDRILL_WRITER_BASE::m_unitsMetric, and GENDRILL_WRITER_BASE::m_zeroFormat.

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

317 {
318  m_unitsMetric = aMetric;
319  m_zeroFormat = aZerosFmt;
320 
321  /* Set conversion scale depending on drill file units */
322  if( m_unitsMetric )
323  m_conversionUnits = 1.0 / IU_PER_MM; // EXCELLON units = mm
324  else
325  m_conversionUnits = 0.001 / IU_PER_MILS; // EXCELLON units = INCHES
326 
327  // Set the zero counts. if aZerosFmt == DECIMAL_FORMAT, these values
328  // will be set, but not used.
329  if( aLeftDigits <= 0 )
330  aLeftDigits = m_unitsMetric ? 3 : 2;
331 
332  if( aRightDigits <= 0 )
333  aRightDigits = m_unitsMetric ? 3 : 4;
334 
335  m_precision.m_lhs = aLeftDigits;
336  m_precision.m_rhs = aRightDigits;
337 }
#define IU_PER_MILS
Definition: plotter.cpp:134
void GENDRILL_WRITER_BASE::SetMapFileFormat ( PlotFormat  aMapFmt)
inlineinherited

Initialize the format for the drill map file.

Parameters
aMapFmt= 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 198 of file gendrill_file_writer_base.h.

198 { m_mapFileFmt = aMapFmt; }
void GENDRILL_WRITER_BASE::SetMergeOption ( bool  aMerge)
inlineinherited

set the option to make separate drill files for PTH and NPTH

Parameters
aMerge= true to make only one file containing PTH and NPTH = false to create 2 separate files

Definition at line 176 of file gendrill_file_writer_base.h.

Referenced by DIALOG_GENDRILL::OnGenReportFile().

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
aMerge_PTH_NPTH= true to create only one file containing PTH and NPTH false to create 2 separate files : one for PTH and one for NPTH

Definition at line 88 of file gendrill_Excellon_writer.h.

References CreateDrillandMapFilesSet(), createDrillFile(), GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, GENDRILL_WRITER_BASE::m_offset, writeCoordinates(), writeEXCELLONEndOfFile(), and writeEXCELLONHeader().

89  {
90  m_mirror = aMirror;
91  m_offset = aOffset;
92  m_minimalHeader = aMinimalHeader;
93  m_merge_PTH_NPTH = aMerge_PTH_NPTH;
94  }
void GENDRILL_WRITER_BASE::SetPageInfo ( const PAGE_INFO aPageInfo)
inlineinherited

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 189 of file gendrill_file_writer_base.h.

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

Definition at line 340 of file gendrill_Excellon_writer.cpp.

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

Referenced by createDrillFile(), and SetOptions().

341 {
342  wxString xs, ys;
343  int xpad = m_precision.m_lhs + m_precision.m_rhs;
344  int ypad = xpad;
345 
346  switch( m_zeroFormat )
347  {
348  default:
349  case DECIMAL_FORMAT:
350  /* In Excellon files, resolution is 1/1000 mm or 1/10000 inch (0.1 mil)
351  * Although in decimal format, Excellon specifications do not specify
352  * clearly the resolution. However it seems to be 1/1000mm or 0.1 mil
353  * like in non decimal formats, so we trunk coordinates to 3 or 4 digits in mantissa
354  * Decimal format just prohibit useless leading 0:
355  * 0.45 or .45 is right, but 00.54 is incorrect.
356  */
357  if( m_unitsMetric )
358  {
359  // resolution is 1/1000 mm
360  xs.Printf( wxT( "%.3f" ), aCoordX );
361  ys.Printf( wxT( "%.3f" ), aCoordY );
362  }
363  else
364  {
365  // resolution is 1/10000 inch
366  xs.Printf( wxT( "%.4f" ), aCoordX );
367  ys.Printf( wxT( "%.4f" ), aCoordY );
368  }
369 
370  //Remove useless trailing 0
371  while( xs.Last() == '0' )
372  xs.RemoveLast();
373 
374  if( xs.Last() == '.' ) // however keep a trailing 0 after the floating point separator
375  xs << '0';
376 
377  while( ys.Last() == '0' )
378  ys.RemoveLast();
379 
380  if( ys.Last() == '.' )
381  ys << '0';
382 
383  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
384  break;
385 
386  case SUPPRESS_LEADING:
387  for( int i = 0; i< m_precision.m_rhs; i++ )
388  {
389  aCoordX *= 10; aCoordY *= 10;
390  }
391 
392  sprintf( aLine, "X%dY%d\n", KiROUND( aCoordX ), KiROUND( aCoordY ) );
393  break;
394 
395  case SUPPRESS_TRAILING:
396  {
397  for( int i = 0; i < m_precision.m_rhs; i++ )
398  {
399  aCoordX *= 10;
400  aCoordY *= 10;
401  }
402 
403  if( aCoordX < 0 )
404  xpad++;
405 
406  if( aCoordY < 0 )
407  ypad++;
408 
409  xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
410  ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
411 
412  size_t j = xs.Len() - 1;
413 
414  while( xs[j] == '0' && j )
415  xs.Truncate( j-- );
416 
417  j = ys.Len() - 1;
418 
419  while( ys[j] == '0' && j )
420  ys.Truncate( j-- );
421 
422  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
423  break;
424  }
425 
426  case KEEP_ZEROS:
427  for( int i = 0; i< m_precision.m_rhs; i++ )
428  {
429  aCoordX *= 10; aCoordY *= 10;
430  }
431 
432  if( aCoordX < 0 )
433  xpad++;
434 
435  if( aCoordY < 0 )
436  ypad++;
437 
438  xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
439  ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
440  sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
441  break;
442  }
443 }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
#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
size_t i
Definition: json11.cpp:597
void EXCELLON_WRITER::writeEXCELLONEndOfFile ( )
private

Definition at line 537 of file gendrill_Excellon_writer.cpp.

References m_file.

Referenced by createDrillFile(), and SetOptions().

538 {
539  //add if minimal here
540  fputs( "T0\nM30\n", m_file );
541  fclose( m_file );
542 }
void EXCELLON_WRITER::writeEXCELLONHeader ( DRILL_LAYER_PAIR  aLayerPair,
bool  aGenerateNPTH_list 
)
private

Definition at line 446 of file gendrill_Excellon_writer.cpp.

References GENDRILL_WRITER_BASE::BuildFileFunctionAttributeString(), DateAndTime(), GENDRILL_WRITER_BASE::DECIMAL_FORMAT, GBR_NC_STRING_FORMAT_NCDRILL, GbrMakeCreationDateAttributeString(), GetBuildVersion(), DRILL_PRECISION::GetPrecisionString(), GENDRILL_WRITER_BASE::KEEP_ZEROS, m_file, GENDRILL_WRITER_BASE::m_merge_PTH_NPTH, m_minimalHeader, GENDRILL_WRITER_BASE::m_precision, GENDRILL_WRITER_BASE::m_unitsMetric, GENDRILL_WRITER_BASE::m_zeroFormat, GENDRILL_WRITER_BASE::SUPPRESS_LEADING, GENDRILL_WRITER_BASE::SUPPRESS_TRAILING, and TO_UTF8.

Referenced by createDrillFile(), and SetOptions().

448 {
449  fputs( "M48\n", m_file ); // The beginning of a header
450 
451  if( !m_minimalHeader )
452  {
453  // The next lines in EXCELLON files are comments:
454  wxString msg;
455  msg << "KiCad " << GetBuildVersion();
456 
457  fprintf( m_file, "; DRILL file {%s} date %s\n", TO_UTF8( msg ), TO_UTF8( DateAndTime() ) );
458  msg = "; FORMAT={";
459 
460  // Print precision:
461  // Note in decimal format the precision is not used.
462  // the floating point notation has higher priority than the precision.
465  else
466  msg << "-:-"; // in decimal format the precision is irrelevant
467 
468  msg << "/ absolute / ";
469  msg << ( m_unitsMetric ? "metric" : "inch" );
470 
471  /* Adding numbers notation format.
472  * this is same as m_Choice_Zeros_Format strings, but NOT translated
473  * because some EXCELLON parsers do not like non ASCII values
474  * so we use ONLY English (ASCII) strings.
475  * if new options are added in m_Choice_Zeros_Format, they must also
476  * be added here
477  */
478  msg << wxT( " / " );
479 
480  const wxString zero_fmt[4] =
481  {
482  "decimal",
483  "suppress leading zeros",
484  "suppress trailing zeros",
485  "keep zeros"
486  };
487 
488  msg << zero_fmt[m_zeroFormat] << "}\n";
489  fputs( TO_UTF8( msg ), m_file );
490 
491  // add the structured comment TF.CreationDate:
492  // The attribute value must conform to the full version of the ISO 8601
494  fputs( TO_UTF8( msg ), m_file );
495 
496  // Add the application name that created the drill file
497  msg = "; #@! TF.GenerationSoftware,Kicad,Pcbnew,";
498  msg << GetBuildVersion() << "\n";
499  fputs( TO_UTF8( msg ), m_file );
500 
501  if( !m_merge_PTH_NPTH )
502  {
503  // Add the standard X2 FileFunction for drill files
504  // TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH]
505  msg = BuildFileFunctionAttributeString( aLayerPair, aGenerateNPTH_list, true )
506  + "\n";
507  fputs( TO_UTF8( msg ), m_file );
508  }
509 
510  fputs( "FMAT,2\n", m_file ); // Use Format 2 commands (version used since 1979)
511  }
512 
513  fputs( m_unitsMetric ? "METRIC" : "INCH", m_file );
514 
515  switch( m_zeroFormat )
516  {
517  case DECIMAL_FORMAT:
518  fputs( "\n", m_file );
519  break;
520 
521  case SUPPRESS_LEADING:
522  fputs( ",TZ\n", m_file );
523  break;
524 
525  case SUPPRESS_TRAILING:
526  fputs( ",LZ\n", m_file );
527  break;
528 
529  case KEEP_ZEROS:
530  // write nothing, but TZ is acceptable when all zeros are kept
531  fputs( "\n", m_file );
532  break;
533  }
534 }
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
#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
const wxString BuildFileFunctionAttributeString(DRILL_LAYER_PAIR aLayerPair, bool aIsNpth, bool aCompatNCdrill=false) const
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
wxString DateAndTime()
Function DateAndTime.
Definition: string.cpp:306

Member Data Documentation

double GENDRILL_WRITER_BASE::m_conversionUnits
protectedinherited
wxString GENDRILL_WRITER_BASE::m_drillFileExtension
protectedinherited
FILE* EXCELLON_WRITER::m_file
private
PlotFormat GENDRILL_WRITER_BASE::m_mapFileFmt
protectedinherited
bool EXCELLON_WRITER::m_minimalHeader
private

Definition at line 48 of file gendrill_Excellon_writer.h.

Referenced by EXCELLON_WRITER(), and writeEXCELLONHeader().

bool EXCELLON_WRITER::m_mirror
private

Definition at line 49 of file gendrill_Excellon_writer.h.

Referenced by createDrillFile(), and EXCELLON_WRITER().

wxPoint GENDRILL_WRITER_BASE::m_offset
protectedinherited
const PAGE_INFO* GENDRILL_WRITER_BASE::m_pageInfo
protectedinherited

Definition at line 151 of file gendrill_file_writer_base.h.

Referenced by GENDRILL_WRITER_BASE::genDrillMapFile().

DRILL_PRECISION GENDRILL_WRITER_BASE::m_precision
protectedinherited
std::vector<DRILL_TOOL> GENDRILL_WRITER_BASE::m_toolListBuffer
protectedinherited
bool GENDRILL_WRITER_BASE::m_unitsMetric
protectedinherited
ZEROS_FMT GENDRILL_WRITER_BASE::m_zeroFormat
protectedinherited

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