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 int *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, int aLayer)
 Write a non copper line or arc to the board file. More...
 
void writePcbPolygon (const SHAPE_POLY_SET &aPolys, int aLayer, const VECTOR2I &aOffset={ 0, 0 })
 Write a non-copper polygon to the board file. More...
 
void writePcbFilledCircle (const VECTOR2I &aCenterPosition, int aRadius, int aLayer)
 Write a filled circle to the board file (with line thickness = 0). More...
 
void writePcbZoneItem (const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
 Write a zone item to the board file. More...
 
void export_copper_item (const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
 Write a track (or via) to the board file. More...
 
void export_flashed_copper_item (const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
 Write a synthetic pad to the board file. More...
 
void export_segline_copper_item (const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
 Write a track (not via) to the board file. More...
 
void export_segarc_copper_item (const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
 Write a set of tracks (arcs are approximated by track segments) to the board file. More...
 
void writeCopperLineItem (const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aLayer)
 Basic write function to write a a PCB_TRACK to the board file from a non flashed item. More...
 
void writePcbHeader (const int *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 50 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 = nullptr;
51}
GERBVIEW_FRAME * m_gerbview_frame

References m_fp, m_gerbview_frame, m_pcb_file_name, and m_pcbCopperLayersCount.

◆ ~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. Many holes will be pads, but we have no way to create those without footprints, and creating a footprint per pad is not really viable. We use vias to mimic holes, with the loss of any hole shape (as we only have round holes in vias at present). We start out with a via size minimally larger than the hole. We'll leave it this way if the pad gets drawn as a copper polygon, or increase it to the proper size if it has a circular, concentric copper flashing.

Definition at line 261 of file export_to_pcbnew.cpp.

262{
263 int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
264 m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
265}
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,
int  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 288 of file export_to_pcbnew.cpp.

289{
290 switch( aGbrItem->m_Shape )
291 {
292 case GBR_SPOT_CIRCLE:
293 case GBR_SPOT_RECT:
294 case GBR_SPOT_OVAL:
295 case GBR_SPOT_POLY:
296 case GBR_SPOT_MACRO:
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 writePcbZoneItem(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a zone item to the board file.
void export_segarc_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a set of tracks (arcs are approximated by track segments) to the board file.
void export_flashed_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a synthetic pad to the board file.
void writePcbPolygon(const SHAPE_POLY_SET &aPolys, int aLayer, const VECTOR2I &aOffset={ 0, 0 })
Write a non-copper polygon to the board file.
void export_segline_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a track (not via) to the board file.
SHAPE_POLY_SET m_Polygon
@ GBR_SPOT_OVAL
@ GBR_SPOT_POLY
@ GBR_SPOT_RECT
@ GBR_POLYGON
@ GBR_SPOT_CIRCLE
@ GBR_ARC
@ GBR_SPOT_MACRO

References export_flashed_copper_item(), export_segarc_copper_item(), export_segline_copper_item(), GBR_ARC, GBR_POLYGON, GBR_SPOT_CIRCLE, GBR_SPOT_MACRO, GBR_SPOT_OVAL, GBR_SPOT_POLY, 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,
int  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 406 of file export_to_pcbnew.cpp.

407{
408 static D_CODE flashed_item_D_CODE( 0 );
409
410 D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
411
412 if( d_codeDescr == nullptr )
413 d_codeDescr = &flashed_item_D_CODE;
414
415 if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE )
416 {
417 // See if there's a via that we can enlarge to fit this flashed item
418 for( EXPORT_VIA& via : m_vias )
419 {
420 if( via.m_Pos == aGbrItem->m_Start )
421 {
422 via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
423 return;
424 }
425 }
426 }
427
428 VECTOR2I offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
429
430 if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE ||
431 ( aGbrItem->m_Shape == GBR_SPOT_OVAL && d_codeDescr->m_Size.x == d_codeDescr->m_Size.y ) )
432 {
433 // export it as filled circle
434 VECTOR2I center = offset;
435 int radius = d_codeDescr->m_Size.x / 2;
436 writePcbFilledCircle( center, radius, aLayer );
437 return;
438 }
439
440 APERTURE_MACRO* macro = d_codeDescr->GetMacro();
441
442 if( macro ) // export a GBR_SPOT_MACRO
443 {
444 SHAPE_POLY_SET macroShape;
445 macroShape = *macro->GetApertureMacroShape( aGbrItem, VECTOR2I( 0, 0 ) );
446
447 // Compensate the Y axis orientation ( writePcbPolygon invert the Y coordinate )
448 macroShape.Outline( 0 ).Mirror( false, true );
449
450 writePcbPolygon( macroShape, aLayer, offset );
451 }
452 else
453 {
454 // Should cover primitives: GBR_SPOT_RECT, GBR_SPOT_OVAL, GBR_SPOT_POLY
455 d_codeDescr->ConvertShapeToPolygon( aGbrItem );
456 writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
457 }
458}
Support the "aperture macro" defined within standard RS274X.
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, const VECTOR2I &aShapePos)
Calculate the primitive shape for flashed items.
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:124
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:204
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:189
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent)
Convert a shape to an equivalent polygon.
Definition: dcode.cpp:297
void writePcbFilledCircle(const VECTOR2I &aCenterPosition, int aRadius, int aLayer)
Write a filled circle to the board file (with line thickness = 0).
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
VECTOR2I GetABPosition(const VECTOR2I &aXYPosition) const
Return the image position of aPosition for this object.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both).
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References D_CODE::ConvertShapeToPolygon(), GBR_SPOT_CIRCLE, GBR_SPOT_OVAL, GERBER_DRAW_ITEM::GetABPosition(), APERTURE_MACRO::GetApertureMacroShape(), GERBER_DRAW_ITEM::GetDcodeDescr(), D_CODE::GetMacro(), 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, SHAPE_LINE_CHAIN::Mirror(), SHAPE_POLY_SET::Outline(), 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,
int  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 153 of file export_to_pcbnew.cpp.

154{
155 // used when a D_CODE is not found. default D_CODE to draw a flashed item
156 static D_CODE dummyD_CODE( 0 );
157
158 VECTOR2I seg_start = aGbrItem->m_Start;
159 VECTOR2I seg_end = aGbrItem->m_End;
160 D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
161 SHAPE_POLY_SET polygon;
162
163 if( d_codeDescr == nullptr )
164 d_codeDescr = &dummyD_CODE;
165
166 switch( aGbrItem->m_Shape )
167 {
168 case GBR_POLYGON:
169 writePcbPolygon( aGbrItem->m_Polygon, aLayer );
170 break;
171
172 case GBR_SPOT_CIRCLE:
173 {
174 VECTOR2I center = aGbrItem->GetABPosition( seg_start );
175 int radius = d_codeDescr->m_Size.x / 2;
176 writePcbFilledCircle( center, radius, aLayer );
177 }
178 break;
179
180 case GBR_SPOT_RECT:
181 case GBR_SPOT_OVAL:
182 case GBR_SPOT_POLY:
183 case GBR_SPOT_MACRO:
184 d_codeDescr->ConvertShapeToPolygon( aGbrItem );
185 writePcbPolygon( d_codeDescr->m_Polygon, aLayer, aGbrItem->GetABPosition( seg_start ) );
186 break;
187
188 case GBR_ARC:
189 {
190 double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
191 (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
192 double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
193 (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
194
195 double angle = RAD2DEG(b - a);
196 seg_start = aGbrItem->m_ArcCentre;
197
198 // Ensure arc orientation is CCW
199 if( angle < 0 )
200 angle += 360.0;
201
202 // Reverse Y axis:
203 seg_start.y = -seg_start.y;
204 seg_end.y = -seg_end.y;
205
206 if( angle == 360.0 || angle == 0 )
207 {
208 fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s) (layer %s) (width %s))\n",
209 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
210 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
211 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
212 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
213 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
214 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
215 }
216 else
217 {
218 fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %s) (layer %s) (width %s))\n",
219 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
220 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
221 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
222 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
223 FormatDouble2Str( angle ).c_str(),
224 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
225 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
226 }
227 }
228 break;
229
230 case GBR_CIRCLE:
231 // Reverse Y axis:
232 seg_start.y = -seg_start.y;
233 seg_end.y = -seg_end.y;
234
235 fprintf( m_fp, "(gr_circle (start %s %s) (end %s %s) (layer %s) (width %s))\n",
236 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
237 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
238 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
239 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
240 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
241 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
242 break;
243
244 case GBR_SEGMENT:
245 // Reverse Y axis:
246 seg_start.y = -seg_start.y;
247 seg_end.y = -seg_end.y;
248
249 fprintf( m_fp, "(gr_line (start %s %s) (end %s %s) (layer %s) (width %s))\n",
250 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
251 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
252 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
253 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
254 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
255 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
256 break;
257 }
258}
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
const wxString GetPCBDefaultLayerName(int aLayerNumber)
@ GBR_SEGMENT
@ GBR_CIRCLE
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
double RAD2DEG(double rad)
Definition: trigo.h:196

References PNS::angle(), D_CODE::ConvertShapeToPolygon(), FormatDouble2Str(), 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(), RAD2DEG(), TO_UTF8, writePcbFilledCircle(), writePcbPolygon(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by ExportPcb().

◆ export_segarc_copper_item()

void GBR_TO_PCB_EXPORTER::export_segarc_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
int  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 352 of file export_to_pcbnew.cpp.

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

References DELTA_ANGLE, GERBER_DRAW_ITEM::m_ArcCentre, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, RADIANS_T, RotatePoint(), writeCopperLineItem(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_copper_item().

◆ export_segline_copper_item()

void GBR_TO_PCB_EXPORTER::export_segline_copper_item ( const GERBER_DRAW_ITEM aGbrItem,
int  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 VECTOR2I 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}

References GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, writeCopperLineItem(), and VECTOR2< T >::y.

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 268 of file export_to_pcbnew.cpp.

269{
270 VECTOR2I via_pos = aVia.m_Pos;
271
272 // Reverse Y axis:
273 via_pos.y = -via_pos.y;
274
275 // Layers are Front to Back
276 fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
277 FormatDouble2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
278 FormatDouble2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
279 FormatDouble2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
280 FormatDouble2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
281
282 fprintf( m_fp, " (layers %s %s))\n",
285}
@ B_Cu
Definition: layer_ids.h:95
@ F_Cu
Definition: layer_ids.h:64
VECTOR2I m_Pos

References B_Cu, F_Cu, FormatDouble2Str(), GetPCBDefaultLayerName(), EXPORT_VIA::m_Drill, m_fp, EXPORT_VIA::m_Pos, EXPORT_VIA::m_Size, MapToPcbUnits(), TO_UTF8, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by ExportPcb().

◆ ExportPcb()

bool GBR_TO_PCB_EXPORTER::ExportPcb ( const int *  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 == nullptr )
66 {
67 wxString msg;
68 msg.Printf( _( "Failed to 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 int pcb_layer_number = aLayerLookUpTable[layer];
85 EXCELLON_IMAGE* excellon = dynamic_cast<EXCELLON_IMAGE*>( images->GetGbrImage( layer ) );
86 GERBER_FILE_IMAGE* gerb = dynamic_cast<GERBER_FILE_IMAGE*>( images->GetGbrImage( layer ) );
87 if( excellon )
88 {
89 for( GERBER_DRAW_ITEM* gerb_item : excellon->GetItems() )
90 collect_hole( gerb_item );
91 }
92 else if( gerb && pcb_layer_number == UNDEFINED_LAYER ) // PCB_LAYER_ID doesn't have an entry for Hole Data,
93 // but the dialog returns UNDEFINED_LAYER for it
94 {
95 for( GERBER_DRAW_ITEM* gerb_item : gerb->GetItems() )
96 collect_hole( gerb_item );
97 }
98 else
99 {
100 continue;
101 }
102 }
103
104 // Next: non copper layers:
105 for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
106 {
107 GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
108
109 if( gerber == nullptr ) // Graphic layer not yet used
110 continue;
111
112 int pcb_layer_number = aLayerLookUpTable[layer];
113
114 if( !IsPcbLayer( pcb_layer_number ) )
115 continue;
116
117 if( pcb_layer_number <= pcbCopperLayerMax ) // copper layer
118 continue;
119
120 for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
121 export_non_copper_item( gerb_item, pcb_layer_number );
122 }
123
124 // Copper layers
125 for( unsigned layer = 0; layer < images->ImagesMaxCount(); ++layer )
126 {
127 GERBER_FILE_IMAGE* gerber = images->GetGbrImage( layer );
128
129 if( gerber == nullptr ) // Graphic layer not yet used
130 continue;
131
132 int pcb_layer_number = aLayerLookUpTable[layer];
133
134 if( pcb_layer_number < 0 || pcb_layer_number > pcbCopperLayerMax )
135 continue;
136
137 for( GERBER_DRAW_ITEM* gerb_item : gerber->GetItems() )
138 export_copper_item( gerb_item, pcb_layer_number );
139 }
140
141 // Now write out the holes we collected earlier as vias
142 for( const EXPORT_VIA& via : m_vias )
143 export_via( via );
144
145 fprintf( m_fp, ")\n" );
146
147 fclose( m_fp );
148 m_fp = nullptr;
149 return true;
150}
Handle a drill image.
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Definition: gbr_layout.cpp:41
void export_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a track (or via) to the board file.
void export_non_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a non copper line or arc to the board file.
void collect_hole(const GERBER_DRAW_ITEM *aGbrItem)
Collect holes from a drill layer.
void writePcbHeader(const int *aLayerLookUpTable)
Write a very basic header to the board file.
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...
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
Hold the image data and parameters for one gerber file and layer parameters.
GERBER_DRAW_ITEMS & GetItems()
GBR_LAYOUT * GetGerberLayout() const
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
#define _(s)
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:814
@ UNDEFINED_LAYER
Definition: layer_ids.h:60

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, UNDEFINED_LAYER, 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 170 of file export_to_pcbnew.h.

171 {
172 return aValue / gerbIUScale.IU_PER_MM;
173 }
constexpr EDA_IU_SCALE gerbIUScale
Definition: base_units.h:108
const double IU_PER_MM
Definition: base_units.h:77

References gerbIUScale, and EDA_IU_SCALE::IU_PER_MM.

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

◆ writeCopperLineItem()

void GBR_TO_PCB_EXPORTER::writeCopperLineItem ( const VECTOR2I aStart,
const VECTOR2I aEnd,
int  aWidth,
int  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.

341{
342 fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
343 FormatDouble2Str( MapToPcbUnits(aStart.x) ).c_str(),
344 FormatDouble2Str( MapToPcbUnits(aStart.y) ).c_str(),
345 FormatDouble2Str( MapToPcbUnits(aEnd.x) ).c_str(),
346 FormatDouble2Str( MapToPcbUnits(aEnd.y) ).c_str(),
347 FormatDouble2Str( MapToPcbUnits( aWidth ) ).c_str(),
348 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
349}

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

Referenced by export_segarc_copper_item(), and export_segline_copper_item().

◆ writePcbFilledCircle()

void GBR_TO_PCB_EXPORTER::writePcbFilledCircle ( const VECTOR2I aCenterPosition,
int  aRadius,
int  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 461 of file export_to_pcbnew.cpp.

463{
464
465 fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)",
466 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x ) ).c_str(),
467 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str(),
468 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x + aRadius ) ).c_str(),
469 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str() );
470
471
472 fprintf( m_fp, "(layer %s) (width 0) (fill solid) )\n",
473 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
474}

References FormatDouble2Str(), 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 int *  aLayerLookUpTable)
private

Write a very basic header to the board file.

Definition at line 477 of file export_to_pcbnew.cpp.

478{
479 fprintf( m_fp, "(kicad_pcb (version 4) (generator gerbview)\n\n" );
480
481 // Write layers section
482 fprintf( m_fp, " (layers \n" );
483
484 for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
485 {
486 int id = ii;
487
488 if( ii == m_pcbCopperLayersCount-1)
489 id = B_Cu;
490
491 fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
492 }
493
494 for( int ii = B_Adhes; ii < PCB_LAYER_ID_COUNT; ii++ )
495 {
496 if( GetPCBDefaultLayerName( ii ).IsEmpty() ) // Layer not available for export
497 continue;
498
499 fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
500 }
501
502 fprintf( m_fp, " )\n\n" );
503}
@ B_Adhes
Definition: layer_ids.h:97
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137

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,
int  aLayer,
const VECTOR2I aOffset = { 0, 0 } 
)
private

Write a non-copper polygon to the board file.

Parameters
aLayeris the technical layer to use.

Definition at line 506 of file export_to_pcbnew.cpp.

508{
509 // Ensure the polygon is valid:
510 if( aPolys.OutlineCount() < 1 )
511 return;
512
513 // aPolys is expected having only one outline and no hole
514 // (because it comes from a gerber file or is built from a aperture )
515 const SHAPE_LINE_CHAIN& poly = aPolys.COutline( 0 );
516
517 fprintf( m_fp, "(gr_poly (pts " );
518
519 #define MAX_COORD_CNT 4
520 int jj = MAX_COORD_CNT;
521 int cnt_max = poly.PointCount() -1;
522
523 // Do not generate last corner, if it is the same point as the first point:
524 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
525 cnt_max--;
526
527 for( int ii = 0; ii <= cnt_max; ii++ )
528 {
529 if( --jj == 0 )
530 {
531 jj = MAX_COORD_CNT;
532 fprintf( m_fp, "\n" );
533 }
534
535 fprintf( m_fp, " (xy %s %s)",
536 FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x + aOffset.x ) ).c_str(),
537 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y + aOffset.y ) ).c_str() );
538 }
539
540 fprintf( m_fp, ")" );
541
542 if( jj != MAX_COORD_CNT )
543 fprintf( m_fp, "\n" );
544
545 fprintf( m_fp, "(layer %s) (width 0) )\n", TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
546}
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
#define MAX_COORD_CNT

References SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), FormatDouble2Str(), GetPCBDefaultLayerName(), m_fp, MapToPcbUnits(), MAX_COORD_CNT, SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), 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,
int  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 549 of file export_to_pcbnew.cpp.

550{
553
554 if( polys.OutlineCount() == 0 )
555 return;
556
557 fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
558 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
559
560 fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
561
562 fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
563 " (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
564
565 // Now, write the zone outlines with holes.
566 // first polygon is the main outline, next are holes
567 // One cannot know the initial zone outline.
568 // However most of (if not all) holes are just items with clearance,
569 // not really a hole in the initial zone outline.
570 // So we build a zone outline only with no hole.
571 fprintf( m_fp, " (polygon\n (pts" );
572
573 SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
574
575 #define MAX_COORD_CNT 4
576 int jj = MAX_COORD_CNT;
577 int cnt_max = poly.PointCount() -1;
578
579 // Do not generate last corner, if it is the same point as the first point:
580 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
581 cnt_max--;
582
583 for( int ii = 0; ii <= cnt_max; ii++ )
584 {
585 if( --jj == 0 )
586 {
587 jj = MAX_COORD_CNT;
588 fprintf( m_fp, "\n " );
589 }
590
591 fprintf( m_fp, " (xy %s %s)", FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
592 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
593 }
594
595 fprintf( m_fp, ")\n" );
596
597 fprintf( m_fp, " )\n)\n" );
598}
void Simplify(POLYGON_MODE aFastMode)
SHAPE_POLY_SET CloneDropTriangulation() const
Creates a new empty polygon in the set and returns its index.

References SHAPE_POLY_SET::CloneDropTriangulation(), SHAPE_LINE_CHAIN::CPoint(), FormatDouble2Str(), GetPCBDefaultLayerName(), m_fp, GERBER_DRAW_ITEM::m_Polygon, MapToPcbUnits(), MAX_COORD_CNT, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_FAST, 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 176 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 177 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 179 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 180 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: