KiCad PCB EDA Suite
Loading...
Searching...
No Matches
export_to_pcbnew.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2007-2023 Jean-Pierre Charras jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <vector>
26
27#include <export_to_pcbnew.h>
28
29#include <confirm.h>
30#include <string_utils.h>
31#include <locale_io.h>
32#include <macros.h>
33#include <trigo.h>
34#include <gerbview_frame.h>
35#include <gerber_file_image.h>
37#include <build_version.h>
39#include "excellon_image.h"
40
41// Imported function
42extern const wxString GetPCBDefaultLayerName( int aLayerNumber );
43
44
45GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName )
46{
47 m_gerbview_frame = aFrame;
48 m_pcb_file_name = aFileName;
49 m_fp = nullptr;
51}
52
53
55{
56}
57
58
59bool GBR_TO_PCB_EXPORTER::ExportPcb( const int* aLayerLookUpTable, int aCopperLayers )
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}
151
152
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_ShapeType )
167 {
168 case GBR_POLYGON:
169 writePcbPolygon( aGbrItem->m_ShapeAsPolygon, 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 {
186 SHAPE_POLY_SET polyshape = d_codeDescr->m_Polygon;
187
188 // Compensate the Y axis orientation ( writePcbPolygon invert the Y coordinate )
189 polyshape.Outline( 0 ).Mirror( { 0, 0 }, FLIP_DIRECTION::TOP_BOTTOM );
190 writePcbPolygon( polyshape, aLayer, aGbrItem->GetABPosition( seg_start ) );
191 }
192 break;
193
194 case GBR_ARC:
195 {
196 double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
197 (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
198 double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
199 (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
200
201 double angle = RAD2DEG(b - a);
202 seg_start = aGbrItem->m_ArcCentre;
203
204 // Ensure arc orientation is CCW
205 if( angle < 0 )
206 angle += 360.0;
207
208 // Reverse Y axis:
209 seg_start.y = -seg_start.y;
210 seg_end.y = -seg_end.y;
211
212 if( angle == 360.0 || angle == 0 )
213 {
214 fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s) (layer %s) (width %s))\n",
215 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
216 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
217 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
218 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
219 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
220 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
221 }
222 else
223 {
224 fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %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 FormatDouble2Str( angle ).c_str(),
230 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
231 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
232 }
233 }
234 break;
235
236 case GBR_CIRCLE:
237 // Reverse Y axis:
238 seg_start.y = -seg_start.y;
239 seg_end.y = -seg_end.y;
240
241 fprintf( m_fp, "(gr_circle (start %s %s) (end %s %s) (layer %s) (width %s))\n",
242 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
243 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
244 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
245 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
246 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
247 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
248 break;
249
250 case GBR_SEGMENT:
251 // Reverse Y axis:
252 seg_start.y = -seg_start.y;
253 seg_end.y = -seg_end.y;
254
255 fprintf( m_fp, "(gr_line (start %s %s) (end %s %s) (layer %s) (width %s))\n",
256 FormatDouble2Str( MapToPcbUnits( seg_start.x ) ).c_str(),
257 FormatDouble2Str( MapToPcbUnits( seg_start.y ) ).c_str(),
258 FormatDouble2Str( MapToPcbUnits( seg_end.x ) ).c_str(),
259 FormatDouble2Str( MapToPcbUnits( seg_end.y ) ).c_str(),
260 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
261 FormatDouble2Str( MapToPcbUnits( aGbrItem->m_Size.x ) ).c_str() );
262 break;
263 }
264}
265
266
268{
269 int size = std::min( aGbrItem->m_Size.x, aGbrItem->m_Size.y );
270 m_vias.emplace_back( aGbrItem->m_Start, size + 1, size );
271}
272
273
275{
276 VECTOR2I via_pos = aVia.m_Pos;
277
278 // Reverse Y axis:
279 via_pos.y = -via_pos.y;
280
281 // Layers are Front to Back
282 fprintf( m_fp, " (via (at %s %s) (size %s) (drill %s)",
283 FormatDouble2Str( MapToPcbUnits( via_pos.x ) ).c_str(),
284 FormatDouble2Str( MapToPcbUnits( via_pos.y ) ).c_str(),
285 FormatDouble2Str( MapToPcbUnits( aVia.m_Size ) ).c_str(),
286 FormatDouble2Str( MapToPcbUnits( aVia.m_Drill ) ).c_str() );
287
288 fprintf( m_fp, " (layers %s %s))\n",
291}
292
293
295{
296 switch( aGbrItem->m_ShapeType )
297 {
298 case GBR_SPOT_CIRCLE:
299 case GBR_SPOT_RECT:
300 case GBR_SPOT_OVAL:
301 case GBR_SPOT_POLY:
302 case GBR_SPOT_MACRO:
303 export_flashed_copper_item( aGbrItem, aLayer );
304 break;
305
306 case GBR_CIRCLE:
307 case GBR_ARC:
308 export_segarc_copper_item( aGbrItem, aLayer );
309 break;
310
311 case GBR_POLYGON:
312 // One can use a polygon or a zone to output a Gerber region.
313 // none are perfect.
314 // The current way is use a polygon, as the zone export
315 // is experimental and only for tests.
316#if 1
317 writePcbPolygon( aGbrItem->m_ShapeAsPolygon, aLayer );
318#else
319 // Only for tests:
320 writePcbZoneItem( aGbrItem, aLayer );
321#endif
322 break;
323
324 case GBR_SEGMENT:
325 {
326 D_CODE* code = aGbrItem->GetDcodeDescr();
327
328 if( code && code->m_ApertType == APT_RECT )
329 {
330 if( aGbrItem->m_ShapeAsPolygon.OutlineCount() == 0 )
331 const_cast<GERBER_DRAW_ITEM*>( aGbrItem )->ConvertSegmentToPolygon();
332
333 writePcbPolygon( aGbrItem->m_ShapeAsPolygon, aLayer );
334 }
335 else
336 {
337 export_segline_copper_item( aGbrItem, aLayer );
338 }
339
340 break;
341 }
342
343 default:
344 break;
345 }
346}
347
348
350{
351 VECTOR2I seg_start, seg_end;
352
353 seg_start = aGbrItem->m_Start;
354 seg_end = aGbrItem->m_End;
355
356 // Reverse Y axis:
357 seg_start.y = -seg_start.y;
358 seg_end.y = -seg_end.y;
359
360 writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
361}
362
363
365 int aWidth, int aLayer )
366{
367 fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
368 FormatDouble2Str( MapToPcbUnits(aStart.x) ).c_str(),
369 FormatDouble2Str( MapToPcbUnits(aStart.y) ).c_str(),
370 FormatDouble2Str( MapToPcbUnits(aEnd.x) ).c_str(),
371 FormatDouble2Str( MapToPcbUnits(aEnd.y) ).c_str(),
372 FormatDouble2Str( MapToPcbUnits( aWidth ) ).c_str(),
373 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
374}
375
376
378{
379 double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
380 (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
381 double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
382 (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
383
384 VECTOR2I start = aGbrItem->m_Start;
385 VECTOR2I end = aGbrItem->m_End;
386
387 /* Because Pcbnew does not know arcs in tracks,
388 * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
389 * The arc is drawn anticlockwise from the start point to the end point.
390 */
391 #define SEG_COUNT_CIRCLE 16
392 #define DELTA_ANGLE 2 * M_PI / SEG_COUNT_CIRCLE
393
394 // calculate the number of segments from a to b.
395 // we want CNT_PER_360 segments fo a circle
396 if( a > b )
397 b += 2 * M_PI;
398
399 VECTOR2I curr_start = start;
400 VECTOR2I seg_start, seg_end;
401
402 int ii = 1;
403
404 for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
405 {
406 seg_start = curr_start;
407 VECTOR2I curr_end = start;
408 RotatePoint( curr_end, aGbrItem->m_ArcCentre, -EDA_ANGLE( DELTA_ANGLE, RADIANS_T ) * ii );
409 seg_end = curr_end;
410
411 // Reverse Y axis:
412 seg_start.y = -seg_start.y;
413 seg_end.y = -seg_end.y;
414 writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
415 curr_start = curr_end;
416 }
417
418 if( end != curr_start )
419 {
420 seg_start = curr_start;
421 seg_end = end;
422
423 // Reverse Y axis:
424 seg_start.y = -seg_start.y;
425 seg_end.y = -seg_end.y;
426 writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
427 }
428}
429
430#include <wx/log.h>
432{
433 static D_CODE flashed_item_D_CODE( 0 );
434
435 D_CODE* d_codeDescr = aGbrItem->GetDcodeDescr();
436
437 if( d_codeDescr == nullptr )
438 d_codeDescr = &flashed_item_D_CODE;
439
440 if( aGbrItem->m_ShapeType == GBR_SPOT_CIRCLE )
441 {
442 // See if there's a via that we can enlarge to fit this flashed item
443 for( EXPORT_VIA& via : m_vias )
444 {
445 if( via.m_Pos == aGbrItem->m_Start )
446 {
447 via.m_Size = std::max( via.m_Size, aGbrItem->m_Size.x );
448 return;
449 }
450 }
451 }
452
453 VECTOR2I offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
454
455 if( aGbrItem->m_ShapeType == GBR_SPOT_CIRCLE ||
456 ( aGbrItem->m_ShapeType == GBR_SPOT_OVAL && d_codeDescr->m_Size.x == d_codeDescr->m_Size.y ) )
457 {
458 // export it as filled circle
459 VECTOR2I center = offset;
460 int radius = d_codeDescr->m_Size.x / 2;
461 writePcbFilledCircle( center, radius, aLayer );
462 return;
463 }
464
465 APERTURE_MACRO* macro = d_codeDescr->GetMacro();
466
467 if( macro ) // export a GBR_SPOT_MACRO
468 {
469 SHAPE_POLY_SET macroShape;
470 macroShape = *macro->GetApertureMacroShape( aGbrItem, VECTOR2I( 0, 0 ) );
471
472 // Compensate the Y axis orientation ( writePcbPolygon invert the Y coordinate )
473 macroShape.Outline( 0 ).Mirror( { 0, 0 }, FLIP_DIRECTION::TOP_BOTTOM );
474
475 writePcbPolygon( macroShape, aLayer, offset );
476 }
477 else
478 {
479 // Should cover primitives: GBR_SPOT_RECT, GBR_SPOT_OVAL, GBR_SPOT_POLY
480 d_codeDescr->ConvertShapeToPolygon( aGbrItem );
481 writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
482 }
483}
484
485
486void GBR_TO_PCB_EXPORTER::writePcbFilledCircle( const VECTOR2I& aCenterPosition, int aRadius,
487 int aLayer )
488{
489
490 fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)",
491 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x ) ).c_str(),
492 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str(),
493 FormatDouble2Str( MapToPcbUnits( aCenterPosition.x + aRadius ) ).c_str(),
494 FormatDouble2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str() );
495
496
497 fprintf( m_fp, "(layer %s) (width 0) (fill solid) )\n",
498 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
499}
500
501
502void GBR_TO_PCB_EXPORTER::writePcbHeader( const int* aLayerLookUpTable )
503{
504 fprintf( m_fp, "(kicad_pcb (version 4) (generator \"gerbview\") (generator_version \"%s\")\n\n", GetMajorMinorVersion().c_str().AsChar() );
505
506 // Write layers section
507 fprintf( m_fp, " (layers \n" );
508
509 for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
510 {
511 int id = ii;
512
513 if( ii == m_pcbCopperLayersCount-1)
514 id = B_Cu;
515
516 fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
517 }
518
519 for( int ii = B_Adhes; ii < PCB_LAYER_ID_COUNT; ii++ )
520 {
521 if( GetPCBDefaultLayerName( ii ).IsEmpty() ) // Layer not available for export
522 continue;
523
524 fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
525 }
526
527 fprintf( m_fp, " )\n\n" );
528}
529
530
532 const VECTOR2I& aOffset )
533{
534 // Ensure the polygon is valid:
535 if( aPolys.OutlineCount() < 1 )
536 return;
537
538 // aPolys is expected having only one outline and no hole
539 // (because it comes from a gerber file or is built from a aperture )
540 const SHAPE_LINE_CHAIN& poly = aPolys.COutline( 0 );
541
542 fprintf( m_fp, "(gr_poly (pts " );
543
544 #define MAX_COORD_CNT 4
545 int jj = MAX_COORD_CNT;
546 int cnt_max = poly.PointCount() -1;
547
548 // Do not generate last corner, if it is the same point as the first point:
549 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
550 cnt_max--;
551
552 for( int ii = 0; ii <= cnt_max; ii++ )
553 {
554 if( --jj == 0 )
555 {
556 jj = MAX_COORD_CNT;
557 fprintf( m_fp, "\n" );
558 }
559
560 fprintf( m_fp, " (xy %s %s)",
561 FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x + aOffset.x ) ).c_str(),
562 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y + aOffset.y ) ).c_str() );
563 }
564
565 fprintf( m_fp, ")" );
566
567 if( jj != MAX_COORD_CNT )
568 fprintf( m_fp, "\n" );
569
570 fprintf( m_fp, "(layer %s) (width 0) )\n", TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
571}
572
573
575{
578
579 if( polys.OutlineCount() == 0 )
580 return;
581
582 fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
583 TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
584
585 fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
586
587 fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
588 " (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
589
590 // Now, write the zone outlines with holes.
591 // first polygon is the main outline, next are holes
592 // One cannot know the initial zone outline.
593 // However most of (if not all) holes are just items with clearance,
594 // not really a hole in the initial zone outline.
595 // So we build a zone outline only with no hole.
596 fprintf( m_fp, " (polygon\n (pts" );
597
598 SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
599
600 #define MAX_COORD_CNT 4
601 int jj = MAX_COORD_CNT;
602 int cnt_max = poly.PointCount() -1;
603
604 // Do not generate last corner, if it is the same point as the first point:
605 if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
606 cnt_max--;
607
608 for( int ii = 0; ii <= cnt_max; ii++ )
609 {
610 if( --jj == 0 )
611 {
612 jj = MAX_COORD_CNT;
613 fprintf( m_fp, "\n " );
614 }
615
616 fprintf( m_fp, " (xy %s %s)", FormatDouble2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
617 FormatDouble2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
618 }
619
620 fprintf( m_fp, ")\n" );
621
622 fprintf( m_fp, " )\n)\n" );
623}
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
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:125
VECTOR2I m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:190
APERTURE_T m_ApertType
Aperture type ( Line, rectangle, circle, oval poly, macro )
Definition: dcode.h:191
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:206
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent)
Convert a shape to an equivalent polygon.
Definition: dcode.cpp:297
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 writePcbZoneItem(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a zone item to the board file.
GERBVIEW_FRAME * m_gerbview_frame
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.
GBR_TO_PCB_EXPORTER(GERBVIEW_FRAME *aFrame, const wxString &aFileName)
void export_flashed_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a synthetic pad to the board file.
double MapToPcbUnits(int aValue) const
Map GerbView internal units to millimeters for Pcbnew board files.
std::vector< EXPORT_VIA > m_vias
void collect_hole(const GERBER_DRAW_ITEM *aGbrItem)
Collect holes from a drill layer.
void writePcbPolygon(const SHAPE_POLY_SET &aPolys, int aLayer, const VECTOR2I &aOffset={ 0, 0 })
Write a non-copper polygon to the board file.
void writePcbFilledCircle(const VECTOR2I &aCenterPosition, int aRadius, int aLayer)
Write a filled circle to the board file (with line thickness = 0).
void export_segline_copper_item(const GERBER_DRAW_ITEM *aGbrItem, int aLayer)
Write a track (not via) to the board file.
void writePcbHeader(const int *aLayerLookUpTable)
Write a very basic header to the board file.
bool ExportPcb(const int *aLayerLookUpTable, int aCopperLayers)
Save a board from a set of Gerber images.
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.
void export_via(const EXPORT_VIA &aVia)
Write a via to the board file.
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.
SHAPE_POLY_SET m_ShapeAsPolygon
GBR_BASIC_SHAPE_TYPE m_ShapeType
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:49
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.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both).
Represent a set of closed polygons.
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
SHAPE_POLY_SET CloneDropTriangulation() const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
This file is part of the common library.
@ APT_RECT
Definition: dcode.h:50
const wxString GetPCBDefaultLayerName(int aLayerNumber)
#define _(s)
@ RADIANS_T
Definition: eda_angle.h:32
#define MAX_COORD_CNT
const wxString GetPCBDefaultLayerName(int aLayerNumber)
#define DELTA_ANGLE
@ GBR_SPOT_OVAL
@ GBR_SEGMENT
@ GBR_SPOT_POLY
@ GBR_SPOT_RECT
@ GBR_CIRCLE
@ GBR_POLYGON
@ GBR_SPOT_CIRCLE
@ GBR_ARC
@ GBR_SPOT_MACRO
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:520
@ B_Adhes
Definition: layer_ids.h:103
@ B_Cu
Definition: layer_ids.h:65
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:135
@ F_Cu
Definition: layer_ids.h:64
This file contains miscellaneous commonly used macros and functions.
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:398
VECTOR2I m_Pos
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:229
double RAD2DEG(double rad)
Definition: trigo.h:167
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691
Definition of file extensions used in Kicad.