KiCad PCB EDA Suite
Loading...
Searching...
No Matches
am_primitive.cpp
Go to the documentation of this file.
1
4
5/*
6 * This program source code file is part of KiCad, a free EDA CAD application.
7 *
8 * Copyright (C) 1992-2017 Jean-Pierre Charras <jp.charras at wanadoo.fr>
9 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
10 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26#include <trigo.h>
28#include <math/util.h> // for KiROUND
29
30#include <gerbview.h>
31#include <gerber_file_image.h>
32
33
37extern int scaletoIU( double aCoord, bool isMetric );
38
39
46static VECTOR2I mapPt( double x, double y, bool isMetric )
47{
48 VECTOR2I ret( scaletoIU( x, isMetric ), scaletoIU( y, isMetric ) );
49
50 return ret;
51}
52
53
55{
56 /*
57 * Some but not all primitives use the first parameter as an exposure control.
58 * Others are always ON.
59 * In a aperture macro shape, a basic primitive with exposure off is a hole in the shape
60 * it is NOT a negative shape
61 */
62 wxASSERT( m_Params.size() );
63
64 switch( m_Primitive_id )
65 {
66 case AMP_CIRCLE:
67 case AMP_LINE2:
68 case AMP_LINE20:
69 case AMP_LINE_CENTER:
71 case AMP_OUTLINE:
72 case AMP_POLYGON:
73 // All have an exposure parameter and can return a value (0 or 1)
74 return m_Params[0].GetValueFromMacro( aApertMacro ) != 0;
75 break;
76
77 case AMP_THERMAL: // Exposure is always on
78 case AMP_MOIRE: // Exposure is always on
79 case AMP_UNKNOWN:
80 default:
81 return 1; // All have no exposure parameter and are always 0N return true
82 break;
83 }
84}
85
86
88 SHAPE_POLY_SET& aShapeBuffer )
89{
90 // Draw the primitive shape for flashed items.
91 // Note: rotation of primitives inside a macro must be always done around the macro origin.
92 // Create a static buffer to avoid a lot of memory reallocation.
93 static std::vector<VECTOR2I> polybuffer;
94 polybuffer.clear();
95
96 aApertMacro->EvalLocalParams( *this );
97
98 switch( m_Primitive_id )
99 {
100 case AMP_CIRCLE: // Circle, given diameter and position
101 {
102 /* Generated by an aperture macro declaration like:
103 * "1,1,0.3,0.5, 1.0*"
104 * type (1), exposure, diameter, pos.x, pos.y, <rotation>
105 * <rotation> is a optional parameter: rotation from origin.
106 * type is not stored in parameters list, so the first parameter is exposure
107 */
108 ConvertShapeToPolygon( aApertMacro, polybuffer );
109
110 // shape rotation (if any):
111 if( m_Params.size() >= 5 )
112 {
113 EDA_ANGLE rotation( m_Params[4].GetValueFromMacro( aApertMacro ), DEGREES_T );
114
115 if( !rotation.IsZero() )
116 {
117 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
118 RotatePoint( polybuffer[ii], -rotation );
119 }
120 }
121
122 break;
123 }
124
125 case AMP_LINE2:
126 case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
127 {
128 /* Vector Line, Primitive Code 20.
129 * A vector line is a rectangle defined by its line width, start and end points.
130 * The line ends are rectangular.
131 */
132 /* Generated by an aperture macro declaration like:
133 * "2,1,0.3,0,0, 0.5, 1.0,-135*"
134 * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
135 * type is not stored in parameters list, so the first parameter is exposure
136 */
137 ConvertShapeToPolygon( aApertMacro, polybuffer );
138
139 // shape rotation:
140 EDA_ANGLE rotation( m_Params[6].GetValueFromMacro( aApertMacro ), DEGREES_T );
141
142 if( !rotation.IsZero() )
143 {
144 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
145 RotatePoint( polybuffer[ii], -rotation );
146 }
147
148 break;
149 }
150
151 case AMP_LINE_CENTER:
152 {
153 /* Center Line, Primitive Code 21
154 * A center line primitive is a rectangle defined by its width, height, and center point
155 */
156 /* Generated by an aperture macro declaration like:
157 * "21,1,0.3,0.03,0,0,-135*"
158 * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
159 * type is not stored in parameters list, so the first parameter is exposure
160 */
161 ConvertShapeToPolygon( aApertMacro, polybuffer );
162
163 // shape rotation:
164 EDA_ANGLE rotation( m_Params[5].GetValueFromMacro( aApertMacro ), DEGREES_T );
165
166 if( !rotation.IsZero() )
167 {
168 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
169 RotatePoint( polybuffer[ii], -rotation );
170 }
171
172 break;
173 }
174
176 {
177 /* Generated by an aperture macro declaration like:
178 * "22,1,0.3,0.03,0,0,-135*"
179 * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
180 * type is not stored in parameters list, so the first parameter is exposure
181 */
182 ConvertShapeToPolygon( aApertMacro, polybuffer );
183
184 // shape rotation:
185 EDA_ANGLE rotation( m_Params[5].GetValueFromMacro( aApertMacro ), DEGREES_T );
186
187 if( !rotation.IsZero() )
188 {
189 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
190 RotatePoint( polybuffer[ii], -rotation );
191 }
192 break;
193 }
194
195 case AMP_THERMAL:
196 {
197 /* Generated by an aperture macro declaration like:
198 * "7, 0,0,1.0,0.3,0.01,-13*"
199 * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
200 * type is not stored in parameters list, so the first parameter is center.x
201 *
202 * The thermal primitive is a ring (annulus) interrupted by four gaps. Exposure is always
203 * on.
204 */
205 std::vector<VECTOR2I> subshape_poly;
206 VECTOR2I center( mapPt( m_Params[0].GetValueFromMacro( aApertMacro ),
207 m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric ) );
208 ConvertShapeToPolygon( aApertMacro, subshape_poly );
209
210 // shape rotation:
211 EDA_ANGLE rotation( m_Params[5].GetValueFromMacro( aApertMacro ), DEGREES_T );
212
213 // Because a thermal shape has 4 identical sub-shapes, only one is created in subshape_poly.
214 // We must draw 4 sub-shapes rotated by 90 deg
215 for( int ii = 0; ii < 4; ii++ )
216 {
217 polybuffer = subshape_poly;
218 EDA_ANGLE sub_rotation = ANGLE_90 * ii;
219
220 for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
221 RotatePoint( polybuffer[jj], -sub_rotation );
222
223 // Move to center position given by the tool, and rotate the full shape around
224 // the center position (origin of the macro):
225 for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
226 {
227 polybuffer[jj] += center;
228 RotatePoint( polybuffer[jj], -rotation );
229 }
230
231 aShapeBuffer.NewOutline();
232
233 for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
234 aShapeBuffer.Append( polybuffer[jj] );
235
236 aShapeBuffer.Append( polybuffer[0] );
237 }
238 }
239 break;
240
241 case AMP_MOIRE:
242 {
243 /* Moire, Primitive Code 6
244 * The moire primitive is a cross hair centered on concentric rings (annuli).
245 * Exposure is always on.
246 */
247
248 /* Generated by an aperture macro declaration like:
249 * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
250 * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness,
251 * crosshair len, rotation. The type is not stored in parameters list, so the first
252 * parameter is pos.x.
253 */
254 int outerDiam = scaletoIU( m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric );
255 int penThickness = scaletoIU( m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric );
256 int gap = scaletoIU( m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric );
257 int numCircles = KiROUND( m_Params[5].GetValueFromMacro( aApertMacro ) );
258
259 // Adjust the allowed approx error to convert arcs to segments:
260 int arc_to_seg_error = gerbIUScale.mmToIU( 0.005 ); // Allow 5 microns
261
262 // Draw circles @ position pos.x, pos.y given by the tool:
263 VECTOR2I center( mapPt( m_Params[0].GetValueFromMacro( aApertMacro ),
264 m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric ) );
265
266 EDA_ANGLE rotation( m_Params[8].GetValueFromMacro( aApertMacro ), DEGREES_T );
267
268 // adjust outerDiam by this on each nested circle
269 int diamAdjust = ( gap + penThickness ) * 2;
270
271 for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
272 {
273 if( outerDiam <= 0 )
274 break;
275
276 // calculate the rotated position of the center:
277 VECTOR2I circle_center = center;
278 RotatePoint( circle_center, -rotation );
279
280 // Note: outerDiam is the outer diameter of the ring.
281 // the ring graphic diameter is (outerDiam - penThickness)
282 if( outerDiam <= penThickness )
283 { // No room to draw a ring (no room for the hole):
284 // draw a circle instead (with no hole), with the right diameter
285 TransformCircleToPolygon( aShapeBuffer, circle_center, outerDiam / 2, arc_to_seg_error,
286 ERROR_INSIDE );
287 }
288 else
289 {
290 TransformRingToPolygon( aShapeBuffer, circle_center, ( outerDiam - penThickness ) / 2,
291 penThickness, arc_to_seg_error, ERROR_INSIDE );
292 }
293 }
294
295 // Draw the cross:
296 ConvertShapeToPolygon( aApertMacro, polybuffer );
297
298 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
299 {
300 // move crossair shape to center and rotate shape:
301 polybuffer[ii] += center;
302 RotatePoint( polybuffer[ii], -rotation );
303 }
304
305 break;
306 }
307
308 case AMP_OUTLINE:
309 {
310 /* Outline, Primitive Code 4
311 * An outline primitive is an area enclosed by an n-point polygon defined by its start
312 * point and n
313 * subsequent points. The outline must be closed, i.e. the last point must be equal to
314 * the start point. There must be at least one subsequent point (to close the outline).
315 * The outline of the primitive is actually the contour (see 2.6) that consists of linear
316 * segments only, so it must conform to all the requirements described for contours.
317 * Warning: Make no mistake: n is the number of subsequent points, being the number of
318 * vertices of the outline or one less than the number of coordinate pairs.
319 */
320 /* Generated by an aperture macro declaration like:
321 * "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
322 * type(4), exposure, corners count, corner1.x, corner.1y, ..., corner1.x, corner.1y,
323 * rotation
324 * type is not stored in parameters list, so the first parameter is exposure
325 */
326 // m_Params[0] is the exposure and m_Params[1] is the corners count after the first corner
327 int numCorners = (int) m_Params[1].GetValueFromMacro( aApertMacro );
328
329 // the shape rotation is the last param of list, after corners
330 int last_prm = m_Params.size() - 1;
331 EDA_ANGLE rotation( m_Params[last_prm].GetValueFromMacro( aApertMacro ), DEGREES_T );
332 VECTOR2I pos;
333
334 // Read points.
335 // Note: numCorners is the polygon corner count, following the first corner
336 // * the polygon is always closed,
337 // * therefore the last XY coordinate is the same as the first
338 int prm_idx = 2; // m_Params[2] is the first X coordinate
339
340 for( int i = 0; i <= numCorners; ++i )
341 {
342 pos.x = scaletoIU( m_Params[prm_idx].GetValueFromMacro( aApertMacro ), m_GerbMetric );
343 prm_idx++;
344 pos.y = scaletoIU( m_Params[prm_idx].GetValueFromMacro( aApertMacro ), m_GerbMetric );
345 prm_idx++;
346 polybuffer.push_back(pos);
347
348 // Guard: ensure prm_idx < last_prm
349 // I saw malformed gerber files with numCorners = number
350 // of coordinates instead of number of coordinates following the first point
351 if( prm_idx >= last_prm )
352 break;
353 }
354
355 // rotate polygon and move it to the actual position shape rotation:
356 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
357 {
358 RotatePoint( polybuffer[ii], -rotation );
359 }
360
361 break;
362 }
363
364 case AMP_POLYGON:
365 {
366 /* Polygon, Primitive Code 5
367 * A polygon primitive is a regular polygon defined by the number of vertices n, the
368 * center point and the diameter of the circumscribed circle
369 */
370 /* Generated by an aperture macro declaration like:
371 * "5,1,0.6,0,0,0.5,25"
372 * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
373 * type is not stored in parameters list, so the first parameter is exposure
374 */
375 VECTOR2I curPos( mapPt( m_Params[2].GetValueFromMacro( aApertMacro ),
376 m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric ) );
377
378 // Creates the shape:
379 ConvertShapeToPolygon( aApertMacro, polybuffer );
380
381 // move and rotate polygonal shape
382 EDA_ANGLE rotation( m_Params[5].GetValueFromMacro( aApertMacro ), DEGREES_T );
383
384 for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
385 {
386 polybuffer[ii] += curPos;
387 RotatePoint( polybuffer[ii], -rotation );
388 }
389
390 break;
391 }
392
393 case AMP_COMMENT:
394 case AMP_UNKNOWN:
395 break;
396 }
397
398 if( polybuffer.size() > 1 ) // a valid polygon has more than 1 corner
399 {
400 aShapeBuffer.NewOutline();
401
402 for( unsigned jj = 0; jj < polybuffer.size(); jj++ )
403 aShapeBuffer.Append( polybuffer[jj] );
404
405 // Close the shape:
406 aShapeBuffer.Append( polybuffer[0] );
407 }
408}
409
410
412 std::vector<VECTOR2I>& aBuffer )
413{
414 switch( m_Primitive_id )
415 {
416 case AMP_CIRCLE:
417 {
418 /* Generated by an aperture macro declaration like:
419 * "1,1,0.3,0.5, 1.0*"
420 * type (1), exposure, diameter, pos.x, pos.y, <rotation>
421 * <rotation> is a optional parameter: rotation from origin.
422 * type is not stored in parameters list, so the first parameter is exposure
423 */
424 int radius = scaletoIU( m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
425
426 // A circle primitive can have a 0 size (for instance when used in roundrect macro),
427 // so skip it
428 if( radius <= 0 )
429 break;
430
431 VECTOR2I center = mapPt( m_Params[2].GetValueFromMacro( aApertMacro ), m_Params[3].GetValueFromMacro( aApertMacro ),
432 m_GerbMetric );
433 VECTOR2I corner;
434
435 const int seg_per_circle = 64; // Number of segments to approximate a circle
436 EDA_ANGLE delta = ANGLE_360 / seg_per_circle;
437
438 for( EDA_ANGLE angle = ANGLE_0; angle < ANGLE_360; angle += delta )
439 {
440 corner.x = radius;
441 corner.y = 0;
442 RotatePoint( corner, angle );
443 corner += center;
444 aBuffer.push_back( corner );
445 }
446
447 break;
448 }
449
450 case AMP_LINE2:
451 case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
452 {
453 int width = scaletoIU( m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric );
454 VECTOR2I start =
455 mapPt( m_Params[2].GetValueFromMacro( aApertMacro ), m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric );
456 VECTOR2I end =
457 mapPt( m_Params[4].GetValueFromMacro( aApertMacro ), m_Params[5].GetValueFromMacro( aApertMacro ), m_GerbMetric );
458 VECTOR2I delta = end - start;
459 int len = delta.EuclideanNorm();
460
461 // To build the polygon, we must create a horizontal polygon starting to "start"
462 // and rotate it to have the end point to "end"
463 VECTOR2I currpt;
464 currpt.y += width / 2; // Upper left
465 aBuffer.push_back( currpt );
466 currpt.x = len; // Upper right
467 aBuffer.push_back( currpt );
468 currpt.y -= width; // lower right
469 aBuffer.push_back( currpt );
470 currpt.x = 0; // lower left
471 aBuffer.push_back( currpt );
472
473 // Rotate rectangle and move it to the actual start point
474 EDA_ANGLE angle( delta );
475
476 for( unsigned ii = 0; ii < 4; ii++ )
477 {
478 RotatePoint( aBuffer[ii], -angle );
479 aBuffer[ii] += start;
480 }
481
482 break;
483 }
484
485 case AMP_LINE_CENTER:
486 {
487 VECTOR2I size =
488 mapPt( m_Params[1].GetValueFromMacro( aApertMacro ), m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric );
489 VECTOR2I pos =
490 mapPt( m_Params[3].GetValueFromMacro( aApertMacro ), m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric );
491
492 // Build poly:
493 pos.x -= size.x / 2;
494 pos.y -= size.y / 2; // Lower left
495 aBuffer.push_back( pos );
496 pos.y += size.y; // Upper left
497 aBuffer.push_back( pos );
498 pos.x += size.x; // Upper right
499 aBuffer.push_back( pos );
500 pos.y -= size.y; // lower right
501 aBuffer.push_back( pos );
502 break;
503 }
504
506 {
507 VECTOR2I size =
508 mapPt( m_Params[1].GetValueFromMacro( aApertMacro ), m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric );
509 VECTOR2I lowerLeft =
510 mapPt( m_Params[3].GetValueFromMacro( aApertMacro ), m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric );
511
512 // Build poly:
513 aBuffer.push_back( lowerLeft );
514 lowerLeft.y += size.y; // Upper left
515 aBuffer.push_back( lowerLeft );
516 lowerLeft.x += size.x; // Upper right
517 aBuffer.push_back( lowerLeft );
518 lowerLeft.y -= size.y; // lower right
519 aBuffer.push_back( lowerLeft );
520 break;
521 }
522
523 case AMP_THERMAL:
524 {
525 // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from
526 // this first rotated by 90, 180 and 270 deg.
527 // m_Params = center.x (unused here), center.y (unused here), outside diam, inside diam,
528 // crosshair thickness.
529 int outerRadius = scaletoIU( m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
530 int innerRadius = scaletoIU( m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
531
532 // Safety checks to guarantee no divide-by-zero
533 outerRadius = std::max( 1, outerRadius );
534 innerRadius = std::max( 1, innerRadius );
535
536 int halfthickness = scaletoIU( m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
537 EDA_ANGLE angle_start( asin( (double) halfthickness / innerRadius ), RADIANS_T );
538
539 // Draw shape in the first quadrant (X and Y > 0)
540 VECTOR2I pos, startpos;
541
542 // Inner arc
543 startpos.x = innerRadius;
544 EDA_ANGLE angle_end = ANGLE_90 - angle_start;
545
546 for( EDA_ANGLE angle = angle_start; angle < angle_end; angle += EDA_ANGLE( 10, DEGREES_T ) )
547 {
548 pos = startpos;
549 RotatePoint( pos, angle );
550 aBuffer.push_back( pos );
551 }
552
553 // Last point
554 pos = startpos;
555 RotatePoint( pos, angle_end );
556 aBuffer.push_back( pos );
557
558 // outer arc
559 startpos.x = outerRadius;
560 startpos.y = 0;
561 angle_start = EDA_ANGLE( asin( (double) halfthickness / outerRadius ), RADIANS_T );
562 angle_end = ANGLE_90 - angle_start;
563
564 // First point, near Y axis, outer arc
565 for( EDA_ANGLE angle = angle_end; angle > angle_start; angle -= EDA_ANGLE( 10, DEGREES_T ) )
566 {
567 pos = startpos;
568 RotatePoint( pos, angle );
569 aBuffer.push_back( pos );
570 }
571
572 // last point
573 pos = startpos;
574 RotatePoint( pos, angle_start );
575 aBuffer.push_back( pos );
576
577 aBuffer.push_back( aBuffer[0] ); // Close poly
578 }
579 break;
580
581 case AMP_MOIRE:
582 {
583 // A cross hair with n concentric circles. Only the cross is built as
584 // polygon because circles can be drawn easily
585 int crossHairThickness = scaletoIU( m_Params[6].GetValueFromMacro( aApertMacro ), m_GerbMetric );
586 int crossHairLength = scaletoIU( m_Params[7].GetValueFromMacro( aApertMacro ), m_GerbMetric );
587
588 // Create cross. First create 1/4 of the shape.
589 // Others point are the same, rotated by 90, 180 and 270 deg
590 VECTOR2I pos( crossHairThickness / 2, crossHairLength / 2 );
591 aBuffer.push_back( pos );
592 pos.y = crossHairThickness / 2;
593 aBuffer.push_back( pos );
594 pos.x = -crossHairLength / 2;
595 aBuffer.push_back( pos );
596 pos.y = -crossHairThickness / 2;
597 aBuffer.push_back( pos );
598
599 // Copy the 4 shape, rotated by 90, 180 and 270 deg
600 for( int jj = 1; jj <= 3; jj ++ )
601 {
602 for( int ii = 0; ii < 4; ii++ )
603 {
604 pos = aBuffer[ii];
605 RotatePoint( pos, ANGLE_90 * jj );
606 aBuffer.push_back( pos );
607 }
608 }
609
610 break;
611 }
612
613 case AMP_OUTLINE:
614 // already is a polygon. Do nothing
615 break;
616
617 case AMP_POLYGON: // Creates a regular polygon
618 {
619 int vertexcount = KiROUND( m_Params[1].GetValueFromMacro( aApertMacro ) );
620 int radius = scaletoIU( m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
621
622 // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
623 if( vertexcount < 3 )
624 vertexcount = 3;
625
626 if( vertexcount > 10 )
627 vertexcount = 10;
628
629 for( int ii = 0; ii <= vertexcount; ii++ )
630 {
631 VECTOR2I pos( radius, 0 );
632 RotatePoint( pos, ANGLE_360 * ii / vertexcount );
633 aBuffer.push_back( pos );
634 }
635
636 break;
637 }
638
639 case AMP_COMMENT:
640 case AMP_UNKNOWN:
641 break;
642 }
643}
int scaletoIU(double aCoord, bool isMetric)
Convert a distance given in floating point to our internal units.
static VECTOR2I mapPt(double x, double y, bool isMetric)
Translate a point from the aperture macro coordinate system to our deci-mils coordinate system.
@ AMP_POLYGON
@ AMP_LINE_LOWER_LEFT
@ AMP_LINE2
@ AMP_CIRCLE
@ AMP_THERMAL
@ AMP_UNKNOWN
@ AMP_COMMENT
@ AMP_LINE_CENTER
@ AMP_MOIRE
@ AMP_OUTLINE
@ AMP_LINE20
@ ERROR_INSIDE
constexpr EDA_IU_SCALE gerbIUScale
Definition base_units.h:120
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
void ConvertBasicShapeToPolygon(APERTURE_MACRO *aApertMacro, SHAPE_POLY_SET &aShapeBuffer)
Generate the polygonal shape of the primitive shape of an aperture macro instance.
bool IsAMPrimitiveExposureOn(APERTURE_MACRO *aApertMacro) const
void ConvertShapeToPolygon(APERTURE_MACRO *aApertMacroe, std::vector< VECTOR2I > &aBuffer)
Convert a shape to an equivalent polygon.
AM_PARAMS m_Params
A sequence of parameters used by the primitive.
AM_PRIMITIVE_ID m_Primitive_id
The primitive type.
Support the "aperture macro" defined within standard RS274X.
void EvalLocalParams(const AM_PRIMITIVE &aPrimitive)
Evaluate m_localParamValues from current m_paramLevelEval to aPrimitive m_LocalParamLevel if m_paramL...
bool IsZero() const
Definition eda_angle.h:136
Represent a set of closed polygons.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void TransformRingToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arcs to multiple straight segments.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
@ RADIANS_T
Definition eda_angle.h:32
@ DEGREES_T
Definition eda_angle.h:31
static constexpr EDA_ANGLE ANGLE_360
Definition eda_angle.h:417
VECTOR2I center
int radius
VECTOR2I end
int delta
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683