KiCad PCB EDA Suite
rs274d.cpp File Reference

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

#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)
 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)
 Initialize 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)
 Initialize 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)
 Create an arc G code when found in polygon 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 
)

Initialize 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.
aMultiquadrantset to true to create arcs up to 360 degrees, false when arc is inside one quadrant
aLayerNegativeset to true if the current layer is negative.

Definition at line 202 of file rs274d.cpp.

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 }
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
constexpr int delta
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

Create an arc G code when found in polygon outlines.

If multiquadrant == true : arc can be 0 to 360 degrees and rel_center is the center coordinate relative to start point. If not multiquadrant, the 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
aMultiquadrantset to true to create arcs up to 360 deg or false when arc is inside one quadrant
aLayerNegativeset to true if the current layer is negative

Definition at line 328 of file rs274d.cpp.

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 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
SHAPE_POLY_SET m_Polygon
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
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:183
GERBER_FILE_IMAGE * m_GerberImageFile
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...

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

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.
aLayerNegativeset to true if the current layer is negative.

Definition at line 99 of file rs274d.cpp.

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 }
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
Definition: dcode.h:52
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
Definition: dcode.h:51
GBR_NETLIST_METADATA m_NetAttributeDict
void SetLayerPolarity(bool aNegative)
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:125
GERBER_FILE_IMAGE * m_GerberImageFile
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, const wxPoint &aShapePos)
Calculate the primitive shape for flashed items.

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 
)

Initialize 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.
aLayerNegativeset to true if the current layer is negative.

Definition at line 153 of file rs274d.cpp.

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