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

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__":