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 (GERBER_DRAW_ITEM *aParent) const
 Function IsAMPrimitiveExposureOn. More...
 
int GetShapeDim (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 (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 (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 class_aperture_macro.h.

Constructor & Destructor Documentation

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

Definition at line 99 of file class_aperture_macro.h.

99  : AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
100  {
101  primitive_id = aId;
102  m_GerbMetric = aGerbMetric;
103  }
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 106 of file class_aperture_macro.h.

106 {}

Member Function Documentation

void AM_PRIMITIVE::ConvertShapeToPolygon ( 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 435 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().

437 {
438  D_CODE* tool = aParent->GetDcodeDescr();
439 
440  switch( primitive_id )
441  {
442  case AMP_CIRCLE:
443  {
444  /* Generated by an aperture macro declaration like:
445  * "1,1,0.3,0.5, 1.0*"
446  * type (1), exposure, diameter, pos.x, pos.y, <rotation>
447  * <rotation> is a optional parameter: rotation from origin.
448  * type is not stored in parameters list, so the first parameter is exposure
449  */
450  wxPoint center = mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
451  int radius = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ) / 2;
452  wxPoint corner;
453  const int delta = 3600 / seg_per_circle; // rot angle in 0.1 degree
454 
455  for( int angle = 0; angle < 3600; angle += delta )
456  {
457  corner.x = radius;
458  corner.y = 0;
459  RotatePoint( &corner, angle );
460  corner += center;
461  aBuffer.push_back( corner );
462  }
463  }
464  break;
465 
466  case AMP_LINE2:
467  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
468  {
469  int width = scaletoIU( params[1].GetValue( tool ), m_GerbMetric );
470  wxPoint start = mapPt( params[2].GetValue( tool ),
471  params[3].GetValue( tool ), m_GerbMetric );
472  wxPoint end = mapPt( params[4].GetValue( tool ),
473  params[5].GetValue( tool ), m_GerbMetric );
474  wxPoint delta = end - start;
475  int len = KiROUND( EuclideanNorm( delta ) );
476 
477  // To build the polygon, we must create a horizontal polygon starting to "start"
478  // and rotate it to have the end point to "end"
479  wxPoint currpt;
480  currpt.y += width / 2; // Upper left
481  aBuffer.push_back( currpt );
482  currpt.x = len; // Upper right
483  aBuffer.push_back( currpt );
484  currpt.y -= width; // lower right
485  aBuffer.push_back( currpt );
486  currpt.x = 0; // lower left
487  aBuffer.push_back( currpt );
488 
489  // Rotate rectangle and move it to the actual start point
490  double angle = ArcTangente( delta.y, delta.x );
491 
492  for( unsigned ii = 0; ii < 4; ii++ )
493  {
494  RotatePoint( &aBuffer[ii], -angle );
495  aBuffer[ii] += start;
496  }
497  }
498  break;
499 
500  case AMP_LINE_CENTER:
501  {
502  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
503  wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), m_GerbMetric );
504 
505  // Build poly:
506  pos.x -= size.x / 2;
507  pos.y -= size.y / 2; // Lower left
508  aBuffer.push_back( pos );
509  pos.y += size.y; // Upper left
510  aBuffer.push_back( pos );
511  pos.x += size.x; // Upper right
512  aBuffer.push_back( pos );
513  pos.y -= size.y; // lower right
514  aBuffer.push_back( pos );
515  }
516  break;
517 
518  case AMP_LINE_LOWER_LEFT:
519  {
520  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
521  wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
522  tool ), m_GerbMetric );
523 
524  // Build poly:
525  aBuffer.push_back( lowerLeft );
526  lowerLeft.y += size.y; // Upper left
527  aBuffer.push_back( lowerLeft );
528  lowerLeft.x += size.x; // Upper right
529  aBuffer.push_back( lowerLeft );
530  lowerLeft.y -= size.y; // lower right
531  aBuffer.push_back( lowerLeft );
532  }
533  break;
534 
535  case AMP_THERMAL:
536  {
537  // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
538  // rotated by 90, 180 and 270 deg.
539  // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
540  int outerRadius = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2;
541  int innerRadius = scaletoIU( params[3].GetValue( tool ), m_GerbMetric ) / 2;
542  int halfthickness = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
543  double angle_start = RAD2DECIDEG( asin( (double) halfthickness / innerRadius ) );
544 
545  // Draw shape in the first cadrant (X and Y > 0)
546  wxPoint pos, startpos;
547 
548  // Inner arc
549  startpos.x = innerRadius;
550  double angle_end = 900 - angle_start;
551  for( double angle = angle_start; angle < angle_end; angle += 100 )
552  {
553  pos = startpos;
554  RotatePoint( &pos, angle );
555  aBuffer.push_back( pos );
556  }
557 
558  // Last point
559  pos = startpos;
560  RotatePoint( &pos, angle_end );
561  aBuffer.push_back( pos );
562 
563  // outer arc
564  startpos.x = outerRadius;
565  startpos.y = 0;
566  angle_start = RAD2DECIDEG( asin( (double) halfthickness / outerRadius ) );
567  angle_end = 900 - angle_start;
568 
569  // First point, near Y axis, outer arc
570  for( double angle = angle_end; angle > angle_start; angle -= 100 )
571  {
572  pos = startpos;
573  RotatePoint( &pos, angle );
574  aBuffer.push_back( pos );
575  }
576 
577  // last point
578  pos = startpos;
579  RotatePoint( &pos, angle_start );
580  aBuffer.push_back( pos );
581 
582  aBuffer.push_back( aBuffer[0] ); // Close poly
583  }
584  break;
585 
586  case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon
587  // because circles can be drawn easily
588  {
589  int crossHairThickness = scaletoIU( params[6].GetValue( tool ), m_GerbMetric );
590  int crossHairLength = scaletoIU( params[7].GetValue( tool ), m_GerbMetric );
591 
592  // Create cross. First create 1/4 of the shape.
593  // Others point are the same, totated by 90, 180 and 270 deg
594  wxPoint pos( crossHairThickness / 2, crossHairLength / 2 );
595  aBuffer.push_back( pos );
596  pos.y = crossHairThickness / 2;
597  aBuffer.push_back( pos );
598  pos.x = -crossHairLength / 2;
599  aBuffer.push_back( pos );
600  pos.y = -crossHairThickness / 2;
601  aBuffer.push_back( pos );
602 
603  // Copy the 4 shape, rotated by 90, 180 and 270 deg
604  for( int jj = 1; jj <= 3; jj ++ )
605  {
606  for( int ii = 0; ii < 4; ii++ )
607  {
608  pos = aBuffer[ii];
609  RotatePoint( &pos, jj*900 );
610  aBuffer.push_back( pos );
611  }
612  }
613  }
614  break;
615 
616  case AMP_OUTLINE:
617  // already is a polygon. Do nothing
618  break;
619 
620  case AMP_POLYGON: // Creates a regular polygon
621  {
622  int vertexcount = KiROUND( params[1].GetValue( tool ) );
623  int radius = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
624  // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
625  if( vertexcount < 3 )
626  vertexcount = 3;
627  if( vertexcount > 10 )
628  vertexcount = 10;
629  for( int ii = 0; ii <= vertexcount; ii++ )
630  {
631  wxPoint pos( radius, 0);
632  RotatePoint( &pos, ii * 3600 / vertexcount );
633  aBuffer.push_back( pos );
634  }
635  }
636  break;
637 
638  case AMP_COMMENT:
639  case AMP_UNKNOWN:
640  case AMP_EOF:
641  break;
642  }
643 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:104
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
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()
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
double RAD2DECIDEG(double rad)
Definition: trigo.h:196
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
static const int delta[8][2]
Definition: solve.cpp:112
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:81
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 ( 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 
105  // Draw the primitive shape for flashed items.
106  static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
107  polybuffer.clear();
108 
109  wxPoint curPos = aShapePos;
110  D_CODE* tool = aParent->GetDcodeDescr();
111  double rotation;
112 
113  switch( primitive_id )
114  {
115  case AMP_CIRCLE: // Circle, given diameter and position
116  {
117  /* Generated by an aperture macro declaration like:
118  * "1,1,0.3,0.5, 1.0*"
119  * type (1), exposure, diameter, pos.x, pos.y, <rotation>
120  * <rotation> is a optional parameter: rotation from origin.
121  * type is not stored in parameters list, so the first parameter is exposure
122  */
123  ConvertShapeToPolygon( aParent, polybuffer );
124 
125  // shape rotation (if any):
126  if( params.size() >= 5 )
127  {
128  rotation = params[4].GetValue( tool ) * 10.0;
129 
130  if( rotation != 0)
131  {
132  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
133  RotatePoint( &polybuffer[ii], -rotation );
134  }
135  }
136 
137 
138  // Move to current position:
139  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
140  {
141  polybuffer[ii] += curPos;
142  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
143  }
144 
146  }
147  break;
148 
149  case AMP_LINE2:
150  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
151  {
152  /* Vector Line, Primitive Code 20.
153  * A vector line is a rectangle defined by its line width, start and end points.
154  * The line ends are rectangular.
155  */
156  /* Generated by an aperture macro declaration like:
157  * "2,1,0.3,0,0, 0.5, 1.0,-135*"
158  * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
159  * type is not stored in parameters list, so the first parameter is exposure
160  */
161  ConvertShapeToPolygon( aParent, polybuffer );
162 
163  // shape rotation:
164  rotation = params[6].GetValue( tool ) * 10.0;
165 
166  if( rotation != 0)
167  {
168  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
169  RotatePoint( &polybuffer[ii], -rotation );
170  }
171 
172  // Move to current position:
173  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
174  {
175  polybuffer[ii] += curPos;
176  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
177  }
178 
180  }
181  break;
182 
183  case AMP_LINE_CENTER:
184  {
185  /* Center Line, Primitive Code 21
186  * A center line primitive is a rectangle defined by its width, height, and center point
187  */
188  /* Generated by an aperture macro declaration like:
189  * "21,1,0.3,0.03,0,0,-135*"
190  * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
191  * type is not stored in parameters list, so the first parameter is exposure
192  */
193  ConvertShapeToPolygon( aParent, polybuffer );
194 
195  // shape rotation:
196  rotation = params[5].GetValue( tool ) * 10.0;
197 
198  if( rotation != 0 )
199  {
200  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
201  RotatePoint( &polybuffer[ii], -rotation );
202  }
203 
204  // Move to current position:
205  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
206  {
207  polybuffer[ii] += curPos;
208  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
209  }
210 
212  }
213  break;
214 
215  case AMP_LINE_LOWER_LEFT:
216  {
217  /* Generated by an aperture macro declaration like:
218  * "22,1,0.3,0.03,0,0,-135*"
219  * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
220  * type is not stored in parameters list, so the first parameter is exposure
221  */
222  ConvertShapeToPolygon( aParent, polybuffer );
223 
224  // shape rotation:
225  rotation = params[5].GetValue( tool ) * 10.0;
226  if( rotation != 0)
227  {
228  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
229  RotatePoint( &polybuffer[ii], -rotation );
230  }
231 
232  // Move to current position:
233  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
234  {
235  polybuffer[ii] += curPos;
236  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
237  }
238 
240  }
241  break;
242 
243  case AMP_THERMAL:
244  {
245  /* Generated by an aperture macro declaration like:
246  * "7, 0,0,1.0,0.3,0.01,-13*"
247  * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
248  * type is not stored in parameters list, so the first parameter is center.x
249  *
250  * The thermal primitive is a ring (annulus) interrupted by four gaps. Exposure is always on.
251  */
252  std::vector<wxPoint> subshape_poly;
253  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric );
254  ConvertShapeToPolygon( aParent, subshape_poly );
255 
256  // shape rotation:
257  rotation = params[5].GetValue( tool ) * 10.0;
258 
259  // Because a thermal shape has 4 identical sub-shapes, only one is created in subshape_poly.
260  // We must draw 4 sub-shapes rotated by 90 deg
261  for( int ii = 0; ii < 4; ii++ )
262  {
263  polybuffer = subshape_poly;
264  double sub_rotation = rotation + 900 * ii;
265 
266  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
267  RotatePoint( &polybuffer[jj], -sub_rotation );
268 
269  // Move to current position:
270  for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
271  {
272  polybuffer[jj] += curPos;
273  polybuffer[jj] = aParent->GetABPosition( polybuffer[jj] );
274  }
275 
277  }
278  }
279  break;
280 
281  case AMP_MOIRE:
282  {
283  /* Moiré, Primitive Code 6
284  * The moiré primitive is a cross hair centered on concentric rings (annuli).
285  * Exposure is always on.
286  */
287  curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
288  m_GerbMetric );
289 
290  /* Generated by an aperture macro declaration like:
291  * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
292  * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
293  * type is not stored in parameters list, so the first parameter is pos.x
294  */
295  int outerDiam = scaletoIU( params[2].GetValue( tool ), m_GerbMetric );
296  int penThickness = scaletoIU( params[3].GetValue( tool ), m_GerbMetric );
297  int gap = scaletoIU( params[4].GetValue( tool ), m_GerbMetric );
298  int numCircles = KiROUND( params[5].GetValue( tool ) );
299 
300  // Draw circles:
301  wxPoint center = aParent->GetABPosition( curPos );
302  // adjust outerDiam by this on each nested circle
303  int diamAdjust = (gap + penThickness) * 2;
304 
305  for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
306  {
307  if( outerDiam <= 0 )
308  break;
309 
310  // Note: outerDiam is the outer diameter of the ring.
311  // the ring graphic diameter is (outerDiam - penThickness)
312  if( outerDiam <= penThickness )
313  { // No room to draw a ring (no room for the hole):
314  // draw a circle instead (with no hole), with the right diameter
315  TransformCircleToPolygon( aShapeBuffer, center,
316  outerDiam / 2, seg_per_circle );
317  }
318  else
319  TransformRingToPolygon( aShapeBuffer, center,
320  (outerDiam - penThickness) / 2,
321  seg_per_circle, penThickness );
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, ..., rotation
355  * type is not stored in parameters list, so the first parameter is exposure
356  */
357  int numPoints = (int) params[1].GetValue( tool );
358  rotation = params[numPoints * 2 + 4].GetValue( tool ) * 10.0;
359  wxPoint pos;
360  // Read points. numPoints does not include the starting point, so add 1.
361  for( int i = 0; i<numPoints + 1; ++i )
362  {
363  int jj = i * 2 + 2;
364  pos.x = scaletoIU( params[jj].GetValue( tool ), m_GerbMetric );
365  pos.y = scaletoIU( params[jj + 1].GetValue( tool ), m_GerbMetric );
366  polybuffer.push_back(pos);
367  }
368  // rotate polygon and move it to the actual position
369  // shape rotation:
370  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
371  {
372  RotatePoint( &polybuffer[ii], -rotation );
373  }
374 
375  // Move to current position:
376  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
377  {
378  polybuffer[ii] += curPos;
379  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
380  }
381 
383  }
384  break;
385 
386  case AMP_POLYGON:
387  /* Polygon, Primitive Code 5
388  * A polygon primitive is a regular polygon defined by the number of vertices n, the center point
389  * and the diameter of the circumscribed circle
390  */
391  /* Generated by an aperture macro declaration like:
392  * "5,1,0.6,0,0,0.5,25"
393  * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
394  * type is not stored in parameters list, so the first parameter is exposure
395  */
396  curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
397  // Creates the shape:
398  ConvertShapeToPolygon( aParent, polybuffer );
399 
400  // rotate polygon and move it to the actual position
401  rotation = params[5].GetValue( tool ) * 10.0;
402  for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
403  {
404  RotatePoint( &polybuffer[ii], -rotation );
405  polybuffer[ii] += curPos;
406  polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
407  }
408 
410 
411  break;
412 
413  case AMP_EOF:
414  // not yet supported, waiting for you.
415  break;
416 
417  case AMP_UNKNOWN:
418  default:
419  DBG( printf( "AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d\n",primitive_id) );
420  break;
421  }
422 }
#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:107
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()
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
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
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...
void ConvertShapeToPolygon(GERBER_DRAW_ITEM *aParent, std::vector< wxPoint > &aBuffer)
Function ConvertShapeToPolygon convert a shape to an equivalent polygon.
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:81
#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 ( 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 655 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.

656 {
657  int dim = -1;
658  D_CODE* tool = aParent->GetDcodeDescr();
659 
660  switch( primitive_id )
661  {
662  case AMP_CIRCLE:
663  // params = exposure, diameter, pos.x, pos.y
664  dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // Diameter
665  break;
666 
667  case AMP_LINE2:
668  case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
669  dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // linne width
670  break;
671 
672  case AMP_LINE_CENTER:
673  {
674  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
675  dim = std::min(size.x, size.y);
676  }
677  break;
678 
679  case AMP_LINE_LOWER_LEFT:
680  {
681  wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
682  dim = std::min(size.x, size.y);
683  }
684  break;
685 
686  case AMP_THERMAL:
687  {
688  // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
689  // rotated by 90, 180 and 270 deg.
690  // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
691  dim = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2; // Outer diam
692  }
693  break;
694 
695  case AMP_MOIRE: // A cross hair with n concentric circles.
696  dim = scaletoIU( params[7].GetValue( tool ), m_GerbMetric ); // = cross hair len
697  break;
698 
699  case AMP_OUTLINE: // a free polygon :
700  // dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
701  {
702  // exposure, corners count, corner1.x, corner.1y, ..., rotation
703  int numPoints = (int) params[1].GetValue( tool );
704  // Read points. numPoints does not include the starting point, so add 1.
705  // and calculate the bounding box;
706  wxSize pos_min, pos_max, pos;
707  for( int i = 0; i<numPoints + 1; ++i )
708  {
709  int jj = i * 2 + 2;
710  pos.x = scaletoIU( params[jj].GetValue( tool ), m_GerbMetric );
711  pos.y = scaletoIU( params[jj + 1].GetValue( tool ), m_GerbMetric );
712  if( i == 0 )
713  pos_min = pos_max = pos;
714  else
715  {
716  // upper right corner:
717  if( pos_min.x > pos.x )
718  pos_min.x = pos.x;
719  if( pos_min.y > pos.y )
720  pos_min.y = pos.y;
721  // lower left corner:
722  if( pos_max.x < pos.x )
723  pos_max.x = pos.x;
724  if( pos_max.y < pos.y )
725  pos_max.y = pos.y;
726  }
727  }
728  // calculate dim
729  wxSize size;
730  size.x = pos_max.x - pos_min.x;
731  size.y = pos_max.y - pos_min.y;
732  dim = std::min( size.x, size.y );
733  }
734  break;
735 
736  case AMP_POLYGON: // Regular polygon
737  dim = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2; // Radius
738  break;
739 
740  case AMP_COMMENT:
741  case AMP_UNKNOWN:
742  case AMP_EOF:
743  break;
744  }
745  return dim;
746 }
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()
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:81
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 ( 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()
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 97 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 95 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: