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, 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 * Binary format knowledge derived from:
24 * https://github.com/sergey-raevskiy/xlay (lay6.h)
25 * https://github.com/OpenBoardView/OpenBoardView (LAYFile.cpp)
26 */
27
28#ifndef SPRINT_LAYOUT_PARSER_H_
29#define SPRINT_LAYOUT_PARSER_H_
30
31#include <cstdint>
32#include <memory>
33#include <string>
34#include <vector>
35#include <map>
36#include <set>
37
38#include <layer_ids.h>
39#include <math/vector2d.h>
40
41class BOARD;
43class FOOTPRINT;
44class NETINFO_ITEM;
45class PAD;
46class PCB_SHAPE;
47class PCB_TEXT;
48class BOARD_ITEM;
49
51{
52
64
66{
67 LAYER_C1 = 1, // top copper
68 LAYER_S1 = 2, // top silkscreen
69 LAYER_C2 = 3, // bottom copper
70 LAYER_S2 = 4, // bottom silkscreen
71 LAYER_I1 = 5, // inner layer 1
72 LAYER_I2 = 6, // inner layer 2
73 LAYER_O = 7, // board outline
74};
75
90
91struct POINT
92{
93 float x;
94 float y;
95};
96
98{
99 bool valid = false;
100 float off_x = 0;
101 float off_y = 0;
102 uint8_t center_mode = 0;
103 double rotation = 0;
104 std::string package;
105 std::string comment;
106 uint8_t use = 0;
107};
108
109struct OBJECT
110{
111 uint8_t type = 0; // OBJECT_TYPE enum value
112 float x = 0;
113 float y = 0;
114 float outer = 0; // THT/circle outer radius, SMD half-width, text height
115 float inner = 0; // THT drill radius, SMD half-height, text stroke width
116 int32_t line_width = 0; // line/poly stroke width, circle end_angle
117 uint8_t layer = 0; // LAYER_ID enum value
118 uint8_t tht_shape = 0; // THT_SHAPE for pads, 1=component-ref for text
119 uint16_t component_id = 0;
120 int32_t start_angle = 0; // circle start angle, pad thermal style bytes
121 uint8_t filled = 0; // nonzero = filled polygon
122 int32_t clearance = 0; // ground plane clearance
123 uint8_t mirror_v = 0;
124 uint8_t mirror_h = 0; // or thermal relief spoke enable
125 uint8_t keepout = 0; // nonzero = ground plane exclusion area
126 int32_t rotation = 0; // rotation in degree units
127 uint8_t plated = 0; // 0 = NPTH, nonzero = plated
128 uint8_t soldermask = 0; // 0 = no mask opening (tented)
129
130 std::string text;
131 std::string identifier;
132 std::vector<uint32_t> groups;
133 std::vector<POINT> points;
134 std::vector<OBJECT> text_children;
136};
137
139{
140 std::string name;
141 uint32_t size_x = 0; // 1/10000 mm
142 uint32_t size_y = 0; // 1/10000 mm
143 int32_t center_x = 0; // 1/10000 mm
144 int32_t center_y = 0; // 1/10000 mm
145 uint8_t ground_plane[7] = {};
146 uint8_t is_multilayer = 0;
147 std::vector<OBJECT> objects;
148};
149
151{
152 uint8_t version = 0;
153 std::vector<BOARD_DATA> boards;
154 std::string project_name;
155 std::string project_author;
156 std::string project_company;
157 std::string project_comment;
158};
159
160} // namespace SPRINT_LAYOUT
161
162
163class NETINFO_ITEM;
164
166{
167public:
170
171 // Parse full Sprint Layout board files (.lay6 / .lay) into internal file data
172 bool ParseBoard( const wxString& aFileName );
173
174 // Parse a macro (LMK) file with objects in BOARD_DATA with index 0
175 bool ParseMacroFile( const wxString& aFileName );
176
177 // Create a BOARD from BOARD_DATA at the given index, and populate the provided footprint map with any footprints found in the file.
178 BOARD* CreateBoard( std::map<wxString, std::unique_ptr<FOOTPRINT>>& aFootprintMap, size_t aBoardIndex = 0 );
179
180 // Create a single FOOTPRINT from the board at index 0
182
184
185private:
186 // Binary reading helpers
187 uint8_t readUint8();
188 uint16_t readUint16();
189 int16_t readInt16();
190 uint32_t readUint32();
191 uint32_t readUnsigned();
192 int32_t readInt32();
193 int32_t readSigned();
194 float readFloat();
195 double readDouble();
196 float readCoord();
197 std::string readFixedString( size_t aMaxLen );
198 std::string readVarString();
199 void skip( size_t aBytes );
200 void seek( int aBytes );
201
202 void parseFileStart( const wxString& aFileName );
207 void parseObject( SPRINT_LAYOUT::OBJECT& aObject, bool aIsTextChild = false );
208 void parseTrailer();
209
210 // Board construction helpers
211 PCB_LAYER_ID mapLayer( uint8_t aSprintLayer ) const;
212 int sprintToKicadCoord( float aValue ) const;
213 VECTOR2I sprintToKicadPos( float aX, float aY ) const;
214 wxString convertString( const std::string& aStr ) const;
215
216 bool layerHasGroundPlane( PCB_LAYER_ID aLayer, const uint8_t aGroundPlane[7] ) const;
217
219 const uint8_t aGroundPlane[7], NETINFO_ITEM* aGndPlaneNet ) const;
220
221 void processPad( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj, const uint8_t aGroundPlane[7],
222 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
223
224 void processCircle( 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 processLine( 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 processSegment( 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 processPoly( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
237 std::vector<std::vector<VECTOR2I>>& aOutlineSegments, const uint8_t aGroundPlane[7],
238 NETINFO_ITEM* aGndPlaneNet, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
239
240 void processText( BOARD_ITEM_CONTAINER* aContainer, const SPRINT_LAYOUT::OBJECT& aObj,
241 std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
242
243 void processItemGroups( BOARD_ITEM* aItem, const SPRINT_LAYOUT::OBJECT& aObj,
244 std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
245
246 void buildOutline( BOARD* aBoard, std::vector<std::vector<VECTOR2I>>& aOutlineSegments,
247 const SPRINT_LAYOUT::BOARD_DATA& aBoardData );
248
249 void resolveGroups( BOARD_ITEM_CONTAINER* aContainer, std::map<uint32_t, std::set<BOARD_ITEM*>>& aGidToItems );
250
252 const uint8_t* m_pos = nullptr;
253 const uint8_t* m_start = nullptr;
254 const uint8_t* m_end = nullptr;
255 std::vector<uint8_t> m_buffer;
256 bool m_parsingMacro = false;
257};
258
259#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:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
Handle the data for a net.
Definition netinfo.h:50
Definition pad.h:55
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:60
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:687