summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'plugin')
-rw-r--r--plugin/main_dialog.fbp847
-rw-r--r--plugin/mesh_dialog.py282
-rw-r--r--plugin/mesh_plugin_dialog.py74
3 files changed, 1085 insertions, 118 deletions
diff --git a/plugin/main_dialog.fbp b/plugin/main_dialog.fbp
index ac7e900..fa89819 100644
--- a/plugin/main_dialog.fbp
+++ b/plugin/main_dialog.fbp
@@ -45,7 +45,7 @@
<property name="minimum_size"></property>
<property name="name">MainDialog</property>
<property name="pos"></property>
- <property name="size">751,480</property>
+ <property name="size">765,659</property>
<property name="style">wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSTAY_ON_TOP</property>
<property name="subclass">; ; forward_declare</property>
<property name="title">Security Mesh Generator Plugin</property>
@@ -246,7 +246,7 @@
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
- <property name="value"></property>
+ <property name="value">mesh</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
@@ -1678,6 +1678,775 @@
</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">Chamfer depth</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_staticText20</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">bSizer10</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">2</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">25</property>
+ <property name="initial">50</property>
+ <property name="max">100</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_chamferSpin</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">% (percent)</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_staticText21</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>
+ <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">Layer</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_staticText22</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">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" 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="choices"></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="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_layerChoice</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="selection">0</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">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">Mesh outline layer</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_staticText23</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">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" 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="choices"></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="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_maskLayerChoice</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="selection">0</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">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">Random seed</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_staticText24</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">bSizer11</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="wxTextCtrl" 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="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></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_seedInput</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="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">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">Leave empty for random seed</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_staticText25</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>
+ <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">Anchor footprint designator</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_staticText26</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">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" 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="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></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_anchorInput</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="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ </object>
+ </object>
</object>
</object>
</object>
@@ -1809,7 +2578,79 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
- <property name="label">Remove Mesh Traces</property>
+ <property name="label">Remove All Mesh Traces</property>
+ <property name="margins"></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_removeAllButton</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="position"></property>
+ <property name="pressed"></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</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" 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="bitmap"></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="current"></property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="disabled"></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="focus"></property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Remove Matching Mesh Traces</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
diff --git a/plugin/mesh_dialog.py b/plugin/mesh_dialog.py
index 3544fd0..25c5b54 100644
--- a/plugin/mesh_dialog.py
+++ b/plugin/mesh_dialog.py
@@ -3,6 +3,8 @@ from dataclasses import dataclass
from contextlib import contextmanager
import textwrap
import random
+import math
+from itertools import count, islice
import wx
@@ -13,6 +15,7 @@ import shapely
from shapely import geometry
from shapely.geometry import polygon
from shapely import affinity
+import shapely.ops
from . import mesh_plugin_dialog
@@ -24,13 +27,17 @@ class AbortError(SystemError):
@dataclass
class GeneratorSettings:
- mesh_angle: float = 0.0 # deg
- trace_width: float = 0.127 # mm
- space_width: float = 0.127 # mm
- anchor_exit: float = 0.0 # deg
- num_traces: int = 2
- offset_x: float = 0.0 # mm
- offset_y: float = 0.0 # mm
+ mesh_angle: float = 0.0 # deg
+ trace_width: float = 0.127 # mm
+ space_width: float = 0.127 # mm
+ anchor_exit: float = 0.0 # deg
+ num_traces: int = 2
+ offset_x: float = 0.0 # mm
+ offset_y: float = 0.0 # mm
+ chamfer: float = 0.0 # unit fraction
+ target_layer_id:int = 0 # kicad layer id, populated later
+ mask_layer_id: int = 0 # kicad layer id, populated later
+ random_seed: str = None
class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
def __init__(self, board):
@@ -38,14 +45,26 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
self.board = board
self.m_cancelButton.Bind(wx.EVT_BUTTON, self.quit)
- self.m_removeButton.Bind(wx.EVT_BUTTON, self.tearup_mesh)
+ self.m_removeButton.Bind(wx.EVT_BUTTON, self.confirm_tearup_mesh)
+ self.m_removeAllButton.Bind(wx.EVT_BUTTON, self.confirm_tearup_mesh_all)
self.m_generateButton.Bind(wx.EVT_BUTTON, self.generate_mesh)
self.m_net_prefix.Bind(wx.EVT_TEXT, self.update_net_label)
+ # currently, BOARD.Remove() is b0rked and kicad crashes. Disable function for now.
+ self.m_removeButton.Disable()
+ self.m_removeAllButton.Disable()
self.tearup_confirm_dialog = wx.MessageDialog(self, "", style=wx.YES_NO | wx.NO_DEFAULT)
self.nets = { str(wxs) for wxs, netinfo in board.GetNetsByName().items() }
self.update_net_label(None)
+ for i in range(pcbnew.PCB_LAYER_ID_COUNT):
+ name = board.GetLayerName(i)
+ self.m_layerChoice.Append(name)
+ self.m_maskLayerChoice.Append(name)
+ if name == 'Eco1.User':
+ self.m_maskLayerChoice.SetSelection(i)
+ elif name == 'F.Cu':
+ self.m_layerChoice.SetSelection(i)
self.SetMinSize(self.GetSize())
@@ -53,7 +72,19 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
prefix = self.m_net_prefix.Value
return { net for net in self.nets if net.startswith(prefix) }
- def tearup_mesh(self, evt):
+ def net_names(self):
+ prefix = self.m_net_prefix.Value
+ for i in count():
+ yield f'{prefix}{i}'
+
+ def confirm_tearup_mesh_all(self, evt):
+ self.tearup_confirm_dialog.SetMessage('Do you really want to tear up all autorouted traces on this board? This stap cannot be undone!')
+ self.tearup_confirm_dialog.SetYesNoLabels("Tear up all autorouted traces", "Close")
+
+ if self.tearup_confirm_dialog.ShowModal() == wx.ID_YES:
+ self.tearup_mesh()
+
+ def confirm_tearup_mesh(self, evt):
matching = self.get_matching_nets()
if not str(self.m_net_prefix.Value):
@@ -67,20 +98,23 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
for netname in (sorted(matching)[:5] + ['...'] if len(matching) > 5 else [])
)
self.tearup_confirm_dialog.SetMessage(message)
- self.tearup_confirm_dialog.SetYesNoLabels("Tear up {} nets".format(len(matching)), "Close")
+ self.tearup_confirm_dialog.SetYesNoLabels("Tear up {} traces".format(len(matching)), "Close")
if self.tearup_confirm_dialog.ShowModal() == wx.ID_YES:
- self.tearup_mesh()
+ self.tearup_mesh(matching)
- def tearup_mesh(self):
+ def tearup_mesh(self, matching=None):
+ count = 0
for track in self.board.GetTracks():
if not (track.GetStatus() & pcbnew.TRACK_AR):
continue
- if not track.GetNet().GetNetname() in matching:
+ if matching is not None and track.GetNet().GetNetname() not in matching:
continue
- board.Remove(track)
+ count += 1
+ self.board.Remove(track)
+ print(f'Tore up {count} trace segments.')
def generate_mesh(self, evt):
try:
@@ -91,72 +125,48 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
anchor_exit = float(self.m_exitSpin.Value),
num_traces = int(self.m_traceCountSpin.Value),
offset_x = float(self.m_offsetXSpin.Value),
- offset_y = float(self.m_offsetYSpin.Value))
+ offset_y = float(self.m_offsetYSpin.Value),
+ 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)
except ValueError as e:
return wx.MessageDialog(self, "Invalid input value: {}.".format(e), "Invalid input").ShowModal()
- nets = self.get_matching_nets()
-
- pads = defaultdict(lambda: [])
- for module in self.board.GetModules():
- for pad in module.Pads():
- net = pad.GetNetname()
- if net in nets:
- pads[net].append(pad)
-
- for net in nets:
- if net not in pads:
- return wx.MessageDialog(self, "Error: No connection pads found for net {}.".format(net)).ShowModal()
-
- if len(pads[net]) == 1:
- return wx.MessageDialog(self, "Error: Only one of two connection pads found for net {}.".format(net)).ShowModal()
-
- if len(pads[net]) > 2:
- return wx.MessageDialog(self, "Error: More than two connection pads found for net {}.".format(net)).ShowModal()
-
- eco1_id = self.board.GetLayerID('Eco1.User')
mesh_zones = []
for drawing in self.board.GetDrawings():
- if drawing.GetLayer() == eco1_id:
+ if drawing.GetLayer() == settings.mask_layer_id:
mesh_zones.append(drawing)
if not mesh_zones:
- return wx.MessageDialog(self, "Error: Could not find any mesh zones on the Eco1.User layer.").ShowModal()
+ return wx.MessageDialog(self, "Error: Could not find any mesh zones on the outline pattern layer.").ShowModal()
- for zone in mesh_zones:
- anchors = []
- for module in self.board.GetModules():
- for foo in module.GraphicalItems():
- if not isinstance(foo, pcbnew.TEXTE_MODULE):
- continue
+ zone_outlines = [ outline for zone in mesh_zones for outline in self.poly_set_to_shapely(zone.GetPolyShape()) ]
+ mask = shapely.ops.unary_union(zone_outlines)
- if foo.GetText() == "mesh_anchor":
- anchors.append(module)
- break
+ anchor = [ mod for mod in self.board.GetModules() if mod.GetReference() == self.m_anchorInput.Value ]
+ if len(anchor) == 0:
+ return wx.MessageDialog(self, f'Error: Could not find anchor footprint "{self.m_anchorInput.Value}".').ShowModal()
+ if len(anchor) > 1:
+ return wx.MessageDialog(self, f'Error: Multiple footprints with anchor footprint reference "{self.m_anchorInput.Value}".').ShowModal()
+ anchor, = anchor
- if not anchors:
- return wx.MessageDialog(self, "Error: No anchor found for mesh zone centered on {:.3f}, {:.3f} mm".format(
- zone.GetCenter().x / pcbnew.IU_PER_MM, zone.GetCenter().y / pcbnew.IU_PER_MM
- )).ShowModal()
- if len(anchors) > 1:
- return wx.MessageDialog(self, "Error: Currently, only a single anchor is supported.").ShowModal()
-
- try:
- def warn(msg):
- dialog = wx.MessageDialog(self, msg + '\n\nDo you want to abort mesh generation?',
- "Mesh Generation Warning").ShowModal()
- dialog = wx.MessageDialog(self, "", style=wx.YES_NO | wx.NO_DEFAULT)
- dialog.SetYesNoLabels("Abort", "Ignore and continue")
+ try:
+ def warn(msg):
+ dialog = wx.MessageDialog(self, msg + '\n\nDo you want to abort mesh generation?',
+ "Mesh Generation Warning").ShowModal()
+ dialog = wx.MessageDialog(self, "", style=wx.YES_NO | wx.NO_DEFAULT)
+ dialog.SetYesNoLabels("Abort", "Ignore and continue")
- if self.tearup_confirm_dialog.ShowModal() == wx.ID_YES:
- raise AbortError()
+ if self.tearup_confirm_dialog.ShowModal() == wx.ID_YES:
+ raise AbortError()
- self.generate_mesh_backend(zone, anchors, warn=warn, settings=settings)
+ self.generate_mesh_backend(mask, anchor, warn=warn, settings=settings)
- except GeneratorError as e:
- return wx.MessageDialog(self, str(e), "Mesh Generation Error").ShowModal()
- except AbortError:
- pass
+ except GeneratorError as e:
+ return wx.MessageDialog(self, str(e), "Mesh Generation Error").ShowModal()
+ except AbortError:
+ pass
def poly_set_to_shapely(self, poly_set):
for i in range(poly_set.OutlineCount()):
@@ -168,27 +178,18 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
outline_points.append((pcbnew.ToMM(point.x), pcbnew.ToMM(point.y)))
yield polygon.Polygon(outline_points)
- def generate_mesh_backend(self, zone, anchors, warn=lambda s: None, settings=GeneratorSettings()):
- anchor, = anchors
-
+ def generate_mesh_backend(self, mask, anchor, warn=lambda s: None, settings=GeneratorSettings()):
anchor_outlines = list(self.poly_set_to_shapely(anchor.GetBoundingPoly()))
if len(anchor_outlines) == 0:
raise GeneratorError('Could not find any outlines for anchor {}'.format(anchor.GetReference()))
if len(anchor_outlines) > 1:
warn('Anchor {} has multiple outlines. Using first outline for trace start.')
- zone_outlines = list(self.poly_set_to_shapely(zone.GetPolyShape()))
- if len(zone_outlines) == 0:
- raise GeneratorError('Could not find any outlines for mesh zone.')
- if len(zone_outlines) > 1:
- raise GeneratorError('Mesh zone has too many outlines (has {}, should have one).'.format(len(zone_outlines)))
- zone_outline, *_rest = zone_outlines
-
width_per_trace = settings.trace_width + settings.space_width
grid_cell_width = width_per_trace * settings.num_traces * 2
- zone_outline_rotated = affinity.rotate(zone_outline, -settings.mesh_angle, origin=zone_outline.centroid)
- bbox = zone_outline_rotated.bounds
+ mask_rotated = affinity.rotate(mask, -settings.mesh_angle, origin=mask.centroid)
+ bbox = mask_rotated.bounds
grid_origin = (bbox[0] + settings.offset_x - grid_cell_width, bbox[1] + settings.offset_y - grid_cell_width)
grid_rows = int((bbox[3] - grid_origin[1]) / grid_cell_width + 2)
@@ -202,7 +203,7 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
cell = polygon.Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
cell = affinity.scale(cell, grid_cell_width, grid_cell_width, origin=(0, 0))
cell = affinity.translate(cell, grid_origin[0] + x*grid_cell_width, grid_origin[1] + y*grid_cell_width)
- cell = affinity.rotate(cell, settings.mesh_angle, origin=zone_outline.centroid)
+ cell = affinity.rotate(cell, settings.mesh_angle, origin=mask.centroid)
row.append(cell)
grid.append(row)
@@ -220,11 +221,11 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
num_valid = 0
with DebugOutput('/mnt/c/Users/jaseg/shared/test.svg') as dbg:
- dbg.add(zone_outline, color='#00000020')
+ dbg.add(mask, color='#00000020')
for y, row in enumerate(grid):
for x, cell in enumerate(row):
- if zone_outline.contains(cell):
+ if mask.contains(cell):
if cell == exit_cell[0]:
color = '#ff00ff80'
elif any(ol.overlaps(cell) for ol in anchor_outlines):
@@ -234,7 +235,7 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
else:
num_valid += 1
color = '#00ff0080'
- elif zone_outline.overlaps(cell):
+ elif mask.overlaps(cell):
color = '#ffff0080'
else:
color = '#ff000080'
@@ -244,7 +245,7 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
dbg.add(foo, color='#0000ff00', stroke_width=0.05, stroke_color='#000000ff')
def is_valid(cell):
- if not zone_outline.contains(cell):
+ if not mask.contains(cell):
return False
if any(ol.overlaps(cell) for ol in anchor_outlines):
return False
@@ -270,15 +271,31 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
0b1000: 0b0010
}[mask]
+ rnd_state = random.Random(settings.random_seed)
def random_iter(it):
l = list(it)
- random.shuffle(l)
+ rnd_state.shuffle(l)
yield from l
+ target_layer_id = self.board.GetLayerID('F.Cu') # FIXME make configurable
+ def add_track(segment:geometry.LineString):
+ coords = list(segment.coords)
+ for (x1, y1), (x2, y2) in zip(coords, coords[1:]):
+ if (x1, y1) == (x2, y2): # zero-length track due to zero chamfer
+ continue
+ track = pcbnew.TRACK(self.board)
+ track.SetStatus(track.GetStatus() | pcbnew.TRACK_AR)
+ track.SetStart(pcbnew.wxPoint(pcbnew.FromMM(x1), pcbnew.FromMM(y1)))
+ track.SetEnd(pcbnew.wxPoint(pcbnew.FromMM(x2), pcbnew.FromMM(y2)))
+ track.SetWidth(pcbnew.FromMM(settings.trace_width))
+ track.SetLayer(target_layer_id)
+ self.board.Add(track)
+
not_visited = { (x, y) for x in range(grid_cols) for y in range(grid_rows) if is_valid(grid[y][x]) }
num_to_visit = len(not_visited)
+ track_count = 0
with DebugOutput('/mnt/c/Users/jaseg/shared/test2.svg') as dbg:
- dbg.add(zone_outline, color='#00000020')
+ dbg.add(mask, color='#00000020')
x, y = exit_cell[1]
visited = 0
@@ -295,23 +312,46 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
x, y, key = n_x, n_y, reciprocal(mask)
break
else:
- for segment in Pattern.render(key, settings.num_traces):
+ 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)
- dbg.add(segment, stroke_width=settings.trace_width, color='#ff000000', stroke_color='#ff000080')
+ stroke_color = {
+ 0b0000: '#ff00ff80',
+ 0b0001: '#ff000080',
+ 0b0010: '#ff000080',
+ 0b0011: '#0000ff80',
+ 0b0100: '#ff000080',
+ 0b0101: '#00ffff80',
+ 0b0110: '#0000ff80',
+ 0b0111: '#00ff0080',
+ 0b1000: '#ff000080',
+ 0b1001: '#0000ff80',
+ 0b1010: '#00ffff80',
+ 0b1011: '#00ff0080',
+ 0b1100: '#0000ff80',
+ 0b1101: '#00ff0080',
+ 0b1110: '#00ff0080',
+ 0b1111: '#ff00ff80',
+ }[key]
+ dbg.add(segment, stroke_width=settings.trace_width, color='#ff000000', stroke_color=stroke_color)
+ add_track(segment) # FIXME (works, disabled for debug)
+ track_count += 1
+ if not stack:
+ break
*stack, (x, y, key) = stack
for foo in anchor_outlines:
dbg.add(foo, color='#0000ff00', stroke_width=0.05, stroke_color='#000000ff')
+ print(f'Added {track_count} trace segments.')
#pcbnew.Refresh()
#self.tearup_mesh()
# TODO generate
def update_net_label(self, evt):
- self.m_netLabel.SetLabel('{} matching nets'.format(len(self.get_matching_nets())))
+ self.m_netLabel.SetLabel('Like: ' + ', '.join(islice(self.net_names(), 3)) + ', ...')
def quit(self, evt):
self.Destroy()
@@ -319,48 +359,58 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
class Pattern:
@staticmethod
- def render(key, n):
- yield from Pattern.LUT[key](n)
+ def render(key, n, cd=0):
+ yield from Pattern.LUT[key](n, cd=math.tan(math.pi/8) * cd)
- def draw_I(n):
+ def draw_I(n, cd):
for i in range(2*n):
sp = (i+0.5) * (1/(2*n))
yield geometry.LineString([(sp, 0), (sp, 1)])
- def draw_U(n):
+ def draw_U(n, cd):
+ pitch = (1/(2*n))
+ cd *= pitch # chamfer depth
for i in range(n):
- sp = (i+0.5) * (1/(2*n))
- yield geometry.LineString([(sp, 0), (sp, 1-sp), (1-sp, 1-sp), (1-sp, 0)])
+ sp = (i+0.5) * pitch
+ yield geometry.LineString([(sp, 0), (sp, 1-sp-cd), (sp+cd, 1-sp), (1-sp-cd, 1-sp), (1-sp, 1-sp-cd), (1-sp, 0)])
- def draw_L(n):
+ def draw_L(n, cd):
+ pitch = (1/(2*n))
+ cd *= pitch # chamfer depth
for i in range(2*n):
- sp = (i+0.5) * (1/(2*n))
- yield geometry.LineString([(sp, 0), (sp, 1-sp), (1, 1-sp)])
+ sp = (i+0.5) * pitch
+ yield geometry.LineString([(sp, 0), (sp, 1-sp-cd), (sp+cd, 1-sp), (1, 1-sp)])
- def draw_T(n):
+ def draw_T(n, cd):
+ pitch = (1/(2*n))
+ cd *= pitch # chamfer depth
for i in range(n):
- sp = (i+0.5) * (1/(2*n))
+ sp = (i+0.5) * pitch
+ # through line
yield geometry.LineString([(0, sp), (1, sp)])
- yield geometry.LineString([(0, 1-sp), (sp, 1-sp), (sp, 1)])
- yield geometry.LineString([(1-sp, 1), (1-sp, 1-sp), (1, 1-sp)])
+ # two corners on the opposite side
+ yield geometry.LineString([(0, 1-sp), (sp-cd, 1-sp), (sp, 1-sp+cd), (sp, 1)])
+ yield geometry.LineString([(1-sp, 1), (1-sp, 1-sp+cd), (1-sp+cd, 1-sp), (1, 1-sp)])
- def draw_X(n):
+ def draw_X(n, cd):
+ pitch = (1/(2*n))
+ cd *= pitch # chamfer depth
for i in range(n):
- sp = (i+0.5) * (1/(2*n))
- yield geometry.LineString([(0, sp), (sp, sp), (sp, 0)])
- yield geometry.LineString([(1-sp, 0), (1-sp, sp), (1, sp)])
- yield geometry.LineString([(0, 1-sp), (sp, 1-sp), (sp, 1)])
- yield geometry.LineString([(1-sp, 1), (1-sp, 1-sp), (1, 1-sp)])
+ sp = (i+0.5) * pitch
+ yield geometry.LineString([(0, sp), (sp-cd, sp), (sp, sp-cd), (sp, 0)])
+ yield geometry.LineString([(1-sp, 0), (1-sp, sp-cd), (1-sp+cd, sp), (1, sp)])
+ yield geometry.LineString([(0, 1-sp), (sp-cd, 1-sp), (sp, 1-sp+cd), (sp, 1)])
+ yield geometry.LineString([(1-sp, 1), (1-sp, 1-sp+cd), (1-sp+cd, 1-sp), (1, 1-sp)])
def rotate(pattern, deg):
- def wrapper(n):
- for segment in pattern(n):
+ def wrapper(n, *args, **kwargs):
+ for segment in pattern(n, *args, **kwargs):
yield affinity.rotate(segment, deg, origin=(0.5, 0.5))
return wrapper
- def raise_error(n):
+ def raise_error(n, *args, **kwargs):
+ #raise ValueError('Tried to render invalid cell. This is a bug.')
return []
- raise ValueError('Tried to render invalid cell. This is a bug.')
LUT = {
0b0000: raise_error,
@@ -407,13 +457,20 @@ class DebugOutputWrapper:
stroke_color = stroke_color or '#000000ff'
stroke_width = 0 if stroke_width is None else stroke_width
- if isinstance(obj, polygon.Polygon):
+ if isinstance(obj, geometry.MultiPolygon):
+ out = ''
+ for geom in obj.geoms:
+ out += gen_svg(geom, fill_color, stroke_color, stroke_width, opacity)
+ return out
+
+ elif isinstance(obj, polygon.Polygon):
exterior_coords = [ ["{},{}".format(*c) for c in obj.exterior.coords] ]
interior_coords = [ ["{},{}".format(*c) for c in interior.coords] for interior in obj.interiors ]
all_coords = exterior_coords + interior_coords
path = " ".join([
"M {0} L {1} z".format(coords[0], " L ".join(coords[1:]))
for coords in all_coords])
+
elif isinstance(obj, geometry.LineString):
all_coords = [ ["{},{}".format(*c) for c in obj.coords] ]
path = " ".join([
@@ -421,6 +478,7 @@ class DebugOutputWrapper:
for coords in all_coords])
else:
raise ValueError(f'Unhandled shapely object type {type(obj)}')
+
return (f'<path fill-rule="evenodd" fill="{fill_color}" opacity="{opacity}" stroke="{stroke_color}" '
f'stroke-width="{stroke_width}" d="{path}" />')
diff --git a/plugin/mesh_plugin_dialog.py b/plugin/mesh_plugin_dialog.py
index fdfbaaf..ce11fd7 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( 751,480 ), 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( 765,659 ), style = wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.MINIMIZE_BOX|wx.RESIZE_BORDER|wx.STAY_ON_TOP )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
@@ -35,7 +35,7 @@ class MainDialog ( wx.Dialog ):
fgSizer1.Add( self.m_staticText1, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
- self.m_net_prefix = wx.TextCtrl( self.m_scrolledWindow1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_net_prefix = wx.TextCtrl( self.m_scrolledWindow1, wx.ID_ANY, u"mesh", wx.DefaultPosition, wx.DefaultSize, 0 )
fgSizer1.Add( self.m_net_prefix, 2, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 5 )
@@ -168,6 +168,71 @@ class MainDialog ( wx.Dialog ):
fgSizer1.Add( bSizer9, 2, wx.EXPAND, 5 )
+ self.m_staticText20 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Chamfer depth", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText20.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText20, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
+
+ bSizer10 = wx.BoxSizer( wx.HORIZONTAL )
+
+ self.m_chamferSpin = wx.SpinCtrlDouble( self.m_scrolledWindow1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.SP_ARROW_KEYS, 0, 100, 50, 25 )
+ self.m_chamferSpin.SetDigits( 2 )
+ bSizer10.Add( self.m_chamferSpin, 0, wx.ALL, 5 )
+
+ self.m_staticText21 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"% (percent)", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText21.Wrap( -1 )
+
+ bSizer10.Add( self.m_staticText21, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+
+
+ fgSizer1.Add( bSizer10, 1, wx.EXPAND, 5 )
+
+ self.m_staticText22 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Layer", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText22.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText22, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
+
+ m_layerChoiceChoices = []
+ self.m_layerChoice = wx.Choice( self.m_scrolledWindow1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_layerChoiceChoices, 0 )
+ self.m_layerChoice.SetSelection( 0 )
+ fgSizer1.Add( self.m_layerChoice, 0, wx.ALL, 5 )
+
+ self.m_staticText23 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Mesh outline layer", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText23.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText23, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
+
+ m_maskLayerChoiceChoices = []
+ self.m_maskLayerChoice = wx.Choice( self.m_scrolledWindow1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_maskLayerChoiceChoices, 0 )
+ self.m_maskLayerChoice.SetSelection( 0 )
+ fgSizer1.Add( self.m_maskLayerChoice, 0, wx.ALL, 5 )
+
+ self.m_staticText24 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Random seed", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText24.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText24, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
+
+ bSizer11 = wx.BoxSizer( wx.HORIZONTAL )
+
+ self.m_seedInput = wx.TextCtrl( self.m_scrolledWindow1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
+ bSizer11.Add( self.m_seedInput, 0, wx.ALL, 5 )
+
+ self.m_staticText25 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Leave empty for random seed", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText25.Wrap( -1 )
+
+ bSizer11.Add( self.m_staticText25, 0, wx.ALL, 5 )
+
+
+ fgSizer1.Add( bSizer11, 1, wx.EXPAND, 5 )
+
+ self.m_staticText26 = wx.StaticText( self.m_scrolledWindow1, wx.ID_ANY, u"Anchor footprint designator", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_staticText26.Wrap( -1 )
+
+ fgSizer1.Add( self.m_staticText26, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
+
+ 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_scrolledWindow1.SetSizer( fgSizer1 )
self.m_scrolledWindow1.Layout()
@@ -182,7 +247,10 @@ class MainDialog ( wx.Dialog ):
bSizer99.Add( ( 0, 0), 1, wx.EXPAND, 5 )
- self.m_removeButton = wx.Button( self, wx.ID_ANY, u"Remove Mesh Traces", wx.DefaultPosition, wx.DefaultSize, 0 )
+ self.m_removeAllButton = wx.Button( self, wx.ID_ANY, u"Remove All Mesh Traces", wx.DefaultPosition, wx.DefaultSize, 0 )
+ bSizer99.Add( self.m_removeAllButton, 0, wx.ALL, 5 )
+
+ self.m_removeButton = wx.Button( self, wx.ID_ANY, u"Remove Matching Mesh Traces", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer99.Add( self.m_removeButton, 0, wx.ALL, 5 )
self.m_generateButton = wx.Button( self, wx.ID_ANY, u"Generate", wx.DefaultPosition, wx.DefaultSize, 0 )