1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22  */
23 
24 #ifndef ALTIUM_PCB_H
25 #define ALTIUM_PCB_H
26 
27 #include <functional>
28 #include <layer_ids.h>
29 #include <vector>
30 
31 #include <altium_parser_pcb.h>
32 
33 
34 enum class ALTIUM_PCB_DIR
35 {
36     FILE_HEADER,
37 
38     ADVANCEDPLACEROPTIONS6,
39     ARCS6,
40     BOARD6,
41     BOARDREGIONS,
42     CLASSES6,
43     COMPONENTBODIES6,
44     COMPONENTS6,
45     CONNECTIONS6,
46     COORDINATES6,
47     DESIGNRULECHECKEROPTIONS6,
48     DIFFERENTIALPAIRS6,
49     DIMENSIONS6,
50     EMBEDDEDBOARDS6,
51     EMBEDDEDFONTS6,
52     EMBEDDEDS6,
53     EXTENDPRIMITIVEINFORMATION,
54     FILEVERSIONINFO,
55     FILLS6,
56     FROMTOS6,
57     MODELS,
58     MODELSNOEMBED,
59     NETS6,
60     PADS6,
61     PADVIALIBRARY,
62     PADVIALIBRARYCACHE,
63     PADVIALIBRARYLINKS,
64     PINSWAPOPTIONS6,
65     PINPAIRSSECTION,
66     POLYGONS6,
67     REGIONS6,
68     RULES6,
69     SHAPEBASEDCOMPONENTBODIES6,
70     SHAPEBASEDREGIONS6,
71     SIGNALCLASSES,
72     SMARTUNIONS,
73     TEXTS,
74     TEXTS6,
75     TEXTURES,
76     TRACKS6,
77     UNIONNAMES,
78     UNIQUEIDPRIMITIVEINFORMATION,
79     VIAS6,
80     WIDESTRINGS6
81 };
82 
83 
84 class BOARD;
85 class PCB_SHAPE;
86 class FOOTPRINT;
87 class ZONE;
88 class PCB_DIMENSION_BASE;
89 class PROGRESS_REPORTER;
90 
91 
92 /**
93  * Helper method which opens a Altium Board File and parses it.
94  *
95  * @param aBoard board the pcb should be appended to
96  * @param aFileName file name of board file
97  * @param aProgressReporter report import progress, might be a nullptr.
98  * @param aFileMapping mapping how altium stream names are mapped
99  */
100 void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, PROGRESS_REPORTER* aProgressReporter,
101                      const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping );
102 
103 
104 namespace CFB
105 {
106 class CompoundFileReader;
107 struct COMPOUND_FILE_ENTRY;
108 } // namespace CFB
109 
110 
111 // type declaration required for a helper method
112 class ALTIUM_PCB;
113 typedef std::function<void( const CFB::CompoundFileReader&, const CFB::COMPOUND_FILE_ENTRY* )>
114         PARSE_FUNCTION_POINTER_fp;
115 
116 
117 class ALTIUM_PCB
118 {
119 public:
120     explicit ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter );
121     ~ALTIUM_PCB();
122 
123     void Parse( const CFB::CompoundFileReader&               aReader,
124                 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping );
125 
126 private:
127     void checkpoint();
128 
129     PCB_LAYER_ID  GetKicadLayer( ALTIUM_LAYER aAltiumLayer ) const;
130     int           GetNetCode( uint16_t aId ) const;
131     const ARULE6* GetRule( ALTIUM_RULE_KIND aKind, const wxString& aName ) const;
132     const ARULE6* GetRuleDefault( ALTIUM_RULE_KIND aKind ) const;
133 
134     void ParseFileHeader(
135             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
136 
137     // Text Format
138     void ParseBoard6Data(
139             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
140     void ParseClasses6Data(
141             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
142     void ParseComponents6Data(
143             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
144     void ParseDimensions6Data(
145             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
146     void ParseModelsData( const CFB::CompoundFileReader& aReader,
147             const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString& aRootDir );
148     void ParseNets6Data(
149             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
150     void ParsePolygons6Data(
151             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
152     void ParseRules6Data(
153             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
154 
155     // Binary Format
156     void ParseArcs6Data(
157             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
158     void ParseComponentsBodies6Data(
159             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
160     void ParsePads6Data(
161             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
162     void ParseVias6Data(
163             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
164     void ParseTracks6Data(
165             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
166     void ParseTexts6Data(
167             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
168     void ParseFills6Data(
169             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
170     void ParseBoardRegionsData(
171             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
172     void ParseShapeBasedRegions6Data(
173             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
174     void ParseRegions6Data(
175             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
176     void ParseWideStrings6Data(
177             const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
178 
179     // Helper Functions
180     void HelperParseDimensions6Linear( const ADIMENSION6& aElem );
181     void HelperParseDimensions6Radial( const ADIMENSION6& aElem );
182     void HelperParseDimensions6Leader( const ADIMENSION6& aElem );
183     void HelperParseDimensions6Datum( const ADIMENSION6& aElem );
184     void HelperParseDimensions6Center( const ADIMENSION6& aElem );
185 
186     void HelperParsePad6NonCopper( const APAD6& aElem );
187 
188     void HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aVertices );
189 
190     PCB_SHAPE* HelperCreateAndAddShape( uint16_t aComponent );
191     void HelperShapeSetLocalCoord( PCB_SHAPE* aShape, uint16_t aComponent );
192 
193     BOARD*                               m_board;
194     std::vector<FOOTPRINT*>              m_components;
195     std::vector<ZONE*>                   m_polygons;
196     std::vector<PCB_DIMENSION_BASE*>     m_radialDimensions;
197     std::map<wxString, wxString>         m_models;
198     std::map<uint32_t, wxString>         m_unicodeStrings;
199     size_t                               m_num_nets;
200     std::map<ALTIUM_LAYER, PCB_LAYER_ID> m_layermap; // used to correctly map copper layers
201     std::map<ALTIUM_RULE_KIND, std::vector<ARULE6>> m_rules;
202 
203     std::map<ALTIUM_LAYER, ZONE*>        m_outer_plane;
204 
205     PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
206     unsigned           m_doneCount;
207     unsigned           m_lastProgressCount;
208     unsigned           m_totalCount; ///< for progress reporting
209 
210     /// Altium stores pour order across all layers
211     int m_highest_pour_index;
212 };
213 
214 
215 #endif //ALTIUM_PCB_H
216