Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to flip back of board 180º #332

Merged
merged 4 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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