diff --git a/plugin/main_dialog.fbp b/plugin/main_dialog.fbp
index fa89819..a2c9594 100644
--- a/plugin/main_dialog.fbp
+++ b/plugin/main_dialog.fbp
@@ -45,7 +45,7 @@
MainDialog
- 765,659
+ 809,762
wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSTAY_ON_TOP
; ; forward_declare
Security Mesh Generator Plugin
@@ -2447,6 +2447,203 @@
+
+
+ 5
+ wxEXPAND
+ 1
+
+
+ bSizer12
+ wxHORIZONTAL
+ none
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ 25
+ 25
+ 100
+
+ 0
+
+ 0
+
+ 0
+
+ 1
+ m_randomnessSpin
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+ wxSP_ARROW_KEYS
+ ; ; forward_declare
+ 0
+
+
+
+
+
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ % (percent)
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_staticText211
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+
diff --git a/plugin/mesh_dialog.py b/plugin/mesh_dialog.py
index 25c5b54..5e6dd9f 100644
--- a/plugin/mesh_dialog.py
+++ b/plugin/mesh_dialog.py
@@ -38,6 +38,7 @@ class GeneratorSettings:
target_layer_id:int = 0 # kicad layer id, populated later
mask_layer_id: int = 0 # kicad layer id, populated later
random_seed: str = None
+ randomness: float = 1.0
class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
def __init__(self, board):
@@ -129,7 +130,8 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
chamfer = float(self.m_chamferSpin.Value)/100.0,
target_layer_id = self.m_layerChoice.GetSelection(),
mask_layer_id = self.m_maskLayerChoice.GetSelection(),
- random_seed = str(self.m_seedInput.Value) or None)
+ random_seed = str(self.m_seedInput.Value) or None,
+ randomness = float(self.m_randomnessSpin.Value)/100.0)
except ValueError as e:
return wx.MessageDialog(self, "Invalid input value: {}.".format(e), "Invalid input").ShowModal()
@@ -268,12 +270,19 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
0b0001: 0b0100,
0b0010: 0b1000,
0b0100: 0b0001,
- 0b1000: 0b0010
+ 0b1000: 0b0010,
+ 0b0000: 0b0000
}[mask]
rnd_state = random.Random(settings.random_seed)
- def random_iter(it):
+ def skewed_random_iter(it, mask, randomness):
l = list(it)
+ if rnd_state.random() < 1.0 - randomness:
+ for x, y, m in l:
+ if m == mask:
+ yield x, y, m
+ break
+ l.remove((x, y, m))
rnd_state.shuffle(l)
yield from l
@@ -300,21 +309,23 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
x, y = exit_cell[1]
visited = 0
key = 0
+ entry_dir = 0
stack = []
while not_visited or stack:
- for n_x, n_y, mask in random_iter(iter_neighbors(x, y)):
+ for n_x, n_y, bmask in skewed_random_iter(iter_neighbors(x, y), entry_dir, settings.randomness):
if (n_x, n_y) in not_visited:
dbg.add(grid[n_y][n_x], color=virihex(visited, max=num_to_visit), opacity=0.2)
- key |= mask
- stack.append((x, y, key))
+ key |= bmask
+ stack.append((x, y, key, bmask))
not_visited.remove((n_x, n_y))
visited += 1
- x, y, key = n_x, n_y, reciprocal(mask)
+ x, y, key, entry_dir = n_x, n_y, reciprocal(bmask), bmask
break
else:
for segment in Pattern.render(key, settings.num_traces, settings.chamfer):
segment = affinity.scale(segment, grid_cell_width, grid_cell_width, origin=(0, 0))
segment = affinity.translate(segment, grid_origin[0] + x*grid_cell_width, grid_origin[1] + y*grid_cell_width)
+ segment = affinity.rotate(segment, settings.mesh_angle, origin=mask.centroid)
stroke_color = {
0b0000: '#ff00ff80',
0b0001: '#ff000080',
@@ -338,7 +349,7 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
track_count += 1
if not stack:
break
- *stack, (x, y, key) = stack
+ *stack, (x, y, key, entry_dir) = stack
for foo in anchor_outlines:
dbg.add(foo, color='#0000ff00', stroke_width=0.05, stroke_color='#000000ff')
diff --git a/plugin/mesh_plugin_dialog.py b/plugin/mesh_plugin_dialog.py
index ce11fd7..e83f6ca 100644
--- a/plugin/mesh_plugin_dialog.py
+++ b/plugin/mesh_plugin_dialog.py
@@ -17,7 +17,7 @@ import wx.xrc
class MainDialog ( wx.Dialog ):
def __init__( self, parent ):
- wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Security Mesh Generator Plugin", pos = wx.DefaultPosition, size = wx.Size( 765,659 ), style = wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.MINIMIZE_BOX|wx.RESIZE_BORDER|wx.STAY_ON_TOP )
+ wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Security Mesh Generator Plugin", pos = wx.DefaultPosition, size = wx.Size( 809,762 ), style = wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.MINIMIZE_BOX|wx.RESIZE_BORDER|wx.STAY_ON_TOP )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
@@ -233,6 +233,25 @@ class MainDialog ( wx.Dialog ):
self.m_anchorInput = wx.TextCtrl( self.m_scrolledWindow1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
fgSizer1.Add( self.m_anchorInput, 0, wx.ALL, 5 )
+ self.m_staticText28 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Routing randomness", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText28.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText28, 0, wx.ALL, 5 )
+
+ bSizer12 = wx.BoxSizer( wx.HORIZONTAL )
+
+ self.m_randomnessSpin = wx.SpinCtrlDouble( self.m_scrolledWindow1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.SP_ARROW_KEYS, 0, 100, 25, 25 )
+ self.m_randomnessSpin.SetDigits( 0 )
+ bSizer12.Add( self.m_randomnessSpin, 0, wx.ALL, 5 )
+
+ self.m_staticText211 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"% (percent)", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText211.Wrap( -1 )
+
+ bSizer12.Add( self.m_staticText211, 0, wx.ALL, 5 )
+
+
+ fgSizer1.Add( bSizer12, 1, wx.EXPAND, 5 )
+
self.m_scrolledWindow1.SetSizer( fgSizer1 )
self.m_scrolledWindow1.Layout()