KiCad PCB EDA Suite
Loading...
Searching...
No Matches
diptrace_pcb_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
37
38#ifndef DIPTRACE_PCB_PARSER_H_
39#define DIPTRACE_PCB_PARSER_H_
40
42#include <math/vector2d.h>
43
44#include <map>
45#include <unordered_map>
46#include <vector>
47
48class BOARD;
49class FOOTPRINT;
50class NETINFO_ITEM;
51class PAD;
52class PCB_SHAPE;
53class PCB_TEXT;
54enum PCB_LAYER_ID : int;
55
56namespace DIPTRACE
57{
58
59// ---------------------------------------------------------------------------
60// Intermediate data structures for parsed DipTrace content
61// ---------------------------------------------------------------------------
62
64{
65 int x = 0;
66 int y = 0;
67 uint8_t arc = 0;
68};
69
71{
72 uint8_t flag = 0;
73 int index = 0;
74 uint32_t color = 0;
75 wxString name;
76 int type = 0;
77 int planeNetIndex = -1;
78 int fieldD = 0;
79};
80
82{
83 wxString name;
86 int layer1 = -1;
87 int layer2 = -1;
88};
89
91{
92 wxString name;
93 int clearance = 0;
94 int trackWidth = 0;
95};
96
97struct DT_PAD
98{
99 int index = 0;
100 int netIndex = -1;
101 int x = 0;
102 int y = 0;
103 wxString number;
104 wxString label;
105 int width = 0;
106 int height = 0;
107 int drillWidth = 0;
108 int drillHeight = 0;
109 int style = 1;
110 uint8_t mountType = 0;
111 uint8_t orientClass = 0;
112
115 std::vector<std::pair<int, int>> polygonVertices;
116};
117
118
120{
121 int x = 0;
122 int y = 0;
125};
126
137
139{
141 int x1 = 0;
142 int y1 = 0;
143 int x2 = 0;
144 int y2 = 0;
145 int midX = 0;
146 int midY = 0;
147 int width = 0;
148 int layer = 0;
149};
150
152{
153 wxString libraryPath;
154 int positionX = 0;
155 int positionY = 0;
158 double placementAngleDeg = 0.0;
159 bool hasPlacementAngle = false;
160 int rotation = 0;
161 int fieldC = 0;
162 int fieldD = 0;
163 wxString patternName;
164 wxString displayName;
165 wxString refdes;
166 wxString value;
167 int layer = 0;
168 int bboxWidth = 0;
169 int bboxHeight = 0;
170 int padWidthHint = 0;
174 int fieldA = 0;
175 int fieldF = 0;
176 bool isStandaloneVia = false;
177 std::vector<uint8_t> flags;
178 std::vector<DT_PAD> pads;
179 std::vector<DT_MOUNT_HOLE> holes;
180 std::vector<DT_FP_SHAPE> shapes;
181 size_t boundaryOffset = 0;
182 size_t stringStartOffset = 0;
183 size_t regionEndOffset = 0;
184 size_t headerEndOffset = 0;
185 size_t padRegionEnd = 0;
186
187 // Text positioning from the 37-byte component tail
189 int valueYOffset = 0;
190 bool refdesVisible = true;
191 bool valueVisible = true;
192 bool hasTailData = false;
193};
194
196{
197 wxString text;
198 wxString fontName;
199 int lineWidth = 0;
200 int layer = 0;
201 int x1 = 0;
202 int y1 = 0;
203 int x2 = 0;
204 int y2 = 0;
205 uint32_t color = 0;
206};
207
209{
210 int componentIndex = -1;
211 int padIndex = -1;
212};
213
214struct DT_NET
215{
216 int index = 0;
217 wxString name;
218 int traceWidth = 0;
221 std::vector<DT_PAD_REF> padRefs;
222};
223
225{
226 int x = 0;
227 int y = 0;
228 int layer = 0;
229 int width = 0;
230 uint8_t routeFlag = 0;
231 int routeMode = 0;
232 bool hasVia = false;
233 int viaOuterDiam = 0;
234 int viaDrillDiam = 0;
235 int viaStyleIdx = -1;
236};
237
239{
240 int netIndex = -1;
241 std::vector<DT_TRACK_NODE> nodes;
242};
243
245{
246 int field0 = 0;
247 int field1 = 0;
248 int field2 = 0;
249 int field3 = 0;
250 int field4 = 0;
251 int field5 = 0;
252};
253
255{
256 int netIndex = -1;
257 int layer = 0;
258 int priority = 0;
259 uint8_t fillMode = 0;
260 uint8_t rawFlag2 = 0;
261 uint8_t connectionMode = 0;
262 int separator = 0;
263 int clearance = 0;
264 int minWidth = 0;
265 int minimumArea = 0;
266 int spokeMode = -1;
267 int lineSpacing = 0;
268 int spokeWidth = 0;
273 int zoneId = -1;
274 int smdSpokeMode = -1;
276 uint8_t viaDirect = 0;
277 uint8_t smdSeparate = 0;
278 uint8_t islandRegion = 0;
279 uint8_t islandInternal = 0;
280 uint8_t islandConnection = 0;
281 uint8_t ratlineMode = 0;
282 uint8_t regionsDone = 0;
283 std::vector<DT_ZONE_CACHED_FILL_RECORD> cachedFillRecords;
284 std::vector<std::pair<int, int>> outline;
285};
286
287
288// ---------------------------------------------------------------------------
289// Main parser class
290// ---------------------------------------------------------------------------
291
296{
297public:
304 PCB_PARSER( const wxString& aFileName, BOARD* aBoard );
305 ~PCB_PARSER();
306
308 void Parse();
309
321
323 int PadLocatorScans() const { return m_padLocatorScans; }
327
336 wxString GenerateDesignRules() const;
337
338private:
339 // --- Section parsers ---
340 void ParseMagic();
342 void ParseOutline();
343 void ParsePostOutline();
344 void ParseLayers();
345 void ParseFontStyle();
346 void ParsePatternNameGroups( int aGroupCount );
347 void ParsePatternStyleGroups( int aGroupCount );
349 void ParseDesignRules();
351
363
365
370 std::vector<std::pair<size_t, size_t>> FieldWalkComponentBoundaries( size_t aUpperBound );
371
372 // --- Component parsing helpers ---
373 bool ParseSingleComponent( size_t aBoundaryOffset, size_t aUpperBound,
374 DT_COMPONENT& aComp );
375
377 static bool ClassifyStandaloneVia( const DT_COMPONENT& aComp );
378
380 void FindPadsInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
381
383 void FindMountHolesInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
384
386 void FindShapesInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
387
389 void FindShapesInFontBlocks( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
390
392 void FindShapesInChainedBlocks( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
393
395 void ParseComponentTail( DT_COMPONENT& aComp, size_t aRegionEnd );
396
397 // --- Net and routing parsing ---
398 void FindAndParseNets( size_t aSearchStart, size_t aSearchEnd );
399 void ParseNetRouting( DT_NET& aNet );
401
402 // --- Zone parsing ---
403 void FindAndParseZones( size_t aSearchStart, size_t aSearchEnd );
404
405 // --- Board object creation ---
406 void ApplyBoardSettings();
407 void CreateBoardOutline();
408 void CreateFootprint( const DT_COMPONENT& aComp );
410 void CreateTextObject( const DT_TEXT_OBJECT& aText );
411 void CreateNets();
412 void CreateTracksAndVias();
413 void CreateZones();
414
416 void CreatePlaneZones();
417
419 NETINFO_ITEM* ResolveNetByIndex( int aDipTraceNetIndex ) const;
420 const DT_NET* ResolveDipTraceNetByIndex( int aDipTraceNetIndex ) const;
421
422 // --- Text object parsing ---
423 void FindAndParseTextObjects( size_t aSearchStart, size_t aSearchEnd );
424 void ParseTextRecords( int aCount );
425
426 // --- Utility ---
427
429 PCB_LAYER_ID MapLayer( int aDipTraceLayer ) const;
430 PCB_LAYER_ID MapCopperLayer( int aDipTraceLayer ) const;
431
433 static int ToKiCadCoord( int aDipTraceCoord );
434
436 static double ToKiCadAngleDeg( int aDipTraceAngle );
437
440
442 static bool TryReadStringAt( const uint8_t* aData, size_t aDataSize,
443 size_t aPos, int aVersion,
444 wxString& aOut, size_t& aNewPos );
445
447 static std::vector<size_t> FindAllBoundaries( const uint8_t* aData, size_t aDataSize,
448 const uint8_t* aPattern, size_t aPatternLen,
449 size_t aStart, size_t aEnd );
450
451 // --- Data ---
457
458 // Parsed intermediate data
459 std::vector<DT_VERTEX> m_outline;
460 std::vector<DT_LAYER> m_layers;
461 std::vector<DT_VIA_STYLE> m_viaStyles;
462 std::vector<DT_DESIGN_RULE> m_designRules;
463 std::vector<DT_COMPONENT> m_components;
464 std::vector<DT_TEXT_OBJECT> m_textObjects;
465 std::vector<DT_NET> m_nets;
466 std::vector<DT_TRACK_CHAIN> m_trackChains;
467 std::vector<DT_ZONE> m_zones;
468 std::unordered_map<int, int> m_copperLayerOrdinalById;
469 std::unordered_map<int, std::vector<VECTOR2I>> m_routingAnchorsByNet;
471
472 // Link table between DipTrace net indices and created KiCad nets.
473 std::unordered_map<int, NETINFO_ITEM*> m_kicadNetByDipTraceIndex;
474 std::unordered_map<int, const DT_NET*> m_dipTraceNetByIndex;
475
476 // Board properties
477 int m_bboxXMin = 0;
478 int m_bboxYMin = 0;
479 int m_bboxXMax = 0;
480 int m_bboxYMax = 0;
481
482 // Section tracking
487
488 // Determinism instrumentation. Each counter records how many objects/sections of its
489 // category were located by byte-pattern scanning rather than a field-derived offset.
490 // The determinism work drives every category to zero, one at a time, while keeping the
491 // scanners as recovery fallbacks. See ScanLocatorUseCount().
497};
498
499} // namespace DIPTRACE
500
501#endif // DIPTRACE_PCB_PARSER_H_
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
Low-level binary reader for DipTrace file formats.
PCB_PARSER(const wxString &aFileName, BOARD *aBoard)
Construct a parser for the given file.
void ParseTextRecords(int aCount)
std::vector< DT_TEXT_OBJECT > m_textObjects
static double ToKiCadAngleDeg(int aDipTraceAngle)
Convert a DipTrace angle value to degrees (tenths of degree).
std::unordered_map< int, NETINFO_ITEM * > m_kicadNetByDipTraceIndex
PCB_LAYER_ID MapCopperLayer(int aDipTraceLayer) const
std::vector< DT_VIA_STYLE > m_viaStyles
static int ToKiCadCoord(int aDipTraceCoord)
Convert a DipTrace coordinate (DipTrace units) to KiCad internal units (nm).
static std::vector< size_t > FindAllBoundaries(const uint8_t *aData, size_t aDataSize, const uint8_t *aPattern, size_t aPatternLen, size_t aStart, size_t aEnd)
Find all occurrences of a byte pattern within data[start:end].
void ParsePatternStyleGroups(int aGroupCount)
std::vector< DT_COMPONENT > m_components
int ScanLocatorUseCount() const
Number of objects or sections that were located by byte-pattern scanning rather than a deterministic ...
void ParseComponentTail(DT_COMPONENT &aComp, size_t aRegionEnd)
Parse the 37-byte tail at the end of a component region to extract text positioning.
void CreateFootprint(const DT_COMPONENT &aComp)
void FindPadsInRegion(DT_COMPONENT &aComp, size_t aRegionStart, size_t aRegionEnd)
Search a component's data region for pad records using pad name anchors.
std::vector< DT_DESIGN_RULE > m_designRules
std::vector< std::pair< size_t, size_t > > FieldWalkComponentBoundaries(size_t aUpperBound)
Deterministically walk the component boundaries from the design-rules end, anchoring on each componen...
std::vector< DT_LAYER > m_layers
void ParsePatternNameGroups(int aGroupCount)
void ParseNetRouting(DT_NET &aNet)
void FindShapesInChainedBlocks(DT_COMPONENT &aComp, size_t aRegionStart, size_t aRegionEnd)
Parse shapes from chained fixed-size records used by some v46+ footprints.
static bool TryReadStringAt(const uint8_t *aData, size_t aDataSize, size_t aPos, int aVersion, wxString &aOut, size_t &aNewPos)
Try to read a string at a given raw data position.
std::vector< DT_NET > m_nets
std::unordered_map< int, std::vector< VECTOR2I > > m_routingAnchorsByNet
void SkipInterRulesetTransition()
Read an inter-ruleset transition block.
NETINFO_ITEM * ResolveNetByIndex(int aDipTraceNetIndex) const
Resolve a DipTrace net index to the corresponding KiCad net object.
std::vector< DT_VERTEX > m_outline
void CreatePlaneZones()
Synthesize board-outline-bounded plane fills for negative/solid-plane copper layers.
bool ParseSingleComponent(size_t aBoundaryOffset, size_t aUpperBound, DT_COMPONENT &aComp)
void FindMountHolesInRegion(DT_COMPONENT &aComp, size_t aRegionStart, size_t aRegionEnd)
Parse component-local mechanical holes (NPTH) from the post-pad region.
void CreateTextObject(const DT_TEXT_OBJECT &aText)
void ApplyPlacementAngles()
Refine component placement angles with the exact values from the placement section.
wxString GenerateDesignRules() const
Build a KiCad custom design-rule (.kicad_dru) document for the per-zone DipTrace properties that have...
static bool ClassifyStandaloneVia(const DT_COMPONENT &aComp)
Decide whether a parsed component is a standalone via rather than a placed footprint.
std::unordered_map< int, const DT_NET * > m_dipTraceNetByIndex
const DT_NET * ResolveDipTraceNetByIndex(int aDipTraceNetIndex) const
void FindAndParseNets(size_t aSearchStart, size_t aSearchEnd)
void FindAndParseTextObjects(size_t aSearchStart, size_t aSearchEnd)
void Parse()
Parse the file and populate the board. Throws IO_ERROR on failure.
std::unordered_map< int, int > m_copperLayerOrdinalById
PCB_LAYER_ID MapLayer(int aDipTraceLayer) const
Map a DipTrace layer index to a KiCad PCB_LAYER_ID.
void FindShapesInRegion(DT_COMPONENT &aComp, size_t aRegionStart, size_t aRegionEnd)
Parse footprint outline shapes from the region after pad data.
void FindAndParseZones(size_t aSearchStart, size_t aSearchEnd)
std::vector< DT_ZONE > m_zones
void FindShapesInFontBlocks(DT_COMPONENT &aComp, size_t aRegionStart, size_t aRegionEnd)
Parse shapes from per-layer font blocks (v46+ format).
std::vector< DT_TRACK_CHAIN > m_trackChains
Handle the data for a net.
Definition netinfo.h:50
Definition pad.h:65
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ DT_SHAPE_FILLOBROUND
Filled obround marker (e.g. diode cathode / pin-1 dot)
int fieldD
Raw header int4; matches Pattern.Float3 in DipXML.
std::vector< DT_FP_SHAPE > shapes
Graphics in normalized coordinates.
int rotation
Raw header int4; matches Pattern.Float1 in DipXML (not placement angle)
int positionX
DipTrace units.
int padHeightHint
Raw bbox companion field (pad height in DipTrace units)
size_t regionEndOffset
Component region end offset (next boundary / upper bound)
bool valueVisible
(Currently same flag as refdesVisible)
bool isStandaloneVia
True for explicit standalone via components.
int fieldF
Raw header int3 field F (component kind discriminator)
int drillWidthHint
Raw bbox companion field (drill width in DipTrace units)
int bboxHeight
Footprint Y extent in DipTrace units (for shape scaling)
int placementQuarterTurns
Board-placement angle snapped to 90-degree turns (metadata Id-6 int3)
size_t boundaryOffset
Boundary marker offset for this component record.
std::vector< uint8_t > flags
int padWidthHint
Raw bbox companion field (pad width in DipTrace units)
size_t stringStartOffset
Parsed start offset of library-path string.
int refdesYOffset
Refdes text Y offset from component origin (DipTrace units)
double placementAngleDeg
Exact board-placement angle in degrees (placement section), when available.
std::vector< DT_MOUNT_HOLE > holes
int bboxWidth
Footprint X extent in DipTrace units (for shape scaling)
int layer
0 = top, 1 = bottom
std::vector< DT_PAD > pads
int positionY
DipTrace units.
int drillHeightHint
Raw bbox companion field (drill height in DipTrace units)
bool hasTailData
True if the 37-byte tail was successfully parsed.
size_t headerEndOffset
Byte offset after parsed component header strings.
int fieldC
Raw header int4; matches Pattern.Float2 in DipXML.
int valueYOffset
Value text Y offset from component origin (DipTrace units)
size_t padRegionEnd
Byte offset after last pad record (for shape finding)
bool refdesVisible
False when text visibility flag is -1.
int fieldA
Raw header int3 field A.
int midY
Arc midpoint Y in normalized units.
int x2
End X in normalized units.
int type
Shape type (DT_SHAPE_TYPE)
int y1
Start Y in normalized units.
int midX
Arc midpoint X in normalized units.
int x1
Start X in normalized units (range ±5000)
int width
Line width in normalized units (-10000 = default)
int layer
DipTrace layer index.
int y2
End Y in normalized units.
int type
Layer type from record field_a (0 = Signal, 1 = Plane)
int planeNetIndex
Plane net DipTrace index from record field_c (-1 = none/Signal)
uint32_t color
0x00RRGGBB
int fieldD
Possibly default trace width.
int outerDiameter
Non-copper/clearance diameter in DipTrace units.
int drillDiameter
Drill diameter in DipTrace units.
int y
Y offset from component origin in DipTrace units.
int x
X offset from component origin in DipTrace units.
wxString name
Stored net name; may be empty in DipTrace files.
int defaultViaDrillDiam
Default via drill from net routing preamble.
int index
Sequential net index from the DipTrace file.
std::vector< DT_PAD_REF > padRefs
Optional net-to-pad links from routing metadata.
int traceWidth
Default trace width in DipTrace units; parsed but not yet used.
int defaultViaOuterDiam
Default via OD from net routing preamble.
int componentIndex
Component index referenced from net routing metadata.
int padIndex
Pad index (1-based within the component)
uint8_t orientClass
Pad orientation class from pad post-block tail byte.
int x
X offset from component origin in DipTrace units.
std::vector< std::pair< int, int > > polygonVertices
Custom polygon vertices relative to pad center (DipTrace units).
int netIndex
Net index from DipTrace file (-1 = unconnected)
int y
Y offset from component origin in DipTrace units.
uint8_t mountType
Explicit mount class from pad post-block (0=through, 1=SMD)
int style
Pad style (0=ellipse, 1=oval, 2=rectangle, 3=polygon)
int drillWidth
Drill width in DipTrace units (0 for SMD)
int height
Copper pad height in DipTrace units.
int drillHeight
Drill height in DipTrace units (0 for SMD)
wxString label
Functional label (e.g. "POS", "GND")
int index
Sequential pad index within the component (1-based)
int width
Copper pad width in DipTrace units.
wxString number
Pad number/name (e.g. "1", "2")
std::vector< DT_TRACK_NODE > nodes
Ordered sequence of routing nodes.
int netIndex
Net this chain belongs to.
int y
Y coordinate in DipTrace units.
int viaDrillDiam
Via drill diameter in DipTrace units.
int x
X coordinate in DipTrace units.
int viaStyleIdx
Index into ViaStyle table (-1 = none)
int routeMode
Raw routing-point mode int3 at payload +37 (observed: 0/1/3)
uint8_t routeFlag
Raw routing-point flag byte at payload +22 (semantics unresolved)
int viaOuterDiam
Via outer diameter in DipTrace units.
bool hasVia
True if a via exists at this node.
int layer
Copper layer index (0=top, 1=bottom, 14+=inner)
int width
Track width in DipTrace units.
uint8_t arc
0 = straight segment, 1 = arc segment
int x
X coordinate in DipTrace units.
int y
Y coordinate in DipTrace units.
int field2
Raw int4 payload field 2.
int field0
Raw int3 discriminator/index.
int field5
Raw int4 payload field 5.
int field1
Raw int4 payload field 1.
int field3
Raw int4 payload field 3.
int field4
Raw int4 payload field 4.
int spokeWidth
Thermal relief spoke width in DipTrace units.
uint8_t viaDirect
Raw ViaDirect flag from zone trailer.
uint8_t smdSeparate
Raw SMD_Separate flag from zone trailer.
int priority
Fill priority; left at the DipTrace default until the binary field is located.
int regionsCounted
Raw trailer int3, likely CopperPour Regions_Counted from Pcb.exe.
int smdSpokeWidth
Raw SMD_SpokeWidth from zone trailer.
uint8_t regionsDone
Raw RegionsDone flag from zone trailer.
int zoneId
Raw per-zone id from zone trailer (matches DipXML CopperPour@Id)
int minimumArea
Minimum island area scalar in DipTrace units (DipXML: MinimumArea)
int minWidth
Copper pour line width in DipTrace units (DipXML: LineWidth)
int layer
DipTrace layer (0=top, 1=bottom)
uint8_t connectionMode
Raw zone flag byte at header +5.
std::vector< std::pair< int, int > > outline
Outline vertices (x, y) in DipTrace units.
uint8_t rawFlag2
Raw zone flag byte at header +4 (semantics unknown)
int clearance
Zone clearance in DipTrace units.
uint8_t ratlineMode
Raw ratline mode (0=Automatically, 1=All Ratlines, 2=Do Not Hide)
int lineSpacing
Copper pour line spacing in DipTrace units (DipXML: LineSpacing)
int cachedFillRecordCount
Cached-fill record count when payload is 23-byte aligned.
std::vector< DT_ZONE_CACHED_FILL_RECORD > cachedFillRecords
Raw 23-byte cached fill records.
int cachedFillByteLen
Raw bytes between style block and trailer in inter-zone gap.
int smdSpokeMode
Raw SMD_Spoke enum from zone trailer.
int separator
Raw zone separator int3 at header +18.
uint8_t islandInternal
Raw IslandInternal flag from zone trailer.
int boardClearance
Raw board-clearance field from zone trailer.
int netIndex
Net index (-1 = unconnected)
uint8_t islandConnection
Raw IslandConnection flag from zone trailer.
uint8_t islandRegion
Raw IslandRegion flag from zone trailer.
int spokeMode
Raw spoke enum from post-fill style block (0=Direct, 3=4 spoke 45, 4=4 spoke)
uint8_t fillMode
Raw zone flag byte at header +3.