#!/usr/bin/env python # some source tips @ # https://github.com/bpkempke/kicad-scripts # https://github.com/MitjaNemec/Kicad_action_plugins # https://github.com/jsreynaud/kicad-action-scripts # import trace_length; reload(trace_length) import sys import os from pcbnew import * import wx import pcbnew import math #import threading debug = False def wxLogDebug(msg,dbg): """printing messages only if show is omitted or True""" if dbg == True: wx.LogMessage(msg) # def getSelTracksLength(pcb): ln = 0. for item in pcb.GetTracks(): if not hasattr(pcbnew,'TRACK'): item = pcbnew.Cast_to_PCB_TRACK(item) trktp = pcbnew.PCB_TRACK else: trktp = pcbnew.TRACK if type(item) is trktp and item.IsSelected(): ln+=(item.GetLength()) return(ln) #print(pcbnew.ToMM(ln)) # def getSelTracks(pcb): tracks=[] for item in pcb.GetTracks(): if not hasattr(pcbnew,'TRACK'): item = pcbnew.Cast_to_PCB_TRACK(item) trktp = pcbnew.PCB_TRACK else: trktp = pcbnew.TRACK if type(item) is trktp and item.IsSelected(): tracks.append(item) return tracks # def find_Tracks_between_Pads(pcb,pad1,pad2): track_list = [] # get list of all selected pads #selected_pads = [pad1, pad2] # get the net the pins are on net = pad1.GetNetname() # find all tracks tracks = pcb.GetTracks() # find all tracks on net tracks_on_net = [] for track in tracks: track_net_name = track.GetNetname() if track_net_name == net: tracks_on_net.append(track) return tracks_on_net # def getTracksListLength(pcb,tracks): ln = 0. for item in tracks: ln+=(item.GetLength()) return(ln) # def selectListTracks(pcb,tracks): for item in tracks: if not hasattr(pcbnew,'TRACK'): item = pcbnew.Cast_to_PCB_TRACK(item) trktp = pcbnew.PCB_TRACK else: trktp = pcbnew.TRACK if type(item) is trktp: item.SetSelected() # def getTrackAngleRadians(track): #return math.degrees(math.atan2((p1.y-p2.y),(p1.x-p2.x))) return (math.atan2((track.GetEnd().y - track.GetStart().y), (track.GetEnd().x - track.GetStart().x))) # # Python plugin stuff class SelectedTracesLenght(pcbnew.ActionPlugin): def defaults(self): self.name = "Measure Length for Selected Tracks\n version 1.3" self.category = "Modify PCB" self.description = "Measure Length for Selected Tracks" self.icon_file_name = os.path.join(os.path.dirname(__file__), "./trace_length.png") self.show_toolbar_button = True def Run(self): #self.pcb = GetBoard() pcb = pcbnew.GetBoard() ln=0. pads=[] tracks=getSelTracks(pcb) if len(tracks) >0: #selected tracks >0 for item in tracks: ln+=(item.GetLength()) else: for item in pcb.GetPads(): if item.IsSelected(): pads.append(item) if len(pads) == 1: tracks=[] tracks = find_Tracks_inNet_Pad(pcb,pads[0]) c_tracks = get_contiguous_tracks(pcb,tracks,pads[0]) tracks=c_tracks # selectListTracks(pcb,tracks) # this seems not to allow deselecting ln = getTracksListLength(pcb,tracks) selectListTracks(pcb,tracks) pcbnew.Refresh() #else: # wx.LogMessage("Solder Mask Expander:\nSelect Tracks\nor One Pad to select connected Tracks") if ln > 0: #wx.LogMessage('Selected Traces Length: {0:.3f} mm'.format(ToMM(ln))) wxLogDebug('showing Selected Tracks',debug) #wx.LogMessage('debug'+str(debug)) msg = u"Selected Tracks Length:\n{0:.3f} mm \u2714".format(ToMM(ln)) if len(tracks) == 1: angle = (math.degrees(getTrackAngleRadians(tracks[0]))) msg+=u"\nTrack Angle: {0:.1f} deg \u2714".format(angle) #selectListTracks(pcb,tracks) #pcbnew.Refresh() wdlg = wx.MessageDialog(None, msg,'Info message',wx.OK | wx.ICON_INFORMATION) result = wdlg.ShowModal() if result == wx.ID_OK: pass clearListTracks(pcb,tracks,True) #timer = threading.Timer(1000, clearListTracks(pcb,tracks,True)) #timer.start() #blocking dialogw #wx.MessageBox("showing selection", 'Info', wx.OK | wx.ICON_INFORMATION) #clearListTracks(pcb,tracks) elif len(pads) != 1: wx.LogMessage('Select Tracks to calculate the Length\nor One Pad to select connected Tracks') # def selectListTracks(pcb,tracks): for item in tracks: if not hasattr(pcbnew,'TRACK'): item = pcbnew.Cast_to_PCB_TRACK(item) trktp = pcbnew.PCB_TRACK else: trktp = pcbnew.TRACK if type(item) is trktp: item.SetSelected() def clearListTracks(pcb,tracks,refresh=None): wxLogDebug('deSelecting Tracks',debug) for trk in tracks: if trk.IsSelected(): trk.ClearSelected() if refresh: pcbnew.Refresh() # # #def getSelTracksLength(pcb): # ln = 0. # for item in pcb.GetTracks(): # if type(item) is pcbnew.TRACK and item.IsSelected(): # ln+=(item.GetLength()) # return(ln) # #print(pcbnew.ToMM(ln)) # def get_contiguous_tracks(pcb,trks,pad): LinePoints = [] LineSegments=[] #start_point = ToMM(pad.GetPosition()) startp = (pad.GetPosition()) start_point = ((startp.x),(startp.y)) for t in (trks): LinePoints.append((t.GetStart().x,t.GetStart().y)) LinePoints.append((t.GetEnd().x, t.GetEnd().y)) wxLogDebug('Points '+str(LinePoints),debug) l= len(LinePoints) for i in range(0,l,2): LineSegments.append((LinePoints[i],LinePoints[i+1])) wxLogDebug(str(LineSegments),debug) #segments = [(1, 2), (2, 3), (4, 5), (6, 5), (7, 6)] #start_point=(4,5) #segments_start=segments segments = LineSegments groups=[] found=False for s in segments: found=False for g in groups: for sCmp in g: wxLogDebug('sCmp: '+(str(sCmp)),debug) wxLogDebug('s: '+(str(s)),debug) if isConn(sCmp,s): #confronto start e end g.append(s) found=True break; if (found): break; if(not found): groups.append([s]) wxLogDebug('groups: '+(str(groups)),debug) wxLogDebug('len groups: '+(str(len(groups))),debug) l = 0 lens = [] for g in groups: lens.append(len(g)) if l= 1: #1nm return True else: return False # def isConn(s1,s2): #if s1[0] == s2[0] or s1[1] == s2[1]: if isEq(s1[0],s2[0]) or isEq(s1[1],s2[1]): return True #elif s1[0] == s2[1] or s1[1] == s2[0]: elif isEq(s1[0],s2[1]) or isEq(s1[1],s2[0]): return True return False # def getSelTracks(pcb): tracks=[] for item in pcb.GetTracks(): if not hasattr(pcbnew,'TRACK'): item = pcbnew.Cast_to_PCB_TRACK(item) trktp = pcbnew.PCB_TRACK else: trktp = pcbnew.TRACK if type(item) is trktp and item.IsSelected(): tracks.append(item) return tracks # def find_Tracks_inNet_Pad(pcb,pad): track_list = [] # get list of all selected pads #selected_pads = [pad1, pad2] # get the net the pins are on net = pad.GetNetname() # find all tracks tracks = pcb.GetTracks() # find all tracks on net tracks_on_net = [] for track in tracks: track_net_name = track.GetNetname() if track_net_name == net: tracks_on_net.append(track) return tracks_on_net # #Solder_Expander().register()