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
434 // Use the shared tessellator rather than a fixed segment count so macro circles keep
435 // the same maximum deviation as circle apertures.
436 int arc_to_seg_error = gerbIUScale.mmToIU( 0.005 ); // Allow 5 microns
437
440
441 for( const VECTOR2I& pt : circle.CPoints() )
442 aBuffer.push_back( pt );
443
444 break;
445 }
446
447 case AMP_LINE2:
448 case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
449 {
450 int width = scaletoIU( m_Params[1].GetValueFromMacro( aApertMacro ), m_GerbMetric );
451 VECTOR2I start =
452 mapPt( m_Params[2].GetValueFromMacro( aApertMacro ), m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric );
453 VECTOR2I end =
454 mapPt( m_Params[4].GetValueFromMacro( aApertMacro ), m_Params[5].GetValueFromMacro( aApertMacro ), m_GerbMetric );
455 VECTOR2I delta = end - start;
456 int len = delta.EuclideanNorm();
457
458 // To build the polygon, we must create a horizontal polygon starting to "start"
459 // and rotate it to have the end point to "end"
460 VECTOR2I currpt;
461 currpt.y += width / 2; // Upper left
462 aBuffer.push_back( currpt );
463 currpt.x = len; // Upper right
464 aBuffer.push_back( currpt );
465 currpt.y -= width; // lower right
466 aBuffer.push_back( currpt );
467 currpt.x = 0; // lower left
468 aBuffer.push_back( currpt );
469
470 // Rotate rectangle and move it to the actual start point
471 EDA_ANGLE angle( delta );
472
473 for( unsigned ii = 0; ii < 4; ii++ )
474 {
475 RotatePoint( aBuffer[ii], -angle );
476 aBuffer[ii] += start;
477 }
478
479 break;
480 }
481
482 case AMP_LINE_CENTER:
483 {
484 VECTOR2I size =
485 mapPt( m_Params[1].GetValueFromMacro( aApertMacro ), m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric );
486 VECTOR2I pos =
487 mapPt( m_Params[3].GetValueFromMacro( aApertMacro ), m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric );
488
489 // Build poly:
490 pos.x -= size.x / 2;
491 pos.y -= size.y / 2; // Lower left
492 aBuffer.push_back( pos );
493 pos.y += size.y; // Upper left
494 aBuffer.push_back( pos );
495 pos.x += size.x; // Upper right
496 aBuffer.push_back( pos );
497 pos.y -= size.y; // lower right
498 aBuffer.push_back( pos );
499 break;
500 }
501
503 {
504 VECTOR2I size =
505 mapPt( m_Params[1].GetValueFromMacro( aApertMacro ), m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric );
506 VECTOR2I lowerLeft =
507 mapPt( m_Params[3].GetValueFromMacro( aApertMacro ), m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric );
508
509 // Build poly:
510 aBuffer.push_back( lowerLeft );
511 lowerLeft.y += size.y; // Upper left
512 aBuffer.push_back( lowerLeft );
513 lowerLeft.x += size.x; // Upper right
514 aBuffer.push_back( lowerLeft );
515 lowerLeft.y -= size.y; // lower right
516 aBuffer.push_back( lowerLeft );
517 break;
518 }
519
520 case AMP_THERMAL:
521 {
522 // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from
523 // this first rotated by 90, 180 and 270 deg.
524 // m_Params = center.x (unused here), center.y (unused here), outside diam, inside diam,
525 // crosshair thickness.
526 int outerRadius = scaletoIU( m_Params[2].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
527 int innerRadius = scaletoIU( m_Params[3].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
528
529 // Safety checks to guarantee no divide-by-zero
530 outerRadius = std::max( 1, outerRadius );
531 innerRadius = std::max( 1, innerRadius );
532
533 int halfthickness = scaletoIU( m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
534 EDA_ANGLE angle_start( asin( (double) halfthickness / innerRadius ), RADIANS_T );
535
536 // Draw shape in the first quadrant (X and Y > 0)
537 VECTOR2I pos, startpos;
538
539 // Inner arc
540 startpos.x = innerRadius;
541 EDA_ANGLE angle_end = ANGLE_90 - angle_start;
542
543 for( EDA_ANGLE angle = angle_start; angle < angle_end; angle += EDA_ANGLE( 10, DEGREES_T ) )
544 {
545 pos = startpos;
546 RotatePoint( pos, angle );
547 aBuffer.push_back( pos );
548 }
549
550 // Last point
551 pos = startpos;
552 RotatePoint( pos, angle_end );
553 aBuffer.push_back( pos );
554
555 // outer arc
556 startpos.x = outerRadius;
557 startpos.y = 0;
558 angle_start = EDA_ANGLE( asin( (double) halfthickness / outerRadius ), RADIANS_T );
559 angle_end = ANGLE_90 - angle_start;
560
561 // First point, near Y axis, outer arc
562 for( EDA_ANGLE angle = angle_end; angle > angle_start; angle -= EDA_ANGLE( 10, DEGREES_T ) )
563 {
564 pos = startpos;
565 RotatePoint( pos, angle );
566 aBuffer.push_back( pos );
567 }
568
569 // last point
570 pos = startpos;
571 RotatePoint( pos, angle_start );
572 aBuffer.push_back( pos );
573
574 aBuffer.push_back( aBuffer[0] ); // Close poly
575 }
576 break;
577
578 case AMP_MOIRE:
579 {
580 // A cross hair with n concentric circles. Only the cross is built as
581 // polygon because circles can be drawn easily
582 int crossHairThickness = scaletoIU( m_Params[6].GetValueFromMacro( aApertMacro ), m_GerbMetric );
583 int crossHairLength = scaletoIU( m_Params[7].GetValueFromMacro( aApertMacro ), m_GerbMetric );
584
585 // Create cross. First create 1/4 of the shape.
586 // Others point are the same, rotated by 90, 180 and 270 deg
587 VECTOR2I pos( crossHairThickness / 2, crossHairLength / 2 );
588 aBuffer.push_back( pos );
589 pos.y = crossHairThickness / 2;
590 aBuffer.push_back( pos );
591 pos.x = -crossHairLength / 2;
592 aBuffer.push_back( pos );
593 pos.y = -crossHairThickness / 2;
594 aBuffer.push_back( pos );
595
596 // Copy the 4 shape, rotated by 90, 180 and 270 deg
597 for( int jj = 1; jj <= 3; jj ++ )
598 {
599 for( int ii = 0; ii < 4; ii++ )
600 {
601 pos = aBuffer[ii];
602 RotatePoint( pos, ANGLE_90 * jj );
603 aBuffer.push_back( pos );
604 }
605 }
606
607 break;
608 }
609
610 case AMP_OUTLINE:
611 // already is a polygon. Do nothing
612 break;
613
614 case AMP_POLYGON: // Creates a regular polygon
615 {
616 int vertexcount = KiROUND( m_Params[1].GetValueFromMacro( aApertMacro ) );
617 int radius = scaletoIU( m_Params[4].GetValueFromMacro( aApertMacro ), m_GerbMetric ) / 2;
618
619 // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
620 if( vertexcount < 3 )
621 vertexcount = 3;
622
623 if( vertexcount > 10 )
624 vertexcount = 10;
625
626 for( int ii = 0; ii <= vertexcount; ii++ )
627 {
628 VECTOR2I pos( radius, 0 );
629 RotatePoint( pos, ANGLE_360 * ii / vertexcount );
630 aBuffer.push_back( pos );
631 }
632
633 break;
634 }
635
636 case AMP_COMMENT:
637 case AMP_UNKNOWN:
638 break;
639 }
640}
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 polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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_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
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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