KiCad PCB EDA Suite
AM_PRIMITIVE Class Reference

Struct AM_PRIMITIVE holds an aperture macro primitive as given in Table 3 of http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf. More...

#include <am_primitive.h>

Public Member Functions

 AM_PRIMITIVE (bool aGerbMetric, AM_PRIMITIVE_ID aId=AMP_UNKNOWN)
 
 ~AM_PRIMITIVE ()
 
bool IsAMPrimitiveExposureOn (const GERBER_DRAW_ITEM *aParent) const
 Function IsAMPrimitiveExposureOn. More...
 
int GetShapeDim (const GERBER_DRAW_ITEM *aParent)
 GetShapeDim Calculate a value that can be used to evaluate the size of text when displaying the D-Code of an item due to the complexity of the shape of some primitives one cannot calculate the "size" of a shape (only a bounding box) but here, the "dimension" of the shape is the diameter of the primitive or for lines the width of the line. More...
 
void DrawBasicShape (const GERBER_DRAW_ITEM *aParent, SHAPE_POLY_SET &aShapeBuffer, wxPoint aShapePos)
 Function drawBasicShape Draw (in fact generate the actual polygonal shape of) the primitive shape of an aperture macro instance. More...
 

Public Attributes

AM_PRIMITIVE_ID primitive_id
 The primitive type. More...
 
AM_PARAMS params
 A sequence of parameters used by. More...
 
bool m_GerbMetric
 

Private Member Functions

void ConvertShapeToPolygon (const GERBER_DRAW_ITEM *aParent, std::vector< wxPoint > &aBuffer)
 Function ConvertShapeToPolygon convert a shape to an equivalent polygon. More...
 

Detailed Description

Struct AM_PRIMITIVE holds an aperture macro primitive as given in Table 3 of http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf.

Definition at line 91 of file am_primitive.h.

Constructor & Destructor Documentation

◆ AM_PRIMITIVE()

AM_PRIMITIVE::AM_PRIMITIVE ( bool  aGerbMetric,
AM_PRIMITIVE_ID  aId = AMP_UNKNOWN 
)
inline

Definition at line 99 of file am_primitive.h.

99  : AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
100  {
101  primitive_id = aId;
102  m_GerbMetric = aGerbMetric;
103  }
bool m_GerbMetric
Definition: am_primitive.h:97
AM_PRIMITIVE(bool aGerbMetric, AM_PRIMITIVE_ID aId=AMP_UNKNOWN)
Definition: am_primitive.h:99
AM_PRIMITIVE_ID
Enum AM_PRIMITIVE_ID is the set of all "aperture macro primitives" (primitive numbers).
Definition: am_primitive.h:70
AM_PRIMITIVE_ID primitive_id
The primitive type.
Definition: am_primitive.h:94

References m_GerbMetric, and primitive_id.

◆ ~AM_PRIMITIVE()

AM_PRIMITIVE::~AM_PRIMITIVE ( )
inline

Definition at line 106 of file am_primitive.h.

106 {}

Member Function Documentation

◆ ConvertShapeToPolygon()

void AM_PRIMITIVE::ConvertShapeToPolygon ( const GERBER_DRAW_ITEM aParent,
std::vector< wxPoint > &  aBuffer 
)
private

Function ConvertShapeToPolygon convert a shape to an equivalent polygon.

Function ConvertShapeToPolygon (virtual) convert a shape to an equivalent polygon.

Arcs and circles are approximated by segments Useful when a shape is not a graphic primitive (shape with hole, rotated shape ... ) and cannot be easily drawn.

Arcs and circles are approximated by segments Useful when a shape is not a graphic primitive (shape with hole, rotated shape ... ) and cannot be easily drawn. note for some schapes conbining circles and solid lines (rectangles), only rectangles are converted because circles are very easy to draw (no rotation problem) so convert them in polygons, and draw them as polygons is not a good idea.

Definition at line 450 of file am_primitive.cpp.

452 {
453  D_CODE* tool = aParent->GetDcodeDescr();
454 
455  switch( primitive_id )
456  {
457  case AMP_CIRCLE:
458  {
459  /* Generated by an aperture macro declaration like:
460  * "1,1,0.3,0.5, 1.0*"
461  * type (1), exposure, diameter, pos.x, pos.y, <rotation>
462  * <rotation> is a optional parameter: rotation from origin.
463  * type is not stored in parameters list, so the first parameter is exposure
464  */
465  wxPoint center = mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
466  int radius = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ) / 2;
467  wxPoint corner;
468  const int delta = 3600 / seg_per_circle; // rot angle in 0.1 degree
469 
470  for( int angle = 0; angle < 3600; angle += delta )
471  {
472  corner.x = radius;
473  corner.y = 0;
474  RotatePoint( &corner, angle );
475  corner += center;
476  aBuffer.push_back( corner );
477  }
478  }
479  break;
480 
481  case AMP_LINE2:
482  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
483  {
484  int width = scaletoIU( params[1].GetValue( tool ), m_GerbMetric );
485  wxPoint start = mapPt( params[2].GetValue( tool ),
486  params[3].GetValue( tool ), m_GerbMetric );
487  wxPoint end = mapPt( params[4].GetValue( tool ),
488  params[5].GetValue( tool ), m_GerbMetric );
489  wxPoint delta = end - start;
490  int len = KiROUND( EuclideanNorm( delta ) );
491 
492  // To build the polygon, we must create a horizontal polygon starting to "start"
493  // and rotate it to have the end point to "end"
494  wxPoint currpt;
495  currpt.y += width / 2; // Upper left
496  aBuffer.push_back( currpt );
497  currpt.x = len; // Upper right
498  aBuffer.push_back( currpt );
499  currpt.y -= width; // lower right
500  aBuffer.push_back( currpt );
501  currpt.x = 0; // lower left
502  aBuffer.push_back( currpt );
503 
504  // Rotate rectangle and move it to the actual start point
505  double angle = ArcTangente( delta.y, delta.x );
506 
507  for( unsigned ii = 0; ii < 4; ii++ )
508  {
509  RotatePoint( &aBuffer[ii], -angle );
510  aBuffer[ii] += start;
511  }
512  }
513  break;
514 
515  case AMP_LINE_CENTER:
516  {
517  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
518  wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), m_GerbMetric );
519 
520  // Build poly:
521  pos.x -= size.x / 2;
522  pos.y -= size.y / 2; // Lower left
523  aBuffer.push_back( pos );
524  pos.y += size.y; // Upper left
525  aBuffer.push_back( pos );
526  pos.x += size.x; // Upper right
527  aBuffer.push_back( pos );
528  pos.y -= size.y; // lower right
529  aBuffer.push_back( pos );
530  }
531  break;
532 
533  case AMP_LINE_LOWER_LEFT:
534  {
535  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
536  wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
537  tool ), m_GerbMetric );
538 
539  // Build poly:
540  aBuffer.push_back( lowerLeft );
541  lowerLeft.y += size.y; // Upper left
542  aBuffer.push_back( lowerLeft );
543  lowerLeft.x += size.x; // Upper right
544  aBuffer.push_back( lowerLeft );
545  lowerLeft.y -= size.y; // lower right
546  aBuffer.push_back( lowerLeft );
547  }
548  break;
549 
550  case AMP_THERMAL:
551  {
552  // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
553  // rotated by 90, 180 and 270 deg.
554  // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
555  int outerRadius = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2;
556  int innerRadius = scaletoIU( params[3].GetValue( tool ), m_GerbMetric ) / 2;
557 
558  // Safety checks to guarantee no divide-by-zero
559  outerRadius = std::max( 1, outerRadius );
560  innerRadius = std::max( 1, innerRadius );
561 
562  int halfthickness = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
563  double angle_start = RAD2DECIDEG( asin( (double) halfthickness / innerRadius ) );
564 
565  // Draw shape in the first cadrant (X and Y > 0)
566  wxPoint pos, startpos;
567 
568  // Inner arc
569  startpos.x = innerRadius;
570  double angle_end = 900 - angle_start;
571  for( double angle = angle_start; angle < angle_end; angle += 100 )
572  {
573  pos = startpos;
574  RotatePoint( &pos, angle );
575  aBuffer.push_back( pos );
576  }
577 
578  // Last point
579  pos = startpos;
580  RotatePoint( &pos, angle_end );
581  aBuffer.push_back( pos );
582 
583  // outer arc
584  startpos.x = outerRadius;
585  startpos.y = 0;
586  angle_start = RAD2DECIDEG( asin( (double) halfthickness / outerRadius ) );
587  angle_end = 900 - angle_start;
588 
589  // First point, near Y axis, outer arc
590  for( double angle = angle_end; angle > angle_start; angle -= 100 )
591  {
592  pos = startpos;
593  RotatePoint( &pos, angle );
594  aBuffer.push_back( pos );
595  }
596 
597  // last point
598  pos = startpos;
599  RotatePoint( &pos, angle_start );
600  aBuffer.push_back( pos );
601 
602  aBuffer.push_back( aBuffer[0] ); // Close poly
603  }
604  break;
605 
606  case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon
607  // because circles can be drawn easily
608  {
609  int crossHairThickness = scaletoIU( params[6].GetValue( tool ), m_GerbMetric );
610  int crossHairLength = scaletoIU( params[7].GetValue( tool ), m_GerbMetric );
611 
612  // Create cross. First create 1/4 of the shape.
613  // Others point are the same, totated by 90, 180 and 270 deg
614  wxPoint pos( crossHairThickness / 2, crossHairLength / 2 );
615  aBuffer.push_back( pos );
616  pos.y = crossHairThickness / 2;
617  aBuffer.push_back( pos );
618  pos.x = -crossHairLength / 2;
619  aBuffer.push_back( pos );
620  pos.y = -crossHairThickness / 2;
621  aBuffer.push_back( pos );
622 
623  // Copy the 4 shape, rotated by 90, 180 and 270 deg
624  for( int jj = 1; jj <= 3; jj ++ )
625  {
626  for( int ii = 0; ii < 4; ii++ )
627  {
628  pos = aBuffer[ii];
629  RotatePoint( &pos, jj*900 );
630  aBuffer.push_back( pos );
631  }
632  }
633  }
634  break;
635 
636  case AMP_OUTLINE:
637  // already is a polygon. Do nothing
638  break;
639 
640  case AMP_POLYGON: // Creates a regular polygon
641  {
642  int vertexcount = KiROUND( params[1].GetValue( tool ) );
643  int radius = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
644  // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
645  if( vertexcount < 3 )
646  vertexcount = 3;
647  if( vertexcount > 10 )
648  vertexcount = 10;
649  for( int ii = 0; ii <= vertexcount; ii++ )
650  {
651  wxPoint pos( radius, 0);
652  RotatePoint( &pos, ii * 3600 / vertexcount );
653  aBuffer.push_back( pos );
654  }
655  }
656  break;
657 
658  case AMP_COMMENT:
659  case AMP_UNKNOWN:
660  case AMP_EOF:
661  break;
662  }
663 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
bool m_GerbMetric
Definition: am_primitive.h:97
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
double RAD2DECIDEG(double rad)
Definition: trigo.h:236
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
int scaletoIU(double aCoord, bool isMetric)
Function scaletoIU converts a distance given in floating point to our internal units.
const int seg_per_circle
static wxPoint mapPt(double x, double y, bool isMetric)
Function mapPt translates a point from the aperture macro coordinate system to our deci-mils coordina...
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:182
AM_PARAMS params
A sequence of parameters used by.
Definition: am_primitive.h:95
AM_PRIMITIVE_ID primitive_id
The primitive type.
Definition: am_primitive.h:94

References AMP_CIRCLE, AMP_COMMENT, AMP_EOF, AMP_LINE2, AMP_LINE20, AMP_LINE_CENTER, AMP_LINE_LOWER_LEFT, AMP_MOIRE, AMP_OUTLINE, AMP_POLYGON, AMP_THERMAL, AMP_UNKNOWN, PNS::angle(), ArcTangente(), EuclideanNorm(), GERBER_DRAW_ITEM::GetDcodeDescr(), KiROUND(), m_GerbMetric, mapPt(), params, primitive_id, RAD2DECIDEG(), RotatePoint(), scaletoIU(), and seg_per_circle.

Referenced by DrawBasicShape().

◆ DrawBasicShape()

void AM_PRIMITIVE::DrawBasicShape ( const GERBER_DRAW_ITEM aParent,
SHAPE_POLY_SET aShapeBuffer,
wxPoint  aShapePos 
)

Function drawBasicShape Draw (in fact generate the actual polygonal shape of) the primitive shape of an aperture macro instance.

Parameters
aParent= the parent GERBER_DRAW_ITEM which is actually drawn
aShapeBuffer= a SHAPE_POLY_SET to put the shape converted to a polygon
aShapePos= the actual shape position

Definition at line 95 of file am_primitive.cpp.

98 {
99  #define TO_POLY_SHAPE { aShapeBuffer.NewOutline(); \
100  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )\
101  aShapeBuffer.Append( polybuffer[jj].x, polybuffer[jj].y );\
102  aShapeBuffer.Append( polybuffer[0].x, polybuffer[0].y );}
103 
104  // Draw the primitive shape for flashed items.
105  static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
106  polybuffer.clear();
107 
108  wxPoint curPos = aShapePos;
109  D_CODE* tool = aParent->GetDcodeDescr();
110  double rotation;
111 
112  switch( primitive_id )
113  {
114  case AMP_CIRCLE: // Circle, given diameter and position
115  {
116  /* Generated by an aperture macro declaration like:
117  * "1,1,0.3,0.5, 1.0*"
118  * type (1), exposure, diameter, pos.x, pos.y, <rotation>
119  * <rotation> is a optional parameter: rotation from origin.
120  * type is not stored in parameters list, so the first parameter is exposure
121  */
122  ConvertShapeToPolygon( aParent, polybuffer );
123 
124  // shape rotation (if any):
125  if( params.size() >= 5 )
126  {
127  rotation = params[4].GetValue( tool ) * 10.0;
128 
129  if( rotation != 0)
130  {
131  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
132  RotatePoint( &polybuffer[ii], -rotation );
133  }
134  }
135 
136 
137  // Move to current position:
138  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
139  {
140  polybuffer[ii] += curPos;
141  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
142  }
143 
145  }
146  break;
147 
148  case AMP_LINE2:
149  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
150  {
151  /* Vector Line, Primitive Code 20.
152  * A vector line is a rectangle defined by its line width, start and end points.
153  * The line ends are rectangular.
154  */
155  /* Generated by an aperture macro declaration like:
156  * "2,1,0.3,0,0, 0.5, 1.0,-135*"
157  * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
158  * type is not stored in parameters list, so the first parameter is exposure
159  */
160  ConvertShapeToPolygon( aParent, polybuffer );
161 
162  // shape rotation:
163  rotation = params[6].GetValue( tool ) * 10.0;
164 
165  if( rotation != 0)
166  {
167  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
168  RotatePoint( &polybuffer[ii], -rotation );
169  }
170 
171  // Move to current position:
172  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
173  {
174  polybuffer[ii] += curPos;
175  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
176  }
177 
179  }
180  break;
181 
182  case AMP_LINE_CENTER:
183  {
184  /* Center Line, Primitive Code 21
185  * A center line primitive is a rectangle defined by its width, height, and center point
186  */
187  /* Generated by an aperture macro declaration like:
188  * "21,1,0.3,0.03,0,0,-135*"
189  * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
190  * type is not stored in parameters list, so the first parameter is exposure
191  */
192  ConvertShapeToPolygon( aParent, polybuffer );
193 
194  // shape rotation:
195  rotation = params[5].GetValue( tool ) * 10.0;
196 
197  if( rotation != 0 )
198  {
199  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
200  RotatePoint( &polybuffer[ii], -rotation );
201  }
202 
203  // Move to current position:
204  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
205  {
206  polybuffer[ii] += curPos;
207  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
208  }
209 
211  }
212  break;
213 
214  case AMP_LINE_LOWER_LEFT:
215  {
216  /* Generated by an aperture macro declaration like:
217  * "22,1,0.3,0.03,0,0,-135*"
218  * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
219  * type is not stored in parameters list, so the first parameter is exposure
220  */
221  ConvertShapeToPolygon( aParent, polybuffer );
222 
223  // shape rotation:
224  rotation = params[5].GetValue( tool ) * 10.0;
225  if( rotation != 0)
226  {
227  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
228  RotatePoint( &polybuffer[ii], -rotation );
229  }
230 
231  // Move to current position:
232  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
233  {
234  polybuffer[ii] += curPos;
235  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
236  }
237 
239  }
240  break;
241 
242  case AMP_THERMAL:
243  {
244  /* Generated by an aperture macro declaration like:
245  * "7, 0,0,1.0,0.3,0.01,-13*"
246  * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
247  * type is not stored in parameters list, so the first parameter is center.x
248  *
249  * The thermal primitive is a ring (annulus) interrupted by four gaps. Exposure is always on.
250  */
251  std::vector<wxPoint> subshape_poly;
252  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric );
253  ConvertShapeToPolygon( aParent, subshape_poly );
254 
255  // shape rotation:
256  rotation = params[5].GetValue( tool ) * 10.0;
257 
258  // Because a thermal shape has 4 identical sub-shapes, only one is created in subshape_poly.
259  // We must draw 4 sub-shapes rotated by 90 deg
260  for( int ii = 0; ii < 4; ii++ )
261  {
262  polybuffer = subshape_poly;
263  double sub_rotation = rotation + 900 * ii;
264 
265  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
266  RotatePoint( &polybuffer[jj], -sub_rotation );
267 
268  // Move to current position:
269  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
270  {
271  polybuffer[jj] += curPos;
272  polybuffer[jj] = aParent->GetABPosition( polybuffer[jj] );
273  }
274 
276  }
277  }
278  break;
279 
280  case AMP_MOIRE:
281  {
282  /* Moire, Primitive Code 6
283  * The moire primitive is a cross hair centered on concentric rings (annuli).
284  * Exposure is always on.
285  */
286  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
287  m_GerbMetric );
288 
289  /* Generated by an aperture macro declaration like:
290  * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
291  * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
292  * type is not stored in parameters list, so the first parameter is pos.x
293  */
294  int outerDiam = scaletoIU( params[2].GetValue( tool ), m_GerbMetric );
295  int penThickness = scaletoIU( params[3].GetValue( tool ), m_GerbMetric );
296  int gap = scaletoIU( params[4].GetValue( tool ), m_GerbMetric );
297  int numCircles = KiROUND( params[5].GetValue( tool ) );
298 
299  // Draw circles:
300  wxPoint center = aParent->GetABPosition( curPos );
301  // adjust outerDiam by this on each nested circle
302  int diamAdjust = (gap + penThickness) * 2;
303 
304  for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
305  {
306  if( outerDiam <= 0 )
307  break;
308 
309  // Note: outerDiam is the outer diameter of the ring.
310  // the ring graphic diameter is (outerDiam - penThickness)
311  if( outerDiam <= penThickness )
312  { // No room to draw a ring (no room for the hole):
313  // draw a circle instead (with no hole), with the right diameter
314  TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, ARC_HIGH_DEF,
315  ERROR_INSIDE );
316  }
317  else
318  {
319  TransformRingToPolygon( aShapeBuffer, center, ( outerDiam - penThickness ) / 2,
320  penThickness, ARC_HIGH_DEF, ERROR_INSIDE );
321  }
322  }
323 
324  // Draw the cross:
325  ConvertShapeToPolygon( aParent, polybuffer );
326 
327  rotation = params[8].GetValue( tool ) * 10.0;
328  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
329  {
330  // shape rotation:
331  RotatePoint( &polybuffer[ii], -rotation );
332  // Move to current position:
333  polybuffer[ii] += curPos;
334  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
335  }
336 
338  }
339  break;
340 
341  case AMP_OUTLINE:
342  {
343  /* Outline, Primitive Code 4
344  * An outline primitive is an area enclosed by an n-point polygon defined by its start point and n
345  * subsequent points. The outline must be closed, i.e. the last point must be equal to the start
346  * point. There must be at least one subsequent point (to close the outline).
347  * The outline of the primitive is actually the contour (see 2.6) that consists of linear segments
348  * only, so it must conform to all the requirements described for contours.
349  * Warning: Make no mistake: n is the number of subsequent points, being the number of
350  * vertices of the outline or one less than the number of coordinate pairs.
351  */
352  /* Generated by an aperture macro declaration like:
353  * "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
354  * type(4), exposure, corners count, corner1.x, corner.1y, ..., corner1.x, corner.1y, rotation
355  * type is not stored in parameters list, so the first parameter is exposure
356  */
357  // params[0] is the exposure and params[1] is the corners count after the first corner
358  int numCorners = (int) params[1].GetValue( tool );
359  // the shape rotation is the last param of list, after corners
360  int last_prm = params.size() - 1;
361  rotation = params[last_prm].GetValue( tool ) * 10.0;
362  wxPoint pos;
363 
364  // Read points.
365  // Note: numCorners is the polygon corner count, following the first corner
366  // * the polygon is always closed,
367  // * therefore the last XY coordinate is the same as the first
368  int prm_idx = 2; // params[2] is the first X coordinate
369 
370  for( int i = 0; i <= numCorners; ++i )
371  {
372  pos.x = scaletoIU( params[prm_idx].GetValue( tool ), m_GerbMetric );
373  prm_idx++;
374  pos.y = scaletoIU( params[prm_idx].GetValue( tool ), m_GerbMetric );
375  prm_idx++;
376  polybuffer.push_back(pos);
377 
378  // Guard: ensure prm_idx < last_prm
379  // I saw malformed gerber files with numCorners = number
380  // of coordinates instead of number of coordinates following the first point
381  if( prm_idx >= last_prm )
382  break;
383  }
384  // rotate polygon and move it to the actual position
385  // shape rotation:
386  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
387  {
388  RotatePoint( &polybuffer[ii], -rotation );
389  }
390 
391  // Move to current position:
392  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
393  {
394  polybuffer[ii] += curPos;
395  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
396  }
397 
399  }
400  break;
401 
402  case AMP_POLYGON:
403  /* Polygon, Primitive Code 5
404  * A polygon primitive is a regular polygon defined by the number of vertices n, the center point
405  * and the diameter of the circumscribed circle
406  */
407  /* Generated by an aperture macro declaration like:
408  * "5,1,0.6,0,0,0.5,25"
409  * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
410  * type is not stored in parameters list, so the first parameter is exposure
411  */
412  curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
413  // Creates the shape:
414  ConvertShapeToPolygon( aParent, polybuffer );
415 
416  // rotate polygon and move it to the actual position
417  rotation = params[5].GetValue( tool ) * 10.0;
418  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
419  {
420  RotatePoint( &polybuffer[ii], -rotation );
421  polybuffer[ii] += curPos;
422  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
423  }
424 
426 
427  break;
428 
429  case AMP_EOF:
430  // not yet supported, waiting for you.
431  break;
432 
433  case AMP_UNKNOWN:
434  default:
435  break;
436  }
437 }
bool m_GerbMetric
Definition: am_primitive.h:97
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
int scaletoIU(double aCoord, bool isMetric)
Function scaletoIU converts a distance given in floating point to our internal units.
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent, std::vector< wxPoint > &aBuffer)
Function ConvertShapeToPolygon convert a shape to an equivalent polygon.
wxPoint GetABPosition(const wxPoint &aXYPosition) const
Return the image position of aPosition for this object.
#define TO_POLY_SHAPE
static wxPoint mapPt(double x, double y, bool isMetric)
Function mapPt translates a point from the aperture macro coordinate system to our deci-mils coordina...
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aCornerBuffer, wxPoint aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines.
AM_PARAMS params
A sequence of parameters used by.
Definition: am_primitive.h:95
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segme...
AM_PRIMITIVE_ID primitive_id
The primitive type.
Definition: am_primitive.h:94

References AMP_CIRCLE, AMP_EOF, AMP_LINE2, AMP_LINE20, AMP_LINE_CENTER, AMP_LINE_LOWER_LEFT, AMP_MOIRE, AMP_OUTLINE, AMP_POLYGON, AMP_THERMAL, AMP_UNKNOWN, ConvertShapeToPolygon(), ERROR_INSIDE, GERBER_DRAW_ITEM::GetABPosition(), GERBER_DRAW_ITEM::GetDcodeDescr(), KiROUND(), m_GerbMetric, mapPt(), params, primitive_id, RotatePoint(), scaletoIU(), TO_POLY_SHAPE, TransformCircleToPolygon(), and TransformRingToPolygon().

◆ GetShapeDim()

int AM_PRIMITIVE::GetShapeDim ( const GERBER_DRAW_ITEM aParent)

GetShapeDim Calculate a value that can be used to evaluate the size of text when displaying the D-Code of an item due to the complexity of the shape of some primitives one cannot calculate the "size" of a shape (only a bounding box) but here, the "dimension" of the shape is the diameter of the primitive or for lines the width of the line.

GetShapeDim Calculate a value that can be used to evaluate the size of text when displaying the D-Code of an item due to the complexity of the shape of some primitives one cannot calculate the "size" of a shape (only abounding box) but here, the "dimension" of the shape is the diameter of the primitive or for lines the width of the line.

Parameters
aParent= the parent GERBER_DRAW_ITEM which is actually drawn
Returns
a dimension, or -1 if no dim to calculate

Definition at line 675 of file am_primitive.cpp.

676 {
677  int dim = -1;
678  D_CODE* tool = aParent->GetDcodeDescr();
679 
680  switch( primitive_id )
681  {
682  case AMP_CIRCLE:
683  // params = exposure, diameter, pos.x, pos.y
684  dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // Diameter
685  break;
686 
687  case AMP_LINE2:
688  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
689  dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // linne width
690  break;
691 
692  case AMP_LINE_CENTER:
693  {
694  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
695  dim = std::min(size.x, size.y);
696  }
697  break;
698 
699  case AMP_LINE_LOWER_LEFT:
700  {
701  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
702  dim = std::min(size.x, size.y);
703  }
704  break;
705 
706  case AMP_THERMAL:
707  {
708  // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
709  // rotated by 90, 180 and 270 deg.
710  // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
711  dim = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2; // Outer diam
712  }
713  break;
714 
715  case AMP_MOIRE: // A cross hair with n concentric circles.
716  dim = scaletoIU( params[7].GetValue( tool ), m_GerbMetric ); // = cross hair len
717  break;
718 
719  case AMP_OUTLINE: // a free polygon :
720  // dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
721  {
722  // exposure, corners count, corner1.x, corner.1y, ..., rotation
723  // note: corners count is the count of corners following corner1
724  int numPoints = (int) params[1].GetValue( tool );
725  // Read points. numPoints does not include the starting point, so add 1.
726  // and calculate the bounding box;
727  wxSize pos_min, pos_max, pos;
728  int prm_idx = 2; // params[2] is the first X coordinate
729  int last_prm = params.size() - 1;
730 
731  for( int i = 0; i<= numPoints; ++i )
732  {
733  pos.x = scaletoIU( params[prm_idx].GetValue( tool ), m_GerbMetric );
734  prm_idx++;
735  pos.y = scaletoIU( params[prm_idx].GetValue( tool ), m_GerbMetric );
736  prm_idx++;
737  if( i == 0 )
738  pos_min = pos_max = pos;
739  else
740  {
741  // upper right corner:
742  if( pos_min.x > pos.x )
743  pos_min.x = pos.x;
744  if( pos_min.y > pos.y )
745  pos_min.y = pos.y;
746  // lower left corner:
747  if( pos_max.x < pos.x )
748  pos_max.x = pos.x;
749  if( pos_max.y < pos.y )
750  pos_max.y = pos.y;
751  }
752 
753  // Guard: ensure prm_idx < last_prm (last prm is orientation)
754  // I saw malformed gerber files with numCorners = number
755  // of coordinates instead of number of coordinates following the first point
756  if( prm_idx >= last_prm )
757  break;
758  }
759  // calculate dim
760  wxSize size;
761  size.x = pos_max.x - pos_min.x;
762  size.y = pos_max.y - pos_min.y;
763  dim = std::min( size.x, size.y );
764  }
765  break;
766 
767  case AMP_POLYGON: // Regular polygon
768  dim = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2; // Radius
769  break;
770 
771  case AMP_COMMENT:
772  case AMP_UNKNOWN:
773  case AMP_EOF:
774  break;
775  }
776  return dim;
777 }
bool m_GerbMetric
Definition: am_primitive.h:97
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
int scaletoIU(double aCoord, bool isMetric)
Function scaletoIU converts a distance given in floating point to our internal units.
static wxPoint mapPt(double x, double y, bool isMetric)
Function mapPt translates a point from the aperture macro coordinate system to our deci-mils coordina...
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
AM_PARAMS params
A sequence of parameters used by.
Definition: am_primitive.h:95
AM_PRIMITIVE_ID primitive_id
The primitive type.
Definition: am_primitive.h:94

References AMP_CIRCLE, AMP_COMMENT, AMP_EOF, AMP_LINE2, AMP_LINE20, AMP_LINE_CENTER, AMP_LINE_LOWER_LEFT, AMP_MOIRE, AMP_OUTLINE, AMP_POLYGON, AMP_THERMAL, AMP_UNKNOWN, GERBER_DRAW_ITEM::GetDcodeDescr(), m_GerbMetric, mapPt(), params, primitive_id, and scaletoIU().

◆ IsAMPrimitiveExposureOn()

bool AM_PRIMITIVE::IsAMPrimitiveExposureOn ( const GERBER_DRAW_ITEM aParent) const

Function IsAMPrimitiveExposureOn.

Returns
true if the first parameter is not 0 (it can be only 0 or 1). Some but not all primitives use the first parameter as an exposure control. Others are always ON. In a aperture macro shape, a basic primitive with exposure off is a hole in the shape it is NOT a negative shape

Definition at line 59 of file am_primitive.cpp.

60 {
61  /*
62  * Some but not all primitives use the first parameter as an exposure control.
63  * Others are always ON.
64  * In a aperture macro shape, a basic primitive with exposure off is a hole in the shape
65  * it is NOT a negative shape
66  */
67  wxASSERT( params.size() );
68 
69  switch( primitive_id )
70  {
71  case AMP_CIRCLE:
72  case AMP_LINE2:
73  case AMP_LINE20:
74  case AMP_LINE_CENTER:
76  case AMP_OUTLINE:
77  case AMP_POLYGON:
78  // All have an exposure parameter and can return a value (0 or 1)
79  return params[0].GetValue( aParent->GetDcodeDescr() ) != 0;
80  break;
81 
82  case AMP_THERMAL: // Exposure is always on
83  case AMP_MOIRE: // Exposure is always on
84  case AMP_EOF:
85  case AMP_UNKNOWN:
86  default:
87  return 1; // All have no exposure parameter and are always 0N return true
88  break;
89  }
90 }
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
AM_PARAMS params
A sequence of parameters used by.
Definition: am_primitive.h:95
AM_PRIMITIVE_ID primitive_id
The primitive type.
Definition: am_primitive.h:94

References AMP_CIRCLE, AMP_EOF, AMP_LINE2, AMP_LINE20, AMP_LINE_CENTER, AMP_LINE_LOWER_LEFT, AMP_MOIRE, AMP_OUTLINE, AMP_POLYGON, AMP_THERMAL, AMP_UNKNOWN, GERBER_DRAW_ITEM::GetDcodeDescr(), params, and primitive_id.

Member Data Documentation

◆ m_GerbMetric

bool AM_PRIMITIVE::m_GerbMetric

Definition at line 97 of file am_primitive.h.

Referenced by AM_PRIMITIVE(), ConvertShapeToPolygon(), DrawBasicShape(), and GetShapeDim().

◆ params

AM_PARAMS AM_PRIMITIVE::params

A sequence of parameters used by.

Definition at line 95 of file am_primitive.h.

Referenced by ConvertShapeToPolygon(), DrawBasicShape(), GetShapeDim(), IsAMPrimitiveExposureOn(), and GERBER_FILE_IMAGE::ReadApertureMacro().

◆ primitive_id

AM_PRIMITIVE_ID AM_PRIMITIVE::primitive_id

The documentation for this class was generated from the following files: