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, see <https://www.gnu.org/licenses/>.
18 */
19
33
34#ifndef DIPTRACE_PCB_PARSER_H_
35#define DIPTRACE_PCB_PARSER_H_
36
38#include <math/vector2d.h>
39
40#include <map>
41#include <unordered_map>
42#include <vector>
43
44class BOARD;
45class FOOTPRINT;
46class NETINFO_ITEM;
47class PAD;
48class PCB_SHAPE;
49class PCB_TEXT;
50enum PCB_LAYER_ID : int;
51
52namespace DIPTRACE
53{
54
55// ---------------------------------------------------------------------------
56// Intermediate data structures for parsed DipTrace content
57// ---------------------------------------------------------------------------
58
60{
61 int x = 0;
62 int y = 0;
63 uint8_t arc = 0;
64};
65
67{
68 uint8_t flag = 0;
69 int index = 0;
70 uint32_t color = 0;
71 wxString name;
72 int type = 0;
73 int planeNetIndex = -1;
74 int fieldD = 0;
75};
76
78{
79 wxString name;
82 int layer1 = -1;
83 int layer2 = -1;
84};
85
87{
88 wxString name;
89 int clearance = 0;
90 int trackWidth = 0;
91};
92
93struct DT_PAD
94{
95 int index = 0;
96 int netIndex = -1;
97 int x = 0;
98 int y = 0;
99 wxString number;
100 wxString label;
101 int width = 0;
102 int height = 0;
103 int drillWidth = 0;
104 int drillHeight = 0;
105 int style = 1;
106 uint8_t mountType = 0;
107 uint8_t orientClass = 0;
108
111 std::vector<std::pair<int, int>> polygonVertices;
112};
113
114
116{
117 int x = 0;
118 int y = 0;
121};
122
133
135{
137 int x1 = 0;
138 int y1 = 0;
139 int x2 = 0;
140 int y2 = 0;
141 int midX = 0;
142 int midY = 0;
143 int width = 0;
144 int layer = 0;
145};
146
148{
149 wxString libraryPath;
150 int positionX = 0;
151 int positionY = 0;
154 double placementAngleDeg = 0.0;
155 bool hasPlacementAngle = false;
156 int rotation = 0;
157 int fieldC = 0;
158 int fieldD = 0;
159 wxString patternName;
160 wxString displayName;
161 wxString refdes;
162 wxString value;
163 int layer = 0;
164 int bboxWidth = 0;
165 int bboxHeight = 0;
166 int padWidthHint = 0;
170 int fieldA = 0;
171 int fieldF = 0;
172 bool isStandaloneVia = false;
173 std::vector<uint8_t> flags;
174 std::vector<DT_PAD> pads;
175 std::vector<DT_MOUNT_HOLE> holes;
176 std::vector<DT_FP_SHAPE> shapes;
177 size_t boundaryOffset = 0;
178 size_t stringStartOffset = 0;
179 size_t regionEndOffset = 0;
180 size_t headerEndOffset = 0;
181 size_t padRegionEnd = 0;
182
183 // Text positioning from the 37-byte component tail
185 int valueYOffset = 0;
186 bool refdesVisible = true;
187 bool valueVisible = true;
188 bool hasTailData = false;
189};
190
192{
193 wxString text;
194 wxString fontName;
195 int lineWidth = 0;
196 int layer = 0;
197 int x1 = 0;
198 int y1 = 0;
199 int x2 = 0;
200 int y2 = 0;
201 uint32_t color = 0;
202};
203
205{
206 int componentIndex = -1;
207 int padIndex = -1;
208};
209
210struct DT_NET
211{
212 int index = 0;
213 wxString name;
214 int traceWidth = 0;
217 std::vector<DT_PAD_REF> padRefs;
218};
219
221{
222 int x = 0;
223 int y = 0;
224 int layer = 0;
225 int width = 0;
226 uint8_t routeFlag = 0;
227 int routeMode = 0;
228 bool hasVia = false;
229 int viaOuterDiam = 0;
230 int viaDrillDiam = 0;
231 int viaStyleIdx = -1;
232};
233
235{
236 int netIndex = -1;
237 std::vector<DT_TRACK_NODE> nodes;
238};
239
241{
242 int field0 = 0;
243 int field1 = 0;
244 int field2 = 0;
245 int field3 = 0;
246 int field4 = 0;
247 int field5 = 0;
248};
249
251{
252 int netIndex = -1;
253 int layer = 0;
254 int priority = 0;
255 uint8_t fillMode = 0;
256 uint8_t rawFlag2 = 0;
257 uint8_t connectionMode = 0;
258 int separator = 0;
259 int clearance = 0;
260 int minWidth = 0;
261 int minimumArea = 0;
262 int spokeMode = -1;
263 int lineSpacing = 0;
264 int spokeWidth = 0;
269 int zoneId = -1;
270 int smdSpokeMode = -1;
272 uint8_t viaDirect = 0;
273 uint8_t smdSeparate = 0;
274 uint8_t islandRegion = 0;
275 uint8_t islandInternal = 0;
276 uint8_t islandConnection = 0;
277 uint8_t ratlineMode = 0;
278 uint8_t regionsDone = 0;
279 std::vector<DT_ZONE_CACHED_FILL_RECORD> cachedFillRecords;
280 std::vector<std::pair<int, int>> outline;
281};
282
283
284// ---------------------------------------------------------------------------
285// Main parser class
286// ---------------------------------------------------------------------------
287
292{
293public:
300 PCB_PARSER( const wxString& aFileName, BOARD* aBoard );
301 ~PCB_PARSER();
302
304 void Parse();
305
317
319 int PadLocatorScans() const { return m_padLocatorScans; }
323
332 wxString GenerateDesignRules() const;
333
334private:
335 // --- Section parsers ---
336 void ParseMagic();
338 void ParseOutline();
339 void ParsePostOutline();
340 void ParseLayers();
341 void ParseFontStyle();
342 void ParsePatternNameGroups( int aGroupCount );
343 void ParsePatternStyleGroups( int aGroupCount );
345 void ParseDesignRules();
347
359
361
366 std::vector<std::pair<size_t, size_t>> FieldWalkComponentBoundaries( size_t aUpperBound );
367
368 // --- Component parsing helpers ---
369 bool ParseSingleComponent( size_t aBoundaryOffset, size_t aUpperBound,
370 DT_COMPONENT& aComp );
371
373 static bool ClassifyStandaloneVia( const DT_COMPONENT& aComp );
374
376 void FindPadsInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
377
379 void FindMountHolesInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
380
382 void FindShapesInRegion( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
383
385 void FindShapesInFontBlocks( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
386
388 void FindShapesInChainedBlocks( DT_COMPONENT& aComp, size_t aRegionStart, size_t aRegionEnd );
389
391 void ParseComponentTail( DT_COMPONENT& aComp, size_t aRegionEnd );
392
393 // --- Net and routing parsing ---
394 void FindAndParseNets( size_t aSearchStart, size_t aSearchEnd );
395 void ParseNetRouting( DT_NET& aNet );
397
398 // --- Zone parsing ---
399 void FindAndParseZones( size_t aSearchStart, size_t aSearchEnd );
400
401 // --- Board object creation ---
402 void ApplyBoardSettings();
403 void CreateBoardOutline();
404 void CreateFootprint( const DT_COMPONENT& aComp );
406 void CreateTextObject( const DT_TEXT_OBJECT& aText );
407 void CreateNets();
408 void CreateTracksAndVias();
409 void CreateZones();
410
412 void CreatePlaneZones();
413
415 NETINFO_ITEM* ResolveNetByIndex( int aDipTraceNetIndex ) const;
416 const DT_NET* ResolveDipTraceNetByIndex( int aDipTraceNetIndex ) const;
417
418 // --- Text object parsing ---
419 void FindAndParseTextObjects( size_t aSearchStart, size_t aSearchEnd );
420 void ParseTextRecords( int aCount );
421
422 // --- Utility ---
423
425 PCB_LAYER_ID MapLayer( int aDipTraceLayer ) const;
426 PCB_LAYER_ID MapCopperLayer( int aDipTraceLayer ) const;
427
429 static int ToKiCadCoord( int aDipTraceCoord );
430
432 static double ToKiCadAngleDeg( int aDipTraceAngle );
433
436
438 static bool TryReadStringAt( const uint8_t* aData, size_t aDataSize,
439 size_t aPos, int aVersion,
440 wxString& aOut, size_t& aNewPos );
441
443 static std::vector<size_t> FindAllBoundaries( const uint8_t* aData, size_t aDataSize,
444 const uint8_t* aPattern, size_t aPatternLen,
445 size_t aStart, size_t aEnd );
446
447 // --- Data ---
453
454 // Parsed intermediate data
455 std::vector<DT_VERTEX> m_outline;
456 std::vector<DT_LAYER> m_layers;
457 std::vector<DT_VIA_STYLE> m_viaStyles;
458 std::vector<DT_DESIGN_RULE> m_designRules;
459 std::vector<DT_COMPONENT> m_components;
460 std::vector<DT_TEXT_OBJECT> m_textObjects;
461 std::vector<DT_NET> m_nets;
462 std::vector<DT_TRACK_CHAIN> m_trackChains;
463 std::vector<DT_ZONE> m_zones;
464 std::unordered_map<int, int> m_copperLayerOrdinalById;
465 std::unordered_map<int, std::vector<VECTOR2I>> m_routingAnchorsByNet;
467
468 // Link table between DipTrace net indices and created KiCad nets.
469 std::unordered_map<int, NETINFO_ITEM*> m_kicadNetByDipTraceIndex;
470 std::unordered_map<int, const DT_NET*> m_dipTraceNetByIndex;
471
472 // Board properties
473 int m_bboxXMin = 0;
474 int m_bboxYMin = 0;
475 int m_bboxXMax = 0;
476 int m_bboxYMax = 0;
477
478 // Section tracking
483
484 // Determinism instrumentation. Each counter records how many objects/sections of its
485 // category were located by byte-pattern scanning rather than a field-derived offset.
486 // The determinism work drives every category to zero, one at a time, while keeping the
487 // scanners as recovery fallbacks. See ScanLocatorUseCount().
493};
494
495} // namespace DIPTRACE
496
497#endif // DIPTRACE_PCB_PARSER_H_
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
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:46
Definition pad.h:61
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ 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.