# -*- coding: utf-8 -*- # # A script to Snap modules to selected Grid for kicad_pcb # requirements: KiCAD pcbnew >= 4.0 # copyright Maurice easyw # # #import snaptogrid; import importlib; importlib.reload(snaptogrid) __version__ = '1.0.1' import sys, os import pcbnew import datetime import wx from pcbnew import * use_grid_origin = True gridReference = 2.54 #1.27 #mm pcbnew.FromMM(1.0) #0.1mm gridSizeMM = gridReference #from . import Send2GridDlg 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 Snap2Grid_Dlg(Snap2GridDlg.Snap2GridDlg): # # 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(RoundTrack_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 # Send2GridDlg.Send2GridDlg.__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 snap_to_grid( pcbnew.ActionPlugin ): """ A plugin to Snap modules to selected Grid for kicad_pcb requirements: KiCAD pcbnew >= 4.0 """ 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 = "Snap Selected Module(s) to Grid\nversion "+__version__ self.category = "Modify PCB" self.description = "Automaticaly Snap Selected Module(s) to Grid 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__), './snap2grid.png') # def Run(self): #self.pcb = GetBoard() import sys,os #mm_ius = 1000000.0 pcb = pcbnew.GetBoard() gridOrigin = pcb.GetGridOrigin() auxOrigin = pcb.GetAuxOrigin() content='' locked_fp='' #wxPoint(77470000, 135890000) for module in pcb.GetModules(): if module.IsSelected(): if use_grid_origin: mpx = module.GetPosition().x - gridOrigin.x mpy = module.GetPosition().y - gridOrigin.y print(mpx,mpy) mpxOnG = int(mpx/FromMM(gridSizeMM))*FromMM(gridSizeMM)+ gridOrigin.x mpyOnG = int(mpy/FromMM(gridSizeMM))*FromMM(gridSizeMM)+ gridOrigin.y print(mpxOnG,mpyOnG) locked='' if not module.IsLocked(): module.SetPosition(wxPoint(mpxOnG,mpyOnG)) else: locked='LOCKED' X_POS=str(module.GetPosition().x) # - gridOrigin.x) #X_POS='{0:.4f}'.format(pcbnew.ToMM(module.GetPosition().x - gridOrigin.x )) X_POS="{0:<11}".format(X_POS) Y_POS=str(module.GetPosition().y) # - gridOrigin.y) Y_POS="{0:<11}".format(Y_POS) ## mpOnGx = PutOnGridMM(module.GetPosition().x, gridSizeMM) ## mpOnGy = PutOnGridMM(module.GetPosition().y, gridSizeMM) ## module.SetPosition(wxPoint(mpOnGx,mpOnGy)) #module.SetPosition(wxPoint(mpOnGx+FromMM(100.0),mpOnGy+FromMM(2.0))) #module.SetOrientation(10) #Y_POS='{0:.4f}'.format(-1*pcbnew.ToMM(module.GetPosition().y - gridOrigin.y)) # else: # mpx = module.GetPosition().x - auxOrigin().x # mpy = module.GetPosition().y - auxOrigin().y # X_POS='{0:.4f}'.format(pcbnew.ToMM(module.GetPosition().x - auxOrigin().x )) # X_POS="{0:<11}".format(X_POS) # Y_POS='{0:.4f}'.format(-1*pcbnew.ToMM(module.GetPosition().y - auxOrigin().y)) # Y_POS="{0:<11}".format(Y_POS) Reference="{0:<10}".format(str(module.GetReference())) Value = str(module.GetValue()) Value=(Value[:17] + '..') if len(Value) > 19 else Value Value="{0:<20}".format(Value) Rotation='{0:.1f}'.format((module.GetOrientation()/10)) Rotation="{0:>6}".format(Rotation)+' ' if module.GetLayer() == 0: Layer=" top" else: Layer=" bottom" #Side="## Side :"+Layer+lsep Layer="{0:<10}".format(Layer) content+=Reference if 'LOCKED' in locked: locked_fp+=Reference + ' LOCKED'+'\n' #os.linesep #content+=Value content+=X_POS content+=Y_POS #content+=str(mpOnGx) #content+=str(mpOnGy) content+=str(mpxOnG) content+=str(mpyOnG) content+=Layer+'\n' #os.linesep if len(content)>0: content+=str(pcbnew.FromMM(gridReference)) wxLogDebug(content,debug) if len (locked_fp)>0: locked_fp+='\n'+'NOT Moved' wxLogDebug(locked_fp,True) else: wxLogDebug('No Modules Selected',True) Refresh() #return content #if 0: # #from https://github.com/MitjaNemec/Kicad_action_plugins # #hack wxFormBuilder py2/py3 # _pcbnew_frame = [x for x in wx.GetTopLevelWindows() if x.GetTitle().lower().startswith('pcbnew')][0] # #aParameters = RoundTrackDlg(None) # aParameters = RoundTrack_Dlg(_pcbnew_frame) # #aParameters = RoundTrack_DlgEx(_pcbnew_frame) # aParameters.Show() # #end hack # aParameters.m_distanceMM.SetValue("5") # aParameters.m_segments.SetValue("16") # aParameters.m_bitmap1.SetBitmap(wx.Bitmap( os.path.join(os.path.dirname(os.path.realpath(__file__)), "round_track_help.png") ) ) # modal_result = aParameters.ShowModal() # segments = self.CheckSegmentsInput( # aParameters.m_segments.GetValue(), "number of segments") # distI = FromMM(self.CheckDistanceInput(aParameters.m_distanceMM.GetValue(), "distance from intersection")) # if segments is not None and distI is not None: # if modal_result == wx.ID_OK: # Round_Selection(pcb, distI, segments) # elif modal_result == wx.ID_DELETE: # Delete_Segments(pcb) # #wx.LogMessage('Round Segments on Track Net Deleted') # elif modal_result == wx.ID_REVERT: # wxLogDebug('Connecting Tracks',debug) # Connect_Segments(pcb) # else: # None # Cancel # else: # None # Invalid input # aParameters.Destroy() # wxLogDebug('showing Selected Tracks',debug) # wx.LogMessage('Select Tracks to calculate the Length\nor One Pad to select connected Tracks') #