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 <class_gerber_file_image.h>
#include <class_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...
 
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. 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

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 
)
static

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 208 of file rs274d.cpp.

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(), GERBER_DRAW_ITEM::SetNetAttributes(), wxPoint::x, and wxPoint::y.

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

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

References abs, 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_PolyCorners, GERBER_DRAW_ITEM::m_Start, RotatePoint(), GERBER_DRAW_ITEM::SetLayerPolarity(), GERBER_DRAW_ITEM::SetNetAttributes(), wxPoint::x, and wxPoint::y.

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command().

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

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, 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().

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  break;
144  }
145 }
Definition: dcode.h:52
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
Definition: dcode.h:51
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
GERBER_FILE_IMAGE * m_GerberImageFile
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 159 of file rs274d.cpp.

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(), and EXCELLON_IMAGE::Execute_Drill_Command().

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