KiCad PCB EDA Suite
rs274d.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include <fctsys.h>
30 #include <common.h>
31 
32 #include <gerbview.h>
33 #include <gerbview_frame.h>
34 #include <trigo.h>
35 #include <gerber_file_image.h>
36 #include <X2_gerber_attributes.h>
37 
38 #include <cmath>
39 
40 /* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes):
41  * Gn =
42  * G01 linear interpolation (right trace)
43  * G02, G20, G21 Circular interpolation, meaning trig <0 (clockwise)
44  * G03, G30, G31 Circular interpolation, meaning trigo> 0 (counterclockwise)
45  * G04 = comment. Since Sept 2014, file attributes and other X2 attributes can be found here
46  * if the line starts by G04 #@!
47  * G06 parabolic interpolation
48  * G07 Cubic Interpolation
49  * G10 linear interpolation (scale x10)
50  * G11 linear interpolation (0.1x range)
51  * G12 linear interpolation (0.01x scale)
52  * G36 Start polygon mode
53  * G37 Stop polygon mode (and close it)
54  * G54 Selection Tool
55  * G60 linear interpolation (scale x100)
56  * G70 Select Units = Inches
57  * G71 Select Units = Millimeters
58  * G74 disable 360 degrees circular interpolation (return to 90 deg mode)
59  * and perhaps circular interpolation (return to linear interpolation )
60  * see rs274xrevd_e.pdf pages 47 and 48
61  * Unfortunately page 47 said G74 disable G02 or G03
62  * and page 48 said G01 must be used to disable G02 or G03.
63  * Currently GerbView disable G02 or G03 after a G74 command (tests using 2 gerber files).
64  * G75 enable 360 degrees circular interpolation
65  * G90 mode absolute coordinates
66  *
67  * X, Y
68  * X and Y are followed by + or - and m + n digits (not separated)
69  * m = integer part
70  * n = part after the comma
71  * Classic formats: m = 2, n = 3 (size 2.3)
72  * m = 3, n = 4 (size 3.4)
73  * eg
74  * GxxX00345Y-06123*
75  *
76  * Tools and D_CODES
77  * Tool number (identification of shapes)
78  * 10 to 999
79  * D_CODES:
80  * D01 ... D9 = command codes:
81  * D01 = activating light (pen down) when placement
82  * D02 = light extinction (pen up) when placement
83  * D03 = Flash
84  * D09 = VAPE Flash (I never see this command in gerber file)
85  * D51 = G54 preceded by -> Select VAPE
86  *
87  * D10 ... D999 = Identification Tool: tool selection
88  */
89 
90 
91 /* Local Functions (are lower case since they are private to this source file)
92 **/
93 
94 
108  APERTURE_T aAperture,
109  int Dcode_index,
110  const wxPoint& aPos,
111  wxSize aSize,
112  bool aLayerNegative )
113 {
114  aGbrItem->m_Size = aSize;
115  aGbrItem->m_Start = aPos;
116  aGbrItem->m_End = aGbrItem->m_Start;
117  aGbrItem->m_DCode = Dcode_index;
118  aGbrItem->SetLayerPolarity( aLayerNegative );
119  aGbrItem->m_Flashed = true;
120  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
121 
122  switch( aAperture )
123  {
124  case APT_POLYGON: // flashed regular polygon
125  aGbrItem->m_Shape = GBR_SPOT_POLY;
126  break;
127 
128  case APT_CIRCLE:
129  aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
130  aGbrItem->m_Size.y = aGbrItem->m_Size.x;
131  break;
132 
133  case APT_OVAL:
134  aGbrItem->m_Shape = GBR_SPOT_OVAL;
135  break;
136 
137  case APT_RECT:
138  aGbrItem->m_Shape = GBR_SPOT_RECT;
139  break;
140 
141  case APT_MACRO:
142  aGbrItem->m_Shape = GBR_SPOT_MACRO;
143 
144  // Cache the bounding box for aperture macros
145  aGbrItem->GetDcodeDescr()->GetMacro()->GetApertureMacroShape( aGbrItem, aPos );
146  break;
147  }
148 }
149 
150 
163  int Dcode_index,
164  const wxPoint& aStart,
165  const wxPoint& aEnd,
166  wxSize aPenSize,
167  bool aLayerNegative )
168 {
169  aGbrItem->m_Flashed = false;
170 
171  aGbrItem->m_Size = aPenSize;
172 
173  aGbrItem->m_Start = aStart;
174  aGbrItem->m_End = aEnd;
175 
176  aGbrItem->m_DCode = Dcode_index;
177  aGbrItem->SetLayerPolarity( aLayerNegative );
178 
179  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
180 }
181 
182 
211 static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index,
212  const wxPoint& aStart, const wxPoint& aEnd,
213  const wxPoint& aRelCenter, wxSize aPenSize,
214  bool aClockwise, bool aMultiquadrant,
215  bool aLayerNegative )
216 {
217  wxPoint center, delta;
218 
219  aGbrItem->m_Shape = GBR_ARC;
220  aGbrItem->m_Size = aPenSize;
221  aGbrItem->m_Flashed = false;
222 
223  if( aGbrItem->m_GerberImageFile )
224  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
225 
226  if( aMultiquadrant )
227  center = aStart + aRelCenter;
228  else
229  {
230  // in single quadrant mode the relative coordinate aRelCenter is always >= 0
231  // So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
232  center = aRelCenter;
233 
234  // calculate arc end coordinate relative to the starting point,
235  // because center is relative to the center point
236  delta = aEnd - aStart;
237 
238  // now calculate the relative to aStart center position, for a draw function
239  // that use trigonometric arc angle (or counter-clockwise)
240  /* Quadrants:
241  * Y
242  * 2 | 1
243  * -------X
244  * 3 | 4
245  * C = actual relative arc center, S = arc start (axis origin) E = relative arc end
246  */
247  if( (delta.x >= 0) && (delta.y >= 0) )
248  {
249  /* Quadrant 1 (trigo or cclockwise):
250  * C | E
251  * ---S---
252  * 3 | 4
253  */
254  center.x = -center.x;
255  }
256  else if( (delta.x >= 0) && (delta.y < 0) )
257  {
258  /* Quadrant 4 (trigo or cclockwise):
259  * 2 | C
260  * ---S---
261  * 3 | E
262  */
263  // Nothing to do
264  }
265  else if( (delta.x < 0) && (delta.y >= 0) )
266  {
267  /* Quadrant 2 (trigo or cclockwise):
268  * E | 1
269  * ---S---
270  * C | 4
271  */
272  center.x = -center.x;
273  center.y = -center.y;
274  }
275  else
276  {
277  /* Quadrant 3 (trigo or cclockwise):
278  * 2 | 1
279  * ---S---
280  * E | C
281  */
282  center.y = -center.y;
283  }
284 
285  // Due to your draw arc function, we need this:
286  if( !aClockwise )
287  center = - center;
288 
289  // Calculate actual arc center coordinate:
290  center += aStart;
291  }
292 
293  if( aClockwise )
294  {
295  aGbrItem->m_Start = aStart;
296  aGbrItem->m_End = aEnd;
297  }
298  else
299  {
300  aGbrItem->m_Start = aEnd;
301  aGbrItem->m_End = aStart;
302  }
303 
304  aGbrItem->m_ArcCentre = center;
305 
306  aGbrItem->m_DCode = Dcode_index;
307  aGbrItem->SetLayerPolarity( aLayerNegative );
308 }
309 
310 
338 static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
339  const wxPoint& aStart, const wxPoint& aEnd,
340  const wxPoint& rel_center,
341  bool aClockwise, bool aMultiquadrant,
342  bool aLayerNegative )
343 {
344  /* in order to calculate arc parameters, we use fillArcGBRITEM
345  * so we muse create a dummy track and use its geometric parameters
346  */
347  static GERBER_DRAW_ITEM dummyGbrItem( NULL );
348 
349  aGbrItem->SetLayerPolarity( aLayerNegative );
350 
351  fillArcGBRITEM( &dummyGbrItem, 0,
352  aStart, aEnd, rel_center, wxSize(0, 0),
353  aClockwise, aMultiquadrant, aLayerNegative );
354 
355  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
356 
357  wxPoint center;
358  center = dummyGbrItem.m_ArcCentre;
359 
360  // Calculate coordinates relative to arc center;
361  wxPoint start = dummyGbrItem.m_Start - center;
362  wxPoint end = dummyGbrItem.m_End - center;
363 
364  /* Calculate angle arc
365  * angles are in 0.1 deg
366  * angle is trigonometrical (counter-clockwise),
367  * and axis is the X,Y gerber coordinates
368  */
369  double start_angle = ArcTangente( start.y, start.x );
370  double end_angle = ArcTangente( end.y, end.x );
371 
372  // dummyTrack has right geometric parameters, but
373  // fillArcGBRITEM calculates arc parameters for a draw function that expects
374  // start_angle < end_angle. So ensure this is the case here:
375  // Due to the fact atan2 returns angles between -180 to + 180 degrees,
376  // this is not always the case ( a modulo 360.0 degrees can be lost )
377  if( start_angle > end_angle )
378  end_angle += 3600;
379 
380  double arc_angle = start_angle - end_angle;
381  // Approximate arc by 36 segments per 360 degree
382  const int increment_angle = 3600 / 36;
383  int count = std::abs( arc_angle / increment_angle );
384 
385  if( aGbrItem->m_Polygon.OutlineCount() == 0 )
386  aGbrItem->m_Polygon.NewOutline();
387 
388  // calculate polygon corners
389  // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
390  // and we must always create a polygon from start to end.
391  wxPoint start_arc = start;
392  for( int ii = 0; ii <= count; ii++ )
393  {
394  double rot;
395  wxPoint end_arc = start;
396  if( aClockwise )
397  rot = ii * increment_angle; // rot is in 0.1 deg
398  else
399  rot = (count - ii) * increment_angle; // rot is in 0.1 deg
400 
401  if( ii < count )
402  RotatePoint( &end_arc, -rot );
403  else // last point
404  end_arc = aClockwise ? end : start;
405 
406  aGbrItem->m_Polygon.Append( VECTOR2I( end_arc + center ) );
407 
408  start_arc = end_arc;
409  }
410 }
411 
412 
413 /* Read the Gnn sequence and returns the value nn.
414  */
416 {
417  int ii = 0;
418  char* text;
419  char line[1024];
420 
421  if( Text == NULL )
422  return 0;
423  Text++;
424  text = line;
425  while( IsNumber( *Text ) )
426  {
427  *(text++) = *(Text++);
428  }
429 
430  *text = 0;
431  ii = atoi( line );
432  return ii;
433 }
434 
435 
436 /* Get the sequence Dnn and returns the value nn
437  */
439 {
440  int ii = 0;
441  char* text;
442  char line[1024];
443 
444  if( Text == NULL )
445  return 0;
446 
447  Text++;
448  text = line;
449  while( IsNumber( *Text ) )
450  *(text++) = *(Text++);
451 
452  *text = 0;
453  ii = atoi( line );
454  return ii;
455 }
456 
457 
458 bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
459 {
460 // D( printf( "%22s: G_CODE<%d>\n", __func__, G_command ); )
461 
462  switch( G_command )
463  {
464  case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can
465  // be safely ignored
466  break;
467 
470  break;
471 
474  break;
475 
478  break;
479 
480  case GC_COMMENT:
481  // Skip comment, but only if the line does not start by "G04 #@! "
482  // which is a metadata, i.e. a X2 command inside the comment.
483  // this comment is called a "structured comment"
484  if( strncmp( text, " #@! ", 5 ) == 0 )
485  {
486  text += 5;
487  // The string starting at text is the same as the X2 attribute,
488  // but a X2 attribute ends by '%'. So we build the X2 attribute string
489  std::string x2buf;
490 
491  while( *text && (*text != '*') )
492  {
493  x2buf += *text;
494  text++;
495  }
496  // add the end of X2 attribute string
497  x2buf += "*%";
498  x2buf += '\0';
499 
500  char* cptr = (char*)x2buf.data();
501  int code_command = ReadXCommandID( cptr );
502  ExecuteRS274XCommand( code_command, NULL, 0, cptr );
503  }
504 
505  while( *text && (*text != '*') )
506  text++;
507  break;
508 
511  break;
512 
515  break;
516 
519  break;
520 
521  case GC_SELECT_TOOL:
522  {
523  int D_commande = DCodeNumber( text );
524  if( D_commande < FIRST_DCODE )
525  return false;
526  if( D_commande > (TOOLS_MAX_COUNT - 1) )
527  D_commande = TOOLS_MAX_COUNT - 1;
528  m_Current_Tool = D_commande;
529  D_CODE* pt_Dcode = GetDCODE( D_commande );
530  if( pt_Dcode )
531  pt_Dcode->m_InUse = true;
532  break;
533  }
534 
535  case GC_SPECIFY_INCHES:
536  m_GerbMetric = false; // false = Inches, true = metric
537  break;
538 
540  m_GerbMetric = true; // false = Inches, true = metric
541  break;
542 
543  case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
544  m_360Arc_enbl = false;
545  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
546  break;
547 
549  m_360Arc_enbl = true;
550  break;
551 
553  m_Relative = false; // false = absolute Coord, true = relative
554  // Coord
555  break;
556 
558  m_Relative = true; // false = absolute Coord, true = relative
559  // Coord
560  break;
561 
563  m_PolygonFillMode = true;
564  m_Exposure = false;
565  break;
566 
568  if( m_Exposure && GetItemsList() ) // End of polygon
569  {
570  GERBER_DRAW_ITEM * gbritem = m_Drawings.GetLast();
571  gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) );
572  StepAndRepeatItem( *gbritem );
573  }
574  m_Exposure = false;
575  m_PolygonFillMode = false;
577  break;
578 
579  case GC_MOVE: // Non existent
580  default:
581  {
582  wxString msg;
583  msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
584  AddMessageToList( msg );
585  return false;
586  }
587  }
588 
589 
590  return true;
591 }
592 
593 
594 bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
595 {
596  wxSize size( 15, 15 );
597 
598  APERTURE_T aperture = APT_CIRCLE;
599  GERBER_DRAW_ITEM* gbritem;
600 
601  int dcode = 0;
602  D_CODE* tool = NULL;
603  wxString msg;
604 
605  if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
606  {
607  if( D_commande > (TOOLS_MAX_COUNT - 1) )
608  D_commande = TOOLS_MAX_COUNT - 1;
609 
610  // remember which tool is selected, nothing is done with it in this
611  // call
612  m_Current_Tool = D_commande;
613 
614  D_CODE* pt_Dcode = GetDCODE( D_commande );
615  if( pt_Dcode )
616  pt_Dcode->m_InUse = true;
617 
618  return true;
619  }
620  else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
621  {
622  m_Last_Pen_Command = D_commande;
623  }
624 
625  if( m_PolygonFillMode ) // Enter a polygon description:
626  {
627  switch( D_commande )
628  {
629  case 1: // code D01 Draw line, exposure ON
630  if( !m_Exposure ) // Start a new polygon outline:
631  {
632  m_Exposure = true;
633  gbritem = new GERBER_DRAW_ITEM( this );
634  m_Drawings.Append( gbritem );
635  gbritem->m_Shape = GBR_POLYGON;
636  gbritem->m_Flashed = false;
637  }
638 
639  switch( m_Iterpolation )
640  {
643  gbritem = m_Drawings.GetLast();
644 
645  fillArcPOLY( gbritem, m_PreviousPos,
647  ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
648  m_360Arc_enbl, GetLayerParams().m_LayerNegative );
649  break;
650 
651  default:
652  gbritem = m_Drawings.GetLast();
653 
654  gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
655  if( gbritem->m_Polygon.OutlineCount() == 0 )
656  {
657  gbritem->m_Polygon.NewOutline();
658  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_Start ) );
659  }
660 
661  gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
662  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_End ) );
663  break;
664  }
665 
668  break;
669 
670  case 2: // code D2: exposure OFF (i.e. "move to")
671  if( m_Exposure && GetItemsList() ) // End of polygon
672  {
673  gbritem = m_Drawings.GetLast();
674  gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) );
675  StepAndRepeatItem( *gbritem );
676  }
677  m_Exposure = false;
680  break;
681 
682  default:
683  return false;
684  }
685  }
686  else
687  {
688  switch( D_commande )
689  {
690  case 1: // code D01 Draw line, exposure ON
691  m_Exposure = true;
692 
693  tool = GetDCODE( m_Current_Tool );
694  if( tool )
695  {
696  size = tool->m_Size;
697  dcode = tool->m_Num_Dcode;
698  aperture = tool->m_Shape;
699  }
700 
701  switch( m_Iterpolation )
702  {
704  gbritem = new GERBER_DRAW_ITEM( this );
705  m_Drawings.Append( gbritem );
706 
707  fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
708  m_CurrentPos, size, GetLayerParams().m_LayerNegative );
709  StepAndRepeatItem( *gbritem );
710  break;
711 
715  wxBell();
716  break;
717 
720  gbritem = new GERBER_DRAW_ITEM( this );
721  m_Drawings.Append( gbritem );
722 
723  fillArcGBRITEM( gbritem, dcode, m_PreviousPos,
724  m_CurrentPos, m_IJPos, size,
726  false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
727  StepAndRepeatItem( *gbritem );
728  break;
729 
730  default:
731  msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
732  m_Iterpolation );
733  AddMessageToList( msg );
734  break;
735  }
736 
738  break;
739 
740  case 2: // code D2: exposure OFF (i.e. "move to")
741  m_Exposure = false;
743  break;
744 
745  case 3: // code D3: flash aperture
746  tool = GetDCODE( m_Current_Tool );
747  if( tool )
748  {
749  size = tool->m_Size;
750  dcode = tool->m_Num_Dcode;
751  aperture = tool->m_Shape;
752  }
753 
754  gbritem = new GERBER_DRAW_ITEM( this );
755  m_Drawings.Append( gbritem );
756  fillFlashedGBRITEM( gbritem, aperture, dcode, m_CurrentPos,
757  size, GetLayerParams().m_LayerNegative );
758  StepAndRepeatItem( *gbritem );
760  break;
761 
762  default:
763  return false;
764  }
765  }
766 
767  return true;
768 }
void AddMessageToList(const wxString &aMessage)
Function AddMessageToList Add a message to the message list.
bool Execute_DCODE_Command(char *&text, int D_command)
Definition: rs274d.cpp:594
D_CODE * GetDCODE(int aDCODE) const
Function GetDCODE returns a pointer to the D_CODE within this GERBER for the given aDCODE...
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:94
static void fillArcPOLY(GERBER_DRAW_ITEM *aGbrItem, const wxPoint &aStart, const wxPoint &aEnd, const wxPoint &rel_center, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Function fillArcPOLY creates an arc G code when found in poly outlines.
Definition: rs274d.cpp:338
Definition: dcode.h:53
bool m_InUse
false if the aperure (previously defined) is not used to draw something
Definition: dcode.h:102
APERTURE_T m_Shape
shape ( Line, rectangle, circle , oval .. )
Definition: dcode.h:95
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
int OutlineCount() const
Returns the number of outlines in the set
void fillLineGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const wxPoint &aStart, const wxPoint &aEnd, wxSize aPenSize, bool aLayerNegative)
Function fillLineGBRITEM initializes a given GBRITEM so that it can draw a linear D code...
Definition: rs274d.cpp:162
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
SHAPE_POLY_SET m_Polygon
#define abs(a)
Definition: auxiliary.h:84
int ReadXCommandID(char *&text)
reads two bytes of data and assembles them into an int with the first byte in the sequence put into t...
Definition: rs274x.cpp:114
static const int delta[8][2]
Definition: solve.cpp:112
Definition: dcode.h:52
int GCodeNumber(char *&Text)
Definition: rs274d.cpp:415
VECTOR2I & Vertex(int aIndex, int aOutline, int aHole)
Returns the index-th vertex in a given hole outline within a given outline
bool ExecuteRS274XCommand(int aCommand, char *aBuff, unsigned int aBuffSize, char *&aText)
executes a RS274X command
Definition: rs274x.cpp:239
D_CODE * GetDcodeDescr() const
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, wxPoint aShapePos)
Function GetApertureMacroShape Calculate the primitive shape for flashed items.
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
T * GetLast() const
Function GetLast returns the last T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:170
#define FIRST_DCODE
Definition: dcode.h:71
int DCodeNumber(char *&Text)
Definition: rs274d.cpp:438
APERTURE_T
Enum APERTURE_T is the set of all gerber aperture types allowed, according to page 16 of http://gerbv...
Definition: dcode.h:50
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:96
int NewOutline()
Creates a new empty polygon in the set and returns its index
bool m_Exposure
whether an aperture macro tool is flashed on or off
bool Execute_G_Command(char *&text, int G_command)
Definition: rs274d.cpp:458
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
void fillFlashedGBRITEM(GERBER_DRAW_ITEM *aGbrItem, APERTURE_T aAperture, int Dcode_index, const wxPoint &aPos, wxSize aSize, bool aLayerNegative)
Function fillFlashedGBRITEM initializes a given GBRITEM so that it can draw a circle which is filled ...
Definition: rs274d.cpp:107
DLIST< GERBER_DRAW_ITEM > m_Drawings
GERBER_DRAW_ITEM * GetItemsList()
Function GetItemsList.
GBR_NETLIST_METADATA m_NetAttributeDict
#define TOOLS_MAX_COUNT
Definition: dcode.h:73
void SetLayerPolarity(bool aNegative)
The common library.
static void fillArcGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const wxPoint &aStart, const wxPoint &aEnd, const wxPoint &aRelCenter, wxSize aPenSize, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Function fillArcGBRITEM initializes a given GBRITEM so that it can draw an arc G code.
Definition: rs274d.cpp:211
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:157
#define IsNumber(x)
void StepAndRepeatItem(const GERBER_DRAW_ITEM &aItem)
Function StepAndRepeatItem Gerber format has a command Step an Repeat This function must be called wh...
GERBER_FILE_IMAGE * m_GerberImageFile
GERBER_LAYER & GetLayerParams()
Function GetLayerParams.
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) ...