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
28#include <cmath>
29
31#include <gerbview.h>
32#include <gerbview_frame.h>
33#include <gerber_file_image.h>
34#include <trigo.h>
36
37
38/* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes).
39 * Some are now deprecated, but deprecated commands must be known by the Gerber reader
40 * Gn =
41 * G01 linear interpolation (linear trace)
42 * G02, G20, G21 Circular interpolation, clockwise
43 * G03, G30, G31 Circular interpolation, counterclockwise
44 * G04 = comment. Since Sept 2014, file attributes and other X2 attributes can be found here
45 * if the line starts by G04 #@!
46 * G06 parabolic interpolation
47 * G07 Cubic Interpolation
48 * G10 linear interpolation (scale x10)
49 * G11 linear interpolation (0.1x range)
50 * G12 linear interpolation (0.01x scale)
51 * G36 Start polygon mode (called a region, because the "polygon" can include arcs)
52 * G37 Stop polygon mode (and close it)
53 * G54 Selection Tool (outdated)
54 * G60 linear interpolation (scale x100)
55 * G70 Select Units = Inches
56 * G71 Select Units = Millimeters
57 * G74 enable 90 deg mode for arcs (CW or CCW)
58 * G75 enable 360 degrees for arcs (CW or CCW)
59 * G90 mode absolute coordinates
60 *
61 * X, Y
62 * X and Y are followed by + or - and m + n digits (not separated)
63 * m = integer part
64 * n = part after the comma
65 *ic formats: m = 2, n = 3 (size 2.3)
66 * m = 3, n = 4 (size 3.4)
67 * eg
68 * GxxX00345Y-06123*
69 *
70 * Tools and D_CODES
71 * Tool number (identification of shapes)
72 * 10 to 999
73 * D_CODES:
74 * D01 ... D9 = command codes:
75 * D01 = activating light (pen down) when placement
76 * D02 = light extinction (pen up) when placement
77 * D03 = Flash
78 * D09 = VAPE Flash (I never see this command in Gerber file)
79 * D51 = G54 preceded by -> Select VAPE
80 *
81 * D10 ... D999 = Identification Tool: tool selection
82 */
83
84
85/* Local Functions (are lower case since they are private to this source file)
86**/
87
88
101 APERTURE_T aAperture,
102 int Dcode_index,
103 const VECTOR2I& aPos,
104 VECTOR2I aSize,
105 bool aLayerNegative )
106{
107 aGbrItem->m_Size = aSize;
108 aGbrItem->m_Start = aPos;
109 aGbrItem->m_End = aGbrItem->m_Start;
110 aGbrItem->m_DCode = Dcode_index;
111 aGbrItem->SetLayerPolarity( aLayerNegative );
112 aGbrItem->m_Flashed = true;
114
115 switch( aAperture )
116 {
117 case APT_POLYGON: // flashed regular polygon
118 aGbrItem->m_ShapeType = GBR_SPOT_POLY;
119 break;
120
121 case APT_CIRCLE:
122 aGbrItem->m_ShapeType = GBR_SPOT_CIRCLE;
123 aGbrItem->m_Size.y = aGbrItem->m_Size.x;
124 break;
125
126 case APT_OVAL:
127 aGbrItem->m_ShapeType = GBR_SPOT_OVAL;
128 break;
129
130 case APT_RECT:
131 aGbrItem->m_ShapeType = GBR_SPOT_RECT;
132 break;
133
134 case APT_MACRO:
135 aGbrItem->m_ShapeType = GBR_SPOT_MACRO;
136
137 // Cache the bounding box for aperture macros
138 aGbrItem->GetDcodeDescr()->GetMacro()->GetApertureMacroShape( aGbrItem, aPos );
139 break;
140 }
141}
142
143
155 int Dcode_index,
156 const VECTOR2I& aStart,
157 const VECTOR2I& aEnd,
158 VECTOR2I aPenSize,
159 bool aLayerNegative )
160{
161 aGbrItem->m_Flashed = false;
162
163 aGbrItem->m_Size = aPenSize;
164
165 aGbrItem->m_Start = aStart;
166 aGbrItem->m_End = aEnd;
167
168 aGbrItem->m_DCode = Dcode_index;
169 aGbrItem->SetLayerPolarity( aLayerNegative );
170
172}
173
174
203void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, const VECTOR2I& aStart,
204 const VECTOR2I& aEnd, const VECTOR2I& aRelCenter, VECTOR2I aPenSize,
205 bool aClockwise, bool aMultiquadrant, bool aLayerNegative )
206{
207 VECTOR2I center, delta;
208
209 aGbrItem->m_ShapeType = GBR_ARC;
210 aGbrItem->m_Size = aPenSize;
211 aGbrItem->m_Flashed = false;
212
213 if( aGbrItem->m_GerberImageFile )
215
216 if( aMultiquadrant )
217 {
218 center = aStart + aRelCenter;
219 }
220 else
221 {
222 // in single quadrant mode the relative coordinate aRelCenter is always >= 0
223 // So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
224 center = aRelCenter;
225
226 // calculate arc end coordinate relative to the starting point,
227 // because center is relative to the center point
228 delta = aEnd - aStart;
229
230 // now calculate the relative to aStart center position, for a draw function
231 // that use trigonometric arc angle (or counter-clockwise)
232 /* Quadrants:
233 * Y
234 * 2 | 1
235 * -------X
236 * 3 | 4
237 * C = actual relative arc center, S = arc start (axis origin) E = relative arc end
238 */
239 if( (delta.x >= 0) && (delta.y >= 0) )
240 {
241 /* Quadrant 1 (trigo or cclockwise):
242 * C | E
243 * ---S---
244 * 3 | 4
245 */
246 center.x = -center.x;
247 }
248 else if( (delta.x >= 0) && (delta.y < 0) )
249 {
250 /* Quadrant 4 (trigo or cclockwise):
251 * 2 | C
252 * ---S---
253 * 3 | E
254 */
255 // Nothing to do
256 }
257 else if( (delta.x < 0) && (delta.y >= 0) )
258 {
259 /* Quadrant 2 (trigo or cclockwise):
260 * E | 1
261 * ---S---
262 * C | 4
263 */
264 center.x = -center.x;
265 center.y = -center.y;
266 }
267 else
268 {
269 /* Quadrant 3 (trigo or cclockwise):
270 * 2 | 1
271 * ---S---
272 * E | C
273 */
274 center.y = -center.y;
275 }
276
277 // Due to your draw arc function, we need this:
278 if( !aClockwise )
279 center = - center;
280
281 // Calculate actual arc center coordinate:
282 center += aStart;
283 }
284
285 if( aClockwise )
286 {
287 aGbrItem->m_Start = aStart;
288 aGbrItem->m_End = aEnd;
289 }
290 else
291 {
292 aGbrItem->m_Start = aEnd;
293 aGbrItem->m_End = aStart;
294 }
295
296 aGbrItem->m_ArcCentre = center;
297
298 aGbrItem->m_DCode = Dcode_index;
299 aGbrItem->SetLayerPolarity( aLayerNegative );
300}
301
302
329static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem, const VECTOR2I& aStart, const VECTOR2I& aEnd,
330 const VECTOR2I& rel_center, bool aClockwise, bool aMultiquadrant,
331 bool aLayerNegative )
332{
333 /* in order to calculate arc parameters, we use fillArcGBRITEM
334 * so we muse create a dummy track and use its geometric parameters
335 */
336 static GERBER_DRAW_ITEM dummyGbrItem( nullptr );
337
338 aGbrItem->SetLayerPolarity( aLayerNegative );
339
340 fillArcGBRITEM( &dummyGbrItem, 0, aStart, aEnd, rel_center, VECTOR2I( 0, 0 ),
341 aClockwise, aMultiquadrant, aLayerNegative );
342
344
345 VECTOR2I center;
346 center = dummyGbrItem.m_ArcCentre;
347
348 // Calculate coordinates relative to arc center;
349 VECTOR2I start = dummyGbrItem.m_Start - center;
350 VECTOR2I end = dummyGbrItem.m_End - center;
351
352 /* Calculate angle arc
353 * angle is trigonometrical (counter-clockwise),
354 * and axis is the X,Y gerber coordinates
355 */
356 EDA_ANGLE start_angle( start );
357 EDA_ANGLE end_angle( end );
358
359 // dummyTrack has right geometric parameters, but
360 // fillArcGBRITEM calculates arc parameters for a draw function that expects
361 // start_angle < end_angle. So ensure this is the case here:
362 // Due to the fact atan2 returns angles between -180 to + 180 degrees,
363 // this is not always the case ( a modulo 360.0 degrees can be lost )
364 //
365 // Note also an arc with same start and end angle is a circle (360 deg arc)
366 // in gerber files
367 if( start_angle >= end_angle )
368 end_angle += ANGLE_360;
369
370 EDA_ANGLE arc_angle = start_angle - end_angle;
371
372 // Approximate arc by segments with a approximation error = err_max
373 // a max err = 5 microns looks good
374 const int approx_err_max = gerbIUScale.mmToIU( 0.005 );
375 int radius = VECTOR2I( aStart - rel_center ).EuclideanNorm();
376 int count = GetArcToSegmentCount( radius, approx_err_max, arc_angle );
377 EDA_ANGLE increment_angle = std::abs( arc_angle ) / count;
378
379 if( aGbrItem->m_ShapeAsPolygon.OutlineCount() == 0 )
380 aGbrItem->m_ShapeAsPolygon.NewOutline();
381
382 // calculate polygon corners
383 // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
384 // and we must always create a polygon from start to end.
385 for( int ii = 0; ii <= count; ii++ )
386 {
387 EDA_ANGLE rot;
388 VECTOR2I end_arc = start;
389
390 if( aClockwise )
391 rot = increment_angle * ii;
392 else
393 rot = increment_angle * ( count - ii );
394
395 if( ii < count )
396 RotatePoint( end_arc, -rot );
397 else // last point
398 end_arc = aClockwise ? end : start;
399
400 aGbrItem->m_ShapeAsPolygon.Append( end_arc + center );
401 }
402}
403
404
406{
407 int retval;
408 char* endptr;
409
410 errno = 0;
411
412 retval = strtol( aText + 1, &endptr, 10 );
413
414 if( endptr == aText || errno != 0 )
415 return 0;
416
417 wxCHECK_MSG( retval < std::numeric_limits<int>::max(), 0, _( "Invalid Code Number" ) );
418
419 aText = endptr;
420
421 return static_cast<int>( retval );
422}
423
424
425bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
426{
427 switch( G_command )
428 {
429 case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored.
430 break;
431
434 break;
435
438 break;
439
442 break;
443
444 case GC_COMMENT:
445 // Skip comment, but only if the line does not start by "G04 #@! "
446 // which is a metadata, i.e. a X2 command inside the comment.
447 // this comment is called a "structured comment"
448 if( strncmp( text, " #@! ", 5 ) == 0 )
449 {
450 text += 5;
451
452 // The string starting at text is the same as the X2 attribute,
453 // but a X2 attribute ends by '%'. So we build the X2 attribute string
454 std::string x2buf;
455
456 while( *text && (*text != '*') )
457 {
458 x2buf += *text;
459 text++;
460 }
461
462 // add the end of X2 attribute string
463 x2buf += "*%";
464 x2buf += '\0';
465
466 char* cptr = (char*)x2buf.data();
467 int code_command = ReadXCommandID( cptr );
468 ExecuteRS274XCommand( code_command, nullptr, 0, cptr );
469 }
470
472
473 break;
474
475 case GC_SELECT_TOOL:
476 {
477 int D_commande = CodeNumber( text );
478
479 if( D_commande < FIRST_DCODE )
480 return false;
481
482 if( D_commande > (TOOLS_MAX_COUNT - 1) )
483 D_commande = TOOLS_MAX_COUNT - 1;
484
485 m_Current_Tool = D_commande;
486 D_CODE* pt_Dcode = GetDCODE( D_commande );
487
488 if( pt_Dcode )
489 pt_Dcode->m_InUse = true;
490
491 break;
492 }
493
495 m_GerbMetric = false; // false = Inches, true = metric
496 break;
497
499 m_GerbMetric = true; // false = Inches, true = metric
500 break;
501
502 case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
503 m_360Arc_enbl = false;
504 m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
505 m_AsArcG74G75Cmd = true;
506 break;
507
509 m_360Arc_enbl = true;
510 m_AsArcG74G75Cmd = true;
511 break;
512
514 m_Relative = false; // false = absolute Coord, true = relative
515 // Coord
516 break;
517
519 m_Relative = true; // false = absolute Coord, true = relative
520 // Coord
521 break;
522
524 m_PolygonFillMode = true;
525 m_Exposure = false;
526 break;
527
529 if( m_Exposure && GetLastItemInList() ) // End of polygon
530 {
532
533 if( gbritem->m_ShapeAsPolygon.VertexCount() )
534 gbritem->m_ShapeAsPolygon.Append( gbritem->m_ShapeAsPolygon.CVertex( 0 ) );
535
536 StepAndRepeatItem( *gbritem );
537 }
538
539 m_Exposure = false;
540 m_PolygonFillMode = false;
542 m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
543 break;
544
545 case GC_MOVE: // Non existent
546 default:
547 {
548 wxString msg;
549 msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
550 AddMessageToList( msg );
551 return false;
552 }
553 }
554
555
556 return true;
557}
558
559
560bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
561{
562 VECTOR2I size( 15, 15 );
563
564 APERTURE_T aperture = APT_CIRCLE;
565 GERBER_DRAW_ITEM* gbritem;
566
567 int dcode = 0;
568 D_CODE* tool = nullptr;
569 wxString msg;
570
571 if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
572 {
573 if( D_commande > (TOOLS_MAX_COUNT - 1) )
574 D_commande = TOOLS_MAX_COUNT - 1;
575
576 // remember which tool is selected, nothing is done with it in this
577 // call
578 m_Current_Tool = D_commande;
579
580 D_CODE* pt_Dcode = GetDCODE( D_commande );
581
582 if( pt_Dcode )
583 pt_Dcode->m_InUse = true;
584 else
585 m_Has_MissingDCode = true;
586
587 return true;
588 }
589 else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
590 {
591 m_Last_Pen_Command = D_commande;
592 }
593
594 if( m_PolygonFillMode ) // Enter a polygon description:
595 {
596 switch( D_commande )
597 {
598 case 1: // code D01 Draw line, exposure ON
599 if( !m_Exposure ) // Start a new polygon outline:
600 {
601 m_Exposure = true;
602 gbritem = new GERBER_DRAW_ITEM( this );
603 AddItemToList( gbritem );
604 gbritem->m_ShapeType = GBR_POLYGON;
605 gbritem->m_Flashed = false;
606 gbritem->m_DCode = 0; // No DCode for a Polygon (Region in Gerber dialect)
607
608
609 if( gbritem->m_GerberImageFile )
610 {
613 }
614 }
615
616 switch( m_Iterpolation )
617 {
620 // Before any arc command, a G74 or G75 command must be set.
621 // Otherwise the Gerber file is invalid
622 if( !m_AsArcG74G75Cmd )
623 {
624 AddMessageToList( _( "Invalid Gerber file: missing G74 or G75 arc command" ) );
625
626 // Disable further warning messages:
627 m_AsArcG74G75Cmd = true;
628 }
629
630 gbritem = GetLastItemInList();
631
632 fillArcPOLY( gbritem, m_PreviousPos,
634 ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
635 m_360Arc_enbl, GetLayerParams().m_LayerNegative );
636 break;
637
638 default:
639 gbritem = GetLastItemInList();
640
641 gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
642
643 if( gbritem->m_ShapeAsPolygon.OutlineCount() == 0 )
644 {
645 gbritem->m_ShapeAsPolygon.NewOutline();
646 gbritem->m_ShapeAsPolygon.Append( VECTOR2I( gbritem->m_Start ) );
647 }
648
649 gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
650 gbritem->m_ShapeAsPolygon.Append( VECTOR2I( gbritem->m_End ) );
651 break;
652 }
653
656 break;
657
658 case 2: // code D2: exposure OFF (i.e. "move to")
659 if( m_Exposure && GetLastItemInList() ) // End of polygon
660 {
661 gbritem = GetLastItemInList();
662 gbritem->m_ShapeAsPolygon.Append( gbritem->m_ShapeAsPolygon.CVertex( 0 ) );
663 StepAndRepeatItem( *gbritem );
664 }
665
666 m_Exposure = false;
669 break;
670
671 default:
672 return false;
673 }
674 }
675 else
676 {
677 switch( D_commande )
678 {
679 case 1: // code D01 Draw line, exposure ON
680 m_Exposure = true;
681
682 tool = GetDCODE( m_Current_Tool );
683
684 if( tool )
685 {
686 size = tool->m_Size;
687 dcode = tool->m_Num_Dcode;
688 aperture = tool->m_ApertType;
689 }
690
691 switch( m_Iterpolation )
692 {
694 gbritem = new GERBER_DRAW_ITEM( this );
695 AddItemToList( gbritem );
696
697 fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
698 m_CurrentPos, size, GetLayerParams().m_LayerNegative );
699 StepAndRepeatItem( *gbritem );
700 break;
701
704 gbritem = new GERBER_DRAW_ITEM( this );
705 AddItemToList( gbritem );
706
708 {
709 fillArcGBRITEM( gbritem, dcode, m_PreviousPos,
710 m_CurrentPos, m_IJPos, size,
712 false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
713 m_LastCoordIsIJPos = false;
714 }
715 else
716 {
717 fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
718 m_CurrentPos, size, GetLayerParams().m_LayerNegative );
719 }
720
721 StepAndRepeatItem( *gbritem );
722
723 break;
724
725 default:
726 msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
728 AddMessageToList( msg );
729 break;
730 }
731
733 break;
734
735 case 2: // code D2: exposure OFF (i.e. "move to")
736 m_Exposure = false;
738 break;
739
740 case 3: // code D3: flash aperture
741 tool = GetDCODE( m_Current_Tool );
742
743 if( tool )
744 {
745 size = tool->m_Size;
746 dcode = tool->m_Num_Dcode;
747 aperture = tool->m_ApertType;
748 }
749
750 gbritem = new GERBER_DRAW_ITEM( this );
751 AddItemToList( gbritem );
752 fillFlashedGBRITEM( gbritem, aperture, dcode, m_CurrentPos,
753 size, GetLayerParams().m_LayerNegative );
754 StepAndRepeatItem( *gbritem );
756 break;
757
758 default:
759 return false;
760 }
761 }
762
763 return true;
764}
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:425
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:560
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:405
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:283
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:100
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:203
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:154
a few functions useful in geometry calculations.
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:100
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:329
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:203
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:154
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:691