KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sprint_layout_parser.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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, see <https://www.gnu.org/licenses/>.
18 *
19 * Binary format knowledge derived from:
20 * https://github.com/sergey-raevskiy/xlay (lay6.h)
21 * https://github.com/OpenBoardView/OpenBoardView (LAYFile.cpp)
22 */
23
24#ifndef SPRINT_LAYOUT_PARSER_H_
25#define SPRINT_LAYOUT_PARSER_H_
26
27#include <cstdint>
28#include <memory>
29#include <string>
30#include <vector>
31#include <map>
32#include <set>
33
34#include <layer_ids.h>
35#include <math/vector2d.h>
36
37class BOARD;
39class FOOTPRINT;
40class NETINFO_ITEM;
41class PAD;
42class PCB_SHAPE;
43class PCB_TEXT;
44class BOARD_ITEM;
45
47{
48
60
62{
63 LAYER_C1 = 1, // top copper
64 LAYER_S1 = 2, // top silkscreen
65 LAYER_C2 = 3, // bottom copper
66 LAYER_S2 = 4, // bottom silkscreen
67 LAYER_I1 = 5, // inner layer 1
68 LAYER_I2 = 6, // inner layer 2
69 LAYER_O = 7, // board outline
70};
71
86
87struct POINT
88{
89 float x;
90 float y;
91};
92
94{
95 bool valid = false;
96 float off_x = 0;
97 float off_y = 0;
98 uint8_t center_mode = 0;
99 double rotation = 0;
100 std::string package;
101 std::string comment;
102 uint8_t use = 0;
103};
104
105struct OBJECT
106{
107 uint8_t type = 0; // OBJECT_TYPE enum value
108 float x = 0;
109 float y = 0;
110 float outer = 0; // THT/circle outer radius, SMD half-width, text height
111 float inner = 0; // THT drill radius, SMD half-height, text stroke width
112 int32_t line_width = 0; // line/poly stroke width, circle end_angle
113 uint8_t layer = 0; // LAYER_ID enum value
114 uint8_t tht_shape = 0; // THT_SHAPE for pads, 1=component-ref for text
115 uint16_t component_id = 0;
116 int32_t start_angle = 0; // circle start angle, pad thermal style bytes
117 uint8_t filled = 0; // nonzero = filled polygon
118 int32_t clearance = 0; // ground plane clearance
119 uint8_t mirror_v = 0;
120 uint8_t mirror_h = 0; // or thermal relief spoke enable
121 uint8_t keepout = 0; // nonzero = ground plane exclusion area
122 int32_t rotation = 0; // rotation in degree units
123 uint8_t plated = 0; // 0 = NPTH, nonzero = plated
124 uint8_t soldermask = 0; // 0 = no mask opening (tented)
125
126 std::string text;
127 std::string identifier;
128 std::vector<uint32_t> groups;
129 std::vector<POINT> points;
130 std::vector<OBJECT> text_children;
132};
133
135{
136 std::string name;
137 uint32_t size_x = 0; // 1/10000 mm
138 uint32_t size_y = 0; // 1/10000 mm
139 int32_t center_x = 0; // 1/10000 mm
140 int32_t center_y = 0; // 1/10000 mm
141 uint8_t ground_plane[7] = {};
142 uint8_t is_multilayer = 0;
143 std::vector<OBJECT> objects;
144};
145
147{
148 uint8_t version = 0;
149 std::vector<BOARD_DATA> boards;
150 std::string project_name;
151 std::string project_author;
152 std::string project_company;
153 std::string project_comment;
154};
155
156} // namespace SPRINT_LAYOUT
157
158
159class NETINFO_ITEM;
160
162{
163public:
166
167 // Parse full Sprint Layout board files (.lay6 / .lay) into internal file data
168 bool ParseBoard( const wxString& aFileName );
169
170 // Parse a macro (LMK) file with objects in BOARD_DATA with index 0
171 bool ParseMacroFile( const wxString& aFileName );
172
173 // Create a BOARD from BOARD_DATA at the given index, and populate the provided footprint map with any footprints found in the file.
174 BOARD* CreateBoard( std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, size_t aBoardIndex = 0 );
175
176 // Create a single FOOTPRINT from the board at index 0
178
180
181private:
182 // Binary reading helpers
183 uint8_t readUint8();
184 uint16_t readUint16();
185 int16_t readInt16();
186 uint32_t readUint32();
187 uint32_t readUnsigned();
188 int32_t readInt32();
189 int32_t readSigned();
190 float readFloat();
191 double readDouble();
192 float readCoord();
193 std::string readFixedString( size_t aMaxLen );
194 std::string readVarString();
195 void skip( size_t aBytes );
196 void seek( int aBytes );
197
198 void parseFileStart( const wxString& aFileName );
203 void parseObject( SPRINT_LAYOUT::OBJECT& aObject, bool aIsTextChild = false );
204 void parseTrailer();
205
206 // Board construction helpers
207 PCB_LAYER_ID mapLayer( uint8_t aSprintLayer ) const;
208 int sprintToKicadCoord( float aValue ) const;
209 VECTOR2I sprintToKicadPos( float aX, float aY ) const;
210 wxString convertString( const std::string& aStr ) const;
211
212 bool layerHasGroundPlane( PCB_LAYER_ID aLayer, const uint8_t aGroundPlane[7] ) const;
213
215 const uint8_t aGroundPlane[7], NETINFO_ITEM* aGndPlaneNet ) const;
216
217 void processPad( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj, const uint8_t aGroundPlane[7],
218 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
219
220 void processCircle( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
221 std::vector<std::vector<VECTOR2I>>& aOutlineSegments, const uint8_t aGroundPlane[7],
222 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
223
224 void processLine( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
225 std::vector<std::vector<VECTOR2I>>& aOutlineSegments, const uint8_t aGroundPlane[7],
226 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
227
228 void processSegment( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
229 std::vector<std::vector<VECTOR2I>>& aOutlineSegments, const uint8_t aGroundPlane[7],
230 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
231
232 void processPoly( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
233 std::vector<std::vector<VECTOR2I>>& aOutlineSegments, const uint8_t aGroundPlane[7],
234 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
235
236 void processText( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
237 std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
238
239 void processItemGroups( BOARD_ITEM* aItem, const SPRINT_LAYOUT::OBJECT& aObj,
240 std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
241
242 void buildOutline( BOARD* aBoard, std::vector<std::vector<VECTOR2I>>& aOutlineSegments,
243 const SPRINT_LAYOUT::BOARD_DATA& aBoardData );
244
245 void resolveGroups( BOARD_ITEM_CONTAINER* aContainer, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
246
248 const uint8_t* m_pos = nullptr;
249 const uint8_t* m_start = nullptr;
250 const uint8_t* m_end = nullptr;
251 std::vector<uint8_t> m_buffer;
252 bool m_parsingMacro = false;
253};
254
255#endif // SPRINT_LAYOUT_PARSER_H_
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:81
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
Handle the data for a net.
Definition netinfo.h:46
Definition pad.h:61
void processPoly(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, std::vector< std::vector< VECTOR2I > > &aOutlineSegments, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
void parsePoints(SPRINT_LAYOUT::OBJECT &aObj)
wxString convertString(const std::string &aStr) const
void processCircle(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, std::vector< std::vector< VECTOR2I > > &aOutlineSegments, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
SPRINT_LAYOUT::FILE_DATA m_fileData
PCB_LAYER_ID mapLayer(uint8_t aSprintLayer) const
void parseFileStart(const wxString &aFileName)
const SPRINT_LAYOUT::FILE_DATA & GetFileData() const
std::string readFixedString(size_t aMaxLen)
void processItemGroups(BOARD_ITEM *aItem, const SPRINT_LAYOUT::OBJECT &aObj, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
NETINFO_ITEM * resolveItemNet(BOARD *aBoard, const SPRINT_LAYOUT::OBJECT &aObj, PCB_LAYER_ID aLayer, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet) const
void processSegment(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, std::vector< std::vector< VECTOR2I > > &aOutlineSegments, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
void buildOutline(BOARD *aBoard, std::vector< std::vector< VECTOR2I > > &aOutlineSegments, const SPRINT_LAYOUT::BOARD_DATA &aBoardData)
void processText(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
void parseGroups(SPRINT_LAYOUT::OBJECT &aObj)
void resolveGroups(BOARD_ITEM_CONTAINER *aContainer, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
void parseObject(SPRINT_LAYOUT::OBJECT &aObject, bool aIsTextChild=false)
BOARD * CreateBoard(std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, size_t aBoardIndex=0)
void parseBoardHeader(SPRINT_LAYOUT::BOARD_DATA &aBoard)
void processPad(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
VECTOR2I sprintToKicadPos(float aX, float aY) const
int sprintToKicadCoord(float aValue) const
void parseObjectsList(SPRINT_LAYOUT::BOARD_DATA &aBoard)
bool ParseMacroFile(const wxString &aFileName)
std::vector< uint8_t > m_buffer
bool layerHasGroundPlane(PCB_LAYER_ID aLayer, const uint8_t aGroundPlane[7]) const
void processLine(BOARD_ITEM_CONTAINER *aContainer, const SPRINT_LAYOUT::OBJECT &aObj, std::vector< std::vector< VECTOR2I > > &aOutlineSegments, const uint8_t aGroundPlane[7], NETINFO_ITEM *aGndPlaneNet, std::map< uint32_t, std::set< BOARD_ITEM * > > &aGidToItems)
bool ParseBoard(const wxString &aFileName)
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
std::vector< OBJECT > objects
std::vector< BOARD_DATA > boards
std::vector< POINT > points
std::vector< OBJECT > text_children
std::vector< uint32_t > groups
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683