first new dialogs release

This commit is contained in:
easyw
2020-02-22 23:30:04 +01:00
parent 11e2ec6366
commit 9621ddd40a
14 changed files with 1616 additions and 4701 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+93
View File
@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Oct 26 2018)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class AnnularDlg
###########################################################################
class AnnularDlg ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Ring Checker", pos = wx.DefaultPosition, size = wx.Size( 380,317 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer3 = wx.BoxSizer( wx.VERTICAL )
self.m_LabelTitle = wx.StaticText( self, wx.ID_ANY, u"Check annular ring", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_LabelTitle.Wrap( -1 )
bSizer3.Add( self.m_LabelTitle, 0, wx.ALL|wx.EXPAND, 5 )
self.m_staticline8 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
bSizer3.Add( self.m_staticline8, 0, wx.EXPAND |wx.ALL, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_staticTextPHD = wx.StaticText( self, wx.ID_ANY, u"PH Drill margin", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTextPHD.Wrap( -1 )
gSizer1.Add( self.m_staticTextPHD, 1, wx.ALL, 5 )
self.m_textCtrlPHD = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_textCtrlPHD, 0, wx.ALIGN_RIGHT|wx.ALL, 5 )
self.m_staticTextARV = wx.StaticText( self, wx.ID_ANY, u"AR Vias", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTextARV.Wrap( -1 )
gSizer1.Add( self.m_staticTextARV, 0, wx.ALL, 5 )
self.m_textCtrlARV = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_textCtrlARV, 0, wx.ALIGN_RIGHT|wx.ALL, 5 )
self.m_staticTextARP = wx.StaticText( self, wx.ID_ANY, u"AR Pads", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTextARP.Wrap( -1 )
gSizer1.Add( self.m_staticTextARP, 0, wx.ALL, 5 )
self.m_textCtrlARP = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_textCtrlARP, 0, wx.ALIGN_RIGHT|wx.ALL, 5 )
bSizer3.Add( gSizer1, 1, wx.ALIGN_CENTER|wx.ALL, 5 )
bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
bSizer1.Add( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_buttonOK = wx.Button( self, wx.ID_OK, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_buttonOK.SetDefault()
bSizer1.Add( self.m_buttonOK, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
self.m_buttonCancel = wx.Button( self, wx.ID_CANCEL, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer1.Add( self.m_buttonCancel, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
bSizer3.Add( bSizer1, 0, wx.ALIGN_RIGHT|wx.EXPAND, 5 )
bSizer4 = wx.BoxSizer( wx.VERTICAL )
bSizer3.Add( bSizer4, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer3 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
@@ -1,540 +1,356 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="14" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file"></property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">0</property>
<property name="name">parametersDlg</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">displayDialog</property>
<property name="pos"></property>
<property name="size">320,521</property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass">; forward_declare</property>
<property name="title">Annular Checker</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiPaneActivated"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMaximize"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnMove"></event>
<event name="OnMoveEnd"></event>
<event name="OnMoveStart"></event>
<event name="OnMoving"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnShow"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer1</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<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">bSizer2</property>
<property name="orient">wxVERTICAL</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="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"></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_staticTitle</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>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxRichTextCtrl" 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="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,400</property>
<property name="moveable">1</property>
<property name="name">m_richText1</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">wxTE_READONLY</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">wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRichTextCharacter"></event>
<event name="OnRichTextContentDeleted"></event>
<event name="OnRichTextContentInserted"></event>
<event name="OnRichTextDelete"></event>
<event name="OnRichTextReturn"></event>
<event name="OnRichTextStyleChanged"></event>
<event name="OnRichTextStyleSheetChanged"></event>
<event name="OnRichTextStyleSheetReplaced"></event>
<event name="OnRichTextStyleSheetReplacing"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxGridSizer" expanded="1">
<property name="cols">2</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gSizer3</property>
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" 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="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">OK</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">ok_btn</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>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnButtonClick"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" 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="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">Copy Text</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">copy_btn</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>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
<event name="OnAux2DClick"></event>
<event name="OnAux2Down"></event>
<event name="OnAux2Up"></event>
<event name="OnButtonClick"></event>
<event name="OnChar"></event>
<event name="OnCharHook"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">Python</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">AnnularResultDlg</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">0</property>
<property name="name">AnnularResultDlg</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">AnnularResultDlg</property>
<property name="pos"></property>
<property name="size">383,521</property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass">; forward_declare</property>
<property name="title">Annular Checker</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer1</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<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">bSizer2</property>
<property name="orient">wxVERTICAL</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="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"></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_staticTitle</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 | wxALL</property>
<property name="proportion">1</property>
<object class="wxRichTextCtrl" 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="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,400</property>
<property name="moveable">1</property>
<property name="name">m_richTextResult</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">wxTE_READONLY</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">wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS</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="wxGridSizer" expanded="1">
<property name="cols">2</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gSizer3</property>
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" 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="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">OK</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">ok_btn</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="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" 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="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">Copy Text</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">copy_btn</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>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
+62
View File
@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Oct 26 2018)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
import wx.richtext
###########################################################################
## Class AnnularResultDlg
###########################################################################
class AnnularResultDlg ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Checker", pos = wx.DefaultPosition, size = wx.Size( 383,521 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticTitle = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTitle.Wrap( -1 )
bSizer2.Add( self.m_staticTitle, 0, wx.ALL, 5 )
self.m_richTextResult = wx.richtext.RichTextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
self.m_richTextResult.SetMinSize( wx.Size( -1,400 ) )
bSizer2.Add( self.m_richTextResult, 1, wx.EXPAND |wx.ALL, 5 )
gSizer3 = wx.GridSizer( 0, 2, 0, 0 )
self.ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.ok_btn, 0, wx.ALL, 5 )
self.copy_btn = wx.Button( self, wx.ID_ANY, u"Copy Text", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.copy_btn, 0, wx.ALL, 5 )
bSizer2.Add( gSizer3, 1, wx.EXPAND, 5 )
bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
-2
View File
@@ -1,2 +0,0 @@
from .annular_checker import annular_check
annular_check().register()
Binary file not shown.
-2
View File
@@ -1,2 +0,0 @@
from .annular_checker_html import annular_check
annular_check().register()
-56
View File
@@ -1,56 +0,0 @@
from annular_checker import annular_check
import pcbnew
import wx
import wx.aui
import threading
import time
import sys
import subprocess
import os
# import pcbnew
from pcbnew import *
# import base64
from wx.lib.embeddedimage import PyEmbeddedImage
plugin = annular_check()
plugin.register()
def check_for_annular_button():
# From Miles McCoo's blog
# https://kicad.mmccoo.com/2017/03/05/adding-your-own-command-buttons-to-the-pcbnew-gui/
def find_pcbnew_window():
windows = wx.GetTopLevelWindows()
pcbnewwn = [w for w in windows if "Pcbnew" in w.GetTitle()]
if len(pcbnewwn) != 1:
return None
return pcbnewwn[0]
def callback(_):
plugin.Run()
import os
path = os.path.dirname(__file__)
bm = wx.Bitmap(path + '/annular.png', wx.BITMAP_TYPE_PNG)
button_wx_item_id = 1
while True:
time.sleep(1.5)
pcbwin = find_pcbnew_window()
if not pcbwin:
continue
top_tb = pcbwin.FindWindowById(pcbnew.ID_H_TOOLBAR)
if button_wx_item_id == 1 or not top_tb.FindTool(button_wx_item_id):
#top_tb.AddSeparator()
button_wx_item_id = wx.NewId()
top_tb.AddTool(button_wx_item_id, "aChecker", bm,
"PCB Annular Checker", wx.ITEM_NORMAL)
top_tb.Bind(wx.EVT_TOOL, callback, id=button_wx_item_id)
top_tb.Realize()
if 0:
t = threading.Thread(target=check_for_annular_button)
t.daemon = True
t.start()
-609
View File
@@ -1,609 +0,0 @@
# -*- coding: utf-8 -*-
#
# A script to check for annular ring violations
# both for TH pads and vias
# requirements: KiCAD pcbnew >= 4.0
# annular.py release "1.5.1"
#
# annular.py checking PCB for Annular Ring in Vias and TH Pads
# (SMD, Connector and NPTH are skipped)
# default Annular Ring >= 0.15 both for TH Pads and Vias
# to change values modify:
#
# AR_SET = 0.150 #minimum annular accepted for pads
# AR_SET_V = 0.150 #minimum annular accepted for vias
# annular.py
___version___="1.6.0"
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations, LogMsg
#wx.LogMessage("My message")
mm_ius = 1000000.0
# (consider always drill +0.1)
DRL_EXTRA=0.1
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = 0.125 #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = 0.125 #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
import sys
import wx
import wx.richtext
import subprocess
import os
import pcbnew
from pcbnew import *
import base64
from wx.lib.embeddedimage import PyEmbeddedImage
sys.path.append(os.path.dirname(__file__))
class annular_check( pcbnew.ActionPlugin ):
"""
A script to check for annular ring violations
both for TH pads and vias
requirements: KiCAD pcbnew >= 4.0
annular.py release "1.5.1"
annular.py checking PCB for Annular Ring in Vias and TH Pads
(SMD, Connector and NPTH are skipped)
default Annular Ring >= 0.15 both for TH Pads and Vias
to change values modify:
AR_SET = 0.150 #minimum annular accepted for pads
AR_SET_V = 0.150 #minimum annular accepted for vias
"""
def defaults( self ):
"""
Method defaults must be redefined
self.name should be the menu label to use
self.category should be the category (not yet used)
self.description should be a comprehensive description
of the plugin
"""
self.name = "Annular check"
self.category = "Checking PCB"
self.description = "Automaticaly check annular on an existing PCB"
#self.pcbnew_icon_support = hasattr(self, "show_toolbar_button")
self.show_toolbar_button = True
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'annular.png')
def Run( self ):
###########################################################################
## Class AR_Prm
###########################################################################
class AR_Prm ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "AR parameters", pos = wx.DefaultPosition, size = wx.Size( 320,193 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 500,500 )
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
bSizer1 = wx.BoxSizer( wx.VERTICAL )
gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText11.Wrap( -1 )
gSizer2.Add( self.m_staticText11, 0, wx.ALL, 5 )
self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, str(DRL_EXTRA), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText1.Wrap( -1 )
gSizer2.Add( self.m_staticText1, 0, wx.ALL, 5 )
self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
self.m_staticText12 = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText12.Wrap( -1 )
gSizer2.Add( self.m_staticText12, 0, wx.ALL, 5 )
self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET_V), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_ok_btn, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.m_ok_btn)
# self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.m_cancel_btn)
# Tooltips
#self.m_cancel_btn.SetToolTip( wx.ToolTip(u"Cancel" ))
self.m_ok_btn.SetToolTip( wx.ToolTip(u"Confirm" ))
self.m_ok_btn.SetFocus()
self.m_staticText1.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET_V.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_staticText12.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_textPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
self.m_staticText11.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
def __del__( self ):
pass
def OnClickOK(self, event):
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
self.m_ok_btn.SetLabel("Clicked")
phd = float(self.m_textPHD.GetValue().replace(',','.'))
ar = float(self.m_textAR_SET.GetValue().replace(',','.'))
arv = float(self.m_textAR_SET_V.GetValue().replace(',','.'))
DRL_EXTRA=phd
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = ar #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = arv #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
self.Destroy()
def OnClickCancel(self, event):
self.m_cancel_btn.SetLabel("Clicked")
self.Destroy()
#wx.MessageDialog(self.frame,"ciao")
#subprocess.check_call(["C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])
#http://stackoverflow.com/questions/1811691/running-an-outside-program-executable-in-python
## class displayDialog(wx.Dialog):
## """
## The default frame
## http://stackoverflow.com/questions/3566603/how-do-i-make-wx-textctrl-multi-line-text-update-smoothly
## """
## global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
## #----------------------------------------------------------------------
## #def __init__(self):
## # """Constructor"""
## # wx.Frame.__init__(self, None, title="Display Frame", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
## # panel = wx.Panel(self)
## def __init__(self, parent):
## wx.Dialog.__init__(self, parent, id=-1, title="Annular Checker")#
## #, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
## #, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
## #, pos=DefaultPosition, size=DefaultSize, style = wx.DEFAULT_FRAME_STYLE & (~wx.MAXIMIZE_BOX), name="fname")
## #, wx.ICON_INFORMATION) #, title="Annular Check", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
## #
##
## self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
## #wx.IconFromBitmap(wx.Bitmap("icon.ico", wx.BITMAP_TYPE_ANY)))
## self.panel = wx.Panel(self)
##
## if found_violations:
## self.title = wx.StaticText(self.panel, label="")
## #self.title.SetForegroundColour('#FF0000')
## #self.title.SetBackgroundColour('#FF0000')
## #font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
## #self.title.SetFont(font)
## else:
## self.title = wx.StaticText(self.panel, label="")
## #self.title.SetBackgroundColour('#00FF00')
## #font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
## #self.title.SetFont(font)
## #self.result = wx.StaticText(self.panel, label="")
## #self.result.SetForegroundColour('#FF0000')
## #self.button = wx.Button(self.panel, label="Save")
## #self.lblname = wx.StaticText(self.panel, label="Your name:")
## #self.editname = wx.TextCtrl(self.panel, size=(140, -1))
## ##self.editname = wx.TextCtrl(self.panel, size = (400, 400), style = wx.TE_MULTILINE|wx.TE_READONLY)
## self.m_richText1 = wx.richtext.RichTextCtrl( self.panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, size = (400, 400), style = 0|wx.VSCROLL|wx.HSCROLL|wx.WANTS_CHARS )# wx.TE_MULTILINE|wx.TE_READONLY) #0|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
## #bSizer1.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 )
##
##
## # Set sizer for the frame, so we can change frame size to match widgets
## self.windowSizer = wx.BoxSizer()
## self.windowSizer.Add(self.panel, 1, wx.ALL | wx.EXPAND)
##
## # Set sizer for the panel content
## self.sizer = wx.GridBagSizer(5, 0)
## self.sizer.Add(self.title, (0, 0))
## #self.sizer.Add(self.result, (1, 0))
## #self.sizer.Add(self.lblname, (1, 0))
## ## self.sizer.Add(self.editname, (1, 0))
## self.sizer.Add(self.m_richText1, (1, 0))
## #self.ok_btn = wx.Button( self, wx.ID_ANY, u"Copy errors", wx.DefaultPosition, wx.DefaultSize, 0 )
## #self.sizer.Add( self.ok_btn, 0, wx.ALL | wx.EXPAND)
## #self.sizer.Add(self.ok_btn, (2, 0)) #, wx.ALL | flag=wx.EXPAND)
## #self.sizer.Add( self.ok_btn, 0, wx.ALL, 5 )
##
## #self.sizer.Add(self.ok_btn, (2, 0), (1, 2), flag=wx.EXPAND)
##
## # Set simple sizer for a nice border
## self.border = wx.BoxSizer()
## self.border.Add(self.sizer, 1, wx.ALL | wx.EXPAND, 5)
##
## #self.ok_btn = wx.Button( self, wx.ID_ANY, u"Copy errors", wx.DefaultPosition, wx.DefaultSize, 0 )
## #self.windowSizer.Add(self.ok_btn, 0, wx.ALL)
## #self.sizer.Add( self.ok_btn, (2,0))
## #self.sizer.Add( self.ok_btn, 0, wx.ALL, 5 )
## # Use the sizers
## self.panel.SetSizerAndFit(self.border)
## self.SetSizerAndFit(self.windowSizer)
## #self.result.SetLabel(msg)
## # Set event handlers
## #self.button.Bind(wx.EVT_BUTTON, self.OnButton)
## #self.Show()
## #self.Bind(wx.EVT_CLOSE,self.OnClose)
##
## #def OnClose(self,e):
## # #wx.LogMessage("c")
## # e.Skip()
## #self.Close()
###########################################################################
## Class displayDialog
###########################################################################
class displayDialog ( wx.Dialog ):
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations, LogMsg
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Checker", pos = wx.DefaultPosition, size = wx.Size( 450,521 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 300,100 )
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
bSizer1 = wx.BoxSizer( wx.VERTICAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticTitle = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTitle.Wrap( -1 )
bSizer2.Add( self.m_staticTitle, 0, wx.ALL, 5 )
self.m_richText1 = wx.richtext.RichTextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
self.m_richText1.SetMinSize( wx.Size( 400,400 ) )
bSizer2.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 )
gSizer3 = wx.GridSizer( 0, 2, 0, 0 )
self.ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.ok_btn, 0, wx.ALL, 5 )
self.copy_btn = wx.Button( self, wx.ID_ANY, u"Copy Text", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.copy_btn, 0, wx.ALL, 5 )
bSizer2.Add( gSizer3, 1, wx.EXPAND, 5 )
bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.ok_btn)
self.Bind(wx.EVT_BUTTON, self.OnClickCopy, self.copy_btn)
self.ok_btn.SetFocus()
# Tooltips
self.copy_btn.SetToolTip( wx.ToolTip(u"Copy Text to Clipboard" ))
self.ok_btn.SetToolTip( wx.ToolTip(u"Exit" ))
def __del__( self ):
pass
def OnClickOK(self, event):
self.Destroy()
def OnClickCopy(self, event):
self.m_richText1.SelectAll()
self.m_richText1.Copy()
#global LogMsg
#copy2clip(LogMsg)
self.copy_btn.SetLabel("Text Copied")
#def setMsg(self, t_msg):
# pass
#self.editname.SetValue(t_msg)
#self.m_richText1.BeginBold()
#self.m_richText1.WriteText(" You are in ")
#self.m_richText1.BeginTextColour('red')
#self.m_richText1.WriteText("danger ")
#self.m_richText1.EndTextColour()
#self.m_richText1.WriteText("at that spot!")
#self.m_richText1.EndBold()
#self.m_richText1.SetValue(t_msg)
#self.m_htmlWin1.SetPage(t_msg)
def annring_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]+DRL_EXTRA_ius))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]+DRL_EXTRA_ius))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
return min(annrX,annrY)
def annringNP_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
#return min(annrX,annrY)
return annrX,annrY
def vias_annring_size(via):
# calculating via annular
annr=(via.GetWidth() - (via.GetDrillValue()+DRL_EXTRA_ius))/2
#print via.GetWidth()
#print via.GetDrillValue()
return annr
def f_mm(raw):
return repr(raw/mm_ius)
board = pcbnew.GetBoard()
PassC=FailC=0
PassCV=FailCV=0
PassCN=FailCN=0
PassCVN=FailCVN=0
fileName = GetBoard().GetFileName()
if len(fileName)==0:
wx.LogMessage("a board needs to be saved/loaded!")
else:
found_violations=False
frame1 = AR_Prm(None)
#frame = wx.Frame(None)
frame1.Center()
#frame.setMsg(LogMsg)
frame1.ShowModal()
frame1.Destroy()
frame = displayDialog(None)
LogMsg=""
writeTxt= frame.m_richText1.WriteText
rt = frame.m_richText1
rt.BeginItalic()
writeTxt("'action_menu_annular_check.py'\n")
#frame.m_richText1.WriteText("'action_menu_annular_check.py'\n")
msg="'action_menu_annular_check.py'\n"
msg+="version = "+___version___
writeTxt("version = "+___version___)
msg+="\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA)
writeTxt("\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA))
rt.EndItalic()
writeTxt('\n\n')
#print (msg)
LogMsg+=msg+'\n\n'
# print "LISTING VIAS:"
for item in board.GetTracks():
if type(item) is pcbnew.VIA:
pos = item.GetPosition()
drill = item.GetDrillValue()
width = item.GetWidth()
ARv = vias_annring_size(item)
if ARv < MIN_AR_SIZE_V:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = item.GetPosition()
msg="AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailCV = FailCV+1
else:
PassCV = PassCV+1
#print type(item)
msg="VIAS that Pass = "+repr(PassCV)+"; Fails = "+repr(FailCV)
if FailCV >0:
rt.BeginBold()
writeTxt("VIAS that Pass = "+repr(PassCV)+"; ")
if FailCV >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCV)+'\n\n')
if FailCV >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
for module in board.GetModules():
try:
module_Pads=module.PadsList()
except:
module_Pads=module.Pads()
for pad in module_Pads: #print(pad.GetAttribute())
if pad.GetAttribute() == PAD_ATTRIB_STANDARD: #TH pad
ARv = annring_size(pad)
#print(f_mm(ARv))
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailC = FailC+1
else:
PassC = PassC+1
if pad.GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED:
ARvX, ARvY = annringNP_size(pad)
#print(f_mm(ARvX));print(f_mm(ARvY))
if (ARvX) != 0 or ARvY != 0:
ARv = min(ARvX, ARvY)
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailCN = FailCN+1
else:
PassCN = PassCN+1
else:
PassCN = PassCN+1
#if FailCV >0:
#writeTxt('\n')
msg = "TH PADS that Pass = "+repr(PassC)+"; Fails = "+repr(FailC)
if FailC >0:
rt.BeginBold()
writeTxt("TH PADS that Pass = "+repr(PassC)+"; ")
if FailC >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailC)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
msg="NPTH PADS that Pass = "+repr(PassCN)+"; Fails = "+repr(FailCN)
#writeTxt('\n')
if FailCN >0:
rt.BeginBold()
writeTxt("NPTH PADS that Pass = "+repr(PassCN)+"; ")
if FailCN >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCN)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
pcbName = (os.path.splitext(GetBoard().GetFileName())[0]) #filename no ext
#wx.LogMessage(pcbName)#LogMsg)
##wx.LogMessage(LogMsg)
FC=r"C:\FreeCAD\bin\freecad.exe"
kSU=r"C:\Cad\Progetti_K\3D-FreeCad-tools\kicad-StepUp-tools.FCMacro"
#subprocess.check_call([FC, kSU, pcbName])
##p = subprocess.Popen([FC, kSU, pcbName])
#found_violations=False
if (FailC+FailCN+FailCV)>0:
found_violations=True
if found_violations:
#frame.m_staticTitle = wx.StaticText(frame, label=" Check result: (Violations found)")
frame.m_staticTitle.SetLabel(" Check result: (Violations found)")
#self.title.SetForegroundColour('#FF0000')
frame.m_staticTitle.SetBackgroundColour('#FF0000')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
frame.m_staticTitle.SetFont(font)
else:
#frame.m_staticTitle = wx.StaticText(frame, label=" Annular Check result: OK")
frame.m_staticTitle.SetLabel(" Annular Check result: OK")
frame.m_staticTitle.SetBackgroundColour('#00FF00')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
frame.m_staticTitle.SetFont(font)
##frame = displayDialog(None)
#frame = wx.Frame(None)
frame.Center()
#frame.setMsg(LogMsg)
#frame.Show(True)
frame.ShowModal()
#frame.show()
frame.Destroy()
#frame = wx.wxFrame(None, 10110, 'T-Make', size=wx.wxSize(100,100),
# style=wx.wxSTAY_ON_TOP)
#frame.show()
# annular_check().register()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='KiCad PCB Annular Checker')
parser.add_argument('file', type=str, help="KiCad PCB file")
args = parser.parse_args()
print("Loading %s" % args.file)
main(pcbnew.LoadBoard(args.file))
else:
annular_check().register()
# "b64_data" is a variable containing your base64 encoded jpeg
annular_ico_b64_data =\
"""
iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIQQAACEEB+v+u9gAAABl0RVh0U29mdHdhcmUAd3d
3Lmlua3NjYXBlLm9yZ5vuPBoAAAJ5SURBVDiNdZRNSFRRFMd/976ZJjeBn2PUoiLaiMFkFkHIQ0NBdBUlJuIqiixmIYjQRgiJYKAMXRRSi6TCD5gaWiSFsy
gixOyDpDAog8wn9SISapz33m0x82bmzcOzO/97/r973nn3XqGUojjCybIm4BhQD9Rl5XlgDnhi6ObTYo8oBIWTZeXAMNDlalW/FJYmMLd5fONA1NBN0wcKJ
8sagftAZWRJcWHS5vCiouJ3pnClUvC8VnDtpOTTDgGwCpwydHM2Bwony8LAe6koH7hjc37aQXN8XwzAv5DgUo9krF0C/ABqDN1ck9n1G0D54C2H6OTmEICt
KcXQTZvTCQegAhgFEFWzpW1A4uAHRaLfQhbPXgD+/8HfkKBhNMDXMACtEmgC6L/reCBWKGAzMmLxbQWWl2Fw0FJavqIkpYhO2m7aHADqNQcOLXq3DcSuKnp
6Ajmhry8g1tfTxGJBVzryLuepl0Bk16qiJJUHKU0qOjryEDe6u4OF6e7vitCGAohIAFk0XCWEQkp8oWmeVAAiu78EFj5vF6S2iFyBtGxJPJ72gSYmPNpyOH
McgAUJzFkazO/zetLRc4J43MayIJWCsTHLuTzkaellTa7rOVE1W9oOPDz6VjF90fI14QQ1RzhKCNsRhfpGEBqvB1jaKQDapKGbCeDBs/2C8Rb/XGTalsUQg
Fin5kKmDN185DrPAD8HzmrcbpUony0flgZXujSGT+SuSC94L20LcA8obXiduSp1H8kdiz8l8KJWEOvUeLNXuJAuQzdnPKAsrBoYAY4DaA7sWck8I1+qKex0
Cug1dHPNFcQmD1sL0AwcACJZeQF4BcwYuvm42PMfVgD11Y9MUIEAAAAASUVORK5CYII=
"""
# execfile("annular.py")
# annular.py Testing PCB for Annular Ring >= 0.15
# AR violation of 0.1 at XY 172.974,110.744
# VIAS that Pass = 100 Fails = 1
# AR violation of 0.1 at XY 172.212,110.744
# AR violation of 0.0 at XY 154.813,96.52
# PADS that Pass = 49 Fails = 2
-455
View File
@@ -1,455 +0,0 @@
# -*- coding: utf-8 -*-
#
# A script to check for annular ring violations
# both for TH pads and vias
# requirements: KiCAD pcbnew >= 4.0
# annular.py release "1.5.1"
#
# annular.py checking PCB for Annular Ring in Vias and TH Pads
# (SMD, Connector and NPTH are skipped)
# default Annular Ring >= 0.15 both for TH Pads and Vias
# to change values modify:
#
# AR_SET = 0.150 #minimum annular accepted for pads
# AR_SET_V = 0.150 #minimum annular accepted for vias
# annular.py
___version___="1.5.7"
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
#wx.LogMessage("My message")
mm_ius = 1000000.0
# (consider always drill +0.1)
DRL_EXTRA=0.1
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = 0.125 #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = 0.125 #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
import sys
import wx
import wx.html
import subprocess
import os
import pcbnew
from pcbnew import *
import base64
from wx.lib.embeddedimage import PyEmbeddedImage
sys.path.append(os.path.dirname(__file__))
class annular_check( pcbnew.ActionPlugin ):
"""
A script to check for annular ring violations
both for TH pads and vias
requirements: KiCAD pcbnew >= 4.0
annular.py release "1.5.1"
annular.py checking PCB for Annular Ring in Vias and TH Pads
(SMD, Connector and NPTH are skipped)
default Annular Ring >= 0.15 both for TH Pads and Vias
to change values modify:
AR_SET = 0.150 #minimum annular accepted for pads
AR_SET_V = 0.150 #minimum annular accepted for vias
"""
def defaults( self ):
"""
Method defaults must be redefined
self.name should be the menu label to use
self.category should be the category (not yet used)
self.description should be a comprehensive description
of the plugin
"""
self.name = "Annular check"
self.category = "Checking PCB"
self.description = "Automaticaly check annular on an existing PCB"
def Run( self ):
###########################################################################
## Class AR_Prm
###########################################################################
class AR_Prm ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "AR parameters", pos = wx.DefaultPosition, size = wx.Size( 320,193 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 500,500 )
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
bSizer1 = wx.BoxSizer( wx.VERTICAL )
gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText11.Wrap( -1 )
gSizer2.Add( self.m_staticText11, 0, wx.ALL, 5 )
self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, str(DRL_EXTRA), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText1.Wrap( -1 )
gSizer2.Add( self.m_staticText1, 0, wx.ALL, 5 )
self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
self.m_staticText12 = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText12.Wrap( -1 )
gSizer2.Add( self.m_staticText12, 0, wx.ALL, 5 )
self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET_V), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_ok_btn, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.m_ok_btn)
# self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.m_cancel_btn)
# Tooltips
#self.m_cancel_btn.SetToolTip( wx.ToolTip(u"Cancel" ))
self.m_ok_btn.SetToolTip( wx.ToolTip(u"Confirm" ))
self.m_staticText1.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET_V.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_staticText12.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_textPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
self.m_staticText11.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
def __del__( self ):
pass
def OnClickOK(self, event):
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
self.m_ok_btn.SetLabel("Clicked")
phd = float(self.m_textPHD.GetValue().replace(',','.'))
ar = float(self.m_textAR_SET.GetValue().replace(',','.'))
arv = float(self.m_textAR_SET_V.GetValue().replace(',','.'))
DRL_EXTRA=phd
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = ar #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = arv #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
self.Destroy()
def OnClickCancel(self, event):
self.m_cancel_btn.SetLabel("Clicked")
self.Destroy()
#wx.MessageDialog(self.frame,"ciao")
#subprocess.check_call(["C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])
#http://stackoverflow.com/questions/1811691/running-an-outside-program-executable-in-python
class displayDialog(wx.Dialog):
"""
The default frame
http://stackoverflow.com/questions/3566603/how-do-i-make-wx-textctrl-multi-line-text-update-smoothly
"""
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
#----------------------------------------------------------------------
#def __init__(self):
# """Constructor"""
# wx.Frame.__init__(self, None, title="Display Frame", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
# panel = wx.Panel(self)
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=-1, title="Annular Checker")#
#, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
#, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
#, pos=DefaultPosition, size=DefaultSize, style = wx.DEFAULT_FRAME_STYLE & (~wx.MAXIMIZE_BOX), name="fname")
#, wx.ICON_INFORMATION) #, title="Annular Check", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
#
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
#wx.IconFromBitmap(wx.Bitmap("icon.ico", wx.BITMAP_TYPE_ANY)))
self.panel = wx.Panel(self)
if found_violations:
self.title = wx.StaticText(self.panel, label="Check result: (Violations found)")
#self.title.SetForegroundColour('#FF0000')
self.title.SetBackgroundColour('#FF0000')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
self.title.SetFont(font)
else:
self.title = wx.StaticText(self.panel, label="Annular Check result: OK")
self.title.SetBackgroundColour('#00FF00')
#self.result = wx.StaticText(self.panel, label="")
#self.result.SetForegroundColour('#FF0000')
#self.button = wx.Button(self.panel, label="Save")
#self.lblname = wx.StaticText(self.panel, label="Your name:")
#self.editname = wx.TextCtrl(self.panel, size=(140, -1))
self.editname = wx.TextCtrl(self.panel, size = (400, 400), style = wx.TE_MULTILINE|wx.TE_READONLY)
self.m_htmlWin1 = wx.html.HtmlWindow( self.panel, wx.ID_ANY, wx.DefaultPosition, wx.Size( 400,400 ), wx.html.HW_SCROLLBAR_AUTO )
#bSizer1.Add( self.m_htmlWin1, 0, wx.ALL, 5 )
# Set sizer for the frame, so we can change frame size to match widgets
self.windowSizer = wx.BoxSizer()
#self.windowSizer.Add(self.m_htmlWin1, 1, wx.ALL | wx.EXPAND)
self.windowSizer.Add(self.panel, 1, wx.ALL | wx.EXPAND)
# Set sizer for the panel content
self.sizer = wx.GridBagSizer(5, 0)
self.sizer.Add(self.title, (0, 0))
#self.sizer.Add(self.result, (1, 0))
#self.sizer.Add(self.lblname, (1, 0))
##self.sizer.Add(self.m_htmlWin1, (1, 0))
self.sizer.Add(self.editname, (1, 0))
#self.sizer.Add(self.button, (2, 0), (1, 2), flag=wx.EXPAND)
# Set simple sizer for a nice border
self.border = wx.BoxSizer()
self.border.Add(self.sizer, 1, wx.ALL | wx.EXPAND, 5)
# Use the sizers
self.panel.SetSizerAndFit(self.border)
self.SetSizerAndFit(self.windowSizer)
#self.result.SetLabel(msg)
# Set event handlers
#self.button.Bind(wx.EVT_BUTTON, self.OnButton)
#self.Show()
#self.Bind(wx.EVT_CLOSE,self.OnClose)
#def OnClose(self,e):
# #wx.LogMessage("c")
# e.Skip()
#self.Close()
#def OnButton(self, e):
# self.result.SetLabel(self.editname.GetValue())
def setMsg(self, t_msg):
self.editname.SetValue(t_msg)
self.m_htmlWin1.SetPage(t_msg)
def annring_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]+DRL_EXTRA_ius))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]+DRL_EXTRA_ius))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
return min(annrX,annrY)
def annringNP_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
#return min(annrX,annrY)
return annrX,annrY
def vias_annring_size(via):
# calculating via annular
annr=(via.GetWidth() - (via.GetDrillValue()+DRL_EXTRA_ius))/2
#print via.GetWidth()
#print via.GetDrillValue()
return annr
def f_mm(raw):
return repr(raw/mm_ius)
board = pcbnew.GetBoard()
PassC=FailC=0
PassCV=FailCV=0
PassCN=FailCN=0
PassCVN=FailCVN=0
fileName = GetBoard().GetFileName()
if len(fileName)==0:
wx.LogMessage("a board needs to be saved/loaded!")
else:
frame = AR_Prm(None)
#frame = wx.Frame(None)
frame.Center()
#frame.setMsg(LogMsg)
frame.ShowModal()
frame.Destroy()
LogMsg="<html><body><b>Hello, world!</b><br>"
msg="action_menu_annular_check.py<br>"
msg+="version = "+___version___
msg+="<br>Testing PCB for Annular Rings<br>TH Pads = "+repr(AR_SET)+" Vias = "+repr(AR_SET_V)+"<br>PHD margin on PTH = "+ repr(DRL_EXTRA)
#print (msg)
LogMsg+=msg+"<br><br>"
# print "LISTING VIAS:"
for item in board.GetTracks():
if type(item) is pcbnew.VIA:
pos = item.GetPosition()
drill = item.GetDrillValue()
width = item.GetWidth()
ARv = vias_annring_size(item)
if ARv < MIN_AR_SIZE_V:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = item.GetPosition()
msg="AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailCV = FailCV+1
else:
PassCV = PassCV+1
#print type(item)
msg="VIAS that Pass = "+repr(PassCV)+"; Fails = "+repr(FailCV)
# print(msg)
LogMsg+=msg+"<br>"
for module in board.GetModules():
try:
module_Pads=module.PadsList()
except:
module_Pads=module.Pads()
for pad in module_Pads: #print(pad.GetAttribute())
if pad.GetAttribute() == PAD_ATTRIB_STANDARD: #TH pad
ARv = annring_size(pad)
#print(f_mm(ARv))
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailC = FailC+1
else:
PassC = PassC+1
if pad.GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED:
ARvX, ARvY = annringNP_size(pad)
#print(f_mm(ARvX));print(f_mm(ARvY))
if (ARvX) != 0 or ARvY != 0:
ARv = min(ARvX, ARvY)
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailCN = FailCN+1
else:
PassCN = PassCN+1
else:
PassCN = PassCN+1
msg = "TH PADS that Pass = "+repr(PassC)+"; Fails = "+repr(FailC)
print(msg)
LogMsg+=msg+"<br>"
msg="NPTH PADS that Pass = "+repr(PassCN)+"; Fails = "+repr(FailCN)
print(msg)
LogMsg+=msg+"</body></html>"
pcbName = (os.path.splitext(GetBoard().GetFileName())[0]) #filename no ext
#wx.LogMessage(pcbName)#LogMsg)
##wx.LogMessage(LogMsg)
FC=r"C:\FreeCAD\bin\freecad.exe"
#kSU=r"C:\Cad\Progetti_K\3D-FreeCad-tools\kicad-StepUp-tools.FCMacro"
#subprocess.check_call([FC, kSU, pcbName])
##p = subprocess.Popen([FC, kSU, pcbName])
found_violations=False
if (FailC+FailCN+FailCV)>0:
found_violations=True
frame = displayDialog(None)
#frame = wx.Frame(None)
frame.Center()
frame.setMsg(LogMsg)
frame.ShowModal()
frame.Destroy()
#frame = wx.wxFrame(None, 10110, 'T-Make', size=wx.wxSize(100,100),
# style=wx.wxSTAY_ON_TOP)
#frame.show()
# annular_check().register()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='KiCad PCB Annular Checker')
parser.add_argument('file', type=str, help="KiCad PCB file")
args = parser.parse_args()
print("Loading %s" % args.file)
main(pcbnew.LoadBoard(args.file))
else:
annular_check().register()
# "b64_data" is a variable containing your base64 encoded jpeg
annular_ico_b64_data =\
"""
iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIQQAACEEB+v+u9gAAABl0RVh0U29mdHdhcmUAd3d
3Lmlua3NjYXBlLm9yZ5vuPBoAAAJ5SURBVDiNdZRNSFRRFMd/976ZJjeBn2PUoiLaiMFkFkHIQ0NBdBUlJuIqiixmIYjQRgiJYKAMXRRSi6TCD5gaWiSFsy
gixOyDpDAog8wn9SISapz33m0x82bmzcOzO/97/r973nn3XqGUojjCybIm4BhQD9Rl5XlgDnhi6ObTYo8oBIWTZeXAMNDlalW/FJYmMLd5fONA1NBN0wcKJ
8sagftAZWRJcWHS5vCiouJ3pnClUvC8VnDtpOTTDgGwCpwydHM2Bwony8LAe6koH7hjc37aQXN8XwzAv5DgUo9krF0C/ABqDN1ck9n1G0D54C2H6OTmEICt
KcXQTZvTCQegAhgFEFWzpW1A4uAHRaLfQhbPXgD+/8HfkKBhNMDXMACtEmgC6L/reCBWKGAzMmLxbQWWl2Fw0FJavqIkpYhO2m7aHADqNQcOLXq3DcSuKnp
6Ajmhry8g1tfTxGJBVzryLuepl0Bk16qiJJUHKU0qOjryEDe6u4OF6e7vitCGAohIAFk0XCWEQkp8oWmeVAAiu78EFj5vF6S2iFyBtGxJPJ72gSYmPNpyOH
McgAUJzFkazO/zetLRc4J43MayIJWCsTHLuTzkaellTa7rOVE1W9oOPDz6VjF90fI14QQ1RzhKCNsRhfpGEBqvB1jaKQDapKGbCeDBs/2C8Rb/XGTalsUQg
Fin5kKmDN185DrPAD8HzmrcbpUony0flgZXujSGT+SuSC94L20LcA8obXiduSp1H8kdiz8l8KJWEOvUeLNXuJAuQzdnPKAsrBoYAY4DaA7sWck8I1+qKex0
Cug1dHPNFcQmD1sL0AwcACJZeQF4BcwYuvm42PMfVgD11Y9MUIEAAAAASUVORK5CYII=
"""
# execfile("annular.py")
# annular.py Testing PCB for Annular Ring >= 0.15
# AR violation of 0.1 at XY 172.974,110.744
# VIAS that Pass = 100 Fails = 1
# AR violation of 0.1 at XY 172.212,110.744
# AR violation of 0.0 at XY 154.813,96.52
# PADS that Pass = 49 Fails = 2
+357 -567
View File
@@ -16,9 +16,13 @@
# annular.py
___version___="AC version: 1.6.0"
#### plugins errors
#import pcbnew;pcbnew.GetWizardsBackTrace()
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations, LogMsg, ___version___
___version___="1.6.1"
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations, LogMsg
#wx.LogMessage("My message")
mm_ius = 1000000.0
# (consider always drill +0.1)
@@ -34,15 +38,112 @@ MIN_AR_SIZE_V = AR_SET_V * mm_ius
import sys
import wx
import wx.richtext
import subprocess
#import subprocess
import os
import pcbnew
from pcbnew import *
import base64
from wx.lib.embeddedimage import PyEmbeddedImage
# import base64
# from wx.lib.embeddedimage import PyEmbeddedImage
from . import AnnularDlg
from . import AnnularResultDlg
sys.path.append(os.path.dirname(__file__))
debug = False
def wxLogDebug(msg,dbg):
"""printing messages only if show is omitted or True"""
if dbg == True:
wx.LogMessage(msg)
#
class AnnularResult_Dlg(AnnularResultDlg.AnnularResultDlg):
# from https://github.com/MitjaNemec/Kicad_action_plugins
# hack for new wxFormBuilder generating code incompatible with old wxPython
# noinspection PyMethodOverriding
def SetSizeHints(self, sz1, sz2):
if wx.__version__ < '4.0':
self.SetSizeHintsSz(sz1, sz2)
else:
super(AnnularResult_Dlg, self).SetSizeHints(sz1, sz2)
def onOK(self, event):
return self.EndModal(wx.ID_OK) # if modal_result == wx.ID_OK:
def OnClickCopy(self, event):
self.m_richTextResult.SelectAll()
self.m_richTextResult.Copy()
#global LogMsg
#copy2clip(LogMsg)
self.copy_btn.SetLabel("Text Copied")
# def onDeleteClick(self, event):
# return self.EndModal(wx.ID_DELETE)
#
# def onConnectClick(self, event):
# return self.EndModal(wx.ID_REVERT)
def __init__(self, parent):
import wx
AnnularResultDlg.AnnularResultDlg.__init__(self, parent)
#self.GetSizer().Fit(self)
self.SetMinSize(self.GetSize())
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.onOK, self.ok_btn)
#self.ok_btn.Bind(wx.EVT_BUTTON, self.EndModal(wx.ID_OK))
self.Bind(wx.EVT_BUTTON, self.OnClickCopy, self.copy_btn)
self.ok_btn.SetFocus()
# Tooltips
self.copy_btn.SetToolTip( wx.ToolTip(u"Copy Text to Clipboard" ))
self.ok_btn.SetToolTip( wx.ToolTip(u"Exit" ))
#def onOK(self, event):
# return self.EndModal(wx.ID_OK) # if modal_result == wx.ID_OK:
#def onConnectClick(self, event):
# return self.EndModal(wx.ID_REVERT)
#self.m_buttonDelete.Bind(wx.EVT_BUTTON, self.onDeleteClick)
#self.m_buttonReconnect.Bind(wx.EVT_BUTTON, self.onConnectClick)
#if wx.__version__ < '4.0':
# self.m_buttonReconnect.SetToolTipString( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
# self.m_buttonRound.SetToolTipString( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
#else:
# self.m_buttonReconnect.SetToolTip( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
# self.m_buttonRound.SetToolTip( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
class Annular_Dlg(AnnularDlg.AnnularDlg):
# from https://github.com/MitjaNemec/Kicad_action_plugins
# hack for new wxFormBuilder generating code incompatible with old wxPython
# noinspection PyMethodOverriding
def SetSizeHints(self, sz1, sz2):
if wx.__version__ < '4.0':
self.SetSizeHintsSz(sz1, sz2)
else:
super(Annular_Dlg, self).SetSizeHints(sz1, sz2)
# def onDeleteClick(self, event):
# return self.EndModal(wx.ID_DELETE)
#
# def onConnectClick(self, event):
# return self.EndModal(wx.ID_REVERT)
def __init__(self, parent):
import wx
AnnularDlg.AnnularDlg.__init__(self, parent)
#self.GetSizer().Fit(self)
self.SetMinSize(self.GetSize())
#self.m_buttonDelete.Bind(wx.EVT_BUTTON, self.onDeleteClick)
#self.m_buttonReconnect.Bind(wx.EVT_BUTTON, self.onConnectClick)
#if wx.__version__ < '4.0':
# self.m_buttonReconnect.SetToolTipString( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
# self.m_buttonRound.SetToolTipString( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
#else:
# self.m_buttonReconnect.SetToolTip( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
# self.m_buttonRound.SetToolTip( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
# Python plugin stuff
class annular_check( pcbnew.ActionPlugin ):
"""
A script to check for annular ring violations
@@ -58,7 +159,7 @@ class annular_check( pcbnew.ActionPlugin ):
AR_SET = 0.150 #minimum annular accepted for pads
AR_SET_V = 0.150 #minimum annular accepted for vias
"""
global ___version___
def defaults( self ):
"""
Method defaults must be redefined
@@ -67,7 +168,7 @@ class annular_check( pcbnew.ActionPlugin ):
self.description should be a comprehensive description
of the plugin
"""
self.name = "Annular check"
self.name = "Annular check \nversion "+___version___
self.category = "Checking PCB"
self.description = "Automaticaly check annular on an existing PCB"
#self.pcbnew_icon_support = hasattr(self, "show_toolbar_button")
@@ -75,582 +176,271 @@ class annular_check( pcbnew.ActionPlugin ):
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'annular.png')
def Run( self ):
###########################################################################
## Class AR_Prm
###########################################################################
#class AR_Prm ( wx.Dialog ):
#
# def __init__( self, parent ):
# wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "AR parameters", pos = wx.DefaultPosition, size = wx.Size( 320,193 ), style = wx.DEFAULT_DIALOG_STYLE )
#
# self.SetSizeHints( 500,500 )
#
# self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
#
# bSizer1 = wx.BoxSizer( wx.VERTICAL )
#
# gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
#
# self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
# self.m_staticText11.Wrap( -1 )
#
# gSizer2.Add( self.m_staticText11, 0, wx.ALL, 5 )
#
# self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, str(DRL_EXTRA), wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
#
# self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
# self.m_staticText1.Wrap( -1 )
#
# gSizer2.Add( self.m_staticText1, 0, wx.ALL, 5 )
#
# self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET), wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
#
# self.m_staticText12 = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
# self.m_staticText12.Wrap( -1 )
#
# gSizer2.Add( self.m_staticText12, 0, wx.ALL, 5 )
#
# self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET_V), wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
#
#
# bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
#
# gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
#
# self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer1.Add( self.m_ok_btn, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
#
# # self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
# # gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
#
#
# bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
#
#
# self.SetSizer( bSizer1 )
# self.Layout()
#
# self.Centre( wx.BOTH )
#
# #### ----- connections
# # Connect Events
# self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.m_ok_btn)
# # self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.m_cancel_btn)
# # Tooltips
# #self.m_cancel_btn.SetToolTip( wx.ToolTip(u"Cancel" ))
# self.m_ok_btn.SetToolTip( wx.ToolTip(u"Confirm" ))
# self.m_ok_btn.SetFocus()
# self.m_staticText1.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
# self.m_textAR_SET.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
# self.m_textAR_SET_V.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
# self.m_staticText12.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
# self.m_textPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
# self.m_staticText11.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
class AR_Prm ( wx.Dialog ):
import sys,os
#mm_ius = 1000000.0
_pcbnew_frame = [x for x in wx.GetTopLevelWindows() if x.GetTitle().lower().startswith('pcbnew')][0]
#aParameters = RoundTrackDlg(None)
aParameters = Annular_Dlg(_pcbnew_frame)
aParameters.m_LabelTitle.SetLabel("Check annular ring: version: "+___version___)
aParameters.m_textCtrlARP.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
aParameters.m_staticTextPHD.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
aParameters.m_textCtrlARV.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
aParameters.m_staticTextARV.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
aParameters.m_textCtrlPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
aParameters.m_staticTextARP.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
aParameters.m_textCtrlPHD.SetValue('0.1')
aParameters.m_textCtrlARP.SetValue('0.125')
aParameters.m_textCtrlARV.SetValue('0.125')
aParameters.Show()
modal_result = aParameters.ShowModal()
#import pcbnew;pcbnew.GetWizardsBackTrace()
if modal_result == wx.ID_OK:
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
phd = float(aParameters.m_textCtrlPHD.GetValue().replace(',','.'))
ar = float(aParameters.m_textCtrlARP.GetValue().replace(',','.'))
arv = float(aParameters.m_textCtrlARV.GetValue().replace(',','.'))
DRL_EXTRA=phd
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Checker", pos = wx.DefaultPosition, size = wx.Size( 320,229 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 320, 320 )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
self.m_StaticTextPHD = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextPHD.Wrap( -1 )
gSizer2.Add( self.m_StaticTextPHD, 0, wx.ALL, 5 )
self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
self.m_StaticTextAR_SET = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextAR_SET.Wrap( -1 )
gSizer2.Add( self.m_StaticTextAR_SET, 0, wx.ALL, 5 )
self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
self.m_StaticTextAR_SET_V = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextAR_SET_V.Wrap( -1 )
gSizer2.Add( self.m_StaticTextAR_SET_V, 0, wx.ALL, 5 )
self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticTextVersion = wx.StaticText( self, wx.ID_ANY, u"Version", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTextVersion.Wrap( -1 )
bSizer2.Add( self.m_staticTextVersion, 0, wx.ALL, 5 )
gSizer2.Add( bSizer2, 1, wx.EXPAND, 5 )
bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_ok_btn, 0, wx.ALL, 5 )
#self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
#gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.m_ok_btn)
# self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.m_cancel_btn)
# Tooltips
#self.m_cancel_btn.SetToolTip( wx.ToolTip(u"Cancel" ))
self.m_ok_btn.SetToolTip( wx.ToolTip(u"Confirm" ))
self.m_ok_btn.SetFocus()
#self.m_staticText1.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET.SetValue(str(AR_SET))
self.m_textAR_SET.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET_V.SetValue(str(AR_SET_V))
self.m_textAR_SET_V.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
#self.m_staticText12.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_staticTextVersion.SetLabel(___version___)
self.m_textPHD.SetValue(str(DRL_EXTRA))
self.m_textPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
#self.m_staticText11.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
def __del__( self ):
pass
def OnClickOK(self, event):
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
self.m_ok_btn.SetLabel("Clicked")
phd = float(self.m_textPHD.GetValue().replace(',','.'))
ar = float(self.m_textAR_SET.GetValue().replace(',','.'))
arv = float(self.m_textAR_SET_V.GetValue().replace(',','.'))
DRL_EXTRA=phd
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = ar #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = arv #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
self.Destroy()
def OnClickCancel(self, event):
self.m_cancel_btn.SetLabel("Clicked")
self.Destroy()
#wx.MessageDialog(self.frame,"ciao")
#subprocess.check_call(["C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])
#http://stackoverflow.com/questions/1811691/running-an-outside-program-executable-in-python
## class displayDialog(wx.Dialog):
## """
## The default frame
## http://stackoverflow.com/questions/3566603/how-do-i-make-wx-textctrl-multi-line-text-update-smoothly
## """
## global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
## #----------------------------------------------------------------------
## #def __init__(self):
## # """Constructor"""
## # wx.Frame.__init__(self, None, title="Display Frame", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
## # panel = wx.Panel(self)
## def __init__(self, parent):
## wx.Dialog.__init__(self, parent, id=-1, title="Annular Checker")#
## #, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
## #, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
## #, pos=DefaultPosition, size=DefaultSize, style = wx.DEFAULT_FRAME_STYLE & (~wx.MAXIMIZE_BOX), name="fname")
## #, wx.ICON_INFORMATION) #, title="Annular Check", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
## #
##
## self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
## #wx.IconFromBitmap(wx.Bitmap("icon.ico", wx.BITMAP_TYPE_ANY)))
## self.panel = wx.Panel(self)
##
## if found_violations:
## self.title = wx.StaticText(self.panel, label="")
## #self.title.SetForegroundColour('#FF0000')
## #self.title.SetBackgroundColour('#FF0000')
## #font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
## #self.title.SetFont(font)
## else:
## self.title = wx.StaticText(self.panel, label="")
## #self.title.SetBackgroundColour('#00FF00')
## #font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
## #self.title.SetFont(font)
## #self.result = wx.StaticText(self.panel, label="")
## #self.result.SetForegroundColour('#FF0000')
## #self.button = wx.Button(self.panel, label="Save")
## #self.lblname = wx.StaticText(self.panel, label="Your name:")
## #self.editname = wx.TextCtrl(self.panel, size=(140, -1))
## ##self.editname = wx.TextCtrl(self.panel, size = (400, 400), style = wx.TE_MULTILINE|wx.TE_READONLY)
## self.m_richText1 = wx.richtext.RichTextCtrl( self.panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, size = (400, 400), style = 0|wx.VSCROLL|wx.HSCROLL|wx.WANTS_CHARS )# wx.TE_MULTILINE|wx.TE_READONLY) #0|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
## #bSizer1.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 )
##
##
## # Set sizer for the frame, so we can change frame size to match widgets
## self.windowSizer = wx.BoxSizer()
## self.windowSizer.Add(self.panel, 1, wx.ALL | wx.EXPAND)
##
## # Set sizer for the panel content
## self.sizer = wx.GridBagSizer(5, 0)
## self.sizer.Add(self.title, (0, 0))
## #self.sizer.Add(self.result, (1, 0))
## #self.sizer.Add(self.lblname, (1, 0))
## ## self.sizer.Add(self.editname, (1, 0))
## self.sizer.Add(self.m_richText1, (1, 0))
## #self.ok_btn = wx.Button( self, wx.ID_ANY, u"Copy errors", wx.DefaultPosition, wx.DefaultSize, 0 )
## #self.sizer.Add( self.ok_btn, 0, wx.ALL | wx.EXPAND)
## #self.sizer.Add(self.ok_btn, (2, 0)) #, wx.ALL | flag=wx.EXPAND)
## #self.sizer.Add( self.ok_btn, 0, wx.ALL, 5 )
##
## #self.sizer.Add(self.ok_btn, (2, 0), (1, 2), flag=wx.EXPAND)
##
## # Set simple sizer for a nice border
## self.border = wx.BoxSizer()
## self.border.Add(self.sizer, 1, wx.ALL | wx.EXPAND, 5)
##
## #self.ok_btn = wx.Button( self, wx.ID_ANY, u"Copy errors", wx.DefaultPosition, wx.DefaultSize, 0 )
## #self.windowSizer.Add(self.ok_btn, 0, wx.ALL)
## #self.sizer.Add( self.ok_btn, (2,0))
## #self.sizer.Add( self.ok_btn, 0, wx.ALL, 5 )
## # Use the sizers
## self.panel.SetSizerAndFit(self.border)
## self.SetSizerAndFit(self.windowSizer)
## #self.result.SetLabel(msg)
## # Set event handlers
## #self.button.Bind(wx.EVT_BUTTON, self.OnButton)
## #self.Show()
## #self.Bind(wx.EVT_CLOSE,self.OnClose)
##
## #def OnClose(self,e):
## # #wx.LogMessage("c")
## # e.Skip()
## #self.Close()
###########################################################################
## Class displayDialog
###########################################################################
class displayDialog ( wx.Dialog ):
AR_SET = ar #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations, LogMsg
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Checker", pos = wx.DefaultPosition, size = wx.Size( 450,521 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 300,100 )
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
bSizer1 = wx.BoxSizer( wx.VERTICAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticTitle = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTitle.Wrap( -1 )
bSizer2.Add( self.m_staticTitle, 0, wx.ALL, 5 )
self.m_richText1 = wx.richtext.RichTextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
self.m_richText1.SetMinSize( wx.Size( 400,400 ) )
bSizer2.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 )
gSizer3 = wx.GridSizer( 0, 2, 0, 0 )
self.ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.ok_btn, 0, wx.ALL, 5 )
self.copy_btn = wx.Button( self, wx.ID_ANY, u"Copy Text", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer3.Add( self.copy_btn, 0, wx.ALL, 5 )
bSizer2.Add( gSizer3, 1, wx.EXPAND, 5 )
bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.ok_btn)
self.Bind(wx.EVT_BUTTON, self.OnClickCopy, self.copy_btn)
self.ok_btn.SetFocus()
# Tooltips
self.copy_btn.SetToolTip( wx.ToolTip(u"Copy Text to Clipboard" ))
self.ok_btn.SetToolTip( wx.ToolTip(u"Exit" ))
def __del__( self ):
pass
def OnClickOK(self, event):
self.Destroy()
def OnClickCopy(self, event):
self.m_richText1.SelectAll()
self.m_richText1.Copy()
#global LogMsg
#copy2clip(LogMsg)
self.copy_btn.SetLabel("Text Copied")
#def setMsg(self, t_msg):
# pass
#self.editname.SetValue(t_msg)
#self.m_richText1.BeginBold()
#self.m_richText1.WriteText(" You are in ")
#self.m_richText1.BeginTextColour('red')
#self.m_richText1.WriteText("danger ")
#self.m_richText1.EndTextColour()
#self.m_richText1.WriteText("at that spot!")
#self.m_richText1.EndBold()
#self.m_richText1.SetValue(t_msg)
#self.m_htmlWin1.SetPage(t_msg)
def annring_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]+DRL_EXTRA_ius))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]+DRL_EXTRA_ius))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
return min(annrX,annrY)
def annringNP_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
#return min(annrX,annrY)
return annrX,annrY
def vias_annring_size(via):
# calculating via annular
annr=(via.GetWidth() - (via.GetDrillValue()+DRL_EXTRA_ius))/2
#print via.GetWidth()
#print via.GetDrillValue()
return annr
def f_mm(raw):
return repr(raw/mm_ius)
board = pcbnew.GetBoard()
PassC=FailC=0
PassCV=FailCV=0
PassCN=FailCN=0
PassCVN=FailCVN=0
fileName = GetBoard().GetFileName()
if len(fileName)==0:
wx.LogMessage("a board needs to be saved/loaded!")
AR_SET_V = arv #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
#snap2grid(gridSizeMM,use_grid_origin)
calculate_AR()
else:
found_violations=False
frame1 = AR_Prm(None)
#frame = wx.Frame(None)
frame1.Center()
#frame.setMsg(LogMsg)
frame1.ShowModal()
frame1.Destroy()
frame = displayDialog(None)
LogMsg=""
writeTxt= frame.m_richText1.WriteText
rt = frame.m_richText1
rt.BeginItalic()
writeTxt("'action_menu_annular_check.py'\n")
#frame.m_richText1.WriteText("'action_menu_annular_check.py'\n")
msg="'action_menu_annular_check.py'\n"
msg+="version = "+___version___
writeTxt("version = "+___version___)
msg+="\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA)
writeTxt("\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA))
rt.EndItalic()
writeTxt('\n\n')
#print (msg)
LogMsg+=msg+'\n\n'
# print "LISTING VIAS:"
for item in board.GetTracks():
if type(item) is pcbnew.VIA:
pos = item.GetPosition()
drill = item.GetDrillValue()
width = item.GetWidth()
ARv = vias_annring_size(item)
if ARv < MIN_AR_SIZE_V:
None # Cancel
def annring_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]+DRL_EXTRA_ius))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]+DRL_EXTRA_ius))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
return min(annrX,annrY)
def annringNP_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
#return min(annrX,annrY)
return annrX,annrY
def vias_annring_size(via):
# calculating via annular
annr=(via.GetWidth() - (via.GetDrillValue()+DRL_EXTRA_ius))/2
#print via.GetWidth()
#print via.GetDrillValue()
return annr
def f_mm(raw):
return repr(raw/mm_ius)
def calculate_AR():
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
board = pcbnew.GetBoard()
PassC=FailC=0
PassCV=FailCV=0
PassCN=FailCN=0
PassCVN=FailCVN=0
fileName = GetBoard().GetFileName()
if len(fileName)==0:
wx.LogMessage("a board needs to be saved/loaded!")
else:
found_violations=False
_pcbnew_frame = [x for x in wx.GetTopLevelWindows() if x.GetTitle().lower().startswith('pcbnew')][0]
aResult = AnnularResult_Dlg(_pcbnew_frame)
#import pcbnew;pcbnew.GetWizardsBackTrace()
writeTxt= aResult.m_richTextResult.WriteText
rt = aResult.m_richTextResult
rt.BeginItalic()
writeTxt("'action_menu_annular_check.py'\n")
#frame.m_richText1.WriteText("'action_menu_annular_check.py'\n")
LogMsg=""
msg="'action_menu_annular_check.py'\n"
msg+="version = "+___version___
writeTxt("version = "+___version___)
msg+="\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA)
writeTxt("\nTesting PCB for Annular Rings\nTH Pads >= "+repr(AR_SET)+" Vias >= "+repr(AR_SET_V)+"\nPHD margin on PTH = "+ repr(DRL_EXTRA))
rt.EndItalic()
writeTxt('\n\n')
#print (msg)
LogMsg+=msg+'\n\n'
# print "LISTING VIAS:"
for item in board.GetTracks():
if type(item) is pcbnew.VIA:
pos = item.GetPosition()
drill = item.GetDrillValue()
width = item.GetWidth()
ARv = vias_annring_size(item)
if ARv < MIN_AR_SIZE_V:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = item.GetPosition()
msg="AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
XYpair = item.GetPosition()
msg="AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailCV = FailCV+1
else:
PassCV = PassCV+1
#print type(item)
msg="VIAS that Pass = "+repr(PassCV)+"; Fails = "+repr(FailCV)
if FailCV >0:
rt.BeginBold()
writeTxt("VIAS that Pass = "+repr(PassCV)+"; ")
if FailCV >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCV)+'\n\n')
if FailCV >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
for module in board.GetModules():
try:
module_Pads=module.PadsList()
except:
module_Pads=module.Pads()
for pad in module_Pads: #print(pad.GetAttribute())
if pad.GetAttribute() == PAD_ATTRIB_STANDARD: #TH pad
ARv = annring_size(pad)
#print(f_mm(ARv))
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
writeTxt("AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailCV = FailCV+1
FailC = FailC+1
else:
PassCV = PassCV+1
#print type(item)
msg="VIAS that Pass = "+repr(PassCV)+"; Fails = "+repr(FailCV)
if FailCV >0:
rt.BeginBold()
writeTxt("VIAS that Pass = "+repr(PassCV)+"; ")
if FailCV >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCV)+'\n\n')
if FailCV >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
for module in board.GetModules():
try:
module_Pads=module.PadsList()
except:
module_Pads=module.Pads()
for pad in module_Pads: #print(pad.GetAttribute())
if pad.GetAttribute() == PAD_ATTRIB_STANDARD: #TH pad
ARv = annring_size(pad)
#print(f_mm(ARv))
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
PassC = PassC+1
if pad.GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED:
ARvX, ARvY = annringNP_size(pad)
#print(f_mm(ARvX));print(f_mm(ARvY))
if (ARvX) != 0 or ARvY != 0:
ARv = min(ARvX, ARvY)
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
msg="AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
writeTxt("AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailC = FailC+1
else:
PassC = PassC+1
if pad.GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED:
ARvX, ARvY = annringNP_size(pad)
#print(f_mm(ARvX));print(f_mm(ARvY))
if (ARvX) != 0 or ARvY != 0:
ARv = min(ARvX, ARvY)
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
rt.BeginTextColour('red')
writeTxt("AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])+'\n')
rt.EndTextColour()
#print (msg)
LogMsg+=msg+'\n'
FailCN = FailCN+1
else:
PassCN = PassCN+1
FailCN = FailCN+1
else:
PassCN = PassCN+1
#if FailCV >0:
#writeTxt('\n')
msg = "TH PADS that Pass = "+repr(PassC)+"; Fails = "+repr(FailC)
if FailC >0:
rt.BeginBold()
writeTxt("TH PADS that Pass = "+repr(PassC)+"; ")
if FailC >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailC)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
msg="NPTH PADS that Pass = "+repr(PassCN)+"; Fails = "+repr(FailCN)
#writeTxt('\n')
if FailCN >0:
rt.BeginBold()
writeTxt("NPTH PADS that Pass = "+repr(PassCN)+"; ")
if FailCN >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCN)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
pcbName = (os.path.splitext(GetBoard().GetFileName())[0]) #filename no ext
#wx.LogMessage(pcbName)#LogMsg)
##wx.LogMessage(LogMsg)
FC=r"C:\FreeCAD\bin\freecad.exe"
kSU=r"C:\Cad\Progetti_K\3D-FreeCad-tools\kicad-StepUp-tools.FCMacro"
#subprocess.check_call([FC, kSU, pcbName])
##p = subprocess.Popen([FC, kSU, pcbName])
#found_violations=False
if (FailC+FailCN+FailCV)>0:
found_violations=True
if found_violations:
#frame.m_staticTitle = wx.StaticText(frame, label=" Check result: (Violations found)")
frame.m_staticTitle.SetLabel(" Check result: (Violations found)")
#self.title.SetForegroundColour('#FF0000')
frame.m_staticTitle.SetBackgroundColour('#FF0000')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
frame.m_staticTitle.SetFont(font)
else:
#frame.m_staticTitle = wx.StaticText(frame, label=" Annular Check result: OK")
frame.m_staticTitle.SetLabel(" Annular Check result: OK")
frame.m_staticTitle.SetBackgroundColour('#00FF00')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
frame.m_staticTitle.SetFont(font)
##frame = displayDialog(None)
#frame = wx.Frame(None)
frame.Center()
#frame.setMsg(LogMsg)
#frame.Show(True)
frame.ShowModal()
#frame.show()
frame.Destroy()
#frame = wx.wxFrame(None, 10110, 'T-Make', size=wx.wxSize(100,100),
# style=wx.wxSTAY_ON_TOP)
#frame.show()
else:
PassCN = PassCN+1
#if FailCV >0:
#writeTxt('\n')
msg = "TH PADS that Pass = "+repr(PassC)+"; Fails = "+repr(FailC)
if FailC >0:
rt.BeginBold()
writeTxt("TH PADS that Pass = "+repr(PassC)+"; ")
if FailC >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailC)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
msg="NPTH PADS that Pass = "+repr(PassCN)+"; Fails = "+repr(FailCN)
#writeTxt('\n')
if FailCN >0:
rt.BeginBold()
writeTxt("NPTH PADS that Pass = "+repr(PassCN)+"; ")
if FailCN >0:
rt.BeginTextColour('red')
writeTxt("Fails = "+repr(FailCN)+'\n')
if FailC >0:
rt.EndTextColour()
rt.EndBold()
print(msg)
LogMsg+=msg+'\n'
pcbName = (os.path.splitext(GetBoard().GetFileName())[0]) #filename no ext
#wx.LogMessage(pcbName)#LogMsg)
##wx.LogMessage(LogMsg)
FC=r"C:\FreeCAD\bin\freecad.exe"
kSU=r"C:\Cad\Progetti_K\3D-FreeCad-tools\kicad-StepUp-tools.FCMacro"
#subprocess.check_call([FC, kSU, pcbName])
##p = subprocess.Popen([FC, kSU, pcbName])
#found_violations=False
if (FailC+FailCN+FailCV)>0:
found_violations=True
if found_violations:
#frame.m_staticTitle = wx.StaticText(frame, label=" Check result: (Violations found)")
aResult.m_staticTitle.SetLabel(" Check result: (Violations found)")
#self.title.SetForegroundColour('#FF0000')
aResult.m_staticTitle.SetBackgroundColour('#FF0000')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
aResult.m_staticTitle.SetFont(font)
else:
#frame.m_staticTitle = wx.StaticText(frame, label=" Annular Check result: OK")
aResult.m_staticTitle.SetLabel(" Annular Check result: OK")
aResult.m_staticTitle.SetBackgroundColour('#00FF00')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
aResult.m_staticTitle.SetFont(font)
aResult.Show()
modal_result = aResult.ShowModal()
if modal_result == wx.ID_OK:
aResult.Destroy()
if modal_result == wx.ID_OK:
aResult.Destroy()
# ##frame = displayDialog(None)
# #frame = wx.Frame(None)
# frame.Center()
# #frame.setMsg(LogMsg)
# #frame.Show(True)
# frame.ShowModal()
# #frame.show()
# frame.Destroy()
# #frame = wx.wxFrame(None, 10110, 'T-Make', size=wx.wxSize(100,100),
# # style=wx.wxSTAY_ON_TOP)
# #frame.show()
# annular_check().register()
if __name__ == "__main__":
-455
View File
@@ -1,455 +0,0 @@
# -*- coding: utf-8 -*-
#
# A script to check for annular ring violations
# both for TH pads and vias
# requirements: KiCAD pcbnew >= 4.0
# annular.py release "1.5.1"
#
# annular.py checking PCB for Annular Ring in Vias and TH Pads
# (SMD, Connector and NPTH are skipped)
# default Annular Ring >= 0.15 both for TH Pads and Vias
# to change values modify:
#
# AR_SET = 0.150 #minimum annular accepted for pads
# AR_SET_V = 0.150 #minimum annular accepted for vias
# annular.py
___version___="1.5.7"
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
#wx.LogMessage("My message")
mm_ius = 1000000.0
# (consider always drill +0.1)
DRL_EXTRA=0.1
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = 0.125 #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = 0.125 #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
import sys
import wx
import wx.html
import subprocess
import os
import pcbnew
from pcbnew import *
import base64
from wx.lib.embeddedimage import PyEmbeddedImage
sys.path.append(os.path.dirname(__file__))
class annular_check( pcbnew.ActionPlugin ):
"""
A script to check for annular ring violations
both for TH pads and vias
requirements: KiCAD pcbnew >= 4.0
annular.py release "1.5.1"
annular.py checking PCB for Annular Ring in Vias and TH Pads
(SMD, Connector and NPTH are skipped)
default Annular Ring >= 0.15 both for TH Pads and Vias
to change values modify:
AR_SET = 0.150 #minimum annular accepted for pads
AR_SET_V = 0.150 #minimum annular accepted for vias
"""
def defaults( self ):
"""
Method defaults must be redefined
self.name should be the menu label to use
self.category should be the category (not yet used)
self.description should be a comprehensive description
of the plugin
"""
self.name = "Annular check"
self.category = "Checking PCB"
self.description = "Automaticaly check annular on an existing PCB"
def Run( self ):
###########################################################################
## Class AR_Prm
###########################################################################
class AR_Prm ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = "AR parameters", pos = wx.DefaultPosition, size = wx.Size( 320,193 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( 500,500 )
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
bSizer1 = wx.BoxSizer( wx.VERTICAL )
gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText11.Wrap( -1 )
gSizer2.Add( self.m_staticText11, 0, wx.ALL, 5 )
self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, str(DRL_EXTRA), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText1.Wrap( -1 )
gSizer2.Add( self.m_staticText1, 0, wx.ALL, 5 )
self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
self.m_staticText12 = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_staticText12.Wrap( -1 )
gSizer2.Add( self.m_staticText12, 0, wx.ALL, 5 )
self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, str(AR_SET_V), wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_ok_btn, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
# gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
#### ----- connections
# Connect Events
self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.m_ok_btn)
# self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.m_cancel_btn)
# Tooltips
#self.m_cancel_btn.SetToolTip( wx.ToolTip(u"Cancel" ))
self.m_ok_btn.SetToolTip( wx.ToolTip(u"Confirm" ))
self.m_staticText1.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET.SetToolTip( wx.ToolTip(u"Annular Ring for Pads (mm)" ))
self.m_textAR_SET_V.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_staticText12.SetToolTip( wx.ToolTip(u"Annular Ring for Vias (mm)" ))
self.m_textPHD.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
self.m_staticText11.SetToolTip( wx.ToolTip(u"Drill extra margin (mm)" ))
def __del__( self ):
pass
def OnClickOK(self, event):
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V
self.m_ok_btn.SetLabel("Clicked")
phd = float(self.m_textPHD.GetValue().replace(',','.'))
ar = float(self.m_textAR_SET.GetValue().replace(',','.'))
arv = float(self.m_textAR_SET_V.GetValue().replace(',','.'))
DRL_EXTRA=phd
DRL_EXTRA_ius=DRL_EXTRA * mm_ius
AR_SET = ar #minimum annular accepted for pads
MIN_AR_SIZE = AR_SET * mm_ius
AR_SET_V = arv #minimum annular accepted for vias
MIN_AR_SIZE_V = AR_SET_V * mm_ius
self.Destroy()
def OnClickCancel(self, event):
self.m_cancel_btn.SetLabel("Clicked")
self.Destroy()
#wx.MessageDialog(self.frame,"ciao")
#subprocess.check_call(["C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])
#http://stackoverflow.com/questions/1811691/running-an-outside-program-executable-in-python
class displayDialog(wx.Dialog):
"""
The default frame
http://stackoverflow.com/questions/3566603/how-do-i-make-wx-textctrl-multi-line-text-update-smoothly
"""
global mm_ius, DRL_EXTRA, AR_SET, AR_SET_V, DRL_EXTRA_ius, MIN_AR_SIZE, MIN_AR_SIZE_V, found_violations
#----------------------------------------------------------------------
#def __init__(self):
# """Constructor"""
# wx.Frame.__init__(self, None, title="Display Frame", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
# panel = wx.Panel(self)
def __init__(self, parent):
wx.Dialog.__init__(self, parent, id=-1, title="Annular Checker")#
#, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
#, style=wx.DEFAULT_DIALOG_STYLE, wx.ICON_INFORMATION)
#, pos=DefaultPosition, size=DefaultSize, style = wx.DEFAULT_FRAME_STYLE & (~wx.MAXIMIZE_BOX), name="fname")
#, wx.ICON_INFORMATION) #, title="Annular Check", style=wx.DEFAULT_FRAME_STYLE, wx.ICON_INFORMATION)
#
self.SetIcon(PyEmbeddedImage(annular_ico_b64_data).GetIcon())
#wx.IconFromBitmap(wx.Bitmap("icon.ico", wx.BITMAP_TYPE_ANY)))
self.panel = wx.Panel(self)
if found_violations:
self.title = wx.StaticText(self.panel, label="Check result: (Violations found)")
#self.title.SetForegroundColour('#FF0000')
self.title.SetBackgroundColour('#FF0000')
font = wx.Font(wx.DEFAULT, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
self.title.SetFont(font)
else:
self.title = wx.StaticText(self.panel, label="Annular Check result: OK")
self.title.SetBackgroundColour('#00FF00')
#self.result = wx.StaticText(self.panel, label="")
#self.result.SetForegroundColour('#FF0000')
#self.button = wx.Button(self.panel, label="Save")
#self.lblname = wx.StaticText(self.panel, label="Your name:")
#self.editname = wx.TextCtrl(self.panel, size=(140, -1))
self.editname = wx.TextCtrl(self.panel, size = (400, 400), style = wx.TE_MULTILINE|wx.TE_READONLY)
self.m_htmlWin1 = wx.html.HtmlWindow( self.panel, wx.ID_ANY, wx.DefaultPosition, wx.Size( 400,400 ), wx.html.HW_SCROLLBAR_AUTO )
#bSizer1.Add( self.m_htmlWin1, 0, wx.ALL, 5 )
# Set sizer for the frame, so we can change frame size to match widgets
self.windowSizer = wx.BoxSizer()
#self.windowSizer.Add(self.m_htmlWin1, 1, wx.ALL | wx.EXPAND)
self.windowSizer.Add(self.panel, 1, wx.ALL | wx.EXPAND)
# Set sizer for the panel content
self.sizer = wx.GridBagSizer(5, 0)
self.sizer.Add(self.title, (0, 0))
#self.sizer.Add(self.result, (1, 0))
#self.sizer.Add(self.lblname, (1, 0))
##self.sizer.Add(self.m_htmlWin1, (1, 0))
self.sizer.Add(self.editname, (1, 0))
#self.sizer.Add(self.button, (2, 0), (1, 2), flag=wx.EXPAND)
# Set simple sizer for a nice border
self.border = wx.BoxSizer()
self.border.Add(self.sizer, 1, wx.ALL | wx.EXPAND, 5)
# Use the sizers
self.panel.SetSizerAndFit(self.border)
self.SetSizerAndFit(self.windowSizer)
#self.result.SetLabel(msg)
# Set event handlers
#self.button.Bind(wx.EVT_BUTTON, self.OnButton)
#self.Show()
#self.Bind(wx.EVT_CLOSE,self.OnClose)
#def OnClose(self,e):
# #wx.LogMessage("c")
# e.Skip()
#self.Close()
#def OnButton(self, e):
# self.result.SetLabel(self.editname.GetValue())
def setMsg(self, t_msg):
self.editname.SetValue(t_msg)
self.m_htmlWin1.SetPage(t_msg)
def annring_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]+DRL_EXTRA_ius))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]+DRL_EXTRA_ius))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
return min(annrX,annrY)
def annringNP_size(pad):
# valid for oval pad/drills
annrX=(pad.GetSize()[0] - (pad.GetDrillSize()[0]))/2
annrY=(pad.GetSize()[1] - (pad.GetDrillSize()[1]))/2
#annr=min(pad.GetSize()) - max(pad.GetDrillSize())
#if annr < MIN_AR_SIZE:
#print annrX
#print annrY
#print pad.GetSize()[0]/mm_ius
#print pad.GetSize()[0]#/mm_ius
#print pad.GetDrillSize()[0]#/mm_ius
#print DRL_EXTRA_ius
#print pad.GetDrillSize()[0]/mm_ius
#print (pad.GetDrillSize()[0]+DRL_EXTRA_ius)/mm_ius
#print annrX/mm_ius
#return min(annrX,annrY)
return annrX,annrY
def vias_annring_size(via):
# calculating via annular
annr=(via.GetWidth() - (via.GetDrillValue()+DRL_EXTRA_ius))/2
#print via.GetWidth()
#print via.GetDrillValue()
return annr
def f_mm(raw):
return repr(raw/mm_ius)
board = pcbnew.GetBoard()
PassC=FailC=0
PassCV=FailCV=0
PassCN=FailCN=0
PassCVN=FailCVN=0
fileName = GetBoard().GetFileName()
if len(fileName)==0:
wx.LogMessage("a board needs to be saved/loaded!")
else:
frame = AR_Prm(None)
#frame = wx.Frame(None)
frame.Center()
#frame.setMsg(LogMsg)
frame.ShowModal()
frame.Destroy()
LogMsg="<html><body><b>Hello, world!</b><br>"
msg="action_menu_annular_check.py<br>"
msg+="version = "+___version___
msg+="<br>Testing PCB for Annular Rings<br>TH Pads = "+repr(AR_SET)+" Vias = "+repr(AR_SET_V)+"<br>PHD margin on PTH = "+ repr(DRL_EXTRA)
#print (msg)
LogMsg+=msg+"<br><br>"
# print "LISTING VIAS:"
for item in board.GetTracks():
if type(item) is pcbnew.VIA:
pos = item.GetPosition()
drill = item.GetDrillValue()
width = item.GetWidth()
ARv = vias_annring_size(item)
if ARv < MIN_AR_SIZE_V:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = item.GetPosition()
msg="AR Via violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailCV = FailCV+1
else:
PassCV = PassCV+1
#print type(item)
msg="VIAS that Pass = "+repr(PassCV)+"; Fails = "+repr(FailCV)
# print(msg)
LogMsg+=msg+"<br>"
for module in board.GetModules():
try:
module_Pads=module.PadsList()
except:
module_Pads=module.Pads()
for pad in module_Pads: #print(pad.GetAttribute())
if pad.GetAttribute() == PAD_ATTRIB_STANDARD: #TH pad
ARv = annring_size(pad)
#print(f_mm(ARv))
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR PTH violation of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailC = FailC+1
else:
PassC = PassC+1
if pad.GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED:
ARvX, ARvY = annringNP_size(pad)
#print(f_mm(ARvX));print(f_mm(ARvY))
if (ARvX) != 0 or ARvY != 0:
ARv = min(ARvX, ARvY)
if ARv < MIN_AR_SIZE:
# print("AR violation at %s." % (pad.GetPosition() / mm_ius )) Raw units, needs fixing
XYpair = pad.GetPosition()
msg="AR NPTH warning of "+f_mm(ARv)+" at XY "+f_mm(XYpair[0])+","+f_mm(XYpair[1])
#print (msg)
LogMsg+=msg+"<br>"
FailCN = FailCN+1
else:
PassCN = PassCN+1
else:
PassCN = PassCN+1
msg = "TH PADS that Pass = "+repr(PassC)+"; Fails = "+repr(FailC)
print(msg)
LogMsg+=msg+"<br>"
msg="NPTH PADS that Pass = "+repr(PassCN)+"; Fails = "+repr(FailCN)
print(msg)
LogMsg+=msg+"</body></html>"
pcbName = (os.path.splitext(GetBoard().GetFileName())[0]) #filename no ext
#wx.LogMessage(pcbName)#LogMsg)
##wx.LogMessage(LogMsg)
FC=r"C:\FreeCAD\bin\freecad.exe"
#kSU=r"C:\Cad\Progetti_K\3D-FreeCad-tools\kicad-StepUp-tools.FCMacro"
#subprocess.check_call([FC, kSU, pcbName])
##p = subprocess.Popen([FC, kSU, pcbName])
found_violations=False
if (FailC+FailCN+FailCV)>0:
found_violations=True
frame = displayDialog(None)
#frame = wx.Frame(None)
frame.Center()
frame.setMsg(LogMsg)
frame.ShowModal()
frame.Destroy()
#frame = wx.wxFrame(None, 10110, 'T-Make', size=wx.wxSize(100,100),
# style=wx.wxSTAY_ON_TOP)
#frame.show()
# annular_check().register()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='KiCad PCB Annular Checker')
parser.add_argument('file', type=str, help="KiCad PCB file")
args = parser.parse_args()
print("Loading %s" % args.file)
main(pcbnew.LoadBoard(args.file))
else:
annular_check().register()
# "b64_data" is a variable containing your base64 encoded jpeg
annular_ico_b64_data =\
"""
iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIQQAACEEB+v+u9gAAABl0RVh0U29mdHdhcmUAd3d
3Lmlua3NjYXBlLm9yZ5vuPBoAAAJ5SURBVDiNdZRNSFRRFMd/976ZJjeBn2PUoiLaiMFkFkHIQ0NBdBUlJuIqiixmIYjQRgiJYKAMXRRSi6TCD5gaWiSFsy
gixOyDpDAog8wn9SISapz33m0x82bmzcOzO/97/r973nn3XqGUojjCybIm4BhQD9Rl5XlgDnhi6ObTYo8oBIWTZeXAMNDlalW/FJYmMLd5fONA1NBN0wcKJ
8sagftAZWRJcWHS5vCiouJ3pnClUvC8VnDtpOTTDgGwCpwydHM2Bwony8LAe6koH7hjc37aQXN8XwzAv5DgUo9krF0C/ABqDN1ck9n1G0D54C2H6OTmEICt
KcXQTZvTCQegAhgFEFWzpW1A4uAHRaLfQhbPXgD+/8HfkKBhNMDXMACtEmgC6L/reCBWKGAzMmLxbQWWl2Fw0FJavqIkpYhO2m7aHADqNQcOLXq3DcSuKnp
6Ajmhry8g1tfTxGJBVzryLuepl0Bk16qiJJUHKU0qOjryEDe6u4OF6e7vitCGAohIAFk0XCWEQkp8oWmeVAAiu78EFj5vF6S2iFyBtGxJPJ72gSYmPNpyOH
McgAUJzFkazO/zetLRc4J43MayIJWCsTHLuTzkaellTa7rOVE1W9oOPDz6VjF90fI14QQ1RzhKCNsRhfpGEBqvB1jaKQDapKGbCeDBs/2C8Rb/XGTalsUQg
Fin5kKmDN185DrPAD8HzmrcbpUony0flgZXujSGT+SuSC94L20LcA8obXiduSp1H8kdiz8l8KJWEOvUeLNXuJAuQzdnPKAsrBoYAY4DaA7sWck8I1+qKex0
Cug1dHPNFcQmD1sL0AwcACJZeQF4BcwYuvm42PMfVgD11Y9MUIEAAAAASUVORK5CYII=
"""
# execfile("annular.py")
# annular.py Testing PCB for Annular Ring >= 0.15
# AR violation of 0.1 at XY 172.974,110.744
# VIAS that Pass = 100 Fails = 1
# AR violation of 0.1 at XY 172.212,110.744
# AR violation of 0.0 at XY 154.813,96.52
# PADS that Pass = 49 Fails = 2
-85
View File
@@ -1,85 +0,0 @@
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jul 11 2018)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class AR_Prm
###########################################################################
class AR_Prm ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Annular Checker", pos = wx.DefaultPosition, size = wx.Size( 320,229 ), style = wx.DEFAULT_DIALOG_STYLE )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
gSizer2 = wx.GridSizer( 0, 2, 0, 0 )
self.m_StaticTextPHD = wx.StaticText( self, wx.ID_ANY, u"PHD margin", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextPHD.Wrap( -1 )
gSizer2.Add( self.m_StaticTextPHD, 0, wx.ALL, 5 )
self.m_textPHD = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textPHD, 0, wx.ALL, 5 )
self.m_StaticTextAR_SET = wx.StaticText( self, wx.ID_ANY, u"AR for pads", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextAR_SET.Wrap( -1 )
gSizer2.Add( self.m_StaticTextAR_SET, 0, wx.ALL, 5 )
self.m_textAR_SET = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET, 0, wx.ALL, 5 )
self.m_StaticTextAR_SET_V = wx.StaticText( self, wx.ID_ANY, u"AR for vias", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
self.m_StaticTextAR_SET_V.Wrap( -1 )
gSizer2.Add( self.m_StaticTextAR_SET_V, 0, wx.ALL, 5 )
self.m_textAR_SET_V = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer2.Add( self.m_textAR_SET_V, 0, wx.ALL, 5 )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticTextVersion = wx.StaticText( self, wx.ID_ANY, u"Version", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticTextVersion.Wrap( -1 )
bSizer2.Add( self.m_staticTextVersion, 0, wx.ALL, 5 )
gSizer2.Add( bSizer2, 1, wx.EXPAND, 5 )
bSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
gSizer1 = wx.GridSizer( 0, 2, 0, 0 )
self.m_ok_btn = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_ok_btn, 0, wx.ALL, 5 )
self.m_cancel_btn = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 )
gSizer1.Add( self.m_cancel_btn, 0, wx.ALL, 5 )
bSizer1.Add( gSizer1, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass