KiCad PCB EDA Suite
Loading...
Searching...
No Matches
rs274d.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) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
29#include <gerbview.h>
30#include <gerbview_frame.h>
31#include <trigo.h>
32#include <gerber_file_image.h>
34
35#include <cmath>
36
37/* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes).
38 * Some are now deprecated, but deprecated commands must be known by the Gerber reader
39 * Gn =
40 * G01 linear interpolation (linear trace)
41 * G02, G20, G21 Circular interpolation, clockwise
42 * G03, G30, G31 Circular interpolation, counterclockwise
43 * G04 = comment. Since Sept 2014, file attributes and other X2 attributes can be found here
44 * if the line starts by G04 #@!
45 * G06 parabolic interpolation
46 * G07 Cubic Interpolation
47 * G10 linear interpolation (scale x10)
48 * G11 linear interpolation (0.1x range)
49 * G12 linear interpolation (0.01x scale)
50 * G36 Start polygon mode (called a region, because the "polygon" can include arcs)
51 * G37 Stop polygon mode (and close it)
52 * G54 Selection Tool (outdated)
53 * G60 linear interpolation (scale x100)
54 * G70 Select Units = Inches
55 * G71 Select Units = Millimeters
56 * G74 enable 90 deg mode for arcs (CW or CCW)
57 * G75 enable 360 degrees for arcs (CW or CCW)
58 * G90 mode absolute coordinates
59 *
60 * X, Y
61 * X and Y are followed by + or - and m + n digits (not separated)
62 * m = integer part
63 * n = part after the comma
64 *ic formats: m = 2, n = 3 (size 2.3)
65 * m = 3, n = 4 (size 3.4)
66 * eg
67 * GxxX00345Y-06123*
68 *
69 * Tools and D_CODES
70 * Tool number (identification of shapes)
71 * 10 to 999
72 * D_CODES:
73 * D01 ... D9 = command codes:
74 * D01 = activating light (pen down) when placement
75 * D02 = light extinction (pen up) when placement
76 * D03 = Flash
77 * D09 = VAPE Flash (I never see this command in Gerber file)
78 * D51 = G54 preceded by -> Select VAPE
79 *
80 * D10 ... D999 = Identification Tool: tool selection
81 */
82
83
84/* Local Functions (are lower case since they are private to this source file)
85**/
86
87
100 APERTURE_T aAperture,
101 int Dcode_index,
102 const VECTOR2I& aPos,
103 VECTOR2I aSize,
104 bool aLayerNegative )
105{
106 aGbrItem->m_Size = aSize;
107 aGbrItem->m_Start = aPos;
108 aGbrItem->m_End = aGbrItem->m_Start;
109 aGbrItem->m_DCode = Dcode_index;
110 aGbrItem->SetLayerPolarity( aLayerNegative );
111 aGbrItem->m_Flashed = true;
113
114 switch( aAperture )
115 {
116 case APT_POLYGON: // flashed regular polygon
117 aGbrItem->m_ShapeType = GBR_SPOT_POLY;
118 break;
119
120 case APT_CIRCLE:
121 aGbrItem->m_ShapeType = GBR_SPOT_CIRCLE;
122 aGbrItem->m_Size.y = aGbrItem->m_Size.x;
123 break;
124
125 case APT_OVAL:
126 aGbrItem->m_ShapeType = GBR_SPOT_OVAL;
127 break;
128
129 case APT_RECT:
130 aGbrItem->m_ShapeType = GBR_SPOT_RECT;
131 break;
132
133 case APT_MACRO:
134 aGbrItem->m_ShapeType = GBR_SPOT_MACRO;
135
136 // Cache the bounding box for aperture macros
137 aGbrItem->GetDcodeDescr()->GetMacro()->GetApertureMacroShape( aGbrItem, aPos );
138 break;
139 }
140}
141
142
154 int Dcode_index,
155 const VECTOR2I& aStart,
156 const VECTOR2I& aEnd,
157 VECTOR2I aPenSize,
158 bool aLayerNegative )
159{
160 aGbrItem->m_Flashed = false;
161
162 aGbrItem->m_Size = aPenSize;
163
164 aGbrItem->m_Start = aStart;
165 aGbrItem->m_End = aEnd;
166
167 aGbrItem->m_DCode = Dcode_index;
168 aGbrItem->SetLayerPolarity( aLayerNegative );
169
171}
172
173
202void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, const VECTOR2I& aStart,
203 const VECTOR2I& aEnd, const VECTOR2I& aRelCenter, VECTOR2I aPenSize,
204 bool aClockwise, bool aMultiquadrant, bool aLayerNegative )
205{
206 VECTOR2I center, delta;
207
208 aGbrItem->m_ShapeType = GBR_ARC;
209 aGbrItem->m_Size = aPenSize;
210 aGbrItem->m_Flashed = false;
211
212 if( aGbrItem->m_GerberImageFile )
214
215 if( aMultiquadrant )
216 {
217 center = aStart + aRelCenter;
218 }
219 else
220 {
221 // in single quadrant mode the relative coordinate aRelCenter is always >= 0
222 // So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
223 center = aRelCenter;
224
225 // calculate arc end coordinate relative to the starting point,
226 // because center is relative to the center point
227 delta = aEnd - aStart;
228
229 // now calculate the relative to aStart center position, for a draw function
230 // that use trigonometric arc angle (or counter-clockwise)
231 /* Quadrants:
232 * Y
233 * 2 | 1
234 * -------X
235 * 3 | 4
236 * C = actual relative arc center, S = arc start (axis origin) E = relative arc end
237 */
238 if( (delta.x >= 0) && (delta.y >= 0) )
239 {
240 /* Quadrant 1 (trigo or cclockwise):
241 * C | E
242 * ---S---
243 * 3 | 4
244 */
245 center.x = -center.x;
246 }
247 else if( (delta.x >= 0) && (delta.y < 0) )
248 {
249 /* Quadrant 4 (trigo or cclockwise):
250 * 2 | C
251 * ---S---
252 * 3 | E
253 */
254 // Nothing to do
255 }
256 else if( (delta.x < 0) && (delta.y >= 0) )
257 {
258 /* Quadrant 2 (trigo or cclockwise):
259 * E | 1
260 * ---S---
261 * C | 4
262 */
263 center.x = -center.x;
264 center.y = -center.y;
265 }
266 else
267 {
268 /* Quadrant 3 (trigo or cclockwise):
269 * 2 | 1
270 * ---S---
271 * E | C
272 */
273 center.y = -center.y;
274 }
275
276 // Due to your draw arc function, we need this:
277 if( !aClockwise )
278 center = - center;
279
280 // Calculate actual arc center coordinate:
281 center += aStart;
282 }
283
284 if( aClockwise )
285 {
286 aGbrItem->m_Start = aStart;
287 aGbrItem->m_End = aEnd;
288 }
289 else
290 {
291 aGbrItem->m_Start = aEnd;
292 aGbrItem->m_End = aStart;
293 }
294
295 aGbrItem->m_ArcCentre = center;
296
297 aGbrItem->m_DCode = Dcode_index;
298 aGbrItem->SetLayerPolarity( aLayerNegative );
299}
300
301
328static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem, const VECTOR2I& aStart, const VECTOR2I& aEnd,
329 const VECTOR2I& rel_center, bool aClockwise, bool aMultiquadrant,
330 bool aLayerNegative )
331{
332 /* in order to calculate arc parameters, we use fillArcGBRITEM
333 * so we muse create a dummy track and use its geometric parameters
334 */
335 static GERBER_DRAW_ITEM dummyGbrItem( nullptr );
336
337 aGbrItem->SetLayerPolarity( aLayerNegative );
338
339 fillArcGBRITEM( &dummyGbrItem, 0, aStart, aEnd, rel_center, VECTOR2I( 0, 0 ),
340 aClockwise, aMultiquadrant, aLayerNegative );
341
343
344 VECTOR2I center;
345 center = dummyGbrItem.m_ArcCentre;
346
347 // Calculate coordinates relative to arc center;
348 VECTOR2I start = dummyGbrItem.m_Start - center;
349 VECTOR2I end = dummyGbrItem.m_End - center;
350
351 /* Calculate angle arc
352 * angle is trigonometrical (counter-clockwise),
353 * and axis is the X,Y gerber coordinates
354 */
355 EDA_ANGLE start_angle( start );
356 EDA_ANGLE end_angle( end );
357
358 // dummyTrack has right geometric parameters, but
359 // fillArcGBRITEM calculates arc parameters for a draw function that expects
360 // start_angle < end_angle. So ensure this is the case here:
361 // Due to the fact atan2 returns angles between -180 to + 180 degrees,
362 // this is not always the case ( a modulo 360.0 degrees can be lost )
363 //
364 // Note also an arc with same start and end angle is a circle (360 deg arc)
365 // in gerber files
366 if( start_angle >= end_angle )
367 end_angle += ANGLE_360;
368
369 EDA_ANGLE arc_angle = start_angle - end_angle;
370
371 // Approximate arc by segments with a approximation error = err_max
372 // a max err = 5 microns looks good
373 const int approx_err_max = gerbIUScale.mmToIU( 0.005 );
374 int radius = VECTOR2I( aStart - rel_center ).EuclideanNorm();
375 int count = GetArcToSegmentCount( radius, approx_err_max, arc_angle );
376 EDA_ANGLE increment_angle = std::abs( arc_angle ) / count;
377
378 if( aGbrItem->m_ShapeAsPolygon.OutlineCount() == 0 )
379 aGbrItem->m_ShapeAsPolygon.NewOutline();
380
381 // calculate polygon corners
382 // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
383 // and we must always create a polygon from start to end.
384 for( int ii = 0; ii <= count; ii++ )
385 {
386 EDA_ANGLE rot;
387 VECTOR2I end_arc = start;
388
389 if( aClockwise )
390 rot = increment_angle * ii;
391 else
392 rot = increment_angle * ( count - ii );
393
394 if( ii < count )
395 RotatePoint( end_arc, -rot );
396 else // last point
397 end_arc = aClockwise ? end : start;
398
399 aGbrItem->m_ShapeAsPolygon.Append( end_arc + center );
400 }
401}
402
403
405{
406 int retval;
407 char* endptr;
408
409 errno = 0;
410
411 retval = strtol( aText + 1, &endptr, 10 );
412
413 if( endptr == aText || errno != 0 )
414 return 0;
415
416 wxCHECK_MSG( retval < std::numeric_limits<int>::max(), 0, _( "Invalid Code Number" ) );
417
418 aText = endptr;
419
420 return static_cast<int>( retval );
421}
422
423
424bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
425{
426 switch( G_command )
427 {
428 case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored.
429 break;
430
433 break;
434
437 break;
438
441 break;
442
443 case GC_COMMENT:
444 // Skip comment, but only if the line does not start by "G04 #@! "
445 // which is a metadata, i.e. a X2 command inside the comment.
446 // this comment is called a "structured comment"
447 if( strncmp( text, " #@! ", 5 ) == 0 )
448 {
449 text += 5;
450
451 // The string starting at text is the same as the X2 attribute,
452 // but a X2 attribute ends by '%'. So we build the X2 attribute string
453 std::string x2buf;
454
455 while( *text && (*text != '*') )
456 {
457 x2buf += *text;
458 text++;
459 }
460
461 // add the end of X2 attribute string
462 x2buf += "*%";
463 x2buf += '\0';
464
465 char* cptr = (char*)x2buf.data();
466 int code_command = ReadXCommandID( cptr );
467 ExecuteRS274XCommand( code_command, nullptr, 0, cptr );
468 }
469
471
472 break;
473
474 case GC_SELECT_TOOL:
475 {
476 int D_commande = CodeNumber( text );
477
478 if( D_commande < FIRST_DCODE )
479 return false;
480
481 if( D_commande > (TOOLS_MAX_COUNT - 1) )
482 D_commande = TOOLS_MAX_COUNT - 1;
483
484 m_Current_Tool = D_commande;
485 D_CODE* pt_Dcode = GetDCODE( D_commande );
486
487 if( pt_Dcode )
488 pt_Dcode->m_InUse = true;
489
490 break;
491 }
492
494 m_GerbMetric = false; // false = Inches, true = metric
495 break;
496
498 m_GerbMetric = true; // false = Inches, true = metric
499 break;
500
501 case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
502 m_360Arc_enbl = false;
503 m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
504 m_AsArcG74G75Cmd = true;
505 break;
506
508 m_360Arc_enbl = true;
509 m_AsArcG74G75Cmd = true;
510 break;
511
513 m_Relative = false; // false = absolute Coord, true = relative
514 // Coord
515 break;
516
518 m_Relative = true; // false = absolute Coord, true = relative
519 // Coord
520 break;
521
523 m_PolygonFillMode = true;
524 m_Exposure = false;
525 break;
526
528 if( m_Exposure && GetLastItemInList() ) // End of polygon
529 {
531
532 if( gbritem->m_ShapeAsPolygon.VertexCount() )
533 gbritem->m_ShapeAsPolygon.Append( gbritem->m_ShapeAsPolygon.CVertex( 0 ) );
534
535 StepAndRepeatItem( *gbritem );
536 }
537
538 m_Exposure = false;
539 m_PolygonFillMode = false;
541 m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
542 break;
543
544 case GC_MOVE: // Non existent
545 default:
546 {
547 wxString msg;
548 msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
549 AddMessageToList( msg );
550 return false;
551 }
552 }
553
554
555 return true;
556}
557
558
559bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
560{
561 VECTOR2I size( 15, 15 );
562
563 APERTURE_T aperture = APT_CIRCLE;
564 GERBER_DRAW_ITEM* gbritem;
565
566 int dcode = 0;
567 D_CODE* tool = nullptr;
568 wxString msg;
569
570 if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
571 {
572 if( D_commande > (TOOLS_MAX_COUNT - 1) )
573 D_commande = TOOLS_MAX_COUNT - 1;
574
575 // remember which tool is selected, nothing is done with it in this
576 // call
577 m_Current_Tool = D_commande;
578
579 D_CODE* pt_Dcode = GetDCODE( D_commande );
580
581 if( pt_Dcode )
582 pt_Dcode->m_InUse = true;
583 else
584 m_Has_MissingDCode = true;
585
586 return true;
587 }
588 else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
589 {
590 m_Last_Pen_Command = D_commande;
591 }
592
593 if( m_PolygonFillMode ) // Enter a polygon description:
594 {
595 switch( D_commande )
596 {
597 case 1: // code D01 Draw line, exposure ON
598 if( !m_Exposure ) // Start a new polygon outline:
599 {
600 m_Exposure = true;
601 gbritem = new GERBER_DRAW_ITEM( this );
602 AddItemToList( gbritem );
603 gbritem->m_ShapeType = GBR_POLYGON;
604 gbritem->m_Flashed = false;
605 gbritem->m_DCode = 0; // No DCode for a Polygon (Region in Gerber dialect)
606
607
608 if( gbritem->m_GerberImageFile )
609 {
612 }
613 }
614
615 switch( m_Iterpolation )
616 {
619 // Before any arc command, a G74 or G75 command must be set.
620 // Otherwise the Gerber file is invalid
621 if( !m_AsArcG74G75Cmd )
622 {
623 AddMessageToList( _( "Invalid Gerber file: missing G74 or G75 arc command" ) );
624
625 // Disable further warning messages:
626 m_AsArcG74G75Cmd = true;
627 }
628
629 gbritem = GetLastItemInList();
630
631 fillArcPOLY( gbritem, m_PreviousPos,
633 ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
634 m_360Arc_enbl, GetLayerParams().m_LayerNegative );
635 break;
636
637 default:
638 gbritem = GetLastItemInList();
639
640 gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
641
642 if( gbritem->m_ShapeAsPolygon.OutlineCount() == 0 )
643 {
644 gbritem->m_ShapeAsPolygon.NewOutline();
645 gbritem->m_ShapeAsPolygon.Append( VECTOR2I( gbritem->m_Start ) );
646 }
647
648 gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
649 gbritem->m_ShapeAsPolygon.Append( VECTOR2I( gbritem->m_End ) );
650 break;
651 }
652
655 break;
656
657 case 2: // code D2: exposure OFF (i.e. "move to")
658 if( m_Exposure && GetLastItemInList() ) // End of polygon
659 {
660 gbritem = GetLastItemInList();
661 gbritem->m_ShapeAsPolygon.Append( gbritem->m_ShapeAsPolygon.CVertex( 0 ) );
662 StepAndRepeatItem( *gbritem );
663 }
664
665 m_Exposure = false;
668 break;
669
670 default:
671 return false;
672 }
673 }
674 else
675 {
676 switch( D_commande )
677 {
678 case 1: // code D01 Draw line, exposure ON
679 m_Exposure = true;
680
681 tool = GetDCODE( m_Current_Tool );
682
683 if( tool )
684 {
685 size = tool->m_Size;
686 dcode = tool->m_Num_Dcode;
687 aperture = tool->m_ApertType;
688 }
689
690 switch( m_Iterpolation )
691 {
693 gbritem = new GERBER_DRAW_ITEM( this );
694 AddItemToList( gbritem );
695
696 fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
697 m_CurrentPos, size, GetLayerParams().m_LayerNegative );
698 StepAndRepeatItem( *gbritem );
699 break;
700
703 gbritem = new GERBER_DRAW_ITEM( this );
704 AddItemToList( gbritem );
705
707 {
708 fillArcGBRITEM( gbritem, dcode, m_PreviousPos,
709 m_CurrentPos, m_IJPos, size,
711 false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
712 m_LastCoordIsIJPos = false;
713 }
714 else
715 {
716 fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
717 m_CurrentPos, size, GetLayerParams().m_LayerNegative );
718 }
719
720 StepAndRepeatItem( *gbritem );
721
722 break;
723
724 default:
725 msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
727 AddMessageToList( msg );
728 break;
729 }
730
732 break;
733
734 case 2: // code D2: exposure OFF (i.e. "move to")
735 m_Exposure = false;
737 break;
738
739 case 3: // code D3: flash aperture
740 tool = GetDCODE( m_Current_Tool );
741
742 if( tool )
743 {
744 size = tool->m_Size;
745 dcode = tool->m_Num_Dcode;
746 aperture = tool->m_ApertType;
747 }
748
749 gbritem = new GERBER_DRAW_ITEM( this );
750 AddItemToList( gbritem );
751 fillFlashedGBRITEM( gbritem, aperture, dcode, m_CurrentPos,
752 size, GetLayerParams().m_LayerNegative );
753 StepAndRepeatItem( *gbritem );
755 break;
756
757 default:
758 return false;
759 }
760 }
761
762 return true;
763}
constexpr EDA_IU_SCALE gerbIUScale
Definition: base_units.h:107
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
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:193
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
bool m_InUse
false if the aperture (previously defined) is not used to draw something
Definition: dcode.h:200
void SetLayerPolarity(bool aNegative)
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
SHAPE_POLY_SET m_ShapeAsPolygon
GBR_BASIC_SHAPE_TYPE m_ShapeType
GERBER_FILE_IMAGE * m_GerberImageFile
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
bool Execute_G_Command(char *&text, int G_command)
Definition: rs274d.cpp:424
int m_Last_Pen_Command
Current or last pen state (0..9, set by Dn option with n < 10.
GERBER_DRAW_ITEM * GetLastItemInList() const
static char m_LineBuffer[GERBER_BUFZ+1]
void StepAndRepeatItem(const GERBER_DRAW_ITEM &aItem)
Gerber format has a command Step an Repeat.
VECTOR2I m_PreviousPos
old current specified coord for plot
void AddMessageToList(const wxString &aMessage)
Add a message to the message list.
VECTOR2I m_IJPos
IJ coord (for arcs & circles )
bool m_Relative
false = absolute Coord, true = relative Coord.
bool Execute_DCODE_Command(char *&text, int D_command)
Definition: rs274d.cpp:559
D_CODE * GetDCODE(int aDCODE) const
Return a pointer to the D_CODE within this GERBER for the given aDCODE.
int m_PolygonFillModeState
a collection of APERTURE_MACROS, sorted by name
bool GetEndOfBlock(char *aBuff, unsigned int aBuffSize, char *&aText, FILE *aGerberFile)
Definition: rs274x.cpp:931
int m_Current_Tool
Current Tool (Dcode) number selected.
void AddItemToList(GERBER_DRAW_ITEM *aItem)
Add a new GERBER_DRAW_ITEM item to the drawings list.
bool ExecuteRS274XCommand(int aCommand, char *aBuff, unsigned int aBuffSize, char *&aText)
Execute a RS274X command.
Definition: rs274x.cpp:197
int ReadXCommandID(char *&text)
Read two bytes of data and assembles them into an int with the first byte in the sequence put into th...
Definition: rs274x.cpp:114
bool m_GerbMetric
false = Inches, true = metric
GBR_NETLIST_METADATA m_NetAttributeDict
int m_Iterpolation
Linear, 90 arc, Circ.
VECTOR2I m_CurrentPos
current specified coord for plot
bool m_LastCoordIsIJPos
A value ( = radius in circular routing in Excellon files ).
int CodeNumber(char *&aText)
Reads the next number and returns the value.
Definition: rs274d.cpp:404
GERBER_LAYER & GetLayerParams()
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of vertices in a given outline/hole.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:281
APERTURE_T
The set of all gerber aperture types allowed from ADD dcode command, like ADD11C,0....
Definition: dcode.h:48
@ APT_RECT
Definition: dcode.h:50
@ APT_OVAL
Definition: dcode.h:51
@ APT_POLYGON
Definition: dcode.h:52
@ APT_CIRCLE
Definition: dcode.h:49
@ APT_MACRO
Definition: dcode.h:54
#define FIRST_DCODE
Definition: dcode.h:69
#define TOOLS_MAX_COUNT
Definition: dcode.h:71
#define _(s)
static constexpr EDA_ANGLE ANGLE_360
Definition: eda_angle.h:407
void fillFlashedGBRITEM(GERBER_DRAW_ITEM *aGbrItem, APERTURE_T aAperture, int Dcode_index, const VECTOR2I &aPos, VECTOR2I aSize, bool aLayerNegative)
functions to read the rs274d commands from a rs274d/rs274x file
Definition: rs274d.cpp:99
void fillArcGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aRelCenter, VECTOR2I aPenSize, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Initialize a given GBRITEM so that it can draw an arc G code.
Definition: rs274d.cpp:202
void fillLineGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const VECTOR2I &aStart, const VECTOR2I &aEnd, VECTOR2I aPenSize, bool aLayerNegative)
Initialize a given GBRITEM so that it can draw a linear D code.
Definition: rs274d.cpp:153
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
@ GBR_SPOT_OVAL
@ GBR_SPOT_POLY
@ GBR_SPOT_RECT
@ GBR_POLYGON
@ GBR_SPOT_CIRCLE
@ GBR_ARC
@ GBR_SPOT_MACRO
#define GERBER_BUFZ
@ GC_SPECIFY_MILLIMETERS
Definition: gerbview.h:54
@ GC_SPECIFY_RELATIVEES_COORD
Definition: gerbview.h:58
@ GC_COMMENT
Definition: gerbview.h:48
@ GC_TURN_ON_360_INTERPOL
Definition: gerbview.h:56
@ GC_LINEAR_INTERPOL_1X
Definition: gerbview.h:45
@ GC_TURN_OFF_360_INTERPOL
Definition: gerbview.h:55
@ GC_SELECT_TOOL
Definition: gerbview.h:51
@ GC_TURN_OFF_POLY_FILL
Definition: gerbview.h:50
@ GC_CIRCLE_POS_INTERPOL
Definition: gerbview.h:47
@ GC_PHOTO_MODE
Definition: gerbview.h:52
@ GC_MOVE
Definition: gerbview.h:44
@ GC_SPECIFY_INCHES
Definition: gerbview.h:53
@ GC_TURN_ON_POLY_FILL
Definition: gerbview.h:49
@ GC_CIRCLE_NEG_INTERPOL
Definition: gerbview.h:46
@ GC_SPECIFY_ABSOLUES_COORD
Definition: gerbview.h:57
@ GERB_INTERPOL_ARC_NEG
Definition: gerbview.h:36
@ GERB_INTERPOL_LINEAR_1X
Definition: gerbview.h:35
@ GERB_INTERPOL_ARC_POS
Definition: gerbview.h:37
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
void fillFlashedGBRITEM(GERBER_DRAW_ITEM *aGbrItem, APERTURE_T aAperture, int Dcode_index, const VECTOR2I &aPos, VECTOR2I aSize, bool aLayerNegative)
functions to read the rs274d commands from a rs274d/rs274x file
Definition: rs274d.cpp:99
static void fillArcPOLY(GERBER_DRAW_ITEM *aGbrItem, const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &rel_center, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Create an arc G code when found in polygon outlines.
Definition: rs274d.cpp:328
void fillArcGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aRelCenter, VECTOR2I aPenSize, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Initialize a given GBRITEM so that it can draw an arc G code.
Definition: rs274d.cpp:202
void fillLineGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const VECTOR2I &aStart, const VECTOR2I &aEnd, VECTOR2I aPenSize, bool aLayerNegative)
Initialize a given GBRITEM so that it can draw a linear D code.
Definition: rs274d.cpp:153
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
constexpr int delta
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
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:676