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-2021 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 <gerbview.h>
30 #include <gerbview_frame.h>
31 #include <trigo.h>
32 #include <gerber_file_image.h>
33 #include <X2_gerber_attributes.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 wxPoint& aPos,
103  wxSize 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;
112  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
113 
114  switch( aAperture )
115  {
116  case APT_POLYGON: // flashed regular polygon
117  aGbrItem->m_Shape = GBR_SPOT_POLY;
118  break;
119 
120  case APT_CIRCLE:
121  aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
122  aGbrItem->m_Size.y = aGbrItem->m_Size.x;
123  break;
124 
125  case APT_OVAL:
126  aGbrItem->m_Shape = GBR_SPOT_OVAL;
127  break;
128 
129  case APT_RECT:
130  aGbrItem->m_Shape = GBR_SPOT_RECT;
131  break;
132 
133  case APT_MACRO:
134  aGbrItem->m_Shape = 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 wxPoint& aStart,
156  const wxPoint& aEnd,
157  wxSize 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 
170  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
171 }
172 
173 
202 void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, const wxPoint& aStart,
203  const wxPoint& aEnd, const wxPoint& aRelCenter, wxSize aPenSize,
204  bool aClockwise, bool aMultiquadrant, bool aLayerNegative )
205 {
206  wxPoint center, delta;
207 
208  aGbrItem->m_Shape = GBR_ARC;
209  aGbrItem->m_Size = aPenSize;
210  aGbrItem->m_Flashed = false;
211 
212  if( aGbrItem->m_GerberImageFile )
213  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
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 
328 static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem, const wxPoint& aStart, const wxPoint& aEnd,
329  const wxPoint& 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, wxSize( 0, 0 ),
340  aClockwise, aMultiquadrant, aLayerNegative );
341 
342  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
343 
344  wxPoint center;
345  center = dummyGbrItem.m_ArcCentre;
346 
347  // Calculate coordinates relative to arc center;
348  wxPoint start = dummyGbrItem.m_Start - center;
349  wxPoint end = dummyGbrItem.m_End - center;
350 
351  /* Calculate angle arc
352  * angles are in 0.1 deg
353  * angle is trigonometrical (counter-clockwise),
354  * and axis is the X,Y gerber coordinates
355  */
356  double start_angle = ArcTangente( start.y, start.x );
357  double end_angle = ArcTangente( end.y, end.x );
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  if( start_angle > end_angle )
365  end_angle += 3600;
366 
367  double arc_angle = start_angle - end_angle;
368 
369  // Approximate arc by 36 segments per 360 degree
370  const int increment_angle = 3600 / 36;
371  int count = std::abs( arc_angle / increment_angle );
372 
373  if( aGbrItem->m_Polygon.OutlineCount() == 0 )
374  aGbrItem->m_Polygon.NewOutline();
375 
376  // calculate polygon corners
377  // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
378  // and we must always create a polygon from start to end.
379  for( int ii = 0; ii <= count; ii++ )
380  {
381  double rot;
382  wxPoint end_arc = start;
383 
384  if( aClockwise )
385  rot = ii * increment_angle; // rot is in 0.1 deg
386  else
387  rot = ( count - ii ) * increment_angle; // rot is in 0.1 deg
388 
389  if( ii < count )
390  RotatePoint( &end_arc, -rot );
391  else // last point
392  end_arc = aClockwise ? end : start;
393 
394  aGbrItem->m_Polygon.Append( VECTOR2I( end_arc + center ) );
395  }
396 }
397 
398 
400 {
401  int ii = 0;
402  char* text;
403  char line[1024];
404 
405  if( Text == nullptr )
406  return 0;
407 
408  Text++;
409  text = line;
410 
411  while( IsNumber( *Text ) )
412  {
413  *(text++) = *(Text++);
414  }
415 
416  *text = 0;
417  ii = atoi( line );
418  return ii;
419 }
420 
421 
423 {
424  int ii = 0;
425  char* text;
426  char line[1024];
427 
428  if( Text == nullptr )
429  return 0;
430 
431  Text++;
432  text = line;
433 
434  while( IsNumber( *Text ) )
435  *(text++) = *(Text++);
436 
437  *text = 0;
438  ii = atoi( line );
439  return ii;
440 }
441 
442 
443 bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
444 {
445  switch( G_command )
446  {
447  case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored.
448  break;
449 
452  break;
453 
456  break;
457 
460  break;
461 
462  case GC_COMMENT:
463  // Skip comment, but only if the line does not start by "G04 #@! "
464  // which is a metadata, i.e. a X2 command inside the comment.
465  // this comment is called a "structured comment"
466  if( strncmp( text, " #@! ", 5 ) == 0 )
467  {
468  text += 5;
469 
470  // The string starting at text is the same as the X2 attribute,
471  // but a X2 attribute ends by '%'. So we build the X2 attribute string
472  std::string x2buf;
473 
474  while( *text && (*text != '*') )
475  {
476  x2buf += *text;
477  text++;
478  }
479 
480  // add the end of X2 attribute string
481  x2buf += "*%";
482  x2buf += '\0';
483 
484  char* cptr = (char*)x2buf.data();
485  int code_command = ReadXCommandID( cptr );
486  ExecuteRS274XCommand( code_command, nullptr, 0, cptr );
487  }
488 
489  while( *text && (*text != '*') )
490  text++;
491 
492  break;
493 
494  case GC_SELECT_TOOL:
495  {
496  int D_commande = DCodeNumber( text );
497 
498  if( D_commande < FIRST_DCODE )
499  return false;
500 
501  if( D_commande > (TOOLS_MAX_COUNT - 1) )
502  D_commande = TOOLS_MAX_COUNT - 1;
503 
504  m_Current_Tool = D_commande;
505  D_CODE* pt_Dcode = GetDCODE( D_commande );
506 
507  if( pt_Dcode )
508  pt_Dcode->m_InUse = true;
509 
510  break;
511  }
512 
513  case GC_SPECIFY_INCHES:
514  m_GerbMetric = false; // false = Inches, true = metric
515  break;
516 
518  m_GerbMetric = true; // false = Inches, true = metric
519  break;
520 
521  case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
522  m_360Arc_enbl = false;
523  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
524  m_AsArcG74G75Cmd = true;
525  break;
526 
528  m_360Arc_enbl = true;
529  m_AsArcG74G75Cmd = true;
530  break;
531 
533  m_Relative = false; // false = absolute Coord, true = relative
534  // Coord
535  break;
536 
538  m_Relative = true; // false = absolute Coord, true = relative
539  // Coord
540  break;
541 
543  m_PolygonFillMode = true;
544  m_Exposure = false;
545  break;
546 
548  if( m_Exposure && GetLastItemInList() ) // End of polygon
549  {
550  GERBER_DRAW_ITEM * gbritem = GetLastItemInList();
551 
552  if( gbritem->m_Polygon.VertexCount() )
553  gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) );
554 
555  StepAndRepeatItem( *gbritem );
556  }
557 
558  m_Exposure = false;
559  m_PolygonFillMode = false;
561  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
562  break;
563 
564  case GC_MOVE: // Non existent
565  default:
566  {
567  wxString msg;
568  msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
569  AddMessageToList( msg );
570  return false;
571  }
572  }
573 
574 
575  return true;
576 }
577 
578 
579 bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
580 {
581  wxSize size( 15, 15 );
582 
583  APERTURE_T aperture = APT_CIRCLE;
584  GERBER_DRAW_ITEM* gbritem;
585 
586  int dcode = 0;
587  D_CODE* tool = nullptr;
588  wxString msg;
589 
590  if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
591  {
592  if( D_commande > (TOOLS_MAX_COUNT - 1) )
593  D_commande = TOOLS_MAX_COUNT - 1;
594 
595  // remember which tool is selected, nothing is done with it in this
596  // call
597  m_Current_Tool = D_commande;
598 
599  D_CODE* pt_Dcode = GetDCODE( D_commande );
600 
601  if( pt_Dcode )
602  pt_Dcode->m_InUse = true;
603  else
604  m_Has_MissingDCode = true;
605 
606  return true;
607  }
608  else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
609  {
610  m_Last_Pen_Command = D_commande;
611  }
612 
613  if( m_PolygonFillMode ) // Enter a polygon description:
614  {
615  switch( D_commande )
616  {
617  case 1: // code D01 Draw line, exposure ON
618  if( !m_Exposure ) // Start a new polygon outline:
619  {
620  m_Exposure = true;
621  gbritem = new GERBER_DRAW_ITEM( this );
622  AddItemToList( gbritem );
623  gbritem->m_Shape = GBR_POLYGON;
624  gbritem->m_Flashed = false;
625  gbritem->m_DCode = 0; // No DCode for a Polygon (Region in Gerber dialect)
626 
627 
628  if( gbritem->m_GerberImageFile )
629  {
631  gbritem->m_AperFunction = gbritem->m_GerberImageFile->m_AperFunction;
632  }
633  }
634 
635  switch( m_Iterpolation )
636  {
639  // Before any arc command, a G74 or G75 command must be set.
640  // Otherwise the Gerber file is invalid
641  if( !m_AsArcG74G75Cmd )
642  {
643  AddMessageToList( _( "Invalid Gerber file: missing G74 or G75 arc command" ) );
644 
645  // Disable further warning messages:
646  m_AsArcG74G75Cmd = true;
647  }
648 
649  gbritem = GetLastItemInList();
650 
651  fillArcPOLY( gbritem, m_PreviousPos,
653  ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
654  m_360Arc_enbl, GetLayerParams().m_LayerNegative );
655  break;
656 
657  default:
658  gbritem = GetLastItemInList();
659 
660  gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
661 
662  if( gbritem->m_Polygon.OutlineCount() == 0 )
663  {
664  gbritem->m_Polygon.NewOutline();
665  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_Start ) );
666  }
667 
668  gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
669  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_End ) );
670  break;
671  }
672 
675  break;
676 
677  case 2: // code D2: exposure OFF (i.e. "move to")
678  if( m_Exposure && GetLastItemInList() ) // End of polygon
679  {
680  gbritem = GetLastItemInList();
681  gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) );
682  StepAndRepeatItem( *gbritem );
683  }
684 
685  m_Exposure = false;
688  break;
689 
690  default:
691  return false;
692  }
693  }
694  else
695  {
696  switch( D_commande )
697  {
698  case 1: // code D01 Draw line, exposure ON
699  m_Exposure = true;
700 
701  tool = GetDCODE( m_Current_Tool );
702 
703  if( tool )
704  {
705  size = tool->m_Size;
706  dcode = tool->m_Num_Dcode;
707  aperture = tool->m_Shape;
708  }
709 
710  switch( m_Iterpolation )
711  {
713  gbritem = new GERBER_DRAW_ITEM( this );
714  AddItemToList( gbritem );
715 
716  fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
717  m_CurrentPos, size, GetLayerParams().m_LayerNegative );
718  StepAndRepeatItem( *gbritem );
719  break;
720 
723  gbritem = new GERBER_DRAW_ITEM( this );
724  AddItemToList( gbritem );
725 
726  if( m_LastCoordIsIJPos )
727  {
728  fillArcGBRITEM( gbritem, dcode, m_PreviousPos,
729  m_CurrentPos, m_IJPos, size,
731  false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
732  m_LastCoordIsIJPos = false;
733  }
734  else
735  {
736  fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
737  m_CurrentPos, size, GetLayerParams().m_LayerNegative );
738  }
739 
740  StepAndRepeatItem( *gbritem );
741 
742  break;
743 
744  default:
745  msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
746  m_Iterpolation );
747  AddMessageToList( msg );
748  break;
749  }
750 
752  break;
753 
754  case 2: // code D2: exposure OFF (i.e. "move to")
755  m_Exposure = false;
757  break;
758 
759  case 3: // code D3: flash aperture
760  tool = GetDCODE( m_Current_Tool );
761 
762  if( tool )
763  {
764  size = tool->m_Size;
765  dcode = tool->m_Num_Dcode;
766  aperture = tool->m_Shape;
767  }
768 
769  gbritem = new GERBER_DRAW_ITEM( this );
770  AddItemToList( gbritem );
771  fillFlashedGBRITEM( gbritem, aperture, dcode, m_CurrentPos,
772  size, GetLayerParams().m_LayerNegative );
773  StepAndRepeatItem( *gbritem );
775  break;
776 
777  default:
778  return false;
779  }
780  }
781 
782  return true;
783 }
void AddMessageToList(const wxString &aMessage)
Add a message to the message list.
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool Execute_DCODE_Command(char *&text, int D_command)
Definition: rs274d.cpp:579
int m_Last_Pen_Command
< Current or last pen state (0..9, set by Dn option with n < 10.
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:188
static void fillArcPOLY(GERBER_DRAW_ITEM *aGbrItem, const wxPoint &aStart, const wxPoint &aEnd, const wxPoint &rel_center, bool aClockwise, bool aMultiquadrant, bool aLayerNegative)
Create an arc G code when found in polygon outlines.
Definition: rs274d.cpp:328
Definition: dcode.h:52
bool m_LastCoordIsIJPos
< True if a IJ coord was read (for arcs & circles ).
bool m_InUse
false if the aperture (previously defined) is not used to draw something
Definition: dcode.h:197
APERTURE_T m_Shape
shape ( Line, rectangle, circle , oval .. )
Definition: dcode.h:189
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the aGlobalIndex-th vertex in the poly set.
int VertexCount(int aOutline=-1, int aHole=-1) const
Returns the number of holes in a given outline.
D_CODE * GetDCODE(int aDCODE) const
Return a pointer to the D_CODE within this GERBER for the given aDCODE.
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
void fillLineGBRITEM(GERBER_DRAW_ITEM *aGbrItem, int Dcode_index, const wxPoint &aStart, const wxPoint &aEnd, wxSize aPenSize, bool aLayerNegative)
Initialize a given GBRITEM so that it can draw a linear D code.
Definition: rs274d.cpp:153
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
SHAPE_POLY_SET m_Polygon
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
Definition: dcode.h:51
int m_PolygonFillModeState
a collection of APERTURE_MACROS, sorted by name
int GCodeNumber(char *&Text)
Definition: rs274d.cpp:399
bool ExecuteRS274XCommand(int aCommand, char *aBuff, unsigned int aBuffSize, char *&aText)
Execute a RS274X command.
Definition: rs274x.cpp:197
GERBER_DRAW_ITEM * GetLastItemInList() const
void AddItemToList(GERBER_DRAW_ITEM *aItem)
Add a new GERBER_DRAW_ITEM item to the drawings list.
#define FIRST_DCODE
Definition: dcode.h:70
int DCodeNumber(char *&Text)
Definition: rs274d.cpp:422
APERTURE_T
The set of all gerber aperture types allowed, according to page 16 of http://gerbv....
Definition: dcode.h:49
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:190
#define _(s)
bool m_Relative
< false = absolute Coord, true = relative Coord.
int NewOutline()
Creates a new hole in a given outline.
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)
Initialize a given GBRITEM so that it can draw an arc G code.
Definition: rs274d.cpp:202
bool Execute_G_Command(char *&text, int G_command)
Definition: rs274d.cpp:443
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
void fillFlashedGBRITEM(GERBER_DRAW_ITEM *aGbrItem, APERTURE_T aAperture, int Dcode_index, const wxPoint &aPos, wxSize aSize, bool aLayerNegative)
Initializes a given GBRITEM so that it can draw a circle which is filled and has no pen border.
Definition: rs274d.cpp:99
GBR_NETLIST_METADATA m_NetAttributeDict
#define TOOLS_MAX_COUNT
Definition: dcode.h:72
void SetLayerPolarity(bool aNegative)
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:125
constexpr int delta
#define IsNumber(x)
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:183
void StepAndRepeatItem(const GERBER_DRAW_ITEM &aItem)
Gerber format has a command Step an Repeat.
GERBER_FILE_IMAGE * m_GerberImageFile
GERBER_LAYER & GetLayerParams()
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, const wxPoint &aShapePos)
Calculate the primitive shape for flashed items.