KiCad PCB EDA Suite
GBR_TO_PCB_EXPORTER Class Reference

A helper class to export a Gerber set of files to Pcbnew. More...

#include <export_to_pcbnew.h>

Public Member Functions

 GBR_TO_PCB_EXPORTER (GERBVIEW_FRAME *aFrame, const wxString &aFileName)
 
 ~GBR_TO_PCB_EXPORTER ()
 
bool ExportPcb (const LAYER_NUM *aLayerLookUpTable, int aCopperLayers)
 Save a board from a set of Gerber images. More...
 

Private Member Functions

void collect_hole (const GERBER_DRAW_ITEM *aGbrItem)
 Collect holes from a drill layer. More...
 
void export_via (const EXPORT_VIA &aVia)
 Write a via to the board file. More...
 
void export_non_copper_item (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a non copper line or arc to the board file. More...
 
void writePcbPolygon (const SHAPE_POLY_SET &aPolys, LAYER_NUM aLayer, const wxPoint &aOffset={ 0, 0 })
 Write a non-copper polygon to the board file. More...
 
void writePcbFilledCircle (const VECTOR2I &aCenterPosition, int aRadius, LAYER_NUM aLayer)
 Write a filled circle to the board file (with line thickness = 0). More...
 
void writePcbZoneItem (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a zone item to the board file. More...
 
void export_copper_item (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a track (or via) to the board file. More...
 
void export_flashed_copper_item (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a synthetic pad to the board file. More...
 
void export_segline_copper_item (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a track (not via) to the board file. More...
 
void export_segarc_copper_item (const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
 Write a set of tracks (arcs are approximated by track segments) to the board file. More...
 
void writeCopperLineItem (const wxPoint &aStart, const wxPoint &aEnd, int aWidth, LAYER_NUM aLayer)
 Basic write function to write a a PCB_TRACK to the board file from a non flashed item. More...
 
void writePcbHeader (const LAYER_NUM *aLayerLookUpTable)
 Write a very basic header to the board file. More...
 
double MapToPcbUnits (int aValue) const
 Map GerbView internal units to millimeters for Pcbnew board files. More...
 

Private Attributes

GERBVIEW_FRAMEm_gerbview_frame
 
wxString m_pcb_file_name
 
FILE * m_fp
 
int m_pcbCopperLayersCount
 
std::vector< EXPORT_VIAm_vias
 

Detailed Description

A helper class to export a Gerber set of files to Pcbnew.

Definition at line 51 of file export_to_pcbnew.h.

Constructor & Destructor Documentation

◆ GBR_TO_PCB_EXPORTER()

GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER ( GERBVIEW_FRAME aFrame,
const wxString &  aFileName 
)

Definition at line 45 of file export_to_pcbnew.cpp.

46 {
47  m_gerbview_frame = aFrame;
48  m_pcb_file_name = aFileName;
49  m_fp = NULL;
51 }
#define NULL
GERBVIEW_FRAME * m_gerbview_frame

References m_fp, m_gerbview_frame, m_pcb_file_name, m_pcbCopperLayersCount, and NULL.

◆ ~GBR_TO_PCB_EXPORTER()

GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER ( )

Definition at line 54 of file export_to_pcbnew.cpp.

55 {
56 }

Member Function Documentation

◆ collect_hole()

void GBR_TO_PCB_EXPORTER::collect_hole ( const GERBER_DRAW_ITEM aGbrItem)
private

Collect holes from a drill layer.

We'll use these later when writing pads & vias.

Definition at line 263 of file export_to_pcbnew.cpp.

264 {
265  int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
266  m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
267 }
std::vector< EXPORT_VIA > m_vias

References GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, and m_vias.

Referenced by ExportPcb().

◆ export_copper_item()

void GBR_TO_PCB_EXPORTER::export_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a track (or via) to the board file.

Parameters
aGbrItemis the Gerber item (line, arc, flashed) to export.
aLayeris the copper layer to use.

Definition at line 290 of file export_to_pcbnew.cpp.

291 {
292  switch( aGbrItem->m_Shape )
293  {
294  case GBR_SPOT_CIRCLE:
295  case GBR_SPOT_RECT:
296  case GBR_SPOT_OVAL:
297  export_flashed_copper_item( aGbrItem, aLayer );
298  break;
299 
300  case GBR_ARC:
301  export_segarc_copper_item( aGbrItem, aLayer );
302  break;
303 
304  case GBR_POLYGON:
305  // One can use a polygon or a zone to output a Gerber region.
306  // none are perfect.
307  // The current way is use a polygon, as the zone export
308  // is experimental and only for tests.
309 #if 1
310  writePcbPolygon( aGbrItem->m_Polygon, aLayer );
311 #else
312  // Only for tests:
313  writePcbZoneItem( aGbrItem, aLayer );
314 #endif
315  break;
316 
317  default:
318  export_segline_copper_item( aGbrItem, aLayer );
319  break;
320  }
321 }
void writePcbPolygon(const SHAPE_POLY_SET &aPolys, LAYER_NUM aLayer, const wxPoint &aOffset={ 0, 0 })
Write a non-copper polygon to the board file.
SHAPE_POLY_SET m_Polygon
void export_flashed_copper_item(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a synthetic pad to the board file.
void export_segline_copper_item(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a track (not via) to the board file.
void export_segarc_copper_item(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a set of tracks (arcs are approximated by track segments) to the board file.
void writePcbZoneItem(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a zone item to the board file.

References export_flashed_copper_item(), export_segarc_copper_item(), export_segline_copper_item(), GBR_ARC, GBR_POLYGON, GBR_SPOT_CIRCLE, GBR_SPOT_OVAL, GBR_SPOT_RECT, GERBER_DRAW_ITEM::m_Polygon, GERBER_DRAW_ITEM::m_Shape, writePcbPolygon(), and writePcbZoneItem().

Referenced by ExportPcb().

◆ export_flashed_copper_item()

void GBR_TO_PCB_EXPORTER::export_flashed_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a synthetic pad to the board file.

We can't create real pads because the Gerbers don't store grouping/footprint info. So we synthesize a pad with a via for the hole (if present) and a copper polygon for the pad.

Parameters
aGbrItemis the flashed Gerber item to export.

Definition at line 414 of file export_to_pcbnew.cpp.

416 {
417  static D_CODE flashed_item_D_CODE( 0 );
418 
419  D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
420  SHAPE_POLY_SET polygon;
421 
422  if( d_codeDescr == NULL )
423  d_codeDescr = &flashed_item_D_CODE;
424 
425  if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE )
426  {
427  // See if there's a via that we can enlarge to fit this flashed item
428  for( EXPORT_VIA& via : m_vias )
429  {
430  if( via.m_Pos == aGbrItem->m_Start )
431  {
432  via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
433  return;
434  }
435  }
436  }
437 
438  wxPoint offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
439 
440  if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE ) // export it as filled circle
441  {
442  VECTOR2I center = offset;
443  int radius = d_codeDescr->m_Size.x / 2;
444  writePcbFilledCircle( center, radius, aLayer );
445  return;
446  }
447 
448  d_codeDescr->ConvertShapeToPolygon();
449  writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
450 }
std::vector< EXPORT_VIA > m_vias
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
void writePcbPolygon(const SHAPE_POLY_SET &aPolys, LAYER_NUM aLayer, const wxPoint &aOffset={ 0, 0 })
Write a non-copper polygon to the board file.
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:188
wxPoint GetABPosition(const wxPoint &aXYPosition) const
Return the image position of aPosition for this object.
#define NULL
Represent a set of closed polygons.
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
void writePcbFilledCircle(const VECTOR2I &aCenterPosition, int aRadius, LAYER_NUM aLayer)
Write a filled circle to the board file (with line thickness = 0).
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:203
void ConvertShapeToPolygon()
Convert a shape to an equivalent polygon.
Definition: dcode.cpp:295

References D_CODE::ConvertShapeToPolygon(), GBR_SPOT_CIRCLE, GERBER_DRAW_ITEM::GetABPosition(), GERBER_DRAW_ITEM::GetDcodeDescr(), D_CODE::m_Polygon, GERBER_DRAW_ITEM::m_Shape, D_CODE::m_Size, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, m_vias, NULL, via, writePcbFilledCircle(), and writePcbPolygon().

Referenced by export_copper_item().

◆ export_non_copper_item()

void GBR_TO_PCB_EXPORTER::export_non_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a non copper line or arc to the board file.

Parameters
aGbrItemis the Gerber item (line, arc) to export.
aLayeris the technical layer to use.

Definition at line 142 of file export_to_pcbnew.cpp.

143 {
144  // used when a D_CODE is not found. default D_CODE to draw a flashed item
145  static D_CODE dummyD_CODE( 0 );
146 
147  wxPoint seg_start = aGbrItem->m_Start;
148  wxPoint seg_end = aGbrItem->m_End;
149  D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
150  SHAPE_POLY_SET polygon;
151 
152  if( d_codeDescr == NULL )
153  d_codeDescr = &dummyD_CODE;
154 
155  switch( aGbrItem->m_Shape )
156  {
157  case GBR_POLYGON:
158  writePcbPolygon( aGbrItem->m_Polygon, aLayer );
159  break;
160 
161  case GBR_SPOT_CIRCLE:
162  {
163  VECTOR2I center = aGbrItem->GetABPosition( seg_start );
164  int radius = d_codeDescr->m_Size.x / 2;
165  writePcbFilledCircle( center, radius, aLayer );
166  }
167  break;
168 
169  case GBR_SPOT_RECT:
170  case GBR_SPOT_OVAL:
171  case GBR_SPOT_POLY:
172  case GBR_SPOT_MACRO:
173  d_codeDescr->ConvertShapeToPolygon();
174  writePcbPolygon( d_codeDescr->m_Polygon, aLayer, aGbrItem->GetABPosition( seg_start ) );
175  break;
176 
177  case GBR_ARC:
178  {
179  double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
180  (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
181  double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
182  (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
183 
184  double angle = RAD2DEG(b - a);
185  seg_start = aGbrItem->m_ArcCentre;
186 
187  // Ensure arc orientation is CCW
188  if( angle < 0 )
189  angle += 360.0;
190 
191  // Reverse Y axis:
192  seg_start.y = -seg_start.y;
193  seg_end.y = -seg_end.y;
194 
195  if( angle == 360.0 || angle == 0 )
196  {
197  fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s) (layer %s) (width %s))\n",
198  Double2Str( MapToPcbUnits(seg_start.x) ).c_str(),
199  Double2Str( MapToPcbUnits(seg_start.y) ).c_str(),
200  Double2Str( MapToPcbUnits(seg_end.x) ).c_str(),
201  Double2Str( MapToPcbUnits(seg_end.y) ).c_str(),
202  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
203  Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str()
204  );
205  }
206  else
207  {
208  fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %s) (layer %s) (width %s))\n",
209  Double2Str( MapToPcbUnits(seg_start.x) ).c_str(),
210  Double2Str( MapToPcbUnits(seg_start.y) ).c_str(),
211  Double2Str( MapToPcbUnits(seg_end.x) ).c_str(),
212  Double2Str( MapToPcbUnits(seg_end.y) ).c_str(),
213  Double2Str( angle ).c_str(),
214  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
215  Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str()
216  );
217  }
218  }
219  break;
220 
221  case GBR_CIRCLE:
222  // Reverse Y axis:
223  seg_start.y = -seg_start.y;
224  seg_end.y = -seg_end.y;
225 
226  fprintf( m_fp, "(gr_circle (start %s %s) (end %s %s) (layer %s) (width %s))\n",
227  Double2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
228  Double2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
229  Double2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
230  Double2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
231  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
232  Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
233  break;
234 
235  case GBR_SEGMENT:
236  // Reverse Y axis:
237  seg_start.y = -seg_start.y;
238  seg_end.y = -seg_end.y;
239 
240  fprintf( m_fp, "(gr_line (start %s %s) (end %s %s) (layer %s) (width %s))\n",
241  Double2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
242  Double2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
243  Double2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
244  Double2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
245  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
246  Double2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
247  break;
248  }
249 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
void writePcbPolygon(const SHAPE_POLY_SET &aPolys, LAYER_NUM aLayer, const wxPoint &aOffset={ 0, 0 })
Write a non-copper polygon to the board file.
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:188
double RAD2DEG(double rad)
Definition: trigo.h:232
SHAPE_POLY_SET m_Polygon
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
wxPoint GetABPosition(const wxPoint &aXYPosition) const
Return the image position of aPosition for this object.
#define NULL
Represent a set of closed polygons.
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void writePcbFilledCircle(const VECTOR2I &aCenterPosition, int aRadius, LAYER_NUM aLayer)
Write a filled circle to the board file (with line thickness = 0).
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:203
void ConvertShapeToPolygon()
Convert a shape to an equivalent polygon.
Definition: dcode.cpp:295
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References PNS::angle(), D_CODE::ConvertShapeToPolygon(), Double2Str(), GBR_ARC, GBR_CIRCLE, GBR_POLYGON, GBR_SEGMENT, GBR_SPOT_CIRCLE, GBR_SPOT_MACRO, GBR_SPOT_OVAL, GBR_SPOT_POLY, GBR_SPOT_RECT, GERBER_DRAW_ITEM::GetABPosition(), GERBER_DRAW_ITEM::GetDcodeDescr(), GetPCBDefaultLayerName(), GERBER_DRAW_ITEM::m_ArcCentre, GERBER_DRAW_ITEM::m_End, m_fp, D_CODE::m_Polygon, GERBER_DRAW_ITEM::m_Polygon, GERBER_DRAW_ITEM::m_Shape, D_CODE::m_Size, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, MapToPcbUnits(), NULL, RAD2DEG(), TO_UTF8, writePcbFilledCircle(), and writePcbPolygon().

Referenced by ExportPcb().

◆ export_segarc_copper_item()

void GBR_TO_PCB_EXPORTER::export_segarc_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a set of tracks (arcs are approximated by track segments) to the board file.

Parameters
aGbrItemis the Gerber item (arc only) to export.
aLayeris the copper layer to use

Definition at line 353 of file export_to_pcbnew.cpp.

354 {
355  double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
356  (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
357  double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
358  (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
359 
360  wxPoint start = aGbrItem->m_Start;
361  wxPoint end = aGbrItem->m_End;
362 
363  /* Because Pcbnew does not know arcs in tracks,
364  * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
365  * The arc is drawn anticlockwise from the start point to the end point.
366  */
367  #define SEG_COUNT_CIRCLE 16
368  #define DELTA_ANGLE 2 * M_PI / SEG_COUNT_CIRCLE
369 
370  // calculate the number of segments from a to b.
371  // we want CNT_PER_360 segments fo a circle
372  if( a > b )
373  b += 2 * M_PI;
374 
375  wxPoint curr_start = start;
376  wxPoint seg_start, seg_end;
377 
378  int ii = 1;
379 
380  for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
381  {
382  seg_start = curr_start;
383  wxPoint curr_end = start;
384  RotatePoint( &curr_end, aGbrItem->m_ArcCentre,
385  -RAD2DECIDEG( DELTA_ANGLE * ii ) );
386  seg_end = curr_end;
387  // Reverse Y axis:
388  seg_start.y = -seg_start.y;
389  seg_end.y = -seg_end.y;
390  writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
391  curr_start = curr_end;
392  }
393 
394  if( end != curr_start )
395  {
396  seg_start = curr_start;
397  seg_end = end;
398  // Reverse Y axis:
399  seg_start.y = -seg_start.y;
400  seg_end.y = -seg_end.y;
401  writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
402  }
403 }
double RAD2DECIDEG(double rad)
Definition: trigo.h:236
#define DELTA_ANGLE
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
void writeCopperLineItem(const wxPoint &aStart, const wxPoint &aEnd, int aWidth, LAYER_NUM aLayer)
Basic write function to write a a PCB_TRACK to the board file from a non flashed item.

References DELTA_ANGLE, GERBER_DRAW_ITEM::m_ArcCentre, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, RAD2DECIDEG(), RotatePoint(), and writeCopperLineItem().

Referenced by export_copper_item().

◆ export_segline_copper_item()

void GBR_TO_PCB_EXPORTER::export_segline_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a track (not via) to the board file.

Parameters
aGbrItemis the Gerber item (line only) to export.
aLayeris the copper layer to use.

Definition at line 324 of file export_to_pcbnew.cpp.

325 {
326  wxPoint seg_start, seg_end;
327 
328  seg_start = aGbrItem->m_Start;
329  seg_end = aGbrItem->m_End;
330 
331  // Reverse Y axis:
332  seg_start.y = -seg_start.y;
333  seg_end.y = -seg_end.y;
334 
335  writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
336 }
void writeCopperLineItem(const wxPoint &aStart, const wxPoint &aEnd, int aWidth, LAYER_NUM aLayer)
Basic write function to write a a PCB_TRACK to the board file from a non flashed item.

References GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, and writeCopperLineItem().

Referenced by export_copper_item().

◆ export_via()

void GBR_TO_PCB_EXPORTER::export_via ( const EXPORT_VIA aVia)
private

Write a via to the board file.

Some of these will represent actual vias while others are used to represent holes in pads. (We can't generate actual pads because the Gerbers don't contain info on how to group them into footprints.)

Definition at line 270 of file export_to_pcbnew.cpp.

271 {
272  wxPoint via_pos = aVia.m_Pos;
273 
274  // Reverse Y axis:
275  via_pos.y = -via_pos.y;
276 
277  // Layers are Front to Back
278  fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
279  Double2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
280  Double2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
281  Double2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
282  Double2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
283 
284  fprintf( m_fp, " (layers %s %s))\n",
287 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References B_Cu, Double2Str(), F_Cu, GetPCBDefaultLayerName(), EXPORT_VIA::m_Drill, m_fp, EXPORT_VIA::m_Pos, EXPORT_VIA::m_Size, MapToPcbUnits(), and TO_UTF8.

Referenced by ExportPcb().

◆ ExportPcb()

bool GBR_TO_PCB_EXPORTER::ExportPcb ( const LAYER_NUM aLayerLookUpTable,
int  aCopperLayers 
)

Save a board from a set of Gerber images.

Definition at line 59 of file export_to_pcbnew.cpp.

60 {
61  LOCALE_IO toggle; // toggles on, then off, the C locale.
62 
63  m_fp = wxFopen( m_pcb_file_name, wxT( "wt" ) );
64 
65  if( m_fp == NULL )
66  {
67  wxString msg;
68  msg.Printf( _( "Cannot create file '%s'." ), m_pcb_file_name );
70  return false;
71  }
72 
73  m_pcbCopperLayersCount = aCopperLayers;
74 
75  writePcbHeader( aLayerLookUpTable );
76 
77  // create an image of gerber data
78  const int pcbCopperLayerMax = 31;
80 
81  // First collect all the holes. We'll use these to generate pads, vias, etc.
82  for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
83  {
84  EXCELLON_IMAGE* excellon = dynamic_cast<EXCELLON_IMAGE*>( images->GetGbrImage( layer ) );
85 
86  if( excellon == NULL ) // Layer not yet used or not a drill image
87  continue;
88 
89  for( GERBER_DRAW_ITEM* gerb_item : excellon->GetItems() )
90  collect_hole( gerb_item );
91  }
92 
93  // Next: non copper layers:
94  for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
95  {
96  GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
97 
98  if( gerber == NULL ) // Graphic layer not yet used
99  continue;
100 
101  LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
102 
103  if( !IsPcbLayer( pcb_layer_number ) )
104  continue;
105 
106  if( pcb_layer_number <= pcbCopperLayerMax ) // copper layer
107  continue;
108 
109  for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
110  export_non_copper_item( gerb_item, pcb_layer_number );
111  }
112 
113  // Copper layers
114  for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
115  {
116  GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
117 
118  if( gerber == NULL ) // Graphic layer not yet used
119  continue;
120 
121  LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
122 
123  if( pcb_layer_number < 0 || pcb_layer_number > pcbCopperLayerMax )
124  continue;
125 
126  for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
127  export_copper_item( gerb_item, pcb_layer_number );
128  }
129 
130  // Now write out the holes we collected earlier as vias
131  for( const EXPORT_VIA& via : m_vias )
132  export_via( via );
133 
134  fprintf( m_fp, ")\n" );
135 
136  fclose( m_fp );
137  m_fp = NULL;
138  return true;
139 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
std::vector< EXPORT_VIA > m_vias
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
GERBER_DRAW_ITEMS & GetItems()
Hold the image data and parameters for one gerber file and layer parameters.
void export_via(const EXPORT_VIA &aVia)
Write a via to the board file.
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
#define NULL
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
void export_copper_item(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a track (or via) to the board file.
GERBVIEW_FRAME * m_gerbview_frame
void collect_hole(const GERBER_DRAW_ITEM *aGbrItem)
Collect holes from a drill layer.
#define _(s)
int LAYER_NUM
This can be replaced with int and removed.
GBR_LAYOUT * GetGerberLayout() const
void export_non_copper_item(const GERBER_DRAW_ITEM *aGbrItem, LAYER_NUM aLayer)
Write a non copper line or arc to the board file.
Handle a drill image.
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Definition: gbr_layout.cpp:41
bool IsPcbLayer(LAYER_NUM aLayer)
Test whether a layer is a valid layer for Pcbnew.
void writePcbHeader(const LAYER_NUM *aLayerLookUpTable)
Write a very basic header to the board file.

References _, collect_hole(), DisplayError(), export_copper_item(), export_non_copper_item(), export_via(), GERBER_FILE_IMAGE_LIST::GetGbrImage(), GERBVIEW_FRAME::GetGerberLayout(), GBR_LAYOUT::GetImagesList(), GERBER_FILE_IMAGE::GetItems(), GERBER_FILE_IMAGE_LIST::ImagesMaxCount(), IsPcbLayer(), m_fp, m_gerbview_frame, m_pcb_file_name, m_pcbCopperLayersCount, m_vias, NULL, via, and writePcbHeader().

Referenced by GERBVIEW_CONTROL::ExportToPcbnew().

◆ MapToPcbUnits()

double GBR_TO_PCB_EXPORTER::MapToPcbUnits ( int  aValue) const
inlineprivate

Map GerbView internal units to millimeters for Pcbnew board files.

Parameters
aValueis a coordinate value to convert in mm.

Definition at line 167 of file export_to_pcbnew.h.

168  {
169  return aValue / IU_PER_MM;
170  }
static constexpr double IU_PER_MM
Mock up a conversion function.

References IU_PER_MM.

Referenced by export_non_copper_item(), export_via(), writeCopperLineItem(), writePcbFilledCircle(), writePcbPolygon(), and writePcbZoneItem().

◆ writeCopperLineItem()

void GBR_TO_PCB_EXPORTER::writeCopperLineItem ( const wxPoint &  aStart,
const wxPoint &  aEnd,
int  aWidth,
LAYER_NUM  aLayer 
)
private

Basic write function to write a a PCB_TRACK to the board file from a non flashed item.

Definition at line 339 of file export_to_pcbnew.cpp.

342 {
343  fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
344  Double2Str( MapToPcbUnits(aStart.x) ).c_str(),
345  Double2Str( MapToPcbUnits(aStart.y) ).c_str(),
346  Double2Str( MapToPcbUnits(aEnd.x) ).c_str(),
347  Double2Str( MapToPcbUnits(aEnd.y) ).c_str(),
348  Double2Str( MapToPcbUnits( aWidth ) ).c_str(),
349  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
350 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References Double2Str(), GetPCBDefaultLayerName(), m_fp, MapToPcbUnits(), and TO_UTF8.

Referenced by export_segarc_copper_item(), and export_segline_copper_item().

◆ writePcbFilledCircle()

void GBR_TO_PCB_EXPORTER::writePcbFilledCircle ( const VECTOR2I aCenterPosition,
int  aRadius,
LAYER_NUM  aLayer 
)
private

Write a filled circle to the board file (with line thickness = 0).

Parameters
aCenterPositionis the actual position of the filled circle, given by <round_flashed_shape>->GetABPosition()
aRadiusis the circle radius.
aLayeris the layer to use.

Definition at line 453 of file export_to_pcbnew.cpp.

455 {
456 
457  fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)",
458  Double2Str( MapToPcbUnits( aCenterPosition.x ) ).c_str(),
459  Double2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str(),
460  Double2Str( MapToPcbUnits( aCenterPosition.x + aRadius ) ).c_str(),
461  Double2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str() );
462 
463 
464  fprintf( m_fp, "(layer %s) (width 0) (fill solid) )\n",
465  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
466 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References Double2Str(), GetPCBDefaultLayerName(), m_fp, MapToPcbUnits(), TO_UTF8, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_flashed_copper_item(), and export_non_copper_item().

◆ writePcbHeader()

void GBR_TO_PCB_EXPORTER::writePcbHeader ( const LAYER_NUM aLayerLookUpTable)
private

Write a very basic header to the board file.

Definition at line 469 of file export_to_pcbnew.cpp.

470 {
471  fprintf( m_fp, "(kicad_pcb (version 4) (generator gerbview)\n\n" );
472 
473  // Write layers section
474  fprintf( m_fp, " (layers \n" );
475 
476  for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
477  {
478  int id = ii;
479 
480  if( ii == m_pcbCopperLayersCount-1)
481  id = B_Cu;
482 
483  fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
484  }
485 
486  for( int ii = B_Adhes; ii < PCB_LAYER_ID_COUNT; ii++ )
487  {
488  if( GetPCBDefaultLayerName( ii ).IsEmpty() ) // Layer not available for export
489  continue;
490 
491  fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
492  }
493 
494  fprintf( m_fp, " )\n\n" );
495 }
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)

References B_Adhes, B_Cu, GetPCBDefaultLayerName(), m_fp, m_pcbCopperLayersCount, PCB_LAYER_ID_COUNT, and TO_UTF8.

Referenced by ExportPcb().

◆ writePcbPolygon()

void GBR_TO_PCB_EXPORTER::writePcbPolygon ( const SHAPE_POLY_SET aPolys,
LAYER_NUM  aLayer,
const wxPoint &  aOffset = { 0, 0 } 
)
private

Write a non-copper polygon to the board file.

Parameters
aLayeris the technical layer to use.

Definition at line 498 of file export_to_pcbnew.cpp.

500 {
501  SHAPE_POLY_SET polys = aPolys;
502 
503  // Cleanup the polygon
505 
506  // Ensure the polygon is valid:
507  if( polys.OutlineCount() == 0 )
508  return;
509 
511 
512  SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
513 
514  fprintf( m_fp, "(gr_poly (pts " );
515 
516  #define MAX_COORD_CNT 4
517  int jj = MAX_COORD_CNT;
518  int cnt_max = poly.PointCount() -1;
519 
520  // Do not generate last corner, if it is the same point as the first point:
521  if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
522  cnt_max--;
523 
524  for( int ii = 0; ii <= cnt_max; ii++ )
525  {
526  if( --jj == 0 )
527  {
528  jj = MAX_COORD_CNT;
529  fprintf( m_fp, "\n" );
530  }
531 
532  fprintf( m_fp, " (xy %s %s)",
533  Double2Str( MapToPcbUnits( poly.CPoint( ii ).x + aOffset.x ) ).c_str(),
534  Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y + aOffset.y ) ).c_str() );
535  }
536 
537  fprintf( m_fp, ")" );
538 
539  if( jj != MAX_COORD_CNT )
540  fprintf( m_fp, "\n" );
541 
542  fprintf( m_fp, "(layer %s) (width 0) )\n",
543  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
544 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
int PointCount() const
Function PointCount()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const VECTOR2I & CPoint(int aIndex) const
Function Point()
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
void Simplify(POLYGON_MODE aFastMode)
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
#define MAX_COORD_CNT
SHAPE_LINE_CHAIN.
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References SHAPE_LINE_CHAIN::CPoint(), Double2Str(), SHAPE_POLY_SET::Fracture(), GetPCBDefaultLayerName(), m_fp, MapToPcbUnits(), MAX_COORD_CNT, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::Simplify(), TO_UTF8, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_copper_item(), export_flashed_copper_item(), and export_non_copper_item().

◆ writePcbZoneItem()

void GBR_TO_PCB_EXPORTER::writePcbZoneItem ( const GERBER_DRAW_ITEM aGbrItem,
LAYER_NUM  aLayer 
)
private

Write a zone item to the board file.

Warning
This is experimental for tests only.
Parameters
aGbrItemis the Gerber item (line, arc) to export.
aLayeris the technical layer to use.

Definition at line 547 of file export_to_pcbnew.cpp.

548 {
549  SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
551 
552  if( polys.OutlineCount() == 0 )
553  return;
554 
555  fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
556  TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
557 
558  fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
559 
560  fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
561  " (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
562 
563  // Now, write the zone outlines with holes.
564  // first polygon is the main outline, next are holes
565  // One cannot know the initial zone outline.
566  // However most of (if not all) holes are just items with clearance,
567  // not really a hole in the initial zone outline.
568  // So we build a zone outline only with no hole.
569  fprintf( m_fp, " (polygon\n (pts" );
570 
571  SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
572 
573  #define MAX_COORD_CNT 4
574  int jj = MAX_COORD_CNT;
575  int cnt_max = poly.PointCount() -1;
576 
577  // Do not generate last corner, if it is the same point as the first point:
578  if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
579  cnt_max--;
580 
581  for( int ii = 0; ii <= cnt_max; ii++ )
582  {
583  if( --jj == 0 )
584  {
585  jj = MAX_COORD_CNT;
586  fprintf( m_fp, "\n " );
587  }
588 
589  fprintf( m_fp, " (xy %s %s)", Double2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
590  Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
591  }
592 
593  fprintf( m_fp, ")\n" );
594 
595  fprintf( m_fp, " )\n)\n" );
596 }
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
int PointCount() const
Function PointCount()
SHAPE_POLY_SET m_Polygon
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const VECTOR2I & CPoint(int aIndex) const
Function Point()
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
void Simplify(POLYGON_MODE aFastMode)
#define MAX_COORD_CNT
SHAPE_LINE_CHAIN.
const wxString GetPCBDefaultLayerName(LAYER_NUM aLayerNumber)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
Definition: string.cpp:940

References SHAPE_LINE_CHAIN::CPoint(), Double2Str(), GetPCBDefaultLayerName(), m_fp, GERBER_DRAW_ITEM::m_Polygon, MapToPcbUnits(), MAX_COORD_CNT, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::Simplify(), TO_UTF8, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_copper_item().

Member Data Documentation

◆ m_fp

◆ m_gerbview_frame

GERBVIEW_FRAME* GBR_TO_PCB_EXPORTER::m_gerbview_frame
private

Definition at line 173 of file export_to_pcbnew.h.

Referenced by ExportPcb(), and GBR_TO_PCB_EXPORTER().

◆ m_pcb_file_name

wxString GBR_TO_PCB_EXPORTER::m_pcb_file_name
private

Definition at line 174 of file export_to_pcbnew.h.

Referenced by ExportPcb(), and GBR_TO_PCB_EXPORTER().

◆ m_pcbCopperLayersCount

int GBR_TO_PCB_EXPORTER::m_pcbCopperLayersCount
private

Definition at line 176 of file export_to_pcbnew.h.

Referenced by ExportPcb(), GBR_TO_PCB_EXPORTER(), and writePcbHeader().

◆ m_vias

std::vector<EXPORT_VIA> GBR_TO_PCB_EXPORTER::m_vias
private

Definition at line 177 of file export_to_pcbnew.h.

Referenced by collect_hole(), export_flashed_copper_item(), and ExportPcb().


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