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

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

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

Referenced by GERBER_FILE_IMAGE::Execute_DCODE_Command().

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 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
int OutlineCount() const
Returns the number of outlines in the set
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
SHAPE_POLY_SET m_Polygon
#define abs(a)
Definition: auxiliary.h:84
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
int NewOutline()
Creates a new empty polygon in the set and returns its index
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:211
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) ...
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, 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().

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 }
Definition: dcode.h:53
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
Definition: dcode.h:52
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.
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:157
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 162 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().

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 }
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
GERBER_FILE_IMAGE * m_GerberImageFile