Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
 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
Esempio n. 5
0
    def setValueDisVisible(self, board = None):
        if board == None:
            board = GetBoard()

        self.board = board

        for module in self.board.GetFootprints():
            module.Value().SetVisible(False)
Esempio n. 6
0
    def generalPosition(self, board = None):
        if board == None:
            board = GetBoard()

        self.board = board
        self.get_placement_info()
        self.getPositionHeaderInfo()
        return self.info, self.headinfo
Esempio n. 7
0
    def generalBOM(self, board = None):
        if board == None:
            board = GetBoard()

        self.board = board
        self.get_bom_info()
        self.generalBOMHeaderInfo()
        return self.info, self.headinfo
Esempio n. 8
0
    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))
Esempio n. 9
0
    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))
Esempio n. 10
0
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
Esempio n. 11
0
    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)
Esempio n. 12
0
 def Run(self):
     InitMainDialog(GetBoard())
Esempio n. 13
0
 def Run(self):
     InitTeardropDialog(GetBoard())
Esempio n. 14
0
def main():
    modules = get_all_module_info(GetBoard())
    net_list = make_net_list(modules)
Esempio n. 15
0
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
Esempio n. 16
0
 def Run(self):
     init_diffpads_dialog(GetBoard())
Esempio n. 17
0
 def Run(self):
     InitAddNetDialog(GetBoard())
Esempio n. 18
0
 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
Esempio n. 19
0
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)