Пример #1
0
def test_inject_eject(brd_file, data_file, obj):
    """Test data injection and ejection to/from a KiCad board file."""

    # Test injection/ejection using both JSON and YAML data formats.
    for ext, load, load_kw, dump, dump_kw in [
        [".json", json.load, {}, json.dump, {"indent": 4}],
        [
            ".yaml",
            yaml.load,
            {"Loader": yaml.Loader},
            yaml.safe_dump,
            {"default_flow_style": False},
        ],
    ]:
        # Inject file data into board and store updated board in a new file.
        brd = pcbnew.LoadBoard(brd_file + ".kicad_pcb")
        with open(data_file + "_in" + ext, "r") as data_fp:
            data_dict = load(data_fp, **load_kw)
        obj.inject(data_dict, brd)
        brd.Save(brd_file + "_out.kicad_pcb")

        # Extract info from the updated board and store it in a new data file.
        brd = pcbnew.LoadBoard(brd_file + "_out.kicad_pcb")
        data_dict = obj.eject(brd)
        with open(data_file + "_out" + ext, "w") as data_fp:
            dump(data_dict, data_fp, **dump_kw)
Пример #2
0
def test_inject_eject(brd_file, data_file, obj):
    """Test data injection and ejection to/from a KiCad board file."""

    # Test injection/ejection using both JSON and YAML data formats.
    for ext, load, load_kw, dump, dump_kw in [
        ['.json', json.load, {}, json.dump, {
            'indent': 4
        }],
        [
            '.yaml', yaml.load, {
                'Loader': yaml.Loader
            }, yaml.safe_dump, {
                'default_flow_style': False
            }
        ],
    ]:
        # Inject file data into board and store updated board in a new file.
        brd = pcbnew.LoadBoard(brd_file + '.kicad_pcb')
        with open(data_file + '_in' + ext, 'r') as data_fp:
            data_dict = load(data_fp, **load_kw)
        obj.inject(data_dict, brd)
        brd.Save(brd_file + '_out.kicad_pcb')

        # Extract info from the updated board and store it in a new data file.
        brd = pcbnew.LoadBoard(brd_file + '_out.kicad_pcb')
        data_dict = obj.eject(brd)
        with open(data_file + '_out' + ext, 'w') as data_fp:
            dump(data_dict, data_fp, **dump_kw)
def main():
    os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "Source_project"))
    source_file = 'multiple_hierarchy.kicad_pcb'

    board = pcbnew.LoadBoard(source_file)
    save_layout = SaveLayout(board)

    pivot_mod_ref = 'Q301'
    pivot_mod = save_layout.get_mod_by_ref(pivot_mod_ref)

    levels = pivot_mod.filename
    # get the level index from user
    index = levels.index(levels[0])

    data_file = 'temp_data_file.pckl'
    save_layout.save_layout(pivot_mod, pivot_mod.sheetname[0:index + 1], data_file)

    # restore layout
    os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "Destination_project"))
    destination_file = 'Destination_project.kicad_pcb'
    board = pcbnew.LoadBoard(destination_file)
    restore_layout = RestoreLayout(board)

    pivot_mod_ref = 'Q3'
    pivot_mod = restore_layout.get_mod_by_ref(pivot_mod_ref)

    restore_layout.restore_layout(pivot_mod, data_file)

    saved = pcbnew.SaveBoard(destination_file.replace(".kicad_pcb", "_temp.kicad_pcb"), board)

    b = 2
def main():
    os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "Source_project"))
    source_file = 'multiple_hierarchy.kicad_pcb'

    board = pcbnew.LoadBoard(source_file)
    save_layout = SaveLayout(board)

    pivot_mod_ref = 'Q301'
    pivot_mod = save_layout.get_mod_by_ref(pivot_mod_ref)

    levels = pivot_mod.filename
    # get the level index from user
    index = levels.index(levels[1])

    data_file = 'source_layout_test.pckl'
    save_layout.save_layout(pivot_mod, pivot_mod.sheetname[0:index + 1], data_file)

    logger.info("--- layout saved succesfully --")
    logger.info("--- proceeding with restoring --")

    # restore layout
    data_file = os.path.abspath(data_file)
    os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "Destination_project"))
    destination_file = 'Destination_project.kicad_pcb'
    board = pcbnew.LoadBoard(destination_file)
    restore_layout = RestoreLayout(board)

    pivot_mod_ref = 'Q3'
    pivot_mod = restore_layout.get_mod_by_ref(pivot_mod_ref)

    restore_layout.restore_layout(pivot_mod, data_file)

    saved = pcbnew.SaveBoard(destination_file.replace(".kicad_pcb", "_temp.kicad_pcb"), board)

    b = 2
 def __init__(self,fname=None):
     if fname == None:
         self.pcb = pcbnew.GetBoard()
     else:
         self.pcb=pcbnew.LoadBoard(fname)
     # Create new pcb layout with suffix "front-panel"
     self.panelFname=self.pcb.GetFileName().split(".kicad_pcb")[0]+"-front-panel.kicad_pcb"
     with open(self.pcb.GetFileName(),"r") as f:
         firstLine=f.readline()+")"
     #"x" --> No overwrite
     #"w" --> Overwrite
     with open(self.panelFname,"w") as f:
         f.write(firstLine)
     self.fp=pcbnew.LoadBoard(self.panelFname)
     self.getDimensions()
Пример #6
0
def add_keepout_to_board(pcb_filename, left_mm, top_mm, width_mm, height_mm):
    l = left_mm * MM_TO_KC
    t = top_mm * MM_TO_KC
    r = (left_mm + width_mm) * MM_TO_KC
    b = (top_mm + height_mm) * MM_TO_KC

    l = int(l)
    t = int(t)
    r = int(r)
    b = int(b)

    pcb = pcbnew.LoadBoard(pcb_filename)
    layer = pcbnew.F_Cu
    area = pcb.InsertArea(0, 0, layer, l, t,
                          pcbnew.ZONE_CONTAINER.DIAGONAL_EDGE)
    area.SetIsKeepout(True)
    area.SetDoNotAllowTracks(True)
    area.SetDoNotAllowVias(True)
    area.SetDoNotAllowCopperPour(True)
    outline = area.Outline()
    outline.Append(r, t)
    outline.Append(r, b)
    outline.Append(l, b)

    # Thanks
    # https://github.com/NilujePerchut/kicad_scripts/blob/master/teardrops/td.py

    pcbnew.SaveBoard(pcb_filename, pcb)
Пример #7
0
def plot(board_filename=None, layers=None):
    if board_filename is None:
        board = pcbnew.GetBoard()
    else:
        board = pcbnew.LoadBoard(os.path.expanduser(board_filename))

    if layers is None:
        layers = LAYERS
    elif isinstance(layers, list):
        layers = layers.keys()

    plot_ctrl = pcbnew.PLOT_CONTROLLER(board)

    plot_opts = plot_ctrl.GetPlotOptions()
    plot_opts.SetPlotFrameRef(False)
    plot_opts.SetLineWidth(pcbnew.FromMM(0.35))
    plot_opts.SetAutoScale(False)
    plot_opts.SetScale(1)
    plot_opts.SetUseGerberAttributes(True)
    plot_opts.SetExcludeEdgeLayer(False)
    plot_opts.SetUseAuxOrigin(False)
    plot_opts.SetPlotViaOnMaskLayer(True)

    for layer, layer_info in layers.items():
        layer_name = layers.get('name', board.GetLayerName(layer))
        plot_opts.SetMirror(layer_info.get('mirrored', False))
        plot_opts.SetNegative(layer_info.get('negative', False))
        plot_ctrl.SetLayer(layer)
        plot_ctrl.OpenPlotfile(layer_name, pcbnew.PLOT_FORMAT_PDF,
                               layer_info.get('description', layer_name))
        plot_ctrl.PlotLayer()
Пример #8
0
    def plot(self, brd_file):

        logging.debug("Starting plot of board {}".format(brd_file))

        board = pcbnew.LoadBoard(brd_file)

        logging.debug("Board loaded")

        self._preflight_checks(board)

        for op in self.cfg.outputs:

            logging.debug("Processing output: {}".format(op.name))

            # fresh plot controller
            pc = pcbnew.PLOT_CONTROLLER(board)

            self._configure_output_dir(pc, op)

            if self._output_is_layer(op):
                self._do_layer_plot(board, pc, op)
            elif self._output_is_drill(op):
                self._do_drill_plot(board, pc, op)
            elif self._output_is_position(op):
                self._do_position_plot(board, pc, op)
            else:
                raise PlotError("Don't know how to plot type {}".format(
                    op.options.type))

            pc.ClosePlot()
Пример #9
0
def generate_top_pcb():
    board = pcbnew.LoadBoard(master_pcb)
    edge_cuts_layer_id = board.GetLayerID('Edge.Cuts')
    print('Creating top PCB: %s' % top_pcb)
    delete_electronics(board)
    for module in board.GetModules():
        is_brace_for_top = not is_brace_not_for_top(module)
        if is_brace(module) and is_brace_for_top:
            continue
        ref = module.GetReference()
        is_mount_for_top = ref.startswith(
            'Mount') and not ref.startswith('MountNotTop')
        if is_mount_for_top:
            continue
        board.Delete(module)
    delete_tracks(board)
    for d in board.GetDrawings():
        if type(d) is pcbnew.TEXTE_PCB:
            if d.GetThickness() == ALL_LAYERS_TEXT_THICKNESS:
                continue
        if d.GetLayerName() == 'Edge.Cuts':
            if type(d) is pcbnew.DRAWSEGMENT:
                if d.GetWidth() == ALL_LAYERS_WIDTH:
                    continue
        if d.GetLayerName() == 'Eco1.User':
            is_for_top_plate = d.GetWidth() != NOT_TOP_PLATE_WIDTH
            if is_for_top_plate:
                d.SetLayer(edge_cuts_layer_id)
                continue
        board.Delete(d)
    refill_zones(board)
    board.Save(top_pcb)
Пример #10
0
def main():
    args = parse_args()
    board = pcbnew.LoadBoard(args.filename)
    filler = pcbnew.ZONE_FILLER(board)
    zones = board.Zones()
    filler.Fill(zones)
    pcbnew.SaveBoard(args.filename, board)
Пример #11
0
def generate_pcb_drill(args):
    logging.info('Generating PCB drill file')
    check_args(args)

    output_dir = os.path.join(args.output_dir, 'gerber')
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    logging.info('   Reading %s', args.input_pcb)

    board = pcbnew.LoadBoard(args.input_pcb)
    excellon_writer = pcbnew.EXCELLON_WRITER(board)

    excellon_writer.SetMapFileFormat(pcbnew.PLOT_FORMAT_GERBER)

    mirror = False
    minimal_header = False
    merge_pth_npth = True
    offset = pcbnew.wxPoint(0, 0)
    excellon_writer.SetOptions(mirror, minimal_header, offset, merge_pth_npth)

    metric_format = True
    excellon_writer.SetFormat(metric_format)

    generate_drill = True
    generate_map = False

    logging.info('   Writing to %s' % output_dir)

    excellon_writer.CreateDrillandMapFilesSet(output_dir, generate_drill,
                                              generate_map)
Пример #12
0
def pcbfunc(Filename = None):
    if Filename: 
        my_board = pcbnew.LoadBoard (Filename)
    else:
        my_board = pcbnew.GetBoard()

    filename = change_extension (my_board.GetFileName(), ".pos")

    f = open (filename, "w")

    f.write ("### Module positions - created on %s ###" % datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
    f.write ("### Printed by get_pos v1")
    f.write ("## Unit = mm, Angle = deg.")
    f.write ("## Side : All")
    f.write ("# Ref     Val        Package                PosX       PosY       Rot  Side  Type")

    origin = my_board.GetAuxOrigin()

    # for v5 use GetLibItemName() instead of GetFootprintName()
    for module in my_board.GetModules():
        f.write ("%s \"%s\" %s %1.3f %1.3f %1.3f %s %s" % ( module.GetReference(), 
                                    module.GetValue(),
                                    module.GetFPID().GetFootprintName(),
                                    pcbnew.ToMM(module.GetPosition().x - origin.x),
                                    pcbnew.ToMM(-module.GetPosition().y + origin.y),
                                    module.GetOrientation() / 10.0,
                                    "top" if module.GetLayer() == 0 else "bottom",
                                    get_class ( module.GetAttributes() )
                                    ))

    f.write ("## End")

    f.close ()

    print ("Written to %s" % filename)
Пример #13
0
def read_kicadpcb(kicadpcb_file):
    """ Open the board file, read the modules and extract the placement
    data.
    """
    board = PN.LoadBoard(kicadpcb_file)
    board_bb = board.ComputeBoundingBox(True)
    bot_left_x = board_bb.GetLeft()
    bot_left_y = board_bb.GetBottom()
    result_mods = {}
    for module in board.GetModules():
        rot = module.GetOrientation() / 10.0
        module_rect = getFootprintRect(module, upright=True)
        x_size = PN.ToMils(module_rect.GetWidth())
        y_size = PN.ToMils(module_rect.GetHeight())
        designator = module.GetReference()
        module_center = module_rect.Centre()
        result_mods[designator] = {
            "DESIGNATOR": designator,
            "VALUE": module.GetValue(),
            "X_SIZE": x_size,
            "Y_SIZE": y_size,
            "ROTATION": rot,
            "SIDE": "top" if (module.GetLayer() is PN.F_Cu) else
            "bot",  #1/T/top for Top, 2/B/bot/bottom for Bottom
            "TYPE": "SMD" if
            (isModuleSMD(module)) else "PTH",  #1/SMT/SMD for SMD, 2 for PTH
            "X_LOC": PN.ToMils(module_center.x - bot_left_x),
            "Y_LOC": PN.ToMils(bot_left_y - module_center.y),
            "FOOTPRINT": "",  #C0805, R0603, TQFP-100
            "POPULATE": "1"  #1 for populate, 0 for do not populate
        }
    return result_mods
Пример #14
0
def main():
    """ Main function for this script. """
    parser = make_parser()
    args = parser.parse_args()
    args.pcb_file = sanitize(args.pcb_file)

    if args.dry_run:
        access_flag = os.R_OK
    else:
        access_flag = os.W_OK

    if not os.access(args.pcb_file, access_flag):
        sys.stderr.write("Error: can't open file [%s]\n" % args.pcb_file)
        sys.exit(1)

    if args.schematic != "":
        args.schematic = sanitize(args.schematic)
        if not os.access(args.schematic, access_flag):
            sys.stderr.write("Error: can't open file [%s]\n" % args.schematic)
            sys.exit(1)

    board = pcbnew.LoadBoard(args.pcb_file)

    records = get_module_records(board)
    records = scale_records(records)
    records = sort_records(records, 100)
    records = calculate_remaps(records)

    if not args.quiet:
        print_records(records)

    remap_pcb(board, args.pcb_file, records, args.dry_run, args.quiet)

    if args.schematic != "":
        remap_schematic(args.schematic, records, args.dry_run, args.quiet)
Пример #15
0
def add_edge_cuts(tmpdir):
    pcb_path = "{}/keyboard-before.kicad_pcb".format(tmpdir)
    try:
        board = pcbnew.LoadBoard(pcb_path)
        positions = [
            module.GetPosition() for module in board.GetModules()
            if re.match(r"^SW\d+$", module.GetReference())
        ]
        xvals = [position.x for position in positions]
        yvals = [position.y for position in positions]
        xmin = min(xvals) - pcbnew.FromMM(12)
        xmax = max(xvals) + pcbnew.FromMM(12)
        ymin = min(yvals) - pcbnew.FromMM(12)
        ymax = max(yvals) + pcbnew.FromMM(12)
        corners = [
            pcbnew.wxPoint(xmin, ymin),
            pcbnew.wxPoint(xmax, ymin),
            pcbnew.wxPoint(xmax, ymax),
            pcbnew.wxPoint(xmin, ymax),
        ]
        for i in range(len(corners)):
            start = corners[i]
            end = corners[(i + 1) % len(corners)]
            segment = pcbnew.DRAWSEGMENT(board)
            segment.SetLayer(pcbnew.Edge_Cuts)
            segment.SetStart(start)
            segment.SetEnd(end)
            board.Add(segment)

        pcbnew.Refresh()
        pcbnew.SaveBoard(pcb_path, board)
    except Exception as err:
        raise Exception("Adding egde cuts failed") from err
Пример #16
0
def getAndRepeatBoard(targetWidthNm,
                      targetHeightNm,
                      numberX,
                      numberY,
                      filePathToSave=None):
    board = pcbnew.GetBoard()
    wh = getWidthHeightNmOfBoard(board)
    if wh is None:
        raise Exception('Cannot get size of board')
    widthNm = wh[0]
    heightNm = wh[1]
    if numberX is None:
        numberX = math.floor(targetWidthNm / widthNm)
        numberY = math.floor(targetHeightNm / heightNm)
    # print(numberX, numberY)
    targetBoard = None
    if filePathToSave is None:
        targetBoard = board
    else:
        # targetBoard = pcbnew.BOARD() # causes segmentation fault on saving
        board.Save(filePathToSave)
        targetBoard = pcbnew.LoadBoard(filePathToSave)
    repeat(targetBoard,
           targetBoard,
           lengthNmX=widthNm,
           lengthNmY=heightNm,
           numberX=numberX,
           numberY=numberY)
    if targetBoard != board:
        print("save as", filePathToSave)
        targetBoard.Save(filePathToSave)
        print("saved")
    else:
        print("clone on board")
    pcbnew.Refresh()
Пример #17
0
def cleanup(args):
    board_file_path = os.path.dirname(args.brd)
    board_file_name = os.path.basename(args.brd)
    board_file = os.path.join(project_root,
                              args.brd + '_' + args.variant + '.kicad_pcb')

    board = pcbnew.LoadBoard(board_file)

    output_dir = os.path.join(
        project_root,
        'CI-BUILD/' + board_file_name + '_' + args.variant + '/DLF')
    file_util.mkdir_p(output_dir)

    #TODO: Remove when stable or add debug flag
    screencast_output_file = os.path.join(output_dir,
                                          'dlf' + args.variant + '.ogv')

    with recorded_xvfb(screencast_output_file,
                       width=800,
                       height=600,
                       colordepth=24):
        with PopenContext(['pcbnew', board_file],
                          close_fds=True) as pcbnew_proc:
            pcbnew_cleanup(args.footprints, args.wait_init)
            pcbnew_proc.terminate()
Пример #18
0
 def __init__(self, file_name, config, logger, board=None):
     super(PcbnewParser, self).__init__(file_name, config, logger)
     self.board = board
     if self.board is None:
         self.board = pcbnew.LoadBoard(self.file_name)  # type: pcbnew.BOARD
     self.font_parser = FontParser()
     self.extra_data_func = parse_schematic_data
Пример #19
0
def add_labels_to_board(pcb_filename, labels):
    pcb = pcbnew.LoadBoard(pcb_filename)

    for label in labels:
        draw_text(pcb, label["text"], label["x_mm"] * MM_TO_KC,
                  label["y_mm"] * MM_TO_KC)
    pcbnew.SaveBoard(pcb_filename, pcb)
Пример #20
0
def test2():
    # load board to be panelized
    #b1 = pcbnew.LoadBoard(r'test1.kicad_pcb')
    b2 = pcbnew.LoadBoard(r'test2.kicad_pcb')
    # Get current work borad, must be a empty board
    brd = pcbnew.GetBoard()
    # Collect items
    bi1 = BoardItems()
    bi2 = BoardItems()
    bi1.Collect(brd)
    bi2.Collect(b2)
    #bi1 = bi1.Clone(brd)
    #bi2 = bi2.Clone(brd)
    # Clone items in board 1
    bb1 = bi1.Clone()
    # Change the module reference
    bi2.UpdateRef(bi1.rb)
    # Clone items in board 2
    bb2 = bi2.Clone()
    # Copy board items to current board
    #bi1.ChangeBrd(brd)
    #bb1.ChangeBrd(brd)
    bi2.ChangeBrd(brd)
    bb2.ChangeBrd(brd)
    # Move them
    bi2.MoveToMM(0, 0)
    bi2.Rotate(180)

    bb1.Mirror()
    bb2.Rotate(180)
    bb2.Mirror()

    bb1.MoveToMM(54, -59)
    bb2.MoveToMM(54, -59)
Пример #21
0
def CollectItemByName(filename=None):
    try:
        brd = pcbnew.LoadBoard(filename)
    except IOError:
        print 'Can not open ', filename
        filename = os.path.split(
            pcbnew.GetBoard().GetFileName())[0] + '\\' + filename
        print 'Try to open ', filename
    try:
        brd = pcbnew.LoadBoard(filename)
    except IOError:
        print 'Can not open ', filename
        return None
    bi = BoardItems()
    bi.Collect(brd)
    return bi
Пример #22
0
def createPrinted(inputboard, outputdir, pcbthickness, thickness, framewidth,
                  ignore, frameclearance, enlargeholes):
    """
    Create a 3D printed self-registering stencil.
    """
    board = pcbnew.LoadBoard(inputboard)
    refs = parseReferences(ignore)
    removeComponents(board, refs)
    Path(outputdir).mkdir(parents=True, exist_ok=True)

    # We create the stencil based on DXF export. Using it avoids the necessity
    # to interpret KiCAD PAD shapes which constantly change with newer and newer
    # versions.
    height = min(pcbthickness, max(0.5, pcbthickness - 0.3))
    bottomPaste, topPaste, outline = pasteDxfExport(board, outputdir)
    topStencil = printedStencil(outline, topPaste, thickness, height,
        framewidth, frameclearance, enlargeholes, True)
    bottomStencil = printedStencil(outline, bottomPaste, thickness, height,
        framewidth, frameclearance, enlargeholes, False)

    bottomStencilFile = os.path.join(outputdir, "bottomStencil.scad")
    solid.scad_render_to_file(bottomStencil, bottomStencilFile,
        file_header=f'$fa = 0.4; $fs = 0.4;', include_orig_code=True)
    renderScad(bottomStencilFile, os.path.join(outputdir, "bottomStencil.stl"))

    topStencilFile = os.path.join(outputdir, "topStencil.scad")
    solid.scad_render_to_file(topStencil, topStencilFile,
        file_header=f'$fa = 0.4; $fs = 0.4;', include_orig_code=True)
    renderScad(topStencilFile, os.path.join(outputdir, "topStencil.stl"))
Пример #23
0
def GetOtherBoard(brd):
    r = brd
    curbrd = pcbnew.GetBoard()
    s = curbrd.GetFileName()
    if not brd:
        brd = curbrd
    elif type(brd) == str:
        if os.path.exists(brd):
            brd = pcbnew.LoadBoard(brd)
        elif os.path.exists(s[0:s.rfind('/')] + '/' + brd):
            brd = pcbnew.LoadBoard(s[0:s.rfind('/')] + '/' + brd)
        else:
            return None
    else:
        return brd
    return brd
Пример #24
0
def place_pcb_modules(filename, placement_data):
    print()
    print('loading pcb: {}'.format(filename))
    print()
    pcb = pcbnew.LoadBoard(filename)
    print()
    print('done')
    print()
    for module in pcb.GetModules():
        ref_str = str(module.GetReference())
        try:
            data = placement_data[ref_str]
        except KeyError:
            continue
        print_module_info(module)

        # Move to new position
        pos = module.GetPosition()
        angle = 0.1 * module.GetOrientation()
        x_new = data['x']
        y_new = data['y']
        angle_new = data['angle']
        pos.x = int(mm_to_nm(x_new))
        pos.y = int(mm_to_nm(y_new))
        module.SetPosition(pos)
        module.SetOrientation(10.0 * angle_new)
        print_module_info(module)

    pathname, basename = os.path.split(filename)
    new_basename = 'mod_{}'.format(basename)
    new_filename = os.path.join(pathname, new_basename)
    pcb.Save(new_filename)
Пример #25
0
def get_board_properties(filename):
    """
    Returns a dict from netclass name -> (tolerance, nets)
    Where tolerance is maximum difference in matched track lengths.
    And nets is a list of (netname, length) for each net in the netclass.

    Only netclasses with length matching tolerances are returned
    """
    pcb = pcbnew.LoadBoard(filename)
    pcb.BuildListOfNets() # required so 'pcb' contains valid netclass data

    tolerances = {}
    nets = {}

    tracks = pcb.GetTracks() # tuples of (netname, classname)
    netclasses = list(set(t.GetNet().GetClassName()  for t in tracks)) # unique netclass names

    result = {}
    for netclass in netclasses:
        tolerance = get_tolerance(netclass)
        if tolerance is None:
            continue
        tracks_netclass = [t for t in tracks if t.GetNet().GetClassName() == netclass] # tracks in this netclass
        netnames = list(set([t.GetNet().GetNetname() for t in tracks_netclass])) # unique netnames in this netclass
        netnames.sort()
        nets = [(n,int(sum(t.GetLength() for t in tracks_netclass if t.GetNet().GetNetname() == n))) for n in netnames]
        result[netclass] = (tolerance, nets)
    return result
Пример #26
0
    def __init__(self, f_name, plot_dir, zone_refill=True):
        '''
        f_name: the .kicad_pcb file to export
        plot_dir: output directory for the Gerber files
        zone_refill: if True, re-calculate copper fills before plotting
        '''
        self.plot_dir = plot_dir
        # Will raise an exception if file cannot be opened
        self.board = board = pcbnew.LoadBoard(f_name)
        self.f_name = basename(f_name)

        # Hack:  the file has SE55DE100 clearance set small enough to
        # pass DRC, but for the Gerber export process it should be set
        # to the actual desired value.
        # Really only sets size of clearance circles where these nets
        # cross power planes.  Programming hints from
        # kicad.mmccoo.com/2017/04/18/modify-design-rules-from-python/
        nc_name = "SE55DE100"
        aa = board.GetDesignSettings().m_NetClasses.Find(nc_name)
        if aa is None:
            print("No %s net_class?" % nc_name)
        else:
            aa_old = aa.GetClearance()
            aa_new = 222000  # according to Michal
            aa_new = 200000  # lets ground plane connect between via pairs escaping FPGA
            print("Adjusting %s clearance from %d to %d" %
                  (nc_name, aa_old, aa_new))
            aa.SetClearance(aa_new)

        if zone_refill:
            print('filling zones ...')
            zf = pcbnew.ZONE_FILLER(board)
            zf.Fill(board.Zones())
Пример #27
0
def generate_base_pcb():
    board = pcbnew.LoadBoard(master_pcb)
    print('Creating base PCB: %s' % base_pcb)
    delete_electronics(board)
    print('Deleted electronics from base PCB')
    for module in board.GetModules():
        if is_brace(module):
            if is_brace_not_for_top(module):
                continue
            board.Delete(module)
    delete_tracks(board)
    print('Deleted tracks from base PCB')
    for d in board.GetDrawings():
        if type(d) is pcbnew.TEXTE_PCB:
            if d.GetThickness() == ALL_LAYERS_TEXT_THICKNESS:
                continue
        if d.GetLayerName() == 'Edge.Cuts':
            if type(d) is pcbnew.DRAWSEGMENT:
                if d.GetWidth() == NOT_TOP_PLATE_WIDTH or d.GetWidth(
                ) == ALL_LAYERS_WIDTH:
                    continue
        board.Delete(d)
    print('Refilling zones in the base PCB')
    refill_zones(board)
    print('Saving the base PCB')
    board.Save(base_pcb)
def test(in_file, out_file, pivot_module_reference, mode, layout):
    board = pcbnew.LoadBoard(in_file)

    placer = Placer(board)

    if mode == 'by ref':
        module_reference_designator = ''.join(i for i in pivot_module_reference if not i.isdigit())
        module_reference_number = int(''.join(i for i in pivot_module_reference if i.isdigit()))

        # get list of all modules with same reference designator
        list_of_all_modules_with_same_designator = placer.get_modules_with_reference_designator(module_reference_designator)
        sorted_list = natural_sort(list_of_all_modules_with_same_designator)

        list_of_consecutive_modules=[]
        start_index = sorted_list.index(pivot_module_reference)
        count_start = module_reference_number
        for mod in sorted_list[start_index:]:
            if int(''.join(i for i in mod if i.isdigit())) == count_start:
                count_start = count_start + 1
                list_of_consecutive_modules.append(mod)
            else:
                break

        count_start = module_reference_number
        reversed_list = list(reversed(sorted_list))
        start_index = reversed_list.index(pivot_module_reference)
        for mod in reversed_list[start_index:]:
            if int(''.join(i for i in mod if i.isdigit())) == count_start:
                count_start = count_start -1
                list_of_consecutive_modules.append(mod)
            else:
                break

        sorted_modules = natural_sort(list(set(list_of_consecutive_modules)))

    if mode == 'by sheet':
        pivot_module = placer.get_mod_by_ref(pivot_module_reference)
        list_of_modules = placer.get_list_of_modules_with_same_id(pivot_module.mod_id)
        modules = []
        for mod in list_of_modules:
            modules.append(mod.ref)
        sorted_modules = natural_sort(modules)

    reference_module = pivot_module_reference

    if layout == 'circular':
        if mode == 'by sheet':
            placer.place_circular(sorted_modules, reference_module, 10.0, 30.0)
        else:
            placer.place_circular(sorted_modules, reference_module, 10.0, 30.0)
    if layout == 'linear':
        placer.place_linear(sorted_modules, reference_module, 5.0, 0.0)
    if layout == 'matrix':
        placer.place_matrix(sorted_modules, reference_module, 5.0, 5.0, 3)

    saved = pcbnew.SaveBoard(out_file, board)
    test_file = out_file.replace("temp", "test")

    return compare_boards.compare_boards(out_file, test_file)
Пример #29
0
def main():

    EXIT_BAD_ARGS = 1
    EXIT_BAD_CONFIG = 2

    parser = argparse.ArgumentParser(
        description='Command-line Plotting for KiCad')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='show debugging information')
    parser.add_argument('-b',
                        '--board-file',
                        required=True,
                        help='The PCB .kicad-pcb board file')
    parser.add_argument('-c',
                        '--plot-config',
                        required=True,
                        help='The plotting config file to use')
    parser.add_argument('-d',
                        '--out-dir',
                        default='.',
                        help='The output directory (cwd if not given)')

    args = parser.parse_args()

    log_level = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(level=log_level)

    if not os.path.isfile(args.board_file):
        logging.error("Board file not found: {}".format(args.board_file))

    if not os.path.isfile(args.plot_config):
        logging.error("Plot config file not found: {}".format(
            args.plot_config))
        sys.exit(EXIT_BAD_ARGS)

    board = pcbnew.LoadBoard(args.board_file)
    logging.debug("Board loaded")

    cr = config_reader.CfgYamlReader()

    with open(args.plot_config) as cf_file:
        cfg = cr.read(cf_file, board)

    # relative to CWD (absolute path overrides)
    outdir = os.path.join(os.getcwd(), args.out_dir)
    cfg.outdir = outdir

    # Finally, once all value are in, check they make sense
    errs = cfg.validate()

    if errs:
        logging.error('Invalid config:\n\n' + "\n".join(errs))
        sys.exit(EXIT_BAD_CONFIG)

    # Set up the plotter and do it
    plotter = kiplot.Plotter(cfg)
    plotter.plot(args.board_file)
def main():
    #board = pcbnew.LoadBoard('fresh_test_project/archive_test_project.kicad_pcb')
    board = pcbnew.LoadBoard(
        'archived_test_project/archive_test_project.kicad_pcb')
    try:
        archive_symbols(board, allow_missing_libraries=True, alt_files=True)
    except (ValueError, IOError, LookupError), error:
        print str(error)