Persist settings
This commit is contained in:
parent
ecde8f1c8f
commit
8913c91e83
3 changed files with 278 additions and 5 deletions
|
|
@ -863,6 +863,203 @@
|
|||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<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="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">Board edge clearance</property>
|
||||
<property name="markup">0</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">m_staticText261</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="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer51</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxSpinCtrlDouble" expanded="1">
|
||||
<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="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="digits">3</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="inc">0.1</property>
|
||||
<property name="initial">1.500000</property>
|
||||
<property name="max">1000</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min">0</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">m_edgeClearanceSpin</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">wxSP_ARROW_KEYS</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="value"></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">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<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="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">mm</property>
|
||||
<property name="markup">0</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">m_staticText61</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="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
import dataclasses
|
||||
from contextlib import contextmanager
|
||||
import textwrap
|
||||
import random
|
||||
import math
|
||||
from itertools import count, islice
|
||||
import json
|
||||
from os import path
|
||||
|
||||
import wx
|
||||
|
||||
|
|
@ -25,12 +27,14 @@ class GeneratorError(ValueError):
|
|||
class AbortError(SystemError):
|
||||
pass
|
||||
|
||||
@dataclass
|
||||
@dataclasses.dataclass
|
||||
class GeneratorSettings:
|
||||
mesh_angle: float = 0.0 # deg
|
||||
trace_width: float = 0.127 # mm
|
||||
space_width: float = 0.127 # mm
|
||||
edge_clearance: float = 1.5 # mm
|
||||
anchor_exit: float = 0.0 # deg
|
||||
anchor: str = None # Footprint designator
|
||||
num_traces: int = 2
|
||||
offset_x: float = 0.0 # mm
|
||||
offset_y: float = 0.0 # mm
|
||||
|
|
@ -40,6 +44,24 @@ class GeneratorSettings:
|
|||
random_seed: str = None
|
||||
randomness: float = 1.0
|
||||
|
||||
def serialize(self):
|
||||
d = dataclasses.asdict(self)
|
||||
d['kimesh_settings_version'] = '1.0.0'
|
||||
return json.dumps(d).encode()
|
||||
|
||||
@classmethod
|
||||
def deserialize(cls, data):
|
||||
d = json.loads(data.decode())
|
||||
version = d.pop('kimesh_settings_version')
|
||||
vtup = tuple(map(int, version.split('.')))
|
||||
if vtup > (2, 0, 0):
|
||||
raise cls.VersionError("Project kimesh settings file is too new for this plugin's version.")
|
||||
return cls(**d)
|
||||
|
||||
class VersionError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
|
||||
def __init__(self, board):
|
||||
mesh_plugin_dialog.MainDialog.__init__(self, None)
|
||||
|
|
@ -67,9 +89,32 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
|
|||
self.m_maskLayerChoice.Append(name)
|
||||
if name == 'User.Eco1':
|
||||
self.m_maskLayerChoice.SetSelection(i)
|
||||
elif name == 'F.Cu':
|
||||
elif name == 'B.Cu':
|
||||
self.m_layerChoice.SetSelection(i)
|
||||
|
||||
if path.isfile(self.settings_fn()):
|
||||
with open(self.settings_fn(), 'rb') as f:
|
||||
try:
|
||||
settings = GeneratorSettings.deserialize(f.read())
|
||||
|
||||
self.m_angleSpin.Value = settings.mesh_angle
|
||||
self.m_traceSpin.Value = settings.trace_width
|
||||
self.m_spaceSpin.Value = settings.space_width
|
||||
self.m_exitSpin.Value = settings.anchor_exit
|
||||
self.m_anchorInput.Value = settings.anchor
|
||||
self.m_traceCountSpin.Value = settings.num_traces
|
||||
self.m_offsetXSpin.Value = settings.offset_x
|
||||
self.m_offsetYSpin.Value = settings.offset_y
|
||||
self.m_chamferSpin.Value = settings.chamfer*100.0
|
||||
self.m_layerChoice.SetSelection(settings.target_layer_id)
|
||||
self.m_maskLayerChoice.SetSelection(settings.mask_layer_id)
|
||||
self.m_seedInput.Value = settings.random_seed or ''
|
||||
self.m_randomnessSpin.Value = settings.randomness*100.0
|
||||
self.m_edgeClearanceSpin.Value = settings.edge_clearance
|
||||
|
||||
except GeneratorSettings.VersionError as e:
|
||||
wx.MessageDialog(self, "Cannot load settings: {}.".format(e), "File I/O error").ShowModal()
|
||||
|
||||
self.SetMinSize(self.GetSize())
|
||||
|
||||
def get_matching_nets(self):
|
||||
|
|
@ -120,13 +165,18 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
|
|||
self.board.Remove(track)
|
||||
print(f'Tore up {count} trace segments.')
|
||||
|
||||
def settings_fn(self):
|
||||
return path.join(path.dirname(self.board.GetFileName()), 'last_kimesh_settings.json')
|
||||
|
||||
def generate_mesh(self, evt):
|
||||
try:
|
||||
settings = GeneratorSettings(
|
||||
mesh_angle = float(self.m_angleSpin.Value),
|
||||
trace_width = float(self.m_traceSpin.Value),
|
||||
space_width = float(self.m_spaceSpin.Value),
|
||||
edge_clearance = float(self.m_edgeClearanceSpin.Value),
|
||||
anchor_exit = float(self.m_exitSpin.Value),
|
||||
anchor = str(self.m_anchorInput.Value),
|
||||
num_traces = int(self.m_traceCountSpin.Value),
|
||||
offset_x = float(self.m_offsetXSpin.Value),
|
||||
offset_y = float(self.m_offsetYSpin.Value),
|
||||
|
|
@ -138,6 +188,13 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
|
|||
except ValueError as e:
|
||||
return wx.MessageDialog(self, "Invalid input value: {}.".format(e), "Invalid input").ShowModal()
|
||||
|
||||
try:
|
||||
with open(self.settings_fn(), 'wb') as f:
|
||||
f.write(settings.serialize())
|
||||
print('Saved settings to', f.name)
|
||||
except:
|
||||
wx.MessageDialog(self, "Cannot save settings: {}.".format(e), "File I/O error").ShowModal()
|
||||
|
||||
mesh_zones = []
|
||||
for drawing in self.board.GetDrawings():
|
||||
if drawing.GetLayer() == settings.mask_layer_id:
|
||||
|
|
@ -151,13 +208,14 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
|
|||
self.board.GetBoardPolygonOutlines(outlines, "")
|
||||
board_outlines = list(self.poly_set_to_shapely(outlines))
|
||||
board_mask = shapely.ops.unary_union(board_outlines)
|
||||
board_mask = board_mask.buffer(-settings.edge_clearance)
|
||||
|
||||
zone_outlines = [ outline for zone in mesh_zones for outline in self.poly_set_to_shapely(zone.GetPolyShape()) ]
|
||||
zone_mask = shapely.ops.unary_union(zone_outlines)
|
||||
|
||||
mask = zone_mask.intersection(board_mask)
|
||||
|
||||
anchor = [ mod for mod in self.board.GetModules() if mod.GetReference() == self.m_anchorInput.Value ]
|
||||
anchor = [ mod for mod in self.board.GetModules() if mod.GetReference() == settings.anchor ]
|
||||
if len(anchor) == 0:
|
||||
return wx.MessageDialog(self, f'Error: Could not find anchor footprint "{self.m_anchorInput.Value}".').ShowModal()
|
||||
if len(anchor) > 1:
|
||||
|
|
@ -546,7 +604,6 @@ def virihex(val, max=1.0, alpha=1.0):
|
|||
|
||||
@contextmanager
|
||||
def DebugOutput(filename):
|
||||
from os import path
|
||||
filename = path.join('/tmp', filename)
|
||||
with open(filename, 'w') as f:
|
||||
wrapper = DebugOutputWrapper(f)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,25 @@ class MainDialog ( wx.Dialog ):
|
|||
|
||||
fgSizer1.Add( bSizer6, 1, wx.EXPAND, 5 )
|
||||
|
||||
self.m_staticText261 = wx.StaticText( self, wx.ID_ANY, u"Board edge clearance", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.m_staticText261.Wrap( -1 )
|
||||
|
||||
fgSizer1.Add( self.m_staticText261, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
|
||||
|
||||
bSizer51 = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
self.m_edgeClearanceSpin = wx.SpinCtrlDouble( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.SP_ARROW_KEYS, 0, 1000, 1.500000, 0.1 )
|
||||
self.m_edgeClearanceSpin.SetDigits( 3 )
|
||||
bSizer51.Add( self.m_edgeClearanceSpin, 0, wx.ALL, 5 )
|
||||
|
||||
self.m_staticText61 = wx.StaticText( self, wx.ID_ANY, u"mm", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.m_staticText61.Wrap( -1 )
|
||||
|
||||
bSizer51.Add( self.m_staticText61, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
|
||||
|
||||
|
||||
fgSizer1.Add( bSizer51, 1, wx.EXPAND, 5 )
|
||||
|
||||
self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"Anchor exit direction", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.m_staticText11.Wrap( -1 )
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue