def SetTeardrops(hpercent=30, vpercent=70, segs=10, pcb=None): """Set teardrops on a teardrop free board""" if pcb is None: pcb = GetBoard() vias = __GetAllVias(pcb)[0] + __GetAllPads(pcb, [PAD_ATTRIB_STANDARD])[0] vias_selected = __GetAllVias(pcb)[1] +\ __GetAllPads(pcb, [PAD_ATTRIB_STANDARD])[1] if len(vias_selected) > 0: vias = vias_selected teardrops = __GetAllTeardrops(pcb) count = 0 for track in [t for t in pcb.GetTracks() if type(t) == TRACK]: for via in [v for v in vias if track.IsPointOnEnds(v[0], v[1] / 2)]: if (track.GetLength() < __TeardropLength(track, via, hpercent)) or\ (track.GetWidth() >= via[1] * vpercent / 100): continue found = False if track.GetNetname() in teardrops.keys(): for teardrop in teardrops[track.GetNetname()]: if __DoesTeardropBelongTo(teardrop, track, via): found = True break if not found: coor = __ComputePoints(track, via, hpercent, vpercent, segs) pcb.Add(__Zone(pcb, coor, track)) count += 1 print('{0} teardrops inserted'.format(count)) return count
def SetTeardrops(hpercent=30, vpercent=70, segs=10, pcb=None, use_smd=False, discard_in_same_zone=True): """Set teardrops on a teardrop free board""" if pcb is None: pcb = GetBoard() pad_types = [PAD_ATTRIB_STANDARD] + [PAD_ATTRIB_SMD] * use_smd vias = __GetAllVias(pcb)[0] + __GetAllPads(pcb, pad_types)[0] vias_selected = __GetAllVias(pcb)[1] + __GetAllPads(pcb, pad_types)[1] if len(vias_selected) > 0: vias = vias_selected teardrops = __GetAllTeardrops(pcb) count = 0 for track in [t for t in pcb.GetTracks() if type(t) == TRACK]: for via in [ v for v in vias if track.IsPointOnEnds(v[0], int(v[1] / 2)) ]: if (track.GetLength() < __TeardropLength(track, via, hpercent)) or\ (track.GetWidth() >= via[1] * vpercent / 100): continue found = False if track.GetNetname() in teardrops.keys(): for teardrop in teardrops[track.GetNetname()]: if __DoesTeardropBelongTo(teardrop, track, via): found = True break # Discard case where pad and track are on different layers, or the pad have no copper at all (paste pads). if (via[3] == "none"): continue if (via[3] == "front") and (not track.IsOnLayer(0)): continue if (via[3] == "back") and track.IsOnLayer(0): continue # Discard case where pad/via is within a zone with the same netname # WARNING: this can severly reduce performances if discard_in_same_zone and \ __IsViaAndTrackInSameNetZone(pcb, via, track): continue if not found: coor = __ComputePoints(track, via, hpercent, vpercent, segs) pcb.Add(__Zone(pcb, coor, track)) count += 1 RebuildAllZones(pcb) print('{0} teardrops inserted'.format(count)) return count
def RmTeardrops(pcb=None): """Remove all teardrops""" if pcb is None: pcb = GetBoard() count = 0 teardrops = __GetAllTeardrops(pcb) for netname in teardrops: for teardrop in teardrops[netname]: pcb.Remove(teardrop) count += 1 print('{0} teardrops removed'.format(count)) return count
def Run(self): BOM_FILEEXTENSION = '.xml' bom_file = os.path.splitext( GetBoard().GetFileName())[0] + BOM_FILEEXTENSION if not os.path.isfile(bom_file): debug_dialog( 'The file \'{}\' doesn\'t exist yet.\nReturn to Eeschma and update/generate it.' .format(bom_file)) elif bom_file == BOM_FILEEXTENSION: debug_dialog('This board have not BOM associated.') bom_file = '' try: try: from kicost.kicost_gui import kicost_gui kicost_gui( bom_file ) # If KiCad and KiCost share the same Python installation. except ImportError: subprocess.call(('kicost', '--guide', bom_file), shell=True) # os.system('kicost --guide \"{}\"'.format(bom_file)) # If using different Python installation. # os.system('eeschema') # subprocess.call('eeschema') except Exception as e: dlg = debug_dialog( 'Error trying to run KiCost as plugin or subprocess,\n\ KiCost is not available or accessible.\n\ Do you want to try to install KiCost?', e, wx.YES_NO) if dlg == wx.YES: debug_dialog('YES') return True else: return False return True
def setValueDisVisible(self, board = None): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Value().SetVisible(False)
def generalPosition(self, board = None): if board == None: board = GetBoard() self.board = board self.get_placement_info() self.getPositionHeaderInfo() return self.info, self.headinfo
def generalBOM(self, board = None): if board == None: board = GetBoard() self.board = board self.get_bom_info() self.generalBOMHeaderInfo() return self.info, self.headinfo
def setValueSize(self, board = None, val = (1, 1, 0.15)): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Value().SetTextWidth(int(float(val[1])*1000000)) module.Value().SetTextHeight(int(float(val[0])*1000000)) module.Value().SetTextThickness(int(float(val[2])*1000000))
def setRefSize(self, board = None, val = (0.7, 0.7, 0.08)): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Reference().SetTextWidth(int(float(val[1])*1000000)) module.Reference().SetTextHeight(int(float(val[0])*1000000)) module.Reference().SetTextThickness(int(float(val[2])*1000000))
def SetTeardrops(hpercent=30, vpercent=70, segs=10, pcb=None, use_smd=False): """Set teardrops on a teardrop free board""" if pcb is None: pcb = GetBoard() pad_types = [PAD_ATTRIB_STANDARD] + [PAD_ATTRIB_SMD] * use_smd vias = __GetAllVias(pcb)[0] + __GetAllPads(pcb, pad_types)[0] vias_selected = __GetAllVias(pcb)[1] + __GetAllPads(pcb, pad_types)[1] if len(vias_selected) > 0: vias = vias_selected teardrops = __GetAllTeardrops(pcb) count = 0 for track in [t for t in pcb.GetTracks() if type(t) == TRACK]: for via in [ v for v in vias if track.IsPointOnEnds(v[0], int(v[1] / 2)) ]: if (track.GetLength() < __TeardropLength(track, via, hpercent)) or\ (track.GetWidth() >= via[1] * vpercent / 100): continue found = False if track.GetNetname() in teardrops.keys(): for teardrop in teardrops[track.GetNetname()]: if __DoesTeardropBelongTo(teardrop, track, via): found = True break # Discard case where pad and track are not on the same layer if (via[3] == "front") and (not track.IsOnLayer(0)): continue if (via[3] == "back") and track.IsOnLayer(0): continue if not found: coor = __ComputePoints(track, via, hpercent, vpercent, segs) pcb.Add(__Zone(pcb, coor, track)) count += 1 RebuildAllZones(pcb) print('{0} teardrops inserted'.format(count)) return count
def setValueOnOtherLayer(self,board = None): if board == None: board = GetBoard() self.board = board origin = self.board.GetAuxOrigin() for module in self.board.GetFootprints(): reference = module.GetReference() #print(module.Reference().GetPosition()) if self.is_non_annotated_ref(reference): continue value = module.GetValue() excluded = False for ig in IGINOR: if value == ig: excluded = True if excluded: module.Value().SetVisible(False) continue value = module.Value() value.SetVisible(True) lay = value.GetLayer() #print(module.GetValue()) #print(pcbnew.B_CrtYd) #print(pcbnew.F_CrtYd) #print(pcbnew.B_Fab) #print(pcbnew.F_Fab) if lay == pcbnew.F_Fab: value.SetLayer(pcbnew.F_CrtYd) elif lay == pcbnew.B_Fab: value.SetLayer(pcbnew.B_CrtYd) value.SetTextThickness(80000) value.SetTextWidth(500000) value.SetTextHeight(500000) mpos = module.GetPosition() value.SetTextPos(mpos)
def Run(self): InitMainDialog(GetBoard())
def Run(self): InitTeardropDialog(GetBoard())
def main(): modules = get_all_module_info(GetBoard()) net_list = make_net_list(modules)
def SetTeardrops(hpercent=50, vpercent=90, segs=10, pcb=None, use_smd=False, discard_in_same_zone=True, follow_tracks=True): """Set teardrops on a teardrop free board""" if pcb is None: pcb = GetBoard() pad_types = [PAD_ATTRIB_STANDARD] + [PAD_ATTRIB_SMD]*use_smd vias = __GetAllVias(pcb)[0] + __GetAllPads(pcb, pad_types)[0] vias_selected = __GetAllVias(pcb)[1] + __GetAllPads(pcb, pad_types)[1] if len(vias_selected) > 0: vias = vias_selected trackLookup = {} if follow_tracks: for t in pcb.GetTracks(): if type(t) == TRACK: net = t.GetNetname() layer = t.GetLayer() if layer not in trackLookup: trackLookup[layer] = {} if net not in trackLookup[layer]: trackLookup[layer][net]=[] trackLookup[layer][net].append(t) teardrops = __GetAllTeardrops(pcb) count = 0 for track in [t for t in pcb.GetTracks() if type(t)==TRACK]: for via in [v for v in vias if track.IsPointOnEnds(v[0], int(v[1]/2))]: if (track.GetWidth() >= via[1] * vpercent / 100): continue if track.IsPointOnEnds(via[0], int(via[1]/2))==STARTPOINT|ENDPOINT: # both start and end are within the via continue found = False if track.GetNetname() in teardrops.keys(): for teardrop in teardrops[track.GetNetname()]: if __DoesTeardropBelongTo(teardrop, track, via): found = True break # Discard case where pad and track are on different layers, or the # pad have no copper at all (paste pads). if (via[3] != -1) and (via[3] != track.GetLayer()): continue # Discard case where pad/via is within a zone with the same netname # WARNING: this can severely reduce performance if discard_in_same_zone and \ __IsViaAndTrackInSameNetZone(pcb, via, track): continue if not found: coor = __ComputePoints(track, via, hpercent, vpercent, segs, follow_tracks, trackLookup) pcb.Add(__Zone(pcb, coor, track)) count += 1 RebuildAllZones(pcb) print('{0} teardrops inserted'.format(count)) return count
def Run(self): init_diffpads_dialog(GetBoard())
def Run(self): InitAddNetDialog(GetBoard())
def get_output_abs_path(self): self.board = GetBoard() path = os.path.dirname(os.path.abspath(self.board.GetFileName())) return path + os.path.sep + OUTPUT_DIR
class KC(): def setRefSize(self, board = None, val = (0.7, 0.7, 0.08)): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Reference().SetTextWidth(int(float(val[1])*1000000)) module.Reference().SetTextHeight(int(float(val[0])*1000000)) module.Reference().SetTextThickness(int(float(val[2])*1000000)) def setValueSize(self, board = None, val = (1, 1, 0.15)): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Value().SetTextWidth(int(float(val[1])*1000000)) module.Value().SetTextHeight(int(float(val[0])*1000000)) module.Value().SetTextThickness(int(float(val[2])*1000000)) def setValueDisVisible(self, board = None): if board == None: board = GetBoard() self.board = board for module in self.board.GetFootprints(): module.Value().SetVisible(False) def setValueOnOtherLayer(self,board = None): if board == None: board = GetBoard() self.board = board origin = self.board.GetAuxOrigin() for module in self.board.GetFootprints(): reference = module.GetReference() #print(module.Reference().GetPosition()) if self.is_non_annotated_ref(reference): continue value = module.GetValue() excluded = False for ig in IGINOR: if value == ig: excluded = True if excluded: module.Value().SetVisible(False) continue value = module.Value() value.SetVisible(True) lay = value.GetLayer() #print(module.GetValue()) #print(pcbnew.B_CrtYd) #print(pcbnew.F_CrtYd) #print(pcbnew.B_Fab) #print(pcbnew.F_Fab) if lay == pcbnew.F_Fab: value.SetLayer(pcbnew.F_CrtYd) elif lay == pcbnew.B_Fab: value.SetLayer(pcbnew.B_CrtYd) value.SetTextThickness(80000) value.SetTextWidth(500000) value.SetTextHeight(500000) mpos = module.GetPosition() value.SetTextPos(mpos) def generalBOM(self, board = None): if board == None: board = GetBoard() self.board = board self.get_bom_info() self.generalBOMHeaderInfo() return self.info, self.headinfo def generalBOMHeaderInfo(self): self.headinfo = [] shtamp = self.get_shtamp_str() self.headinfo.append(shtamp) ver = self.board.GetTitleBlock().GetRevision() name = '# File name: ' + self.get_board_name() + ' Revision: ' + ver + EOL self.headinfo.append(name) def generalPosition(self, board = None): if board == None: board = GetBoard() self.board = board self.get_placement_info() self.getPositionHeaderInfo() return self.info, self.headinfo def getPositionHeaderInfo(self): self.headinfo = [] shtamp = self.get_shtamp_str() self.headinfo.append(shtamp) ver = self.board.GetTitleBlock().GetRevision() name = '# File name: ' + self.get_board_name() + ' Revision: ' + ver + EOL self.headinfo.append(name) total1 = '# Total(All): ' + str(self.numALL) + EOL self.headinfo.append(total1) total1 = '# Total(SMT): ' + str(self.numSMT) + EOL self.headinfo.append(total1) def get_placement_info(self): self.info = [] self.numALL = 0 self.numSMT = 0 origin = self.board.GetAuxOrigin() for module in self.board.GetFootprints(): reference = module.GetReference() if self.is_non_annotated_ref(reference): continue value = module.GetValue() excluded = False ''' for ig in IGINOR: if value == ig: excluded = True if excluded: continue ''' self.numALL += 1 package = str(module.GetFPID().GetLibItemName()) pos = module.GetPosition() - origin pos_x = pcbnew.ToMM(pos.x) if module.IsFlipped(): pos_x = -pos_x pos_y = -pcbnew.ToMM(pos.y) rotation = module.GetOrientationDegrees() if module.IsFlipped(): side = u'bottom' else: side = u'top' is_smd = self.is_smd_module(module) smdor = u'HID' if is_smd: self.numSMT +=1 smdor = u'SMD' self.info.append([reference, value, package, pos_x, pos_y, rotation, side, smdor]) self.info.sort(key=self.get_ref_num) self.info.sort(key=self.get_ref_group) self.info.sort(key=self.get_side_group, reverse=True) def get_bom_info(self): self.info = [] self.cnt = 0 for module in self.board.GetFootprints(): reference = module.GetReference() if self.is_non_annotated_ref(reference): continue value = module.GetValue() excluded = False ''' for ig in IGINOR: if value == ig: excluded = True if excluded: continue ''' package = str(module.GetFPID().GetLibItemName()) cnt = 1 self.info.append([reference, value, package, cnt]) self.info.sort(key=self.get_ref_num) self.info.sort(key=self.get_ref_group) def is_non_annotated_ref(self, ref): return ref[-1] == u'*' def is_smd_module(self, module): attr = module.GetAttributes() return (attr == pcbnew.MOD_CMS) or (attr == pcbnew.MOD_VIRTUAL) def get_ref_group(self, item): return re.sub('[0-9]*$', u'', item[REF]) def get_side_group(self, item): return re.sub('[0-9]*$', u'', item[SIDE]) def get_ref_num(self, item): try: return int(re.findall('[0-9]*$', item[REF])[0]) except: return 0 def mkdir_out(self, path): if os.path.exists(path) == False: os.makedirs(path) def clean_output(self, path): if os.path.exists(path): shutil.rmtree(path, ignore_errors=False, onerror=None) os.makedirs(path) def save_info(self,board, info, headinfo, type='ALL'): self.info = info self.headinfo = headinfo self.board = board self.mkdir_out(self.get_output_abs_path()) self.collect_fields_length_statistic(BOM_HEADER) path = self.get_output_abs_path() name = path + os.path.sep + self.get_board_name() ver = self.board.GetTitleBlock().GetRevision() pos_file = open(name + u'-' + ver + u'-' + type +u'.csv', mode='w') for item in self.headinfo: pos_file.write(item) self.write_info(pos_file, BOM_HEADER) pos_file.close() def write_info(self, ofile, header): self.write_item(header, ofile) for item in self.info: self.write_item(item, ofile) def save_placement_info(self,board, info, headinfo, type='ALL'): self.info = info self.headinfo = headinfo self.board = board self.mkdir_out(self.get_output_abs_path()) self.collect_fields_length_statistic(HEADER) path = self.get_output_abs_path() name = path + os.path.sep + self.get_board_name() ver = self.board.GetTitleBlock().GetRevision() pos_file = open(name + u'-' + ver + u'-' + type+ u'.pos', mode='w') for item in self.headinfo: pos_file.write(item) self.write_placement_info(pos_file, type, HEADER) pos_file.close() def collect_fields_length_statistic(self, head): self.fields_max_length = [] for i in range(0, len(head)): self.fields_max_length.append(len(head[i])) self.fields_max_length[0] += 1 for item in self.info: for field in range(0, len(self.info[0]) - 1): cur_len = len(str(item[field])) if self.fields_max_length[field] < cur_len: self.fields_max_length[field] = cur_len def get_shtamp_str(self): return '# Author: ' + getpass.getuser() + \ ' , Timeshtamp: ' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+ \ ' , Plugin: ' + __version__ + \ EOL def get_output_abs_path(self): self.board = GetBoard() path = os.path.dirname(os.path.abspath(self.board.GetFileName())) return path + os.path.sep + OUTPUT_DIR def get_board_name(self): name = self.board.GetTitleBlock().GetComment(0) if name == '': name = os.path.splitext(os.path.basename(self.board.GetFileName()))[0] return name def get_separators_str(self, n): separators = '' for i in range(0, n): separators += SEP return separators def write_placement_info(self, ofile, isall, head): self.write_item(head, ofile) for item in self.info: if isall == 'SMT': if item[IS_SMD] == "HID": continue self.write_item(item, ofile) def write_item(self, items, ofile): for i, item in enumerate(items): ofile.write(str(item)) num_sep = self.fields_max_length[i] - len(str(item)) + 1 ofile.write(self.get_separators_str(num_sep)) if i < len(items) - 1: ofile.write('|') ofile.write(EOL)