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

251{
252 int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
253 m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
254}
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 277 of file export_to_pcbnew.cpp.

278{
279 switch( aGbrItem->m_Shape )
280 {
281 case GBR_SPOT_CIRCLE:
282 case GBR_SPOT_RECT:
283 case GBR_SPOT_OVAL:
284 case GBR_SPOT_POLY:
285 case GBR_SPOT_MACRO:
286 export_flashed_copper_item( aGbrItem, aLayer );
287 break;
288
289 case GBR_ARC:
290 export_segarc_copper_item( aGbrItem, aLayer );
291 break;
292
293 case GBR_POLYGON:
294 // One can use a polygon or a zone to output a Gerber region.
295 // none are perfect.
296 // The current way is use a polygon, as the zone export
297 // is experimental and only for tests.
298#if 1
299 writePcbPolygon( aGbrItem->m_Polygon, aLayer );
300#else
301 // Only for tests:
302 writePcbZoneItem( aGbrItem, aLayer );
303#endif
304 break;
305
306 default:
307 export_segline_copper_item( aGbrItem, aLayer );
308 break;
309 }
310}
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 395 of file export_to_pcbnew.cpp.

396{
397 static D_CODE flashed_item_D_CODE( 0 );
398
399 D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
400
401 if( d_codeDescr == nullptr )
402 d_codeDescr = &flashed_item_D_CODE;
403
404 if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE )
405 {
406 // See if there's a via that we can enlarge to fit this flashed item
407 for( EXPORT_VIA& via : m_vias )
408 {
409 if( via.m_Pos == aGbrItem->m_Start )
410 {
411 via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
412 return;
413 }
414 }
415 }
416
417 VECTOR2I offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
418
419 if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE ) // export it as filled circle
420 {
421 VECTOR2I center = offset;
422 int radius = d_codeDescr->m_Size.x / 2;
423 writePcbFilledCircle( center, radius, aLayer );
424 return;
425 }
426
427 APERTURE_MACRO* macro = d_codeDescr->GetMacro();
428 SHAPE_POLY_SET* macroShape = macro->GetApertureMacroShape( aGbrItem, VECTOR2I( 0, 0 ) );
429 writePcbPolygon( *macroShape, aLayer, offset );
430}
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:124
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:189
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.
Represent a set of closed polygons.
Support the "aperture macro" defined within standard RS274X.
Definition: am_primitive.h:167
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, const VECTOR2I &aShapePos)
Calculate the primitive shape for flashed items.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References GBR_SPOT_CIRCLE, GERBER_DRAW_ITEM::GetABPosition(), APERTURE_MACRO::GetApertureMacroShape(), GERBER_DRAW_ITEM::GetDcodeDescr(), D_CODE::GetMacro(), GERBER_DRAW_ITEM::m_Shape, D_CODE::m_Size, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, m_vias, 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 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 VECTOR2I seg_start = aGbrItem->m_Start;
148 VECTOR2I seg_end = aGbrItem->m_End;
149 D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
150 SHAPE_POLY_SET polygon;
151
152 if( d_codeDescr == nullptr )
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( aGbrItem );
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 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
199 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
200 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
201 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
202 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
203 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
204 }
205 else
206 {
207 fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %s) (layer %s) (width %s))\n",
208 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
209 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
210 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
211 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
212 FormatDouble2Str( angle ).c_str(),
213 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
214 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
215 }
216 }
217 break;
218
219 case GBR_CIRCLE:
220 // Reverse Y axis:
221 seg_start.y = -seg_start.y;
222 seg_end.y = -seg_end.y;
223
224 fprintf( m_fp, "(gr_circle (start %s %s) (end %s %s) (layer %s) (width %s))\n",
225 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
226 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
227 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
228 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
229 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
230 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
231 break;
232
233 case GBR_SEGMENT:
234 // Reverse Y axis:
235 seg_start.y = -seg_start.y;
236 seg_end.y = -seg_end.y;
237
238 fprintf( m_fp, "(gr_line (start %s %s) (end %s %s) (layer %s) (width %s))\n",
239 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
240 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
241 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
242 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
243 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
244 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
245 break;
246 }
247}
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:204
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent)
Convert a shape to an equivalent polygon.
Definition: dcode.cpp:294
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 341 of file export_to_pcbnew.cpp.

342{
343 double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
344 (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
345 double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
346 (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
347
348 VECTOR2I start = aGbrItem->m_Start;
349 VECTOR2I end = aGbrItem->m_End;
350
351 /* Because Pcbnew does not know arcs in tracks,
352 * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
353 * The arc is drawn anticlockwise from the start point to the end point.
354 */
355 #define SEG_COUNT_CIRCLE 16
356 #define DELTA_ANGLE 2 * M_PI / SEG_COUNT_CIRCLE
357
358 // calculate the number of segments from a to b.
359 // we want CNT_PER_360 segments fo a circle
360 if( a > b )
361 b += 2 * M_PI;
362
363 VECTOR2I curr_start = start;
364 VECTOR2I seg_start, seg_end;
365
366 int ii = 1;
367
368 for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
369 {
370 seg_start = curr_start;
371 VECTOR2I curr_end = start;
372 RotatePoint( curr_end, aGbrItem->m_ArcCentre, -EDA_ANGLE( DELTA_ANGLE, RADIANS_T ) * ii );
373 seg_end = curr_end;
374
375 // Reverse Y axis:
376 seg_start.y = -seg_start.y;
377 seg_end.y = -seg_end.y;
378 writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
379 curr_start = curr_end;
380 }
381
382 if( end != curr_start )
383 {
384 seg_start = curr_start;
385 seg_end = end;
386
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 }
392}
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 313 of file export_to_pcbnew.cpp.

314{
315 VECTOR2I seg_start, seg_end;
316
317 seg_start = aGbrItem->m_Start;
318 seg_end = aGbrItem->m_End;
319
320 // Reverse Y axis:
321 seg_start.y = -seg_start.y;
322 seg_end.y = -seg_end.y;
323
324 writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
325}

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

258{
259 VECTOR2I via_pos = aVia.m_Pos;
260
261 // Reverse Y axis:
262 via_pos.y = -via_pos.y;
263
264 // Layers are Front to Back
265 fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
266 FormatDouble2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
267 FormatDouble2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
268 FormatDouble2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
269 FormatDouble2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
270
271 fprintf( m_fp, " (layers %s %s))\n",
274}
@ 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 EXCELLON_IMAGE* excellon = dynamic_cast<EXCELLON_IMAGE*>( images->GetGbrImage( layer ) );
85
86 if( excellon == nullptr ) // 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 == nullptr ) // Graphic layer not yet used
99 continue;
100
101 int 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 == nullptr ) // Graphic layer not yet used
119 continue;
120
121 int 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 = nullptr;
138 return true;
139}
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:280
#define _(s)
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:812

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

330{
331 fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
332 FormatDouble2Str( MapToPcbUnits(aStart.x) ).c_str(),
333 FormatDouble2Str( MapToPcbUnits(aStart.y) ).c_str(),
334 FormatDouble2Str( MapToPcbUnits(aEnd.x) ).c_str(),
335 FormatDouble2Str( MapToPcbUnits(aEnd.y) ).c_str(),
336 FormatDouble2Str( MapToPcbUnits( aWidth ) ).c_str(),
337 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
338}

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

435{
436
437 fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)",
438 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x ) ).c_str(),
439 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str(),
440 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x + aRadius ) ).c_str(),
441 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str() );
442
443
444 fprintf( m_fp, "(layer %s) (width 0) (fill solid) )\n",
445 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
446}

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

450{
451 fprintf( m_fp, "(kicad_pcb (version 4) (generator gerbview)\n\n" );
452
453 // Write layers section
454 fprintf( m_fp, " (layers \n" );
455
456 for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
457 {
458 int id = ii;
459
460 if( ii == m_pcbCopperLayersCount-1)
461 id = B_Cu;
462
463 fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
464 }
465
466 for( int ii = B_Adhes; ii < PCB_LAYER_ID_COUNT; ii++ )
467 {
468 if( GetPCBDefaultLayerName( ii ).IsEmpty() ) // Layer not available for export
469 continue;
470
471 fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
472 }
473
474 fprintf( m_fp, " )\n\n" );
475}
@ 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 478 of file export_to_pcbnew.cpp.

480{
481 // Ensure the polygon is valid:
482 if( aPolys.OutlineCount() < 1 )
483 return;
484
485 // aPolys is expected having only one outline and no hole
486 // (because it comes from a gerber file or is built from a aperture )
487 const SHAPE_LINE_CHAIN& poly = aPolys.COutline( 0 );
488
489 fprintf( m_fp, "(gr_poly (pts " );
490
491 #define MAX_COORD_CNT 4
492 int jj = MAX_COORD_CNT;
493 int cnt_max = poly.PointCount() -1;
494
495 // Do not generate last corner, if it is the same point as the first point:
496 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
497 cnt_max--;
498
499 for( int ii = 0; ii <= cnt_max; ii++ )
500 {
501 if( --jj == 0 )
502 {
503 jj = MAX_COORD_CNT;
504 fprintf( m_fp, "\n" );
505 }
506
507 fprintf( m_fp, " (xy %s %s)",
508 FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x + aOffset.x ) ).c_str(),
509 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y + aOffset.y ) ).c_str() );
510 }
511
512 fprintf( m_fp, ")" );
513
514 if( jj != MAX_COORD_CNT )
515 fprintf( m_fp, "\n" );
516
517 fprintf( m_fp, "(layer %s) (width 0) )\n", TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
518}
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 521 of file export_to_pcbnew.cpp.

522{
525
526 if( polys.OutlineCount() == 0 )
527 return;
528
529 fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
530 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
531
532 fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
533
534 fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
535 " (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
536
537 // Now, write the zone outlines with holes.
538 // first polygon is the main outline, next are holes
539 // One cannot know the initial zone outline.
540 // However most of (if not all) holes are just items with clearance,
541 // not really a hole in the initial zone outline.
542 // So we build a zone outline only with no hole.
543 fprintf( m_fp, " (polygon\n (pts" );
544
545 SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
546
547 #define MAX_COORD_CNT 4
548 int jj = MAX_COORD_CNT;
549 int cnt_max = poly.PointCount() -1;
550
551 // Do not generate last corner, if it is the same point as the first point:
552 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
553 cnt_max--;
554
555 for( int ii = 0; ii <= cnt_max; ii++ )
556 {
557 if( --jj == 0 )
558 {
559 jj = MAX_COORD_CNT;
560 fprintf( m_fp, "\n " );
561 }
562
563 fprintf( m_fp, " (xy %s %s)", FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
564 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
565 }
566
567 fprintf( m_fp, ")\n" );
568
569 fprintf( m_fp, " )\n)\n" );
570}
void Simplify(POLYGON_MODE aFastMode)
SHAPE_LINE_CHAIN & Outline(int aIndex)
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: