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-2022 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  //
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 += 3600;
369 
370  double arc_angle = start_angle - end_angle;
371 
372  // Approximate arc by 36 segments per 360 degree
373  const int increment_angle = 3600 / 36;
374  int count = std::abs( arc_angle / increment_angle );
375 
376  if( aGbrItem->m_Polygon.OutlineCount() == 0 )
377  aGbrItem->m_Polygon.NewOutline();
378 
379  // calculate polygon corners
380  // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
381  // and we must always create a polygon from start to end.
382  for( int ii = 0; ii <= count; ii++ )
383  {
384  double rot;
385  wxPoint end_arc = start;
386 
387  if( aClockwise )
388  rot = ii * increment_angle; // rot is in 0.1 deg
389  else
390  rot = ( count - ii ) * increment_angle; // rot is in 0.1 deg
391 
392  if( ii < count )
393  RotatePoint( &end_arc, -rot );
394  else // last point
395  end_arc = aClockwise ? end : start;
396 
397  aGbrItem->m_Polygon.Append( VECTOR2I( end_arc + center ) );
398  }
399 }
400 
401 
402 int GERBER_FILE_IMAGE::CodeNumber( char*& aText )
403 {
404  int retval;
405  char* endptr;
406 
407  errno = 0;
408 
409  retval = strtol( aText + 1, &endptr, 10 );
410 
411  if( endptr == aText || errno != 0 )
412  return 0;
413 
414  wxCHECK_MSG( retval < std::numeric_limits<int>::max(), 0, _( "Invalid Code Number" ) );
415 
416  aText = endptr;
417 
418  return static_cast<int>( retval );
419 }
420 
421 
422 bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
423 {
424  switch( G_command )
425  {
426  case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored.
427  break;
428 
431  break;
432 
435  break;
436 
439  break;
440 
441  case GC_COMMENT:
442  // Skip comment, but only if the line does not start by "G04 #@! "
443  // which is a metadata, i.e. a X2 command inside the comment.
444  // this comment is called a "structured comment"
445  if( strncmp( text, " #@! ", 5 ) == 0 )
446  {
447  text += 5;
448 
449  // The string starting at text is the same as the X2 attribute,
450  // but a X2 attribute ends by '%'. So we build the X2 attribute string
451  std::string x2buf;
452 
453  while( *text && (*text != '*') )
454  {
455  x2buf += *text;
456  text++;
457  }
458 
459  // add the end of X2 attribute string
460  x2buf += "*%";
461  x2buf += '\0';
462 
463  char* cptr = (char*)x2buf.data();
464  int code_command = ReadXCommandID( cptr );
465  ExecuteRS274XCommand( code_command, nullptr, 0, cptr );
466  }
467 
468  while( *text && (*text != '*') )
469  text++;
470 
471  break;
472 
473  case GC_SELECT_TOOL:
474  {
475  int D_commande = CodeNumber( text );
476 
477  if( D_commande < FIRST_DCODE )
478  return false;
479 
480  if( D_commande > (TOOLS_MAX_COUNT - 1) )
481  D_commande = TOOLS_MAX_COUNT - 1;
482 
483  m_Current_Tool = D_commande;
484  D_CODE* pt_Dcode = GetDCODE( D_commande );
485 
486  if( pt_Dcode )
487  pt_Dcode->m_InUse = true;
488 
489  break;
490  }
491 
492  case GC_SPECIFY_INCHES:
493  m_GerbMetric = false; // false = Inches, true = metric
494  break;
495 
497  m_GerbMetric = true; // false = Inches, true = metric
498  break;
499 
500  case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
501  m_360Arc_enbl = false;
502  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
503  m_AsArcG74G75Cmd = true;
504  break;
505 
507  m_360Arc_enbl = true;
508  m_AsArcG74G75Cmd = true;
509  break;
510 
512  m_Relative = false; // false = absolute Coord, true = relative
513  // Coord
514  break;
515 
517  m_Relative = true; // false = absolute Coord, true = relative
518  // Coord
519  break;
520 
522  m_PolygonFillMode = true;
523  m_Exposure = false;
524  break;
525 
527  if( m_Exposure && GetLastItemInList() ) // End of polygon
528  {
529  GERBER_DRAW_ITEM * gbritem = GetLastItemInList();
530 
531  if( gbritem->m_Polygon.VertexCount() )
532  gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) );
533 
534  StepAndRepeatItem( *gbritem );
535  }
536 
537  m_Exposure = false;
538  m_PolygonFillMode = false;
540  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
541  break;
542 
543  case GC_MOVE: // Non existent
544  default:
545  {
546  wxString msg;
547  msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
548  AddMessageToList( msg );
549  return false;
550  }
551  }
552 
553 
554  return true;
555 }
556 
557 
558 bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
559 {
560  wxSize size( 15, 15 );
561 
562  APERTURE_T aperture = APT_CIRCLE;
563  GERBER_DRAW_ITEM* gbritem;
564 
565  int dcode = 0;
566  D_CODE* tool = nullptr;
567  wxString msg;
568 
569  if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
570  {
571  if( D_commande > (TOOLS_MAX_COUNT - 1) )
572  D_commande = TOOLS_MAX_COUNT - 1;
573 
574  // remember which tool is selected, nothing is done with it in this
575  // call
576  m_Current_Tool = D_commande;
577 
578  D_CODE* pt_Dcode = GetDCODE( D_commande );
579 
580  if( pt_Dcode )
581  pt_Dcode->m_InUse = true;
582  else
583  m_Has_MissingDCode = true;
584 
585  return true;
586  }
587  else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
588  {
589  m_Last_Pen_Command = D_commande;
590  }
591 
592  if( m_PolygonFillMode ) // Enter a polygon description:
593  {
594  switch( D_commande )
595  {
596  case 1: // code D01 Draw line, exposure ON
597  if( !m_Exposure ) // Start a new polygon outline:
598  {
599  m_Exposure = true;
600  gbritem = new GERBER_DRAW_ITEM( this );
601  AddItemToList( gbritem );
602  gbritem->m_Shape = GBR_POLYGON;
603  gbritem->m_Flashed = false;
604  gbritem->m_DCode = 0; // No DCode for a Polygon (Region in Gerber dialect)
605 
606 
607  if( gbritem->m_GerberImageFile )
608  {
610  gbritem->m_AperFunction = gbritem->m_GerberImageFile->m_AperFunction;
611  }
612  }
613 
614  switch( m_Iterpolation )
615  {
618  // Before any arc command, a G74 or G75 command must be set.
619  // Otherwise the Gerber file is invalid
620  if( !m_AsArcG74G75Cmd )
621  {
622  AddMessageToList( _( "Invalid Gerber file: missing G74 or G75 arc command" ) );
623 
624  // Disable further warning messages:
625  m_AsArcG74G75Cmd = true;
626  }
627 
628  gbritem = GetLastItemInList();
629 
630  fillArcPOLY( gbritem, m_PreviousPos,
632  ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
633  m_360Arc_enbl, GetLayerParams().m_LayerNegative );
634  break;
635 
636  default:
637  gbritem = GetLastItemInList();
638 
639  gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
640 
641  if( gbritem->m_Polygon.OutlineCount() == 0 )
642  {
643  gbritem->m_Polygon.NewOutline();
644  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_Start ) );
645  }
646 
647  gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
648  gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_End ) );
649  break;
650  }
651 
654  break;
655 
656  case 2: // code D2: exposure OFF (i.e. "move to")
657  if( m_Exposure && GetLastItemInList() ) // End of polygon
658  {
659  gbritem = GetLastItemInList();
660  gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) );
661  StepAndRepeatItem( *gbritem );
662  }
663 
664  m_Exposure = false;
667  break;
668 
669  default:
670  return false;
671  }
672  }
673  else
674  {
675  switch( D_commande )
676  {
677  case 1: // code D01 Draw line, exposure ON
678  m_Exposure = true;
679 
680  tool = GetDCODE( m_Current_Tool );
681 
682  if( tool )
683  {
684  size = tool->m_Size;
685  dcode = tool->m_Num_Dcode;
686  aperture = tool->m_Shape;
687  }
688 
689  switch( m_Iterpolation )
690  {
692  gbritem = new GERBER_DRAW_ITEM( this );
693  AddItemToList( gbritem );
694 
695  fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
696  m_CurrentPos, size, GetLayerParams().m_LayerNegative );
697  StepAndRepeatItem( *gbritem );
698  break;
699 
702  gbritem = new GERBER_DRAW_ITEM( this );
703  AddItemToList( gbritem );
704 
705  if( m_LastCoordIsIJPos )
706  {
707  fillArcGBRITEM( gbritem, dcode, m_PreviousPos,
708  m_CurrentPos, m_IJPos, size,
710  false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
711  m_LastCoordIsIJPos = false;
712  }
713  else
714  {
715  fillLineGBRITEM( gbritem, dcode, m_PreviousPos,
716  m_CurrentPos, size, GetLayerParams().m_LayerNegative );
717  }
718 
719  StepAndRepeatItem( *gbritem );
720 
721  break;
722 
723  default:
724  msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
725  m_Iterpolation );
726  AddMessageToList( msg );
727  break;
728  }
729 
731  break;
732 
733  case 2: // code D2: exposure OFF (i.e. "move to")
734  m_Exposure = false;
736  break;
737 
738  case 3: // code D3: flash aperture
739  tool = GetDCODE( m_Current_Tool );
740 
741  if( tool )
742  {
743  size = tool->m_Size;
744  dcode = tool->m_Num_Dcode;
745  aperture = tool->m_Shape;
746  }
747 
748  gbritem = new GERBER_DRAW_ITEM( this );
749  AddItemToList( gbritem );
750  fillFlashedGBRITEM( gbritem, aperture, dcode, m_CurrentPos,
751  size, GetLayerParams().m_LayerNegative );
752  StepAndRepeatItem( *gbritem );
754  break;
755 
756  default:
757  return false;
758  }
759  }
760 
761  return true;
762 }
void AddMessageToList(const wxString &aMessage)
Add a message to the message list.
int CodeNumber(char *&aText)
Reads the next number and returns the value.
Definition: rs274d.cpp:402
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:558
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
Return the number of points in the shape poly set.
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:622
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:115
Definition: dcode.h:51
int m_PolygonFillModeState
a collection of APERTURE_MACROS, sorted by name
bool ExecuteRS274XCommand(int aCommand, char *aBuff, unsigned int aBuffSize, char *&aText)
Execute a RS274X command.
Definition: rs274x.cpp:198
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
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:422
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
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.