KiCad PCB EDA Suite
rs274d.cpp File Reference

functions to read the rs274d commands from a rs274d/rs274x file More...

#include <fctsys.h>
#include <common.h>
#include <gerbview.h>
#include <gerbview_frame.h>
#include <trigo.h>
#include <gerber_file_image.h>
#include <X2_gerber_attributes.h>
#include <cmath>

Go to the source code of this file.

Functions

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 and has no pen border. More...
 
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. More...
 
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. More...
 
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. More...
 

Detailed Description

functions to read the rs274d commands from a rs274d/rs274x file

Definition in file rs274d.cpp.

Function Documentation

◆ fillArcGBRITEM()

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.

if multiquadrant == true : arc can be 0 to 360 degrees and rel_center is the center coordinate relative to start point.

if multiquadrant == false arc can be only 0 to 90 deg, and only in the same quadrant :

  • absolute angle 0 to 90 (quadrant 1) or
  • absolute angle 90 to 180 (quadrant 2) or
  • absolute angle 180 to 270 (quadrant 3) or
  • absolute angle 270 to 0 (quadrant 4)
Parameters
aGbrItemis the GBRITEM to fill in.
Dcode_indexis the DCODE value, like D14
aStartis the starting point
aEndis the ending point
aRelCenteris the center coordinate relative to start point, given in ABSOLUTE VALUE and the sign of values x et y de rel_center must be calculated from the previously given constraint: arc only in the same quadrant.
aClockwisetrue if arc must be created clockwise
aPenSizeThe size of the flash. Note rectangular shapes are legal.
aMultiquadrant= true to create arcs upto 360 deg, false when arc is inside one quadrant
aLayerNegative= true if the current layer is negative

Definition at line 207 of file rs274d.cpp.

212 {
213  wxPoint center, delta;
214 
215  aGbrItem->m_Shape = GBR_ARC;
216  aGbrItem->m_Size = aPenSize;
217  aGbrItem->m_Flashed = false;
218 
219  if( aGbrItem->m_GerberImageFile )
220  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
221 
222  if( aMultiquadrant )
223  center = aStart + aRelCenter;
224  else
225  {
226  // in single quadrant mode the relative coordinate aRelCenter is always >= 0
227  // So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
228  center = aRelCenter;
229 
230  // calculate arc end coordinate relative to the starting point,
231  // because center is relative to the center point
232  delta = aEnd - aStart;
233 
234  // now calculate the relative to aStart center position, for a draw function
235  // that use trigonometric arc angle (or counter-clockwise)
236  /* Quadrants:
237  * Y
238  * 2 | 1
239  * -------X
240  * 3 | 4
241  * C = actual relative arc center, S = arc start (axis origin) E = relative arc end
242  */
243  if( (delta.x >= 0) && (delta.y >= 0) )
244  {
245  /* Quadrant 1 (trigo or cclockwise):
246  * C | E
247  * ---S---
248  * 3 | 4
249  */
250  center.x = -center.x;
251  }
252  else if( (delta.x >= 0) && (delta.y < 0) )
253  {
254  /* Quadrant 4 (trigo or cclockwise):
255  * 2 | C
256  * ---S---
257  * 3 | E
258  */
259  // Nothing to do
260  }
261  else if( (delta.x < 0) && (delta.y >= 0) )
262  {
263  /* Quadrant 2 (trigo or cclockwise):
264  * E | 1
265  * ---S---
266  * C | 4
267  */
268  center.x = -center.x;
269  center.y = -center.y;
270  }
271  else
272  {
273  /* Quadrant 3 (trigo or cclockwise):
274  * 2 | 1
275  * ---S---
276  * E | C
277  */
278  center.y = -center.y;
279  }
280 
281  // Due to your draw arc function, we need this:
282  if( !aClockwise )
283  center = - center;
284 
285  // Calculate actual arc center coordinate:
286  center += aStart;
287  }
288 
289  if( aClockwise )
290  {
291  aGbrItem->m_Start = aStart;
292  aGbrItem->m_End = aEnd;
293  }
294  else
295  {
296  aGbrItem->m_Start = aEnd;
297  aGbrItem->m_End = aStart;
298  }
299 
300  aGbrItem->m_ArcCentre = center;
301 
302  aGbrItem->m_DCode = Dcode_index;
303  aGbrItem->SetLayerPolarity( aLayerNegative );
304 }
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
static const int delta[8][2]
Definition: solve.cpp:112
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
GERBER_FILE_IMAGE * m_GerberImageFile

References delta, GBR_ARC, GERBER_DRAW_ITEM::m_ArcCentre, GERBER_DRAW_ITEM::m_DCode, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Flashed, GERBER_DRAW_ITEM::m_GerberImageFile, GERBER_FILE_IMAGE::m_NetAttributeDict, GERBER_DRAW_ITEM::m_Shape, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, GERBER_DRAW_ITEM::SetLayerPolarity(), and GERBER_DRAW_ITEM::SetNetAttributes().

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command(), fillArcPOLY(), and EXCELLON_IMAGE::FinishRouteCommand().

◆ fillArcPOLY()

static void fillArcPOLY ( GERBER_DRAW_ITEM aGbrItem,
const wxPoint &  aStart,
const wxPoint &  aEnd,
const wxPoint &  rel_center,
bool  aClockwise,
bool  aMultiquadrant,
bool  aLayerNegative 
)
static

Function fillArcPOLY creates an arc G code when found in poly outlines.

if multiquadrant == true : arc can be 0 to 360 degrees and rel_center is the center coordinate relative to start point.

if multiquadrant == false arc can be only 0 to 90 deg, and only in the same quadrant :

  • absolute angle 0 to 90 (quadrant 1) or
  • absolute angle 90 to 180 (quadrant 2) or
  • absolute angle 180 to 270 (quadrant 3) or
  • absolute angle 270 to 0 (quadrant 4)
Parameters
aGbrItemis the GBRITEM to fill in.
aStartis the starting point
aEndis the ending point
rel_centeris the center coordinate relative to start point, given in ABSOLUTE VALUE and the sign of values x et y de rel_center must be calculated from the previously given constraint: arc only in the same quadrant.
aClockwisetrue if arc must be created clockwise
aMultiquadrant= true to create arcs upto 360 deg, false when arc is inside one quadrant
aLayerNegative= true if the current layer is negative

Definition at line 334 of file rs274d.cpp.

339 {
340  /* in order to calculate arc parameters, we use fillArcGBRITEM
341  * so we muse create a dummy track and use its geometric parameters
342  */
343  static GERBER_DRAW_ITEM dummyGbrItem( NULL );
344 
345  aGbrItem->SetLayerPolarity( aLayerNegative );
346 
347  fillArcGBRITEM( &dummyGbrItem, 0,
348  aStart, aEnd, rel_center, wxSize(0, 0),
349  aClockwise, aMultiquadrant, aLayerNegative );
350 
351  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
352 
353  wxPoint center;
354  center = dummyGbrItem.m_ArcCentre;
355 
356  // Calculate coordinates relative to arc center;
357  wxPoint start = dummyGbrItem.m_Start - center;
358  wxPoint end = dummyGbrItem.m_End - center;
359 
360  /* Calculate angle arc
361  * angles are in 0.1 deg
362  * angle is trigonometrical (counter-clockwise),
363  * and axis is the X,Y gerber coordinates
364  */
365  double start_angle = ArcTangente( start.y, start.x );
366  double end_angle = ArcTangente( end.y, end.x );
367 
368  // dummyTrack has right geometric parameters, but
369  // fillArcGBRITEM calculates arc parameters for a draw function that expects
370  // start_angle < end_angle. So ensure this is the case here:
371  // Due to the fact atan2 returns angles between -180 to + 180 degrees,
372  // this is not always the case ( a modulo 360.0 degrees can be lost )
373  if( start_angle > end_angle )
374  end_angle += 3600;
375 
376  double arc_angle = start_angle - end_angle;
377  // Approximate arc by 36 segments per 360 degree
378  const int increment_angle = 3600 / 36;
379  int count = std::abs( arc_angle / increment_angle );
380 
381  if( aGbrItem->m_Polygon.OutlineCount() == 0 )
382  aGbrItem->m_Polygon.NewOutline();
383 
384  // calculate polygon corners
385  // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
386  // and we must always create a polygon from start to end.
387  wxPoint start_arc = start;
388  for( int ii = 0; ii <= count; ii++ )
389  {
390  double rot;
391  wxPoint end_arc = start;
392  if( aClockwise )
393  rot = ii * increment_angle; // rot is in 0.1 deg
394  else
395  rot = (count - ii) * increment_angle; // rot is in 0.1 deg
396 
397  if( ii < count )
398  RotatePoint( &end_arc, -rot );
399  else // last point
400  end_arc = aClockwise ? end : start;
401 
402  aGbrItem->m_Polygon.Append( VECTOR2I( end_arc + center ) );
403 
404  start_arc = end_arc;
405  }
406 }
int OutlineCount() const
Returns the number of outlines in the set
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
SHAPE_POLY_SET m_Polygon
#define abs(a)
Definition: auxiliary.h:84
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
int NewOutline()
Creates a new empty polygon in the set and returns its index
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:207
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
GERBER_FILE_IMAGE * m_GerberImageFile
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)

References abs, SHAPE_POLY_SET::Append(), ArcTangente(), fillArcGBRITEM(), GERBER_DRAW_ITEM::m_ArcCentre, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_GerberImageFile, GERBER_FILE_IMAGE::m_NetAttributeDict, GERBER_DRAW_ITEM::m_Polygon, GERBER_DRAW_ITEM::m_Start, SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::OutlineCount(), RotatePoint(), GERBER_DRAW_ITEM::SetLayerPolarity(), and GERBER_DRAW_ITEM::SetNetAttributes().

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command().

◆ fillFlashedGBRITEM()

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 and has no pen border.

Parameters
aGbrItemThe GBRITEM to fill in.
aAperturethe associated type of aperture
Dcode_indexThe DCODE value, like D14
aPosThe center point of the flash
aSizeThe diameter of the round flash
aLayerNegative= true if the current layer is negative

Definition at line 103 of file rs274d.cpp.

109 {
110  aGbrItem->m_Size = aSize;
111  aGbrItem->m_Start = aPos;
112  aGbrItem->m_End = aGbrItem->m_Start;
113  aGbrItem->m_DCode = Dcode_index;
114  aGbrItem->SetLayerPolarity( aLayerNegative );
115  aGbrItem->m_Flashed = true;
116  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
117 
118  switch( aAperture )
119  {
120  case APT_POLYGON: // flashed regular polygon
121  aGbrItem->m_Shape = GBR_SPOT_POLY;
122  break;
123 
124  case APT_CIRCLE:
125  aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
126  aGbrItem->m_Size.y = aGbrItem->m_Size.x;
127  break;
128 
129  case APT_OVAL:
130  aGbrItem->m_Shape = GBR_SPOT_OVAL;
131  break;
132 
133  case APT_RECT:
134  aGbrItem->m_Shape = GBR_SPOT_RECT;
135  break;
136 
137  case APT_MACRO:
138  aGbrItem->m_Shape = GBR_SPOT_MACRO;
139 
140  // Cache the bounding box for aperture macros
141  aGbrItem->GetDcodeDescr()->GetMacro()->GetApertureMacroShape( aGbrItem, aPos );
142  break;
143  }
144 }
D_CODE * GetDcodeDescr() const
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
Definition: dcode.h:53
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
Definition: dcode.h:52
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, wxPoint aShapePos)
Function GetApertureMacroShape Calculate the primitive shape for flashed items.
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:157
GERBER_FILE_IMAGE * m_GerberImageFile

References APT_CIRCLE, APT_MACRO, APT_OVAL, APT_POLYGON, APT_RECT, GBR_SPOT_CIRCLE, GBR_SPOT_MACRO, GBR_SPOT_OVAL, GBR_SPOT_POLY, GBR_SPOT_RECT, APERTURE_MACRO::GetApertureMacroShape(), GERBER_DRAW_ITEM::GetDcodeDescr(), D_CODE::GetMacro(), GERBER_DRAW_ITEM::m_DCode, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Flashed, GERBER_DRAW_ITEM::m_GerberImageFile, GERBER_FILE_IMAGE::m_NetAttributeDict, GERBER_DRAW_ITEM::m_Shape, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, GERBER_DRAW_ITEM::SetLayerPolarity(), and GERBER_DRAW_ITEM::SetNetAttributes().

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command(), and EXCELLON_IMAGE::Execute_Drill_Command().

◆ fillLineGBRITEM()

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.

Parameters
aGbrItemThe GERBER_DRAW_ITEM to fill in.
Dcode_indexThe DCODE value, like D14
aStartThe starting point of the line
aEndThe ending point of the line
aPenSizeThe size of the flash. Note rectangular shapes are legal.
aLayerNegative= true if the current layer is negative

Definition at line 158 of file rs274d.cpp.

164 {
165  aGbrItem->m_Flashed = false;
166 
167  aGbrItem->m_Size = aPenSize;
168 
169  aGbrItem->m_Start = aStart;
170  aGbrItem->m_End = aEnd;
171 
172  aGbrItem->m_DCode = Dcode_index;
173  aGbrItem->SetLayerPolarity( aLayerNegative );
174 
175  aGbrItem->SetNetAttributes( aGbrItem->m_GerberImageFile->m_NetAttributeDict );
176 }
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
GERBER_FILE_IMAGE * m_GerberImageFile

References GERBER_DRAW_ITEM::m_DCode, GERBER_DRAW_ITEM::m_End, GERBER_DRAW_ITEM::m_Flashed, GERBER_DRAW_ITEM::m_GerberImageFile, GERBER_FILE_IMAGE::m_NetAttributeDict, GERBER_DRAW_ITEM::m_Size, GERBER_DRAW_ITEM::m_Start, GERBER_DRAW_ITEM::SetLayerPolarity(), and GERBER_DRAW_ITEM::SetNetAttributes().

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command(), EXCELLON_IMAGE::Execute_Drill_Command(), and EXCELLON_IMAGE::FinishRouteCommand().