Skip to content

Commit a335f79

Browse files
committed
Add tracks and zones support
Issue #113
1 parent 6610e68 commit a335f79

File tree

5 files changed

+116
-7
lines changed

5 files changed

+116
-7
lines changed

InteractiveHtmlBom/ecad/kicad.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,49 @@ def parse_modules(self, pcb_modules):
339339

340340
return modules
341341

342+
def parse_tracks(self, tracks):
343+
result = {pcbnew.F_Cu: [], pcbnew.B_Cu: []}
344+
for track in tracks:
345+
if track.GetClass() == "VIA":
346+
track_dict = {
347+
"start": self.normalize(track.GetStart()),
348+
"end": self.normalize(track.GetEnd()),
349+
"width": track.GetWidth() * 1e-6,
350+
"net": track.GetNetname(),
351+
}
352+
for l in [pcbnew.F_Cu, pcbnew.B_Cu]:
353+
if track.IsOnLayer(l):
354+
result[l].append(track_dict)
355+
else:
356+
if track.GetLayer() in [pcbnew.F_Cu, pcbnew.B_Cu]:
357+
result[track.GetLayer()].append({
358+
"start": self.normalize(track.GetStart()),
359+
"end": self.normalize(track.GetEnd()),
360+
"width": track.GetWidth() * 1e-6,
361+
"net": track.GetNetname(),
362+
})
363+
364+
return {
365+
'F': result.get(pcbnew.F_Cu),
366+
'B': result.get(pcbnew.B_Cu)
367+
}
368+
369+
def parse_zones(self, zones):
370+
result = {pcbnew.F_Cu: [], pcbnew.B_Cu: []}
371+
for zone in zones:
372+
if not zone.IsFilled() or zone.GetIsKeepout():
373+
continue
374+
if zone.GetLayer() in [pcbnew.F_Cu, pcbnew.B_Cu]:
375+
result[zone.GetLayer()].append({
376+
"polygons": self.parse_poly_set(zone.GetFilledPolysList()),
377+
"net": zone.GetNetname(),
378+
})
379+
380+
return {
381+
'F': result.get(pcbnew.F_Cu),
382+
'B': result.get(pcbnew.B_Cu)
383+
}
384+
342385
@staticmethod
343386
def module_to_component(module):
344387
# type: (pcbnew.MODULE) -> Component
@@ -409,6 +452,8 @@ def parse(self):
409452
"bom": {},
410453
"font_data": self.font_parser.get_parsed_font()
411454
}
455+
pcbdata["tracks"] = self.parse_tracks(self.board.GetTracks())
456+
pcbdata["zones"] = self.parse_zones(self.board.Zones())
412457
components = [self.module_to_component(m) for m in pcb_modules]
413458

414459
return pcbdata, components

InteractiveHtmlBom/web/ibom.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
--fabrication-edge-color: #907651;
1111
--fabrication-polygon-color: #907651;
1212
--fabrication-text-color: #a27c24;
13+
--track-color: #def5f1;
14+
--zone-color: #def5f1;
1315
}
1416

1517
html, body {
@@ -23,6 +25,8 @@ html, body {
2325
--pad-color: #808080;
2426
--pin1-outline-color: #ffa800;
2527
--pin1-outline-color-highlight: #ccff00;
28+
--track-color: #42524f;
29+
--zone-color: #42524f;
2630
background-color: #252c30;
2731
color: #eee;
2832
}

InteractiveHtmlBom/web/ibom.html

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,30 @@
5555
<input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
5656
Show footprint pads
5757
</label>
58-
<label class="menu-label">
58+
<label class="menu-label" style="width: calc(50% - 18px)">
5959
<input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
60-
Show fabrication layer
61-
</label>
62-
<label class="menu-label">
60+
Fab layer
61+
</label><!-- This comment eats space! All of it!
62+
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
6363
<input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
64-
Show silkscreen
64+
Silkscreen
6565
</label>
6666
<label class="menu-label" style="width: calc(50% - 18px)">
6767
<input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
6868
References
6969
</label><!-- This comment eats space! All of it!
70-
--><label class="menu-label" style="width: calc(50% - 18px); border-left: 0;">
70+
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
7171
<input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
7272
Values
7373
</label>
74+
<label class="menu-label" style="width: calc(50% - 18px)">
75+
<input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
76+
Tracks
77+
</label><!-- This comment eats space! All of it!
78+
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
79+
<input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
80+
Zones
81+
</label>
7482
<label class="menu-label">
7583
<input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
7684
DNP components outlined

InteractiveHtmlBom/web/ibom.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ function valuesVisible(value) {
4646
redrawIfInitDone();
4747
}
4848

49+
function tracksVisible(value) {
50+
writeStorage("tracksVisible", value);
51+
renderTracks = value;
52+
redrawIfInitDone();
53+
}
54+
55+
function zonesVisible(value) {
56+
writeStorage("zonesVisible", value);
57+
renderZones = value;
58+
redrawIfInitDone();
59+
}
60+
4961
function dnpOutline(value) {
5062
writeStorage("dnpOutline", value);
5163
renderDnpOutline = value;
@@ -853,6 +865,14 @@ function initDefaults() {
853865
document.getElementById("valuesCheckbox").checked = b;
854866
valuesVisible(b);
855867

868+
b = getStorageBooleanOrDefault("tracksVisible", true);
869+
document.getElementById("tracksCheckbox").checked = b;
870+
tracksVisible(b);
871+
872+
b = getStorageBooleanOrDefault("zonesVisible", true);
873+
document.getElementById("zonesCheckbox").checked = b;
874+
zonesVisible(b);
875+
856876
b = getStorageBooleanOrDefault("dnpOutline", false);
857877
document.getElementById("dnpOutlineCheckbox").checked = b;
858878
dnpOutline(b);

InteractiveHtmlBom/web/render.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ var renderPads = true;
66
var renderReferences = true;
77
var renderValues = true;
88
var renderDnpOutline = false;
9+
var renderTracks = true;
10+
var renderZones = true;
911

1012
function deg2rad(deg) {
1113
return deg * Math.PI / 180;
@@ -327,6 +329,26 @@ function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonCo
327329
}
328330
}
329331

332+
function drawTracks(canvas, layer, color) {
333+
ctx = canvas.getContext("2d");
334+
ctx.strokeStyle = color;
335+
ctx.lineCap = "round";
336+
for(var track of pcbdata.tracks[layer]) {
337+
ctx.lineWidth = track.width;
338+
ctx.beginPath();
339+
ctx.moveTo(...track.start);
340+
ctx.lineTo(...track.end);
341+
ctx.stroke();
342+
}
343+
}
344+
345+
function drawZones(canvas, layer, color) {
346+
ctx = canvas.getContext("2d");
347+
for(var zone of pcbdata.zones[layer]) {
348+
drawPolygons(ctx, color, zone.polygons, ctx.fill.bind(ctx));
349+
}
350+
}
351+
330352
function clearCanvas(canvas) {
331353
var ctx = canvas.getContext("2d");
332354
ctx.save();
@@ -351,10 +373,20 @@ function drawBackground(canvasdict) {
351373
clearCanvas(canvasdict.fab);
352374
clearCanvas(canvasdict.silk);
353375
drawEdgeCuts(canvasdict.bg, canvasdict.transform.s);
376+
377+
var style = getComputedStyle(topmostdiv);
378+
if (renderTracks) {
379+
var trackColor = style.getPropertyValue('--track-color');
380+
drawTracks(canvasdict.bg, canvasdict.layer, trackColor);
381+
}
382+
if (renderZones) {
383+
var zoneColor = style.getPropertyValue('--zone-color');
384+
drawZones(canvasdict.bg, canvasdict.layer, zoneColor);
385+
}
386+
354387
drawModules(canvasdict.bg, canvasdict.layer,
355388
canvasdict.transform.s * canvasdict.transform.zoom, false);
356389

357-
var style = getComputedStyle(topmostdiv);
358390
var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
359391
var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
360392
var textColor = style.getPropertyValue('--silkscreen-text-color');

0 commit comments

Comments
 (0)