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 <class_aperture_macro.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 92 of file class_aperture_macro.h.

Constructor & Destructor Documentation

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

Definition at line 100 of file class_aperture_macro.h.

100  : AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
101  {
102  primitive_id = aId;
103  m_GerbMetric = aGerbMetric;
104  }
AM_PRIMITIVE_ID
Enum AM_PRIMITIVE_ID is the set of all "aperture macro primitives" (primitive numbers).
AM_PRIMITIVE(bool aGerbMetric, AM_PRIMITIVE_ID aId=AMP_UNKNOWN)
AM_PRIMITIVE_ID primitive_id
The primitive type.
AM_PRIMITIVE::~AM_PRIMITIVE ( )
inline

Definition at line 107 of file class_aperture_macro.h.

107 {}

Member Function Documentation

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 451 of file class_aperture_macro.cpp.

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(), delta, EuclideanNorm(), GERBER_DRAW_ITEM::GetDcodeDescr(), KiROUND(), m_GerbMetric, mapPt(), params, primitive_id, RAD2DECIDEG(), RotatePoint(), scaletoIU(), seg_per_circle, wxPoint::x, and wxPoint::y.

Referenced by DrawBasicShape().

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

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(), DBG, GERBER_DRAW_ITEM::GetABPosition(), GERBER_DRAW_ITEM::GetDcodeDescr(), KiROUND(), m_GerbMetric, mapPt(), params, primitive_id, RotatePoint(), scaletoIU(), seg_per_circle, TO_POLY_SHAPE, TransformCircleToPolygon(), TransformRingToPolygon(), wxPoint::x, and wxPoint::y.

100 {
101  #define TO_POLY_SHAPE { aShapeBuffer.NewOutline(); \
102  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )\
103  aShapeBuffer.Append( polybuffer[jj].x, polybuffer[jj].y );\
104  aShapeBuffer.Append( polybuffer[0].x, polybuffer[0].y );}
105 
106  // Draw the primitive shape for flashed items.
107  static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
108  polybuffer.clear();
109 
110  wxPoint curPos = aShapePos;
111  D_CODE* tool = aParent->GetDcodeDescr();
112  double rotation;
113 
114  switch( primitive_id )
115  {
116  case AMP_CIRCLE: // Circle, given diameter and position
117  {
118  /* Generated by an aperture macro declaration like:
119  * "1,1,0.3,0.5, 1.0*"
120  * type (1), exposure, diameter, pos.x, pos.y, <rotation>
121  * <rotation> is a optional parameter: rotation from origin.
122  * type is not stored in parameters list, so the first parameter is exposure
123  */
124  ConvertShapeToPolygon( aParent, polybuffer );
125 
126  // shape rotation (if any):
127  if( params.size() >= 5 )
128  {
129  rotation = params[4].GetValue( tool ) * 10.0;
130 
131  if( rotation != 0)
132  {
133  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
134  RotatePoint( &polybuffer[ii], -rotation );
135  }
136  }
137 
138 
139  // Move to current position:
140  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
141  {
142  polybuffer[ii] += curPos;
143  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
144  }
145 
147  }
148  break;
149 
150  case AMP_LINE2:
151  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
152  {
153  /* Vector Line, Primitive Code 20.
154  * A vector line is a rectangle defined by its line width, start and end points.
155  * The line ends are rectangular.
156  */
157  /* Generated by an aperture macro declaration like:
158  * "2,1,0.3,0,0, 0.5, 1.0,-135*"
159  * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
160  * type is not stored in parameters list, so the first parameter is exposure
161  */
162  ConvertShapeToPolygon( aParent, polybuffer );
163 
164  // shape rotation:
165  rotation = params[6].GetValue( tool ) * 10.0;
166 
167  if( rotation != 0)
168  {
169  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
170  RotatePoint( &polybuffer[ii], -rotation );
171  }
172 
173  // Move to current position:
174  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
175  {
176  polybuffer[ii] += curPos;
177  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
178  }
179 
181  }
182  break;
183 
184  case AMP_LINE_CENTER:
185  {
186  /* Center Line, Primitive Code 21
187  * A center line primitive is a rectangle defined by its width, height, and center point
188  */
189  /* Generated by an aperture macro declaration like:
190  * "21,1,0.3,0.03,0,0,-135*"
191  * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
192  * type is not stored in parameters list, so the first parameter is exposure
193  */
194  ConvertShapeToPolygon( aParent, polybuffer );
195 
196  // shape rotation:
197  rotation = params[5].GetValue( tool ) * 10.0;
198 
199  if( rotation != 0 )
200  {
201  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
202  RotatePoint( &polybuffer[ii], -rotation );
203  }
204 
205  // Move to current position:
206  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
207  {
208  polybuffer[ii] += curPos;
209  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
210  }
211 
213  }
214  break;
215 
216  case AMP_LINE_LOWER_LEFT:
217  {
218  /* Generated by an aperture macro declaration like:
219  * "22,1,0.3,0.03,0,0,-135*"
220  * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
221  * type is not stored in parameters list, so the first parameter is exposure
222  */
223  ConvertShapeToPolygon( aParent, polybuffer );
224 
225  // shape rotation:
226  rotation = params[5].GetValue( tool ) * 10.0;
227  if( rotation != 0)
228  {
229  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
230  RotatePoint( &polybuffer[ii], -rotation );
231  }
232 
233  // Move to current position:
234  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
235  {
236  polybuffer[ii] += curPos;
237  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
238  }
239 
241  }
242  break;
243 
244  case AMP_THERMAL:
245  {
246  /* Generated by an aperture macro declaration like:
247  * "7, 0,0,1.0,0.3,0.01,-13*"
248  * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
249  * type is not stored in parameters list, so the first parameter is center.x
250  *
251  * The thermal primitive is a ring (annulus) interrupted by four gaps. Exposure is always on.
252  */
253  std::vector<wxPoint> subshape_poly;
254  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric );
255  ConvertShapeToPolygon( aParent, subshape_poly );
256 
257  // shape rotation:
258  rotation = params[5].GetValue( tool ) * 10.0;
259 
260  // Because a thermal shape has 4 identical sub-shapes, only one is created in subshape_poly.
261  // We must draw 4 sub-shapes rotated by 90 deg
262  for( int ii = 0; ii < 4; ii++ )
263  {
264  polybuffer = subshape_poly;
265  double sub_rotation = rotation + 900 * ii;
266 
267  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
268  RotatePoint( &polybuffer[jj], -sub_rotation );
269 
270  // Move to current position:
271  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
272  {
273  polybuffer[jj] += curPos;
274  polybuffer[jj] = aParent->GetABPosition( polybuffer[jj] );
275  }
276 
278  }
279  }
280  break;
281 
282  case AMP_MOIRE:
283  {
284  /* Moiré, Primitive Code 6
285  * The moiré primitive is a cross hair centered on concentric rings (annuli).
286  * Exposure is always on.
287  */
288  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
289  m_GerbMetric );
290 
291  /* Generated by an aperture macro declaration like:
292  * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
293  * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
294  * type is not stored in parameters list, so the first parameter is pos.x
295  */
296  int outerDiam = scaletoIU( params[2].GetValue( tool ), m_GerbMetric );
297  int penThickness = scaletoIU( params[3].GetValue( tool ), m_GerbMetric );
298  int gap = scaletoIU( params[4].GetValue( tool ), m_GerbMetric );
299  int numCircles = KiROUND( params[5].GetValue( tool ) );
300 
301  // Draw circles:
302  wxPoint center = aParent->GetABPosition( curPos );
303  // adjust outerDiam by this on each nested circle
304  int diamAdjust = (gap + penThickness) * 2;
305 
306  for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
307  {
308  if( outerDiam <= 0 )
309  break;
310 
311  // Note: outerDiam is the outer diameter of the ring.
312  // the ring graphic diameter is (outerDiam - penThickness)
313  if( outerDiam <= penThickness )
314  { // No room to draw a ring (no room for the hole):
315  // draw a circle instead (with no hole), with the right diameter
316  TransformCircleToPolygon( aShapeBuffer, center,
317  outerDiam / 2, seg_per_circle );
318  }
319  else
320  TransformRingToPolygon( aShapeBuffer, center,
321  (outerDiam - penThickness) / 2,
322  seg_per_circle, penThickness );
323  }
324 
325  // Draw the cross:
326  ConvertShapeToPolygon( aParent, polybuffer );
327 
328  rotation = params[8].GetValue( tool ) * 10.0;
329  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
330  {
331  // shape rotation:
332  RotatePoint( &polybuffer[ii], -rotation );
333  // Move to current position:
334  polybuffer[ii] += curPos;
335  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
336  }
337 
339  }
340  break;
341 
342  case AMP_OUTLINE:
343  {
344  /* Outline, Primitive Code 4
345  * An outline primitive is an area enclosed by an n-point polygon defined by its start point and n
346  * subsequent points. The outline must be closed, i.e. the last point must be equal to the start
347  * point. There must be at least one subsequent point (to close the outline).
348  * The outline of the primitive is actually the contour (see 2.6) that consists of linear segments
349  * only, so it must conform to all the requirements described for contours.
350  * Warning: Make no mistake: n is the number of subsequent points, being the number of
351  * vertices of the outline or one less than the number of coordinate pairs.
352  */
353  /* Generated by an aperture macro declaration like:
354  * "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
355  * type(4), exposure, corners count, corner1.x, corner.1y, ..., corner1.x, corner.1y, rotation
356  * type is not stored in parameters list, so the first parameter is exposure
357  */
358  // params[0] is the exposure and params[1] is the corners count after the first corner
359  int numCorners = (int) params[1].GetValue( tool );
360  // the shape rotation is the last param of list, after corners
361  int last_prm = params.size() - 1;
362  rotation = params[last_prm].GetValue( tool ) * 10.0;
363  wxPoint pos;
364 
365  // Read points.
366  // Note: numCorners is the polygon corner count, following the first corner
367  // * the polygon is always closed,
368  // * therefore the last XY coordinate is the same as the first
369  int prm_idx = 2; // params[2] is the first X coordinate
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  DBG( printf( "AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d\n",primitive_id) );
436  break;
437  }
438 }
#define TO_POLY_SHAPE
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:106
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...
void TransformCircleToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines...
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
D_CODE * GetDcodeDescr() const
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent, std::vector< wxPoint > &aBuffer)
Function ConvertShapeToPolygon convert a shape to an equivalent polygon.
const int seg_per_circle
int scaletoIU(double aCoord, bool isMetric)
Function scaletoIU converts a distance given in floating point to our internal units.
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aCircleToSegmentsCount, int aWidth)
Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segme...
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
#define DBG(x)
Definition: fctsys.h:33
wxPoint GetABPosition(const wxPoint &aXYPosition) const
Function GetABPosition returns the image position of aPosition for this object.
AM_PARAMS params
A sequence of parameters used by.
AM_PRIMITIVE_ID primitive_id
The primitive type.
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 671 of file class_aperture_macro.cpp.

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(), min, params, primitive_id, scaletoIU(), wxPoint::x, and wxPoint::y.

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

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.

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

Member Data Documentation

bool AM_PRIMITIVE::m_GerbMetric

Definition at line 98 of file class_aperture_macro.h.

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

AM_PARAMS AM_PRIMITIVE::params

A sequence of parameters used by.

Definition at line 96 of file class_aperture_macro.h.

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

AM_PRIMITIVE_ID AM_PRIMITIVE::primitive_id

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