Skip to content

Commit

Permalink
Option to offset rotation of back layers 180º (#332)
Browse files Browse the repository at this point in the history
* Option to flip back of pcb

* Update form builder project, move checkbox

* Rename feature to "offset back rotation"

* Missed a few spots
  • Loading branch information
dotsam authored Oct 18, 2022
1 parent 31b20f8 commit 4e53f4e
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 11 deletions.
13 changes: 12 additions & 1 deletion InteractiveHtmlBom/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Config:
html_config_fields = [
'dark_mode', 'show_pads', 'show_fabrication', 'show_silkscreen',
'highlight_pin1', 'redraw_on_drag', 'board_rotation', 'checkboxes',
'bom_view', 'layer_view'
'bom_view', 'layer_view', 'offset_back_rotation'
]
default_show_group_fields = ["Value", "Footprint"]

Expand All @@ -51,6 +51,7 @@ class Config:
highlight_pin1 = False
redraw_on_drag = True
board_rotation = 0
offset_back_rotation = False
checkboxes = ','.join(default_checkboxes)
bom_view = bom_view_choices[1]
layer_view = layer_view_choices[1]
Expand Down Expand Up @@ -114,6 +115,8 @@ def load_from_ini(self):
self.highlight_pin1 = f.ReadBool('highlight_pin1', self.highlight_pin1)
self.redraw_on_drag = f.ReadBool('redraw_on_drag', self.redraw_on_drag)
self.board_rotation = f.ReadInt('board_rotation', self.board_rotation)
self.offset_back_rotation = f.ReadBool(
'offset_back_rotation', self.offset_back_rotation)
self.checkboxes = f.Read('checkboxes', self.checkboxes)
self.bom_view = f.Read('bom_view', self.bom_view)
self.layer_view = f.Read('layer_view', self.layer_view)
Expand Down Expand Up @@ -166,6 +169,7 @@ def save(self, locally):
f.WriteBool('highlight_pin1', self.highlight_pin1)
f.WriteBool('redraw_on_drag', self.redraw_on_drag)
f.WriteInt('board_rotation', self.board_rotation)
f.WriteBool('offset_back_rotation', self.offset_back_rotation)
f.Write('checkboxes', self.checkboxes)
f.Write('bom_view', self.bom_view)
f.Write('layer_view', self.layer_view)
Expand Down Expand Up @@ -210,6 +214,8 @@ def set_from_dialog(self, dlg):
self.highlight_pin1 = dlg.html.highlightPin1Checkbox.IsChecked()
self.redraw_on_drag = dlg.html.continuousRedrawCheckbox.IsChecked()
self.board_rotation = dlg.html.boardRotationSlider.Value
self.offset_back_rotation = \
dlg.html.offsetBackRotationCheckbox.IsChecked()
self.checkboxes = dlg.html.bomCheckboxesCtrl.Value
self.bom_view = self.bom_view_choices[dlg.html.bomDefaultView.Selection]
self.layer_view = self.layer_view_choices[
Expand Down Expand Up @@ -255,6 +261,7 @@ def transfer_to_dialog(self, dlg):
dlg.html.highlightPin1Checkbox.Value = self.highlight_pin1
dlg.html.continuousRedrawCheckbox.value = self.redraw_on_drag
dlg.html.boardRotationSlider.Value = self.board_rotation
dlg.html.offsetBackRotationCheckbox.Value = self.offset_back_rotation
dlg.html.bomCheckboxesCtrl.Value = self.checkboxes
dlg.html.bomDefaultView.Selection = self.bom_view_choices.index(
self.bom_view)
Expand Down Expand Up @@ -332,6 +339,9 @@ def add_options(cls, parser, version):
default=cls.board_rotation * 5,
help='Board rotation in degrees (-180 to 180). '
'Will be rounded to multiple of 5.')
parser.add_argument('--offset-back-rotation',
help='Offset the back of the pcb by 180 degrees',
action='store_true')
parser.add_argument('--checkboxes',
default=cls.checkboxes,
help='Comma separated list of checkbox columns.')
Expand Down Expand Up @@ -417,6 +427,7 @@ def set_from_args(self, args):
self.highlight_pin1 = args.highlight_pin1
self.redraw_on_drag = not args.no_redraw_on_drag
self.board_rotation = math.fmod(args.board_rotation // 5, 37)
self.offset_back_rotation = args.offset_back_rotation
self.checkboxes = args.checkboxes
self.bom_view = args.bom_view
self.layer_view = args.layer_view
Expand Down
5 changes: 3 additions & 2 deletions InteractiveHtmlBom/dialog/dialog_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.

b_sizer.Add( bSizer18, 0, wx.EXPAND, 5 )

self.offsetBackRotationCheckbox = wx.CheckBox( self, wx.ID_ANY, u"Offset back rotation", wx.DefaultPosition, wx.DefaultSize, 0 )
b_sizer.Add( self.offsetBackRotationCheckbox, 0, wx.ALL, 5 )

sbSizer31 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Checkboxes" ), wx.HORIZONTAL )

self.bomCheckboxesCtrl = wx.TextCtrl( sbSizer31.GetStaticBox(), wx.ID_ANY, u"Sourced,Placed", wx.DefaultPosition, wx.DefaultSize, 0 )
Expand Down Expand Up @@ -569,5 +572,3 @@ def OnNetlistFileChanged( self, event ):

def OnBoardVariantFieldChange( self, event ):
event.Skip()


4 changes: 4 additions & 0 deletions InteractiveHtmlBom/web/ibom.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@
<span style="float: right"><span id="rotationDegree">0</span>&#176;</span>
<input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)">
</label>
<label class="menu-label">
<input id="offsetBackRotationCheckbox" type="checkbox" onchange="setOffsetBackRotation(this.checked)">
Offset back rotation
</label>
<label class="menu-label">
<div style="margin-left: 5px">Bom checkboxes</div>
<input id="bomCheckboxes" class="menu-textbox" type=text
Expand Down
23 changes: 15 additions & 8 deletions InteractiveHtmlBom/web/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,12 @@ function prepareCanvas(canvas, flip, transform) {
ctx.scale(-1, 1);
}
ctx.translate(transform.x, transform.y);
ctx.rotate(deg2rad(settings.boardRotation));
ctx.rotate(deg2rad(settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0)));
ctx.scale(transform.s, transform.s);
}

function prepareLayer(canvasdict) {
var flip = (canvasdict.layer == "B");
var flip = (canvasdict.layer === "B");
for (var c of ["bg", "fab", "silk", "highlight"]) {
prepareCanvas(canvasdict[c], flip, canvasdict.transform);
}
Expand All @@ -576,14 +576,14 @@ function rotateVector(v, angle) {
];
}

function applyRotation(bbox) {
function applyRotation(bbox, flip) {
var corners = [
[bbox.minx, bbox.miny],
[bbox.minx, bbox.maxy],
[bbox.maxx, bbox.miny],
[bbox.maxx, bbox.maxy],
];
corners = corners.map((v) => rotateVector(v, settings.boardRotation));
corners = corners.map((v) => rotateVector(v, settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0)));
return {
minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity),
miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity),
Expand All @@ -593,7 +593,8 @@ function applyRotation(bbox) {
}

function recalcLayerScale(layerdict, width, height) {
var bbox = applyRotation(pcbdata.edges_bbox);
var flip = (layerdict.layer === "B");
var bbox = applyRotation(pcbdata.edges_bbox, flip);
var scalefactor = 0.98 * Math.min(
width / (bbox.maxx - bbox.minx),
height / (bbox.maxy - bbox.miny)
Expand All @@ -602,7 +603,6 @@ function recalcLayerScale(layerdict, width, height) {
scalefactor = 1;
}
layerdict.transform.s = scalefactor;
var flip = (layerdict.layer == "B");
if (flip) {
layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5;
} else {
Expand Down Expand Up @@ -794,13 +794,14 @@ function handleMouseClick(e, layerdict) {
var x = e.offsetX;
var y = e.offsetY;
var t = layerdict.transform;
if (layerdict.layer == "B") {
var flip = layerdict.layer === "B";
if (flip) {
x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s;
} else {
x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s;
}
y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s;
var v = rotateVector([x, y], -settings.boardRotation);
var v = rotateVector([x, y], -settings.boardRotation + (flip && settings.offsetBackRotation ? - 180 : 0));
if ("nets" in pcbdata) {
var net = netHitScan(layerdict.layer, ...v);
if (net !== highlightedNet) {
Expand Down Expand Up @@ -992,6 +993,12 @@ function setBoardRotation(value) {
resizeAll();
}

function setOffsetBackRotation(value) {
settings.offsetBackRotation = value;
writeStorage("offsetBackRotation", value);
resizeAll();
}

function initRender() {
allcanvas = {
front: {
Expand Down
4 changes: 4 additions & 0 deletions InteractiveHtmlBom/web/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ function overwriteSettings(newSettings) {
writeStorage("boardRotation", settings.boardRotation);
document.getElementById("boardRotation").value = settings.boardRotation / 5;
document.getElementById("rotationDegree").textContent = settings.boardRotation;
setOffsetBackRotation(settings.offsetBackRotation);
document.getElementById("offsetBackRotationCheckbox").checked = settings.offsetBackRotation;
initDone = true;
prepCheckboxes();
changeBomLayout(settings.bomlayout);
Expand Down Expand Up @@ -477,6 +479,7 @@ var settings = {
highlightpin1: false,
redrawOnDrag: true,
boardRotation: 0,
offsetBackRotation: false,
renderPads: true,
renderReferences: true,
renderValues: true,
Expand Down Expand Up @@ -572,6 +575,7 @@ function initDefaults() {
}
document.getElementById("boardRotation").value = settings.boardRotation / 5;
document.getElementById("rotationDegree").textContent = settings.boardRotation;
initBooleanSetting("offsetBackRotation", config.offset_back_rotation, "offsetBackRotationCheckbox", setOffsetBackRotation);
}

// Helper classes for user js callbacks.
Expand Down
64 changes: 64 additions & 0 deletions settings_dialog.fbp
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,70 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Offset back rotation</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">offsetBackRotationCheckbox</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
Expand Down

0 comments on commit 4e53f4e

Please sign in to comment.