1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 #ifndef ALTIUM_PARSER_PCB_H
26 #define ALTIUM_PARSER_PCB_H
27 
28 #include <cstdint>
29 #include <cstring>
30 #include <memory>
31 #include <vector>
32 
33 #include <footprint.h>
34 #include <wx/gdicmn.h>
35 
36 // tthis constant specifies an unconnected net
37 const uint16_t ALTIUM_NET_UNCONNECTED = std::numeric_limits<uint16_t>::max();
38 
39 // this constant specifies a item which is not inside an component
40 const uint16_t ALTIUM_COMPONENT_NONE = std::numeric_limits<uint16_t>::max();
41 
42 // this constant specifies a item which does not define a polygon
43 const uint16_t ALTIUM_POLYGON_NONE = std::numeric_limits<uint16_t>::max();
44 
45 
46 enum class ALTIUM_UNIT
47 {
48     UNKNOWN = 0,
49 
50     INCHES      = 1,
51     MILS        = 2,
52     MILLIMETERS = 3,
53     CENTIMETER  = 4
54 };
55 
56 enum class ALTIUM_CLASS_KIND
57 {
58     UNKNOWN = -1,
59 
60     NET_CLASS              = 0,
61     SOURCE_SCHEMATIC_CLASS = 1,
62     FROM_TO                = 2,
63     PAD_CLASS              = 3,
64     LAYER_CLASS            = 4,
65     UNKNOWN_CLASS          = 5,
66     DIFF_PAIR_CLASS        = 6,
67     POLYGON_CLASS          = 7
68 };
69 
70 enum class ALTIUM_DIMENSION_KIND
71 {
72     UNKNOWN = 0,
73 
74     LINEAR          = 1,
75     ANGULAR         = 2,
76     RADIAL          = 3,
77     LEADER          = 4,
78     DATUM           = 5,
79     BASELINE        = 6,
80     CENTER          = 7,
81     LINEAR_DIAMETER = 8,
82     RADIAL_DIAMETER = 9
83 };
84 
85 enum class ALTIUM_REGION_KIND
86 {
87     UNKNOWN = -1,
88 
89     COPPER            = 0, // KIND=0
90     POLYGON_CUTOUT    = 1, // KIND=1
91     UNKNOWN_2         = 2, // KIND=2
92     UNKNOWN_3         = 3, // KIND=3
93     CAVITY_DEFINITION = 4, // KIND=4
94     BOARD_CUTOUT      = 5, // KIND=0 AND ISBOARDCUTOUT=TRUE
95 };
96 
97 enum class ALTIUM_RULE_KIND
98 {
99     UNKNOWN = 0,
100 
101     CLEARANCE              = 1,
102     DIFF_PAIR_ROUTINGS     = 2,
103     HEIGHT                 = 3,
104     HOLE_SIZE              = 4,
105     HOLE_TO_HOLE_CLEARANCE = 5,
106     WIDTH                  = 6,
107     PASTE_MASK_EXPANSION   = 7,
108     PLANE_CLEARANCE        = 8,
109     POLYGON_CONNECT        = 9,
110 };
111 
112 enum class ALTIUM_CONNECT_STYLE
113 {
114     UNKNOWN = 0,
115     DIRECT  = 1,
116     RELIEF  = 2,
117     NONE    = 3
118 };
119 
120 enum class ALTIUM_RECORD
121 {
122     ARC    = 1,
123     PAD    = 2,
124     VIA    = 3,
125     TRACK  = 4,
126     TEXT   = 5,
127     FILL   = 6,
128     REGION = 11,
129     MODEL  = 12
130 };
131 
132 enum class ALTIUM_PAD_SHAPE
133 {
134     UNKNOWN   = 0,
135     CIRCLE    = 1,
136     RECT      = 2,
137     OCTAGONAL = 3
138 };
139 
140 enum class ALTIUM_PAD_SHAPE_ALT
141 {
142     UNKNOWN   = 0,
143     CIRCLE    = 1,
144     RECT      = 2, // TODO: valid?
145     OCTAGONAL = 3, // TODO: valid?
146     ROUNDRECT = 9
147 };
148 
149 enum class ALTIUM_PAD_HOLE_SHAPE
150 {
151     UNKNOWN = -1,
152     ROUND   = 0,
153     SQUARE  = 1,
154     SLOT    = 2
155 };
156 
157 enum class ALTIUM_PAD_MODE
158 {
159     SIMPLE            = 0,
160     TOP_MIDDLE_BOTTOM = 1,
161     FULL_STACK        = 2
162 };
163 
164 enum class ALTIUM_PAD_RULE
165 {
166     UNKNOWN = 0,
167     RULE    = 1,
168     MANUAL  = 2
169 };
170 
171 enum class ALTIUM_POLYGON_HATCHSTYLE
172 {
173     UNKNOWN = 0,
174 
175     SOLID      = 1,
176     DEGREE_45  = 2,
177     DEGREE_90  = 3,
178     HORIZONTAL = 4,
179     VERTICAL   = 5,
180     NONE       = 6
181 };
182 
183 enum class ALTIUM_TEXT_POSITION
184 {
185     MANUAL        = 0, // only relevant for NAMEAUTOPOSITION and COMMENTAUTOPOSITION
186     LEFT_TOP      = 1,
187     LEFT_CENTER   = 2,
188     LEFT_BOTTOM   = 3,
189     CENTER_TOP    = 4,
190     CENTER_CENTER = 5,
191     CENTER_BOTTOM = 6,
192     RIGHT_TOP     = 7,
193     RIGHT_CENTER  = 8,
194     RIGHT_BOTTOM  = 9
195 };
196 
197 enum class ALTIUM_TEXT_TYPE
198 {
199     UNKNOWN = -1,
200 
201     STROKE   = 0,
202     TRUETYPE = 1,
203     BARCODE  = 2
204 };
205 
206 struct ALTIUM_VERTICE
207 {
208     const bool    isRound;
209     const int32_t radius;
210     const double  startangle;
211     const double  endangle;
212     const wxPoint position;
213     const wxPoint center;
214 
ALTIUM_VERTICEALTIUM_VERTICE215     explicit ALTIUM_VERTICE( const wxPoint& aPosition )
216             : isRound( false ),
217               radius( 0 ),
218               startangle( 0. ),
219               endangle( 0. ),
220               position( aPosition ),
221               center( wxPoint( 0, 0 ) )
222     {
223     }
224 
ALTIUM_VERTICEALTIUM_VERTICE225     explicit ALTIUM_VERTICE( bool aIsRound, int32_t aRadius, double aStartAngle, double aEndAngle,
226             const wxPoint aPosition, const wxPoint aCenter )
227             : isRound( aIsRound ),
228               radius( aRadius ),
229               startangle( aStartAngle ),
230               endangle( aEndAngle ),
231               position( aPosition ),
232               center( aCenter )
233     {
234     }
235 };
236 
237 enum class ALTIUM_LAYER
238 {
239     UNKNOWN = 0,
240 
241     TOP_LAYER    = 1,
242     MID_LAYER_1  = 2,
243     MID_LAYER_2  = 3,
244     MID_LAYER_3  = 4,
245     MID_LAYER_4  = 5,
246     MID_LAYER_5  = 6,
247     MID_LAYER_6  = 7,
248     MID_LAYER_7  = 8,
249     MID_LAYER_8  = 9,
250     MID_LAYER_9  = 10,
251     MID_LAYER_10 = 11,
252     MID_LAYER_11 = 12,
253     MID_LAYER_12 = 13,
254     MID_LAYER_13 = 14,
255     MID_LAYER_14 = 15,
256     MID_LAYER_15 = 16,
257     MID_LAYER_16 = 17,
258     MID_LAYER_17 = 18,
259     MID_LAYER_18 = 19,
260     MID_LAYER_19 = 20,
261     MID_LAYER_20 = 21,
262     MID_LAYER_21 = 22,
263     MID_LAYER_22 = 23,
264     MID_LAYER_23 = 24,
265     MID_LAYER_24 = 25,
266     MID_LAYER_25 = 26,
267     MID_LAYER_26 = 27,
268     MID_LAYER_27 = 28,
269     MID_LAYER_28 = 29,
270     MID_LAYER_29 = 30,
271     MID_LAYER_30 = 31,
272     BOTTOM_LAYER = 32,
273 
274     TOP_OVERLAY    = 33,
275     BOTTOM_OVERLAY = 34,
276     TOP_PASTE      = 35,
277     BOTTOM_PASTE   = 36,
278     TOP_SOLDER     = 37,
279     BOTTOM_SOLDER  = 38,
280 
281     INTERNAL_PLANE_1  = 39,
282     INTERNAL_PLANE_2  = 40,
283     INTERNAL_PLANE_3  = 41,
284     INTERNAL_PLANE_4  = 42,
285     INTERNAL_PLANE_5  = 43,
286     INTERNAL_PLANE_6  = 44,
287     INTERNAL_PLANE_7  = 45,
288     INTERNAL_PLANE_8  = 46,
289     INTERNAL_PLANE_9  = 47,
290     INTERNAL_PLANE_10 = 48,
291     INTERNAL_PLANE_11 = 49,
292     INTERNAL_PLANE_12 = 50,
293     INTERNAL_PLANE_13 = 51,
294     INTERNAL_PLANE_14 = 52,
295     INTERNAL_PLANE_15 = 53,
296     INTERNAL_PLANE_16 = 54,
297 
298     DRILL_GUIDE    = 55,
299     KEEP_OUT_LAYER = 56,
300 
301     MECHANICAL_1  = 57,
302     MECHANICAL_2  = 58,
303     MECHANICAL_3  = 59,
304     MECHANICAL_4  = 60,
305     MECHANICAL_5  = 61,
306     MECHANICAL_6  = 62,
307     MECHANICAL_7  = 63,
308     MECHANICAL_8  = 64,
309     MECHANICAL_9  = 65,
310     MECHANICAL_10 = 66,
311     MECHANICAL_11 = 67,
312     MECHANICAL_12 = 68,
313     MECHANICAL_13 = 69,
314     MECHANICAL_14 = 70,
315     MECHANICAL_15 = 71,
316     MECHANICAL_16 = 72,
317 
318     DRILL_DRAWING     = 73,
319     MULTI_LAYER       = 74,
320     CONNECTIONS       = 75,
321     BACKGROUND        = 76,
322     DRC_ERROR_MARKERS = 77,
323     SELECTIONS        = 78,
324     VISIBLE_GRID_1    = 79,
325     VISIBLE_GRID_2    = 80,
326     PAD_HOLES         = 81,
327     VIA_HOLES         = 82,
328 };
329 
330 class ALTIUM_PARSER;
331 
332 struct ABOARD6_LAYER_STACKUP
333 {
334     wxString name;
335 
336     size_t nextId;
337     size_t prevId;
338 
339     int32_t copperthick;
340 
341     double   dielectricconst;
342     int32_t  dielectricthick;
343     wxString dielectricmaterial;
344 };
345 
346 struct ABOARD6
347 {
348     wxPoint sheetpos;
349     wxSize  sheetsize;
350 
351     int                                layercount;
352     std::vector<ABOARD6_LAYER_STACKUP> stackup;
353 
354     std::vector<ALTIUM_VERTICE> board_vertices;
355 
356     explicit ABOARD6( ALTIUM_PARSER& aReader );
357 };
358 
359 struct ACLASS6
360 {
361     wxString name;
362     wxString uniqueid;
363 
364     ALTIUM_CLASS_KIND kind;
365 
366     std::vector<wxString> names;
367 
368     explicit ACLASS6( ALTIUM_PARSER& aReader );
369 };
370 
371 struct ACOMPONENT6
372 {
373     ALTIUM_LAYER layer;
374     wxPoint      position;
375     double       rotation;
376     bool         locked;
377     bool         nameon;
378     bool         commenton;
379     wxString     sourcedesignator;
380     wxString     sourcefootprintlibrary;
381     wxString     pattern;
382     wxString     sourcecomponentlibrary;
383     wxString     sourcelibreference;
384 
385     ALTIUM_TEXT_POSITION nameautoposition;
386     ALTIUM_TEXT_POSITION commentautoposition;
387 
388     explicit ACOMPONENT6( ALTIUM_PARSER& aReader );
389 };
390 
391 struct ADIMENSION6
392 {
393     ALTIUM_LAYER          layer;
394     ALTIUM_DIMENSION_KIND kind;
395 
396     wxString textformat;
397     wxString textprefix;
398     wxString textsuffix;
399 
400     int32_t height;
401     double  angle;
402 
403     uint32_t linewidth;
404     uint32_t textheight;
405     uint32_t textlinewidth;
406     int32_t  textprecision;
407     uint32_t textgap;
408     bool     textbold;
409     bool     textitalic;
410 
411     int32_t arrowsize;
412 
413     ALTIUM_UNIT textunit;
414 
415     wxPoint xy1;
416 
417     std::vector<wxPoint> referencePoint;
418     std::vector<wxPoint> textPoint;
419 
420     explicit ADIMENSION6( ALTIUM_PARSER& aReader );
421 };
422 
423 struct AMODEL
424 {
425     wxString name;
426     wxString id;
427     bool     isEmbedded;
428 
429     FP_3DMODEL::VECTOR3D rotation;
430 
431     explicit AMODEL( ALTIUM_PARSER& aReader );
432 };
433 
434 struct ANET6
435 {
436     wxString name;
437 
438     explicit ANET6( ALTIUM_PARSER& aReader );
439 };
440 
441 struct APOLYGON6
442 {
443     ALTIUM_LAYER layer;
444     uint16_t     net;
445     bool         locked;
446 
447     ALTIUM_POLYGON_HATCHSTYLE hatchstyle;
448 
449     int32_t gridsize;
450     int32_t trackwidth;
451     int32_t minprimlength;
452     bool    useoctagons;
453 
454     // Note: Altium pour index is the opposite of KiCad zone priority!
455     int32_t pourindex;
456 
457     std::vector<ALTIUM_VERTICE> vertices;
458 
459     explicit APOLYGON6( ALTIUM_PARSER& aReader );
460 };
461 
462 
463 struct ARULE6
464 {
465     wxString name;
466     int      priority;
467 
468     ALTIUM_RULE_KIND kind;
469 
470     wxString scope1expr;
471     wxString scope2expr;
472 
473     // ALTIUM_RULE_KIND::CLEARANCE
474     int clearanceGap;
475 
476     // ALTIUM_RULE_KIND::PLANE_CLEARANCE
477     int planeclearanceClearance;
478 
479     // ALTIUM_RULE_KIND::POLYGON_CONNECT
480     int32_t              polygonconnectAirgapwidth;
481     int32_t              polygonconnectReliefconductorwidth;
482     int                  polygonconnectReliefentries;
483     ALTIUM_CONNECT_STYLE polygonconnectStyle;
484 
485     // TODO: implement different types of rules we need to parse
486 
487     explicit ARULE6( ALTIUM_PARSER& aReader );
488 };
489 
490 struct AREGION6
491 {
492     bool is_locked;
493     bool is_keepout;
494 
495     bool is_shapebased;
496 
497     ALTIUM_LAYER layer;
498     uint16_t     net;
499     uint16_t     component;
500     uint16_t     subpolyindex;
501     uint16_t     holecount;
502 
503     ALTIUM_REGION_KIND kind; // I assume this means if normal or keepout?
504 
505     std::vector<ALTIUM_VERTICE>              outline;
506     std::vector<std::vector<ALTIUM_VERTICE>> holes;
507 
508     explicit AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices );
509 };
510 
511 struct AARC6
512 {
513     bool is_locked;
514     bool is_keepout;
515     bool is_polygonoutline;
516 
517     ALTIUM_LAYER layer;
518     uint16_t     net;
519     uint16_t     component;
520     uint16_t     subpolyindex;
521 
522     wxPoint  center;
523     uint32_t radius;
524     double   startangle;
525     double   endangle;
526     uint32_t width;
527 
528     explicit AARC6( ALTIUM_PARSER& aReader );
529 };
530 
531 struct ACOMPONENTBODY6
532 {
533     uint16_t             component;
534 
535     wxString             modelName;
536     wxString             modelId;
537     bool                 modelIsEmbedded;
538 
539     FP_3DMODEL::VECTOR3D modelPosition;
540     FP_3DMODEL::VECTOR3D modelRotation;
541     double               rotation;
542     double               bodyOpacity;
543 
544     explicit ACOMPONENTBODY6( ALTIUM_PARSER& aReader );
545 };
546 
547 struct APAD6_SIZE_AND_SHAPE
548 {
549     ALTIUM_PAD_HOLE_SHAPE holeshape;
550     uint32_t              slotsize;
551     double                slotrotation;
552 
553     wxSize               inner_size[29];
554     ALTIUM_PAD_SHAPE     inner_shape[29];
555     wxPoint              holeoffset[32];
556     ALTIUM_PAD_SHAPE_ALT alt_shape[32];
557     uint8_t              cornerradius[32];
558 };
559 
560 struct APAD6
561 {
562     bool is_locked;
563     bool is_tent_top;
564     bool is_tent_bottom;
565     bool is_test_fab_top;
566     bool is_test_fab_bottom;
567 
568     wxString name;
569 
570     ALTIUM_LAYER layer;
571     uint16_t     net;
572     uint16_t     component;
573 
574     wxPoint  position;
575     wxSize   topsize;
576     wxSize   midsize;
577     wxSize   botsize;
578     uint32_t holesize;
579 
580     ALTIUM_PAD_SHAPE topshape;
581     ALTIUM_PAD_SHAPE midshape;
582     ALTIUM_PAD_SHAPE botshape;
583 
584     ALTIUM_PAD_MODE padmode;
585 
586     double          direction;
587     bool            plated;
588     ALTIUM_PAD_RULE pastemaskexpansionmode;
589     int32_t         pastemaskexpansionmanual;
590     ALTIUM_PAD_RULE soldermaskexpansionmode;
591     int32_t         soldermaskexpansionmanual;
592     double          holerotation;
593 
594     ALTIUM_LAYER tolayer;
595     ALTIUM_LAYER fromlayer;
596 
597     std::unique_ptr<APAD6_SIZE_AND_SHAPE> sizeAndShape;
598 
599     explicit APAD6( ALTIUM_PARSER& aReader );
600 };
601 
602 struct AVIA6
603 {
604     bool is_locked;
605     bool is_tent_top;
606     bool is_tent_bottom;
607     bool is_test_fab_top;
608     bool is_test_fab_bottom;
609 
610     uint16_t net;
611 
612     wxPoint  position;
613     uint32_t diameter;
614     uint32_t holesize;
615 
616     ALTIUM_LAYER    layer_start;
617     ALTIUM_LAYER    layer_end;
618     ALTIUM_PAD_MODE viamode;
619 
620     explicit AVIA6( ALTIUM_PARSER& aReader );
621 };
622 
623 struct ATRACK6
624 {
625     bool is_locked;
626     bool is_keepout;
627     bool is_polygonoutline;
628 
629     ALTIUM_LAYER layer;
630     uint16_t     net;
631     uint16_t     component;
632     uint16_t     subpolyindex;
633 
634     wxPoint  start;
635     wxPoint  end;
636     uint32_t width;
637 
638     explicit ATRACK6( ALTIUM_PARSER& aReader );
639 };
640 
641 struct ATEXT6
642 {
643     ALTIUM_LAYER layer;
644     uint16_t     component;
645 
646     wxPoint              position;
647     uint32_t             height;
648     double               rotation;
649     uint32_t             strokewidth;
650     ALTIUM_TEXT_POSITION textposition;
651 
652     bool isBold;
653     bool isItalic;
654     bool isMirrored;
655     bool isInverted;
656 
657     bool isComment;
658     bool isDesignator;
659 
660     ALTIUM_TEXT_TYPE fonttype;
661 
662     wxString text;
663 
664     explicit ATEXT6( ALTIUM_PARSER& aReader, std::map<uint32_t, wxString>& aStringTable );
665 };
666 
667 struct AFILL6
668 {
669     bool is_locked;
670     bool is_keepout;
671 
672     ALTIUM_LAYER layer;
673     uint16_t     component;
674     uint16_t     net;
675 
676     wxPoint pos1;
677     wxPoint pos2;
678     double  rotation;
679 
680     explicit AFILL6( ALTIUM_PARSER& aReader );
681 };
682 
683 
684 #endif //ALTIUM_PARSER_PCB_H
685