Пример #1
0
    def plot_drill(self, pcb):
        "plot drill files"

        pctl = pcbnew.PLOT_CONTROLLER(pcb)

        drill_path = os.path.dirname(
            pcb.GetFileName()) + PCB_MAN_PACK_DIR + "Drill/"
        if not os.path.exists(drill_path):
            os.makedirs(drill_path)

        report_path = os.path.dirname(pcb.GetFileName()) + REPORTS_DIR
        if not os.path.exists(report_path):
            os.makedirs(report_path)

        pctl = pcbnew.PLOT_CONTROLLER(pcb)

        popt = pctl.GetPlotOptions()

        popt.SetOutputDirectory(drill_path)

        # Set some important plot options:
        popt.SetPlotFrameRef(False)
        popt.SetLineWidth(pcbnew.FromMM(0.1))

        popt.SetAutoScale(False)
        popt.SetScale(1)
        popt.SetMirror(False)
        popt.SetExcludeEdgeLayer(False)
        popt.SetPlotValue(False)
        popt.SetPlotReference(False)
        popt.SetUseGerberAttributes(True)
        popt.SetUseGerberProtelExtensions(False)
        popt.SetUseAuxOrigin(True)

        # Fabricators need drill files.
        # sometimes a drill map file is asked (for verification purpose)
        drlwriter = pcbnew.EXCELLON_WRITER(pcb)
        drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)

        mirror = False
        minimalHeader = False
        offset = pcb.GetAuxOrigin()
        # False to generate 2 separate drill files (one for plated holes, one for non plated holes)
        # True to generate only one drill file
        mergeNPTH = True
        drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

        metricFmt = True
        drlwriter.SetFormat(metricFmt)

        genDrl = True
        genMap = True
        drlwriter.CreateDrillandMapFilesSet(drill_path, genDrl, genMap)

        # One can create a text file to report drill statistics
        rptfn = report_path + 'drill_report.rpt'
        drlwriter.GenDrillReportFile(rptfn)
        pctl.ClosePlot()
Пример #2
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()
Пример #3
0
    def Run(self):
        pcb = pcbnew.GetBoard()

        pctl = pcbnew.PLOT_CONTROLLER(pcb)

        popt = pctl.GetPlotOptions()

        popt.SetOutputDirectory("Outputs/PCB_Manufacturing/")

        # Set some important plot options:
        popt.SetPlotFrameRef(True)
        popt.SetLineWidth(pcbnew.FromMM(0.1))

        popt.SetAutoScale(False)
        popt.SetScale(1)
        popt.SetMirror(False)
        popt.SetExcludeEdgeLayer(False)
        popt.SetPlotValue(False)
        popt.SetPlotReference(True)

        #Create a pdf file of the top fab Layer
        pctl.SetLayer(pcbnew.Dwgs_User)
        pctl.OpenPlotfile("Fab_Drawings", pcbnew.PLOT_FORMAT_PDF,
                          "Fab_Drawings")
        pctl.PlotLayer()

        pctl.ClosePlot()
Пример #4
0
    def plot_fab_drawings(self, pcb):
        "plot fab drawings"

        pctl = pcbnew.PLOT_CONTROLLER(pcb)

        popt = pctl.GetPlotOptions()

        fab_path = os.path.dirname(pcb.GetFileName()) + PCB_MAN_PACK_DIR

        popt.SetOutputDirectory(fab_path)

        # Set some important plot options:
        popt.SetPlotFrameRef(True)
        popt.SetLineWidth(pcbnew.FromMM(0.1))

        popt.SetAutoScale(False)
        popt.SetScale(1)
        popt.SetMirror(False)
        popt.SetExcludeEdgeLayer(False)
        popt.SetPlotValue(False)
        popt.SetPlotReference(True)

        #Create a pdf file of the top fab Layer
        pctl.SetLayer(pcbnew.Dwgs_User)
        pctl.OpenPlotfile("Fab_Drawings", pcbnew.PLOT_FORMAT_PDF,
                          "Fab_Drawings")
        pctl.PlotLayer()

        pctl.ClosePlot()
Пример #5
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()
Пример #6
0
    def genPostscript(self, board, path):
        pc = pcbnew.PLOT_CONTROLLER(board)
        po = pc.GetPlotOptions()
        # set global options
        po.SetPlotFrameRef(False)
        po.SetOutputDirectory(path)
        po.SetA4Output(True)
        po.SetScale(1.0)
        po.SetExcludeEdgeLayer(False)
        po.SetDrillMarksType(po.SMALL_DRILL_SHAPE)
        # Set options for front Copper layer
        pc.SetLayer(pcbnew.F_Cu)
        po.SetMirror(True)
        # Plot front Copper
        pc.OpenPlotfile("CuTOP", pcbnew.PLOT_FORMAT_POST, "front_copper")
        pc.PlotLayer()
        pc.ClosePlot()
        #Plot bottom Copper
        # Set options for Bottom Copper layer
        pc.SetLayer(pcbnew.B_Cu)
        po.SetMirror(False)
        pc.OpenPlotfile("CuBOT", pcbnew.PLOT_FORMAT_POST, "bottom_copper")
        pc.PlotLayer()
        pc.ClosePlot()

        logging.info('Postcripts done')
Пример #7
0
def get_board_substrate(board, colors, holes, back, silk):
    """
    Plots all front layers from the board and arranges them in a visually appealing style.
    return SVG g element with the board substrate
    """
    toPlot = []
    if (back):
        toPlot = [("board", [pcbnew.Edge_Cuts], process_board_substrate_base),
                  ("clad", [pcbnew.B_Mask], process_board_substrate_layer),
                  ("copper", [pcbnew.B_Cu], process_board_substrate_layer),
                  ("pads", [pcbnew.B_Cu], process_board_substrate_layer),
                  ("pads-mask", [pcbnew.B_Mask], process_board_substrate_mask)]
        if silk:
            toPlot.append(
                ("silk", [pcbnew.B_SilkS], process_board_substrate_layer))
    else:
        toPlot = [("board", [pcbnew.Edge_Cuts], process_board_substrate_base),
                  ("clad", [pcbnew.F_Mask], process_board_substrate_layer),
                  ("copper", [pcbnew.F_Cu], process_board_substrate_layer),
                  ("pads", [pcbnew.F_Cu], process_board_substrate_layer),
                  ("pads-mask", [pcbnew.F_Mask], process_board_substrate_mask)]
        if silk:
            toPlot.append(
                ("silk", [pcbnew.F_SilkS], process_board_substrate_layer))
    toPlot.append(
        ("outline", [pcbnew.Edge_Cuts], process_board_substrate_layer))
    container = etree.Element('g')
    container.attrib["clip-path"] = "url(#cut-off)"
    tmp = tempfile.mkdtemp()
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(tmp)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetSubtractMaskFromSilk(True)
    try:
        popt.SetPlotOutlineMode(False)
    except:
        # Method does not exist in older versions of KiCad
        pass
    popt.SetTextMode(pcbnew.PLOTTEXTMODE_STROKE)
    for f, layers, _ in toPlot:
        pctl.OpenPlotfile(f, pcbnew.PLOT_FORMAT_SVG, f)
        for l in layers:
            pctl.SetColorMode(False)
            pctl.SetLayer(l)
            pctl.PlotLayer()
    pctl.ClosePlot()
    boardsize = get_board_size(board)
    for f, _, process in toPlot:
        for svg_file in os.listdir(tmp):
            if svg_file.endswith("-" + f + ".svg"):
                process(container, f, os.path.join(tmp, svg_file), colors,
                        boardsize)
    shutil.rmtree(tmp)

    if holes:
        container.append(get_hole_mask(board))
        container.attrib["mask"] = "url(#hole-mask)"
    return container
Пример #8
0
def get_board_substrate(board, colors):
    """
    Plots all front layers from the board and arranges them in a visually appealing style.
    return SVG g element with the board substrate
    """
    toPlot = [("board", [pcbnew.Edge_Cuts], process_board_substrate_base),
              ("copper", [pcbnew.F_Cu], process_board_substrate_layer),
              ("pads", [pcbnew.F_Paste], process_board_substrate_layer),
              ("silk", [pcbnew.F_SilkS], process_board_substrate_layer)]
    container = etree.Element('g')
    tmp = tempfile.mkdtemp()
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(tmp)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetTextMode(pcbnew.PLOTTEXTMODE_STROKE)
    for f, layers, _ in toPlot:
        pctl.OpenPlotfile(f, pcbnew.PLOT_FORMAT_SVG, f)
        for l in layers:
            pctl.SetColorMode(False)
            pctl.SetLayer(l)
            pctl.PlotLayer()
    pctl.ClosePlot()
    for f, _, process in toPlot:
        for svg_file in os.listdir(tmp):
            if svg_file.endswith("-" + f + ".svg"):
                process(container, f, os.path.join(tmp, svg_file), colors)
    shutil.rmtree(tmp)
    return container
Пример #9
0
def render(layers, name, mirror):
    # Export new files
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()

    popt.SetOutputDirectory(plotDir)
    popt.SetPlotFrameRef(False)
    popt.SetLineWidth(pcbnew.FromMM(0.15))
    popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetMirror(mirror)
    popt.SetUseGerberAttributes(True)
    popt.SetExcludeEdgeLayer(False)
    popt.SetUseAuxOrigin(False)
    popt.SetUseAuxOrigin(False)
    popt.SetPlotReference(True)
    popt.SetPlotValue(True)
    popt.SetPlotInvisibleText(False)
    popt.SetPlotFrameRef(False)

    pctl.SetLayer(Dwgs_User)
    pctl.OpenPlotfile(name, PLOT_FORMAT_PDF, name)
    pctl.SetColorMode(True)

    for layer_info in layers:
        pctl.SetLayer(layer_info[1])
        pctl.PlotLayer()

    pctl.ClosePlot()
Пример #10
0
def get_layers(board, colors, toPlot):
    """
    Plot given layers, process them and return them as <g>
    """
    container = etree.Element('g')
    tmp = tempfile.mkdtemp()
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(tmp)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetSubtractMaskFromSilk(True)
    try:
        popt.SetPlotOutlineMode(False)
    except:
        # Method does not exist in older versions of KiCad
        pass
    popt.SetTextMode(pcbnew.PLOTTEXTMODE_STROKE)
    for f, layers, _ in toPlot:
        pctl.OpenPlotfile(f, pcbnew.PLOT_FORMAT_SVG, f)
        for l in layers:
            pctl.SetColorMode(False)
            pctl.SetLayer(l)
            pctl.PlotLayer()
    pctl.ClosePlot()
    boardsize = board.ComputeBoundingBox()
    for f, _, process in toPlot:
        for svg_file in os.listdir(tmp):
            if svg_file.endswith("-" + f + ".svg"):
                process(container, f, os.path.join(tmp, svg_file), colors,
                        boardsize)
    shutil.rmtree(tmp)
    return container
Пример #11
0
def processBoard(boardName, plotDir):
    """Convert layers of KiCad PCB to SVGs"""
    print(boardName)
    print(plotDir)
    # Load board and initialize plot controller
    board = pcbnew.LoadBoard(boardName)
    boardBox = board.ComputeBoundingBox()
    boardXl = boardBox.GetX()
    boardYl = boardBox.GetY()
    boardWidth = boardBox.GetWidth()
    boardHeight = boardBox.GetHeight()
    print(boardXl, boardYl, boardWidth, boardHeight)

    pctl = pcbnew.PLOT_CONTROLLER(board)
    pctl.SetColorMode(True)

    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(plotDir)
    popt.SetPlotFrameRef(False)
    popt.SetLineWidth(pcbnew.FromMM(0.15))
    popt.SetAutoScale(False)
    popt.SetScale(2)
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(True)
    popt.SetExcludeEdgeLayer(False)
    popt.SetUseAuxOrigin(True)

    layers = [
        ("F_Cu", pcbnew.F_Cu, "Top layer"),
        ("B_Cu", pcbnew.B_Cu, "Bottom layer"),
        ("B_Paste", pcbnew.B_Paste, "Paste bottom"),
        ("F_Paste", pcbnew.F_Paste, "Paste top"),
        ("F_SilkS", pcbnew.F_SilkS, "Silk top"),
        ("B_SilkS", pcbnew.B_SilkS, "Silk top"),
        ("B_Mask", pcbnew.B_Mask, "Mask bottom"),
        ("F_Mask", pcbnew.F_Mask, "Mask top"),
        ("Edge_Cuts", pcbnew.Edge_Cuts, "Edges"),
        ("Margin", pcbnew.Margin, "Margin"),
        ("In1_Cu", pcbnew.In1_Cu, "Inner1"),
        ("In2_Cu", pcbnew.In2_Cu, "Inner2"),
        ("Dwgs_User", pcbnew.Dwgs_User, "Dwgs_User"),
        ("Cmts_User", pcbnew.Cmts_User, "Comments_User"),
        ("Eco1_User", pcbnew.Eco1_User, "ECO1"),
        ("Eco2_User", pcbnew.Eco2_User, "ECO2"),
        ("B_Fab", pcbnew.B_Fab, "Fab bottom"),
        ("F_Fab", pcbnew.F_Fab, "Fab top"),
        ("B_Adhes", pcbnew.B_Adhes, "Adhesive bottom"),
        ("F_Adhes", pcbnew.F_Adhes, "Adhesive top"),
        ("B_CrtYd", pcbnew.B_CrtYd, "Courtyard bottom"),
        ("F_CrtYd", pcbnew.F_CrtYd, "Courtyard top"),
    ]

    for layer_info in layers:
        pctl.SetLayer(layer_info[1])
        pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_SVG, layer_info[2])
        pctl.PlotLayer()

    return (boardXl, boardYl, boardWidth, boardHeight)
Пример #12
0
def RunCheck(name):
    # Load board and initialize plot controller
    #board = pcbnew.LoadBoard(name)
    board = pcbnew.GetBoard()
    pc = pcbnew.PLOT_CONTROLLER(board)
    po = pc.GetPlotOptions()
    po.SetPlotFrameRef(False)

    # Set current layer
    pc.SetLayer(pcbnew.F_Cu)

    # Plot single layer to file
    #pc.OpenPlotfile("front_copper", pcbnew.PLOT_FORMAT_SVG, "front_copper")
    #print("Plotting to " + pc.GetPlotFileName())
    #pc.PlotLayer()
    #pc.ClosePlot()

    #F.Mask
    pc.SetLayer(pcbnew.F_Mask)
    pc.OpenPlotfile("front_mask", pcbnew.PLOT_FORMAT_SVG, "front_mask")
    print("Plotting to " + pc.GetPlotFileName())
    name_mask = pc.GetPlotFileName()
    pc.PlotLayer()
    pc.ClosePlot()

    #F.SilkS
    pc.SetLayer(pcbnew.F_SilkS)
    pc.OpenPlotfile("front_silk", pcbnew.PLOT_FORMAT_SVG, "front_silk")
    print("Plotting to " + pc.GetPlotFileName())
    name_silk = pc.GetPlotFileName()
    pc.PlotLayer()
    pc.ClosePlot()

    out_silk = io.BytesIO()
    cairosvg.svg2png(url=name_silk, write_to=out_silk, scale=2.0)
    image_silk = Image.open(out_silk)
    out_mask = io.BytesIO()
    cairosvg.svg2png(url=name_mask, write_to=out_mask, scale=2.0)
    image_mask = Image.open(out_mask)

    #image_silk.show()

    pixels_silk = image_silk.load()  # create the pixel map
    pixels_mask = image_mask.load()

    # https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.paste
    #image_silk = image_silk.convert("RGB")
    for i in range(image_silk.size[0]):  # for every pixel:
        for j in range(image_silk.size[1]):
            if pixels_silk[i, j] != (0, 0, 0,
                                     0) and pixels_mask[i, j] != (0, 0, 0, 0):

                pixels_silk[i, j] = (255, 0, 0)

    image_silk = trim(image_silk)
    #image_silk.save("test.png",optimize=0)
    image_silk.show()
Пример #13
0
def generate_pcb_gerber(args):
    logging.info('Generating PCB gerber files')
    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)
    plot_controller = pcbnew.PLOT_CONTROLLER(board)

    plot_options = plot_controller.GetPlotOptions()
    plot_options.SetOutputDirectory(output_dir)
    plot_options.SetPlotFrameRef(False)

    plot_options.SetLineWidth(pcbnew.FromMM(0.1))

    plot_options.SetAutoScale(False)
    plot_options.SetScale(1)
    plot_options.SetMirror(False)

    plot_options.SetUseGerberAttributes(True)
    plot_options.SetUseGerberProtelExtensions(True)

    plot_options.SetExcludeEdgeLayer(True)
    plot_options.SetUseAuxOrigin(False)
    plot_controller.SetColorMode(True)

    plot_options.SetSubtractMaskFromSilk(True)
    plot_options.SetPlotReference(True)
    plot_options.SetPlotValue(False)

    layers = [
        ("F.Cu", pcbnew.F_Cu, "Top layer"),
        ("B.Cu", pcbnew.B_Cu, "Bottom layer"),
        ("F.Paste", pcbnew.F_Paste, "Paste top"),
        ("B.Paste", pcbnew.B_Paste, "Paste bottom"),
        ("F.SilkS", pcbnew.F_SilkS, "Silk top"),
        ("B.SilkS", pcbnew.B_SilkS, "Silk top"),
        ("F.Mask", pcbnew.F_Mask, "Mask top"),
        ("B.Mask", pcbnew.B_Mask, "Mask bottom"),
        ("Edge.Cuts", pcbnew.Edge_Cuts, "Edges"),
    ]

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

    for layer_info in layers:
        plot_controller.SetLayer(layer_info[1])
        plot_controller.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER,
                                     layer_info[2])
        plot_controller.PlotLayer()

    plot_controller.ClosePlot()
Пример #14
0
def plot_layers(f_name, plot_dir, layers=['F.Cu', 'B.Cu'], zone_refill=True):
    '''
    f_name: the .kicad_pcb file to plot
    plot_dir: output directory for the .pdf files
    layers: list of layer names to plot
    zone_refill: if True, re-calculate copper fills before plotting
    returns: dict with coordinates of bounding box containing the PCB [inches]
    '''
    if not os.path.isfile(f_name) or not os.access(f_name, os.R_OK):
        print("%s: not readable, aborting" % f_name)
        return None
    try:
        board = pcbnew.LoadBoard(f_name)
    except Exception:
        print("%s: failed to load with pcbnew, aborting" % f_name)
        return None
    # after this point, chances of failure are low

    if zone_refill:
        print('filling zones ...')
        zf = pcbnew.ZONE_FILLER(board)
        zf.Fill(board.Zones())

    boardbox = board.ComputeBoundingBox()
    bounds = {
        'x': boardbox.GetX() / 1e6 / 25.4,
        'y': boardbox.GetY() / 1e6 / 25.4,
        'W': boardbox.GetWidth() / 1e6 / 25.4,
        'H': boardbox.GetHeight() / 1e6 / 25.4,
    }
    # print('bounds [inch]:', bounds)

    pctl = pcbnew.PLOT_CONTROLLER(board)
    # pctl.SetColorMode(True)

    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(plot_dir)
    popt.SetPlotFrameRef(False)
    # popt.SetLineWidth(pcbnew.FromMM(0.15))
    # popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetMirror(False)
    # popt.SetUseGerberAttributes(True)
    popt.SetExcludeEdgeLayer(False)
    # popt.SetUseAuxOrigin(True)
    popt.SetDrillMarksType(popt.FULL_DRILL_SHAPE)

    for layer in layers:
        pctl.SetLayer(board.GetLayerID(layer))
        pctl.OpenPlotfile(layer, pcbnew.PLOT_FORMAT_PDF, layer)
        pctl.PlotLayer()
        pctl.ClosePlot()

    return bounds
Пример #15
0
    def __init__(self, board, build_directory):
        self.board = board
        self.build_directory = build_directory
        self.plot_controller = pcbnew.PLOT_CONTROLLER(board)
        self.plot_options = self.plot_controller.GetPlotOptions()
        self.plot_options.SetOutputDirectory(build_directory)

        self.plot_options.SetPlotFrameRef(False)
        self.plot_options.SetLineWidth(pcbnew.FromMM(0.35))
        self.plot_options.SetScale(1)
        self.plot_options.SetUseAuxOrigin(True)
        self.plot_options.SetMirror(False)
        self.plot_options.SetExcludeEdgeLayer(True)
Пример #16
0
    def __init__(self, board_file):
        self.name = os.path.splitext(os.path.basename(board_file))[0]
        self.board = pcbnew.LoadBoard(board_file)
        self.plot_controller = pcbnew.PLOT_CONTROLLER(self.board)
        self.plot_options = self.plot_controller.GetPlotOptions()

        self.plot_options.SetPlotFrameRef(False)
        self.plot_options.SetLineWidth(pcbnew.FromMM(0.35))
        self.plot_options.SetScale(1)
        self.plot_options.SetUseAuxOrigin(True)
        self.plot_options.SetMirror(False)
        self.plot_options.SetExcludeEdgeLayer(False)
        self.plot_controller.SetColorMode(True)
Пример #17
0
    def export_gerbers(self, layers=None, n_inner_layers=0):
        '''
        layers: list of layer names to plot
        or
        n_inner_layers: number of inner layers to plot
        '''
        if layers is None:
            l_names = ['Cu', 'Mask', 'Paste', 'SilkS']
            layers = [f + ll for ll in l_names for f in ['F.', 'B.']]
            layers += ['Edge.Cuts']
            layers += ['In{}.Cu'.format(i + 1) for i in range(n_inner_layers)]

        # -----------------------
        #  Generate Gerber files
        # -----------------------
        pctl = pcbnew.PLOT_CONTROLLER(self.board)

        # General options
        popt = pctl.GetPlotOptions()
        popt.SetOutputDirectory(self.plot_dir)
        popt.SetPlotFrameRef(False)
        popt.SetPlotValue(True)
        popt.SetPlotReference(True)
        popt.SetPlotInvisibleText(False)
        popt.SetExcludeEdgeLayer(True)
        popt.SetPlotPadsOnSilkLayer(False)
        popt.SetPlotViaOnMaskLayer(False)
        popt.SetUseAuxOrigin(False)
        popt.SetDrillMarksType(popt.NO_DRILL_SHAPE)
        popt.SetScale(1.0)
        popt.SetLineWidth(pcbnew.FromMM(0.1))  # .1 mm
        popt.SetMirror(False)
        popt.SetNegative(False)

        # Gerber options
        popt.SetUseGerberProtelExtensions(False)
        popt.SetCreateGerberJobFile(False)
        popt.SetSubtractMaskFromSilk(False)
        popt.SetGerberPrecision(6)
        popt.SetUseGerberAttributes(False)
        popt.SetIncludeGerberNetlistInfo(False)

        f_name = self.f_name.replace('.kicad_pcb', '')
        for layer in layers:
            print('> {:s}-{:s}.gbr'.format(f_name, layer.replace('.', '_')))
            pctl.SetLayer(self.board.GetLayerID(layer))
            pctl.OpenPlotfile(layer, pcbnew.PLOT_FORMAT_GERBER, layer)
            pctl.PlotLayer()
            pctl.ClosePlot()
Пример #18
0
    def plot(self, brd_file, target, invert, skip_pre):

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

        board = pcbnew.LoadBoard(brd_file)

        logger.debug("Board loaded")

        self._preflight_checks(brd_file, skip_pre)

        n = len(target)
        if n == 0 and invert:
            # Skip all targets
            logger.debug('Skipping all outputs')
            return

        for op in self.cfg.outputs:

            if (n == 0) or ((op.name in target) ^ invert):
                logger.debug("Processing output: {}".format(op.name))
                logger.info('- %s (%s) [%s]' %
                            (op.description, op.name, op.options.type))

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

                self._configure_output_dir(pc, op)

                try:
                    if self._output_is_layer(op):
                        self._do_layer_plot(board, pc, op, brd_file)
                    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)
                    elif self._output_is_bom(op):
                        self._do_bom(board, pc, op, brd_file)
                    elif self._output_is_sch_print(op):
                        self._do_sch_print(board, pc, op, brd_file)
                    elif self._output_is_pcb_print(op):
                        self._do_pcb_print(board, pc, op, brd_file)
                    else:
                        plot_error("Don't know how to plot type " +
                                   op.options.type)
                except PlotError as e:
                    plot_error("In section '" + op.name + "' (" +
                               op.options.type + "): " + str(e))
            else:
                logger.debug('Skipping %s output', op.name)
def plotLayers(
    board,
    gerberDirPath,
    useAuxOrigin,
    gerberProtelExtensions,
    layerRenameRules,
    boardProjectName,
):
    targetLayerCount = board.GetCopperLayerCount() + 5
    pc = pcbnew.PLOT_CONTROLLER(board)
    po = pc.GetPlotOptions()

    po.SetOutputDirectory(gerberDirPath)
    po.SetPlotValue(True)
    po.SetPlotReference(True)
    po.SetExcludeEdgeLayer(False)
    if hasattr(po, "SetLineWidth"):
        po.SetLineWidth(pcbnew.FromMM(0.1))
    else:
        po.SetSketchPadLineWidth(pcbnew.FromMM(0.1))
    po.SetSubtractMaskFromSilk(True)
    po.SetUseAuxOrigin(useAuxOrigin)
    po.SetUseGerberProtelExtensions(gerberProtelExtensions)

    plotFiles = []
    for i in range(targetLayerCount):
        layerId = layers[i][0]
        layerTypeName = layers[i][1]
        pc.SetLayer(layerId)
        pc.OpenPlotfile(layerTypeName, pcbnew.PLOT_FORMAT_GERBER,
                        layerTypeName)
        pc.PlotLayer()
        plotFiles.append(pc.GetPlotFileName())
    pc.ClosePlot()

    if len(layerRenameRules) > 0:
        for i in range(targetLayerCount):
            plotFilePath = plotFiles[i]
            layerId = layers[i][0]
            if layerId in layerRenameRules:
                newFileName = layerRenameRules[layerId]
                newFileName = newFileName.replace('[boardProjectName]',
                                                  boardProjectName)
                newFilePath = '%s/%s' % (gerberDirPath, newFileName)
                renameFile(plotFilePath, newFilePath)
Пример #20
0
    def Run(self):
        # config = Config()
        pcb_file_name = pcbnew.GetBoard().GetFileName()
        if not pcb_file_name:
            ibom.logerror(
                'Please save the board file before generating manufactoring data.'
            )
            return
        print(pcb_file_name)

        board = pcbnew.LoadBoard(pcb_file_name)
        pctl = pcbnew.PLOT_CONTROLLER(board)
        popt = pctl.GetPlotOptions()

        popt.SetOutputDirectory("export/")
        # popt.SetOutputDirectory(sys.argv[2])

        plot_pdf.generatePdf(pctl, popt)
        popt.SetMirror(False)
        rtlab.generateGerber(pctl, popt, board)
Пример #21
0
    def plot_assembly_drawings(self, pcb, top_en, bottom_en):
        "plot assembly drawings"

        pctl = pcbnew.PLOT_CONTROLLER(pcb)

        popt = pctl.GetPlotOptions()

        popt.SetOutputDirectory(self.pcb_assembly_path)

        # Set some important plot options:
        popt.SetPlotFrameRef(True)
        popt.SetLineWidth(pcbnew.FromMM(0.1))

        popt.SetAutoScale(False)
        popt.SetScale(1)
        popt.SetMirror(False)
        popt.SetExcludeEdgeLayer(False)
        popt.SetPlotValue(False)
        popt.SetPlotReference(True)

        if (top_en):
            #Create a pdf file of the top fab Layer
            pctl.SetLayer(pcbnew.F_Fab)
            pctl.OpenPlotfile("Assembly_TOP", pcbnew.PLOT_FORMAT_PDF,
                              "Assembly_TOP")
            pctl.PlotLayer()

        if (bottom_en):
            popt.SetMirror(True)
            #Create a pdf file of the bottom fab Layer
            pctl.SetLayer(pcbnew.B_Fab)
            pctl.OpenPlotfile("Assembly_BOTTOM", pcbnew.PLOT_FORMAT_PDF,
                              "Assembly_BOTTOM")
            pctl.PlotLayer()

        pctl.ClosePlot()
Пример #22
0
def generate_gerber(name, output_dir):
    board = pcbnew.LoadBoard(name)
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()

    ###########################################################################
    # Output options
    plot_format = pcbnew.PLOT_FORMAT_GERBER
    popt.SetOutputDirectory(output_dir)

    ###########################################################################
    # Included Layers:
    layers = [
        {
            'layer': pcbnew.F_Cu,
            'suffix': 'F.Cu'
        },
        {
            'layer': pcbnew.B_Cu,
            'suffix': 'B.Cu'
        },
        {
            'layer': pcbnew.F_SilkS,
            'suffix': 'F.SilkS'
        },
        {
            'layer': pcbnew.B_SilkS,
            'suffix': 'B.SilkS'
        },
        {
            'layer': pcbnew.B_Paste,
            'suffix': 'B.Paste'
        },
        {
            'layer': pcbnew.F_Paste,
            'suffix': 'F.Paste'
        },
        {
            'layer': pcbnew.B_Mask,
            'suffix': 'B.Mask'
        },
        {
            'layer': pcbnew.F_Mask,
            'suffix': 'F.Mask'
        },
        {
            'layer': pcbnew.Edge_Cuts,
            'suffix': 'Edge.Cuts'
        },
    ]

    ###########################################################################
    # General Options:
    popt.SetPlotFrameRef(False)
    popt.SetPlotValue(True)
    popt.SetPlotReference(True)
    # popt.SetPlotInvisibleText(False)
    # popt.SetPlotViaOnMaskLayer(False)
    popt.SetExcludeEdgeLayer(True)
    popt.SetPlotPadsOnSilkLayer(False)
    popt.SetUseAuxOrigin(False)

    # popt.SetMirror(False)
    # popt.SetNegative(False)

    ###########################################################################
    popt.SetDrillMarksType(popt.NO_DRILL_SHAPE)
    popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetPlotMode(pcbnew.FILLED)
    popt.SetLineWidth(pcbnew.FromMM(0.1))

    ###########################################################################
    # Gerber Options:
    popt.SetUseGerberProtelExtensions(True)
    # popt.SetUseGerberAttributes(True)

    popt.SetCreateGerberJobFile(False)
    popt.SetSubtractMaskFromSilk(False)

    # popt.SetFormat()

    ###########################################################################
    # Generate files now

    for l in layers:
        pctl.SetLayer(l['layer'])
        # pctl.OpenPlotfile()
        pctl.OpenPlotfile(l['suffix'], pcbnew.PLOT_FORMAT_GERBER, l['layer'])
        print(l['suffix'])
        pctl.PlotLayer()

    pctl.ClosePlot()
Пример #23
0
            def OnExec(self, e):
                try:
                    self.settings = self.editor.Get()
                    global zip_fname
                    board = pcbnew.GetBoard()
                    board_fname = board.GetFileName()
                    board_dir = os.path.dirname(board_fname)
                    board_basename = (os.path.splitext(
                        os.path.basename(board_fname)))[0]
                    gerber_dir = '%s/%s' % (board_dir,
                                            self.gerberdir.GetValue())
                    zip_fname = '%s/%s' % (gerber_dir,
                                           self.zipfilename.GetValue().replace(
                                               '*', board_basename))
                    if not os.path.exists(gerber_dir):
                        os.mkdir(gerber_dir)
                    refill(board)
                    zipfiles = []
                    # PLOT
                    message('PlotStart')
                    pc = pcbnew.PLOT_CONTROLLER(board)
                    po = pc.GetPlotOptions()

                    po.SetOutputDirectory(gerber_dir)
                    po.SetPlotFrameRef(
                        self.settings.get('PlotBorderAndTitle', False))
                    po.SetPlotValue(
                        self.settings.get('PlotFootprintValues', True))
                    po.SetPlotReference(
                        self.settings.get('PlotFootprintReferences', True))
                    po.SetPlotInvisibleText(
                        self.settings.get('ForcePlotInvisible', False))
                    po.SetExcludeEdgeLayer(
                        self.settings.get('ExcludeEdgeLayer', True))
                    if hasattr(po, 'SetPlotPadsOnSilkLayer'):
                        po.SetPlotPadsOnSilkLayer(not self.settings.get(
                            'ExcludePadsFromSilk', False))
                    po.SetPlotViaOnMaskLayer(
                        self.settings.get('DoNotTentVias', False))
                    if hasattr(po, 'SetUseAuxOrigin'):
                        po.SetUseAuxOrigin(
                            self.settings.get('UseAuxOrigin', False))
                    if hasattr(po, 'SetLineWidth'):
                        po.SetLineWidth(
                            FromMM(float(self.settings.get('LineWidth'))))
                    po.SetSubtractMaskFromSilk(
                        self.settings.get('SubtractMaskFromSilk', True))
                    po.SetUseGerberX2format(
                        self.settings.get('UseExtendedX2format', False))
                    po.SetIncludeGerberNetlistInfo(
                        self.settings.get('IncludeNetlistInfo', False))
                    po.SetGerberPrecision(6 if self.settings.get(
                        'CoodinateFormat46', True) else 5)
                    #                   SetDrillMarksType() : Draw Drill point to Cu layers if 1 (default)
                    #                                         But seems set to 0 in Plot Dialog
                    po.SetDrillMarksType(0)
                    layer = self.settings.get('Layers', {})
                    forcedel(zip_fname)
                    for i in range(len(layer_list)):
                        layer_list[i]['fname'] = ''
                    for i in layer:
                        fnam = layer[i]
                        id = getid(i)
                        if (len(fnam) > 0 and board.IsLayerEnabled(id)):
                            pc.SetLayer(id)
                            pc.OpenPlotfile(i, PLOT_FORMAT_GERBER, i)
                            pc.PlotLayer()
                            pc.ClosePlot()
                            targetname = '%s/%s' % (
                                gerber_dir, fnam.replace('*', board_basename))
                            forcedel(targetname)
                            forceren(pc.GetPlotFileName(), targetname)
                            layer_list[getindex(i)]['fname'] = targetname
                            zipfiles.append(targetname)
                    message('Drill')
                    # DRILL
                    drill_fname = ''
                    drill_map_fname = ''
                    npth_fname = ''
                    npth_map_fname = ''
                    drill_report_fname = ''
                    drill = self.settings.get('Drill', {})
                    fname = drill.get('Drill', '')
                    if len(fname) > 0:
                        drill_fname = '%s/%s' % (
                            gerber_dir, fname.replace('*', board_basename))
                        forcedel(drill_fname)
                    fname = drill.get('DrillMap', '')
                    if len(fname) > 0:
                        drill_map_fname = '%s/%s' % (
                            gerber_dir, fname.replace('*', board_basename))
                        forcedel(drill_map_fname)
                    fname = drill.get('NPTH', '')
                    if len(fname) > 0:
                        npth_fname = '%s/%s' % (
                            gerber_dir, fname.replace('*', board_basename))
                        forcedel(npth_fname)
                    fname = drill.get('NPTHMap', '')
                    if len(fname) > 0:
                        npth_map_fname = '%s/%s' % (
                            gerber_dir, fname.replace('*', board_basename))
                        forcedel(npth_map_fname)
                    fname = drill.get('Report', '')
                    if len(fname) > 0:
                        drill_report_fname = '%s/%s' % (
                            gerber_dir, fname.replace('*', board_basename))
                        forcedel(drill_report_fname)

                    ew = EXCELLON_WRITER(board)
                    excellon_format = EXCELLON_WRITER.DECIMAL_FORMAT
                    zeros = self.settings.get('ZerosFormat')
                    if zeros.get('SuppressLeading'):
                        excellon_format = EXCELLON_WRITER.SUPPRESS_LEADING
                    if zeros.get('SuppressTrailing'):
                        excellon_format = EXCELLON_WRITER.SUPPRESS_TRAILING
                    if zeros.get('KeepZeros'):
                        excellon_format = EXCELLON_WRITER.KEEP_ZEROS
                    ew.SetFormat(self.settings.get('DrillUnitMM', True),
                                 excellon_format, 3, 3)
                    offset = wxPoint(0, 0)
                    if self.settings.get('UseAuxOrigin', False):
                        if hasattr(board, 'GetAuxOrigin'):
                            offset = board.GetAuxOrigin()
                        else:
                            bds = board.GetDesignSettings()
                            offset = bds.m_AuxOrigin
                    ew.SetOptions(self.settings.get('MirrorYAxis', False),
                                  self.settings.get('MinimalHeader', False),
                                  offset,
                                  self.settings.get('MergePTHandNPTH', False))
                    ew.SetRouteModeForOvalHoles(
                        self.settings.get('RouteModeForOvalHoles'))
                    map_format = pcbnew.PLOT_FORMAT_GERBER
                    map_ext = 'gbr'
                    map = self.settings.get('MapFileFormat')
                    if map.get('HPGL'):
                        map_format = pcbnew.PLOT_FORMAT_HPGL
                        map_ext = 'plt'
                    if map.get('PostScript'):
                        map_format = pcbnew.PLOT_FORMAT_POST
                        map_ext = 'ps'
                    if map.get('Gerber'):
                        map_format = pcbnew.PLOT_FORMAT_GERBER
                        map_ext = 'gbr'
                    if map.get('DXF'):
                        map_format = pcbnew.PLOT_FORMAT_DXF
                        map_ext = 'dxf'
                    if map.get('SVG'):
                        map_format = pcbnew.PLOT_FORMAT_SVG
                        map_ext = 'svg'
                    if map.get('PDF'):
                        map_format = pcbnew.PLOT_FORMAT_PDF
                        map_ext = 'pdf'
                    ew.SetMapFileFormat(map_format)
                    enable_map = len(drill_map_fname) > 0 or len(
                        npth_map_fname) > 0
                    message('MapFile')
                    ew.CreateDrillandMapFilesSet(gerber_dir, True, enable_map)
                    if self.settings.get('MergePTHandNPTH', False):
                        if drill_fname:
                            forceren(
                                '%s/%s.drl' % (gerber_dir, board_basename),
                                drill_fname)
                            zipfiles.append(drill_fname)
                        if drill_map_fname:
                            forceren(
                                '%s/%s-drl_map.%s' %
                                (gerber_dir, board_basename, map_ext),
                                drill_map_fname)
                            zipfiles.append(drill_map_fname)
                    else:
                        if drill_fname:
                            forceren(
                                '%s/%s-PTH.drl' % (gerber_dir, board_basename),
                                drill_fname)
                            zipfiles.append(drill_fname)
                        if drill_map_fname:
                            forceren(
                                '%s/%s-PTH-drl_map.%s' %
                                (gerber_dir, board_basename, map_ext),
                                drill_map_fname)
                            zipfiles.append(drill_map_fname)
                        if npth_fname:
                            forceren(
                                '%s/%s-NPTH.drl' %
                                (gerber_dir, board_basename), npth_fname)
                            zipfiles.append(npth_fname)
                        if npth_map_fname:
                            forceren(
                                '%s/%s-NPTH-drl_map.gbr' %
                                (gerber_dir, board_basename), npth_map_fname)
                            zipfiles.append(npth_map_fname)
                    if drill_report_fname:
                        ew.GenDrillReportFile(drill_report_fname)
                        zipfiles.append(drill_report_fname)

                # OptionalFile
                    message('optional')
                    files = self.settings.get('OptionalFiles', [])
                    for n in range(len(files)):
                        if (len(files[n]['name'])):
                            optional_fname = '%s/%s' % (gerber_dir,
                                                        files[n]['name'])
                            optional_content = files[n]['content']
                            optional_content = optional_content.replace(
                                '${basename}', board_basename)
                            for i in range(len(layer_list)):
                                kpath = '${filepath(' + layer_list[i][
                                    'name'] + ')}'
                                kname = '${filename(' + layer_list[i][
                                    'name'] + ')}'
                                path = layer_list[i]['fname']
                                name = os.path.basename(path)
                                optional_content = optional_content.replace(
                                    kname, name)
                            if optional_fname:
                                with codecs.open(optional_fname, 'w',
                                                 'utf-8') as f:
                                    f.write(optional_content)
                            zipfiles.append(optional_fname)

                # ZIP
                    message('Zip')
                    with zipfile.ZipFile(
                            zip_fname, 'w',
                            compression=zipfile.ZIP_DEFLATED) as f:
                        for i in range(len(zipfiles)):
                            fnam = zipfiles[i]
                            if os.path.exists(fnam):
                                f.write(fnam, os.path.basename(fnam))
                    alert(getstr('COMPLETE') % zip_fname, wx.ICON_INFORMATION)
                except Exception:
                    s = traceback.format_exc(chain=False)
                    print(s)
                    alert(s, wx.ICON_ERROR)
                e.Skip()
Пример #24
0
#!/usr/bin/env python3
import sys
# from pcbnew import *
import pcbnew

import plot_pdf
import rtlab
# http://scottbezek.blogspot.com/2016/04/scripting-kicad-pcbnew-exports.html

filename = sys.argv[1]  #e.g left-main/left-main.kicad_pcb

board = pcbnew.LoadBoard(filename)

pctl = pcbnew.PLOT_CONTROLLER(board)

popt = pctl.GetPlotOptions()

# popt.SetOutputDirectory("plot/")
popt.SetOutputDirectory(sys.argv[2])

plot_pdf.generatePdf(pctl, popt)

popt.SetMirror(False)

rtlab.generateGerber(pctl, popt, board)
Пример #25
0
    def screenshot(self):
        print("Taking a screenshot")
        self.board = pcbnew.GetBoard()
        board_path = self.board.GetFileName()
        board_filename = os.path.basename(board_path)
        board_filename_noex = os.path.splitext(board_filename)[0]
        project_folder = os.path.dirname(board_path)
        timelapse_folder = board_filename_noex + '-timelapse'
        timelapse_folder_path = os.path.join(project_folder, timelapse_folder)
        if not os.path.exists(timelapse_folder_path):
            print('Timelapse folder does not exist. creating one now')
            os.mkdir(timelapse_folder_path)
            print('Timelapse folder created')

        timelapse_files = os.listdir(timelapse_folder_path)
        timelapse_number = extract_biggest_number(timelapse_files)
        pc = pcbnew.PLOT_CONTROLLER(self.board)
        po = pc.GetPlotOptions()
        po.SetOutputDirectory(timelapse_folder_path)
        po.SetPlotFrameRef(False)
        po.SetLineWidth(pcbnew.FromMM(0.35))
        po.SetScale(1)
        po.SetUseAuxOrigin(True)
        po.SetMirror(False)
        po.SetExcludeEdgeLayer(True)
        # Set current layer

        # Plot single layer to file

        timelapse_number += 1
        processed_svg_files = []
        for layer in layers:
            pc.SetLayer(layer['layer'])
            layer['layer']
            pc.OpenPlotfile(
                '-' + layer['name'] + '-' + str(timelapse_number).zfill(4),
                pcbnew.PLOT_FORMAT_SVG, layer['name'])
            pc.PlotLayer()
            pc.ClosePlot()
            output_filename = pc.GetPlotFileName()
            processor = SvgProcessor(output_filename)

            def colorize(original):
                if original.lower() == '#000000':
                    return layer['color']
                return original

            processor.apply_color_transform(colorize)
            processor.wrap_with_group({
                'opacity': str(layer['alpha']),
            })

            output_filename2 = os.path.join(
                timelapse_folder_path,
                'processed-' + os.path.basename(output_filename))
            processor.write(output_filename2)
            processed_svg_files.append((output_filename2, processor))
            os.remove(output_filename)

        final_svg = os.path.join(
            timelapse_folder_path, board_filename_noex + '-' +
            str(timelapse_number).zfill(4) + '.svg')
        shutil.copyfile(processed_svg_files[0][0], final_svg)
        output_processor = SvgProcessor(final_svg)
        for processed_svg_file, processor in processed_svg_files:
            output_processor.import_groups(processor)
            os.remove(processed_svg_file)
        output_processor.write(final_svg)
Пример #26
0
def convert(pcb, dir):
    board = pcb
    plotDir = os.path.abspath(dir)

    # prepare the gerber job file
    gen_job_file = False

    pctl = pcbnew.PLOT_CONTROLLER(board)

    popt = pctl.GetPlotOptions()

    popt.SetOutputDirectory(plotDir)

    # Set some important plot options (see pcb_plot_params.h):
    popt.SetPlotFrameRef(False)  # do not change it
    popt.SetLineWidth(pcbnew.FromMM(0.35))

    popt.SetAutoScale(False)  # do not change it
    popt.SetScale(1)  # do not change it
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(True)
    popt.SetIncludeGerberNetlistInfo(True)
    popt.SetCreateGerberJobFile(gen_job_file)
    popt.SetUseGerberProtelExtensions(False)
    popt.SetExcludeEdgeLayer(False)
    popt.SetScale(1)
    popt.SetUseAuxOrigin(True)

    # This by gerbers only
    popt.SetSubtractMaskFromSilk(False)
    # Disable plot pad holes
    popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)
    # Skip plot pad NPTH when possible: when drill size and shape == pad size and shape
    # usually sel to True for copper layers
    popt.SetSkipPlotNPTH_Pads(False)

    # prepare the gerber job file
    jobfile_writer = pcbnew.GERBER_JOBFILE_WRITER(board)

    # Once the defaults are set it become pretty easy...
    # I have a Turing-complete programming language here: I'll use it...
    # param 0 is a string added to the file base name to identify the drawing
    # param 1 is the layer ID
    # param 2 is a comment
    plot_plan = [
        ("F_Cu", pcbnew.F_Cu, "Top layer"),
        ("B_Cu", pcbnew.B_Cu, "Bottom layer"),
        ("B_Paste", pcbnew.B_Paste, "Paste Bottom"),
        ("F_Paste", pcbnew.F_Paste, "Paste top"),
        ("F_SilkS", pcbnew.F_SilkS, "Silk top"),
        ("B_SilkS", pcbnew.B_SilkS, "Silk top"),
        ("B_Mask", pcbnew.B_Mask, "Mask bottom"),
        ("F_Mask", pcbnew.F_Mask, "Mask top"),
        ("Edge_Cuts", pcbnew.Edge_Cuts, "Edges"),
    ]

    for layer_info in plot_plan:
        if layer_info[1] <= pcbnew.B_Cu:
            popt.SetSkipPlotNPTH_Pads(True)
        else:
            popt.SetSkipPlotNPTH_Pads(False)

        pctl.SetLayer(layer_info[1])
        pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER,
                          layer_info[2])
        print 'plot %s' % pctl.GetPlotFileName()
        if gen_job_file == True:
            jobfile_writer.AddGbrFile(layer_info[1],
                                      os.path.basename(pctl.GetPlotFileName()))
        if pctl.PlotLayer() == False:
            print "plot error"

    # generate internal copper layers, if any
    lyrcnt = board.GetCopperLayerCount()

    for innerlyr in range(1, lyrcnt - 1):
        popt.SetSkipPlotNPTH_Pads(True)
        pctl.SetLayer(innerlyr)
        lyrname = 'In%s_Cu' % innerlyr
        pctl.OpenPlotfile(lyrname, pcbnew.PLOT_FORMAT_GERBER, "inner")
        print 'plot %s' % pctl.GetPlotFileName()
        if pctl.PlotLayer() == False:
            print "plot error"

    # At the end you have to close the last plot, otherwise you don't know when
    # the object will be recycled!
    pctl.ClosePlot()

    # Fabricators need drill files.
    # sometimes a drill map file is asked (for verification purpose)
    drlwriter = pcbnew.EXCELLON_WRITER(board)
    drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)

    mirror = False
    minimalHeader = False
    offset = pcbnew.wxPoint(0, 0)
    # False to generate 2 separate drill files (one for plated holes, one for non plated holes)
    # True to generate only one drill file
    mergeNPTH = True
    drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

    metricFmt = True
    drlwriter.SetFormat(metricFmt)

    genDrl = True
    genMap = True
    print 'create drill and map files in %s' % pctl.GetPlotDirName()
    drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), genDrl, genMap)
Пример #27
0
def main():
    if len(sys.argv) <= 1 or len(sys.argv) >= 3:
        print("Usage: " + sys.argv[0] + " <project name>")
        exit(1)

    cwd = os.getcwd()
    projectname = sys.argv[1]
    board = pcbnew.LoadBoard(cwd + "/" + projectname + ".kicad_pcb")
    pc = pcbnew.PLOT_CONTROLLER(board)
    po = pc.GetPlotOptions()
    # Set General Options:
    po.SetOutputDirectory(cwd)
    po.SetPlotFrameRef(False)
    po.SetPlotValue(True)
    po.SetPlotReference(True)
    po.SetPlotInvisibleText(False)
    po.SetPlotViaOnMaskLayer(True)
    po.SetExcludeEdgeLayer(False)
    #po.SetPlotPadsOnSilkLayer(PLOT_PADS_ON_SILK_LAYER)
    #po.SetUseAuxOrigin(PLOT_USE_AUX_ORIGIN)
    po.SetMirror(False)
    #po.SetNegative(PLOT_NEGATIVE)
    #po.SetDrillMarksType(PLOT_DRILL_MARKS_TYPE)
    #po.SetScale(PLOT_SCALE)
    po.SetAutoScale(True)
    #po.SetPlotMode(PLOT_MODE)
    #po.SetLineWidth(pcbnew.FromMM(PLOT_LINE_WIDTH))
    
    # Set Gerber Options
    #po.SetUseGerberAttributes(GERBER_USE_GERBER_ATTRIBUTES)
    #po.SetUseGerberProtelExtensions(GERBER_USE_GERBER_PROTEL_EXTENSIONS)
    #po.SetCreateGerberJobFile(GERBER_CREATE_GERBER_JOB_FILE)
    #po.SetSubtractMaskFromSilk(GERBER_SUBTRACT_MASK_FROM_SILK)
    #po.SetIncludeGerberNetlistInfo(GERBER_INCLUDE_GERBER_NETLIST_INFO)
    
    # plot layers

    dict_layerInfo = ({
        "F_Cu": pcbnew.F_Cu,
        "F_Mask": pcbnew.F_Mask,
        "F_Paste": pcbnew.F_Paste,
        "F_SilkS": pcbnew.F_SilkS,
        "B_Cu": pcbnew.B_Cu,
        "B_Mask": pcbnew.B_Mask,
        "B_Paste": pcbnew.B_Paste,
        "B_SilkS": pcbnew.B_SilkS,
        "Edge_Cuts": pcbnew.Edge_Cuts,
        "Eco1_User": pcbnew.Eco1_User,
        "Eco2_User": pcbnew.Eco2_User
    })
    
    for key in dict_layerInfo :
        val = dict_layerInfo[key]
        pc.SetLayer(val)
        sheetDesc = key
        if val not in [ pcbnew.Edge_Cuts, pcbnew.Eco1_User, pcbnew.Eco2_User ]:
            sheetDesc = sheetDesc.replace("F_", "Front ").replace("B_", "Back ") + " Layer"
        pc.OpenPlotfile(key, pcbnew.PLOT_FORMAT_GERBER, sheetDesc)
        pc.PlotLayer()
        pc.ClosePlot()
    
    # generate drill file
    # options:
    METRIC = True
    ZERO_FORMAT = pcbnew.GENDRILL_WRITER_BASE.DECIMAL_FORMAT
    INTEGER_DIGITS = 3
    MANTISSA_DIGITS = 3
    MIRROR_Y_AXIS = False
    HEADER = True
    OFFSET = pcbnew.wxPoint(0,0)
    MERGE_PTH_NPTH = False
    DRILL_FILE = True
    MAP_FILE = False
    REPORTER = None

    drill_writer = pcbnew.EXCELLON_WRITER(board)
    drill_writer.SetFormat(METRIC, ZERO_FORMAT, INTEGER_DIGITS, MANTISSA_DIGITS)
    drill_writer.SetOptions(MIRROR_Y_AXIS, HEADER, OFFSET, MERGE_PTH_NPTH)
    drill_writer.CreateDrillandMapFilesSet(cwd, DRILL_FILE, MAP_FILE, REPORTER)
Пример #28
0
def main(args):
    # kicad helpfully avoids simply writing to named files
    # and mangles everything based on the name of the input
    # file. :(
    # hope this never changes...
    basename, _junk = os.path.splitext(os.path.basename(args.pcb))

    board = pcb.LoadBoard(args.pcb)
    pctrl = pcb.PLOT_CONTROLLER(board)
    popt = pctrl.GetPlotOptions()

    # Default options
    popt.SetPlotFrameRef(False)
    popt.SetLineWidth(pcb.FromMM(0.35))

    popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(True)
    popt.SetUseGerberProtelExtensions(False)
    popt.SetExcludeEdgeLayer(False)
    popt.SetScale(1)
    popt.SetUseAuxOrigin(True)

    popt.SetSubtractMaskFromSilk(False)

    # layers are number from front F_Cu==0, B_Cu==31
    # inner layers are 1..30
    # count includes B_Cu
    ncu = board.GetCopperLayerCount()
    log.info("Design has %d Cu layers", ncu)
    if ncu == 1:
        log.warn("Not tested w/ single layer board")
    assert ncu >= 1, "No Cu layers?"

    with TempDir() as dname, ZipFile(args.gbrzip, mode='w') as zip:
        popt.SetOutputDirectory(dname)

        generated = []

        for ext, layer, desc in oshnames:
            if layer >= ncu - 1 and layer < pcb.B_Cu:
                log.info("No %s", desc)
                continue  # skip unused inner

            pctrl.SetLayer(layer)
            pctrl.OpenPlotfile(ext, pcb.PLOT_FORMAT_GERBER, desc)
            if not pctrl.PlotLayer():
                log.error("Failed to write layer %s", desc)
            generated.append((os.path.join(dname,
                                           "%s-%s.gbr" % (basename, ext)),
                              '%s.%s' % (basename, ext)))

        pctrl.ClosePlot()
        # files actually generated at this point

        for inf, outf in generated:
            zip.write(inf, outf)

        drill = pcb.EXCELLON_WRITER(board)
        drill.SetMapFileFormat(pcb.PLOT_FORMAT_GERBER)

        mirror = False
        minimalHeader = False
        offset = pcb.wxPoint(0, 0)
        merge = True
        drill.SetOptions(mirror, minimalHeader, offset, merge)

        metricFmt = True
        drill.SetFormat(metricFmt)

        # can't use drlwriter.CreateDrillFile()
        # as this wants swig wrapped FILE*
        # and I can't see how to create one (can't just use ctypes)

        genDrl = True
        genMap = True
        drill.CreateDrillandMapFilesSet(dname, genDrl, genMap)
        zip.write(os.path.join(dname, "%s.drl" % basename),
                  "%s.XLN" % basename)

        zip.write(os.path.join(dname, "%s-drl_map.gbr" % basename),
                  "%s.fab.gbr" % basename)
Пример #29
0
def main():
    # load command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--pcb')
    parser.add_argument('--plot')
    args = parser.parse_args()

    # load board
    board = pcbnew.LoadBoard(args.pcb)

    # get plot options
    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()

    # set up output directory
    plotDir = args.plot + '/'
    popt.SetOutputDirectory(plotDir)

    # Set plot options according to:
    # http://docs.oshpark.com/design-tools/kicad/generating-kicad-gerbers/

    # Options
    popt.SetPlotFrameRef(False)
    popt.SetPlotPadsOnSilkLayer(False)
    popt.SetPlotValue(True)
    popt.SetPlotReference(True)
    popt.SetPlotInvisibleText(False)
    popt.SetPlotViaOnMaskLayer(True)
    popt.SetExcludeEdgeLayer(True)
    popt.SetMirror(False)
    popt.SetNegative(False)
    popt.SetUseAuxOrigin(False)

    popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)
    popt.SetAutoScale(False)
    popt.SetScale(1)
    # TODO: Plot mode = filled
    popt.SetLineWidth(pcbnew.FromMM(0.1))

    # Gerber options
    popt.SetUseGerberProtelExtensions(True)
    popt.SetUseGerberAttributes(False)
    popt.SetSubtractMaskFromSilk(False)
    popt.SetGerberPrecision(6)

    # Layers to be plotted
    plot_plan = [
        ("CuTop", pcbnew.F_Cu, "Top layer"),
        ("CuBottom", pcbnew.B_Cu, "Bottom layer"),
        ("EdgeCuts", pcbnew.Edge_Cuts, "Edges")]

    # Plot the layers
    for layer_info in plot_plan:
        pctl.SetLayer(layer_info[1])
        pctl.OpenPlotfile(layer_info[0],
                          pcbnew.PLOT_FORMAT_GERBER,
                          layer_info[2])
        fullname = pctl.GetPlotFileName()
        basename = os.path.basename(fullname)
        print 'Plotting %s' % basename
        if not pctl.PlotLayer():
            raise Exception('Plotting error.')

    # Done with plotting gerbers
    pctl.ClosePlot()

    drlwriter = pcbnew.EXCELLON_WRITER(board)

    # Set Excellon format according to:
    # http://docs.oshpark.com/design-tools/kicad/generating-kicad-gerbers/

    # Drill units, zeros format
    metricFmt = False
    zerosFmt = pcbnew.EXCELLON_WRITER.DECIMAL_FORMAT
    drlwriter.SetFormat(metricFmt, zerosFmt)

    # Drill map format
    drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_POST)

    # Drill file options
    mirror = False
    minimalHeader = False
    mergeNPTH = True
    offset = pcbnew.wxPoint(0, 0)
    drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

    genDrl = True
    genMap = False
    pctl.GetPlotDirName()
    print 'Creating drill file.'
    drlwriter.CreateDrillandMapFilesSet(plotDir, genDrl, genMap)
Пример #30
0
def kicad_file_to_gerber_archive_file(input_path, output_path):
    board = pcbnew.LoadBoard(input_path)

    pctl = pcbnew.PLOT_CONTROLLER(board)

    popt = pctl.GetPlotOptions()
    popt.SetPlotFrameRef(False)
    popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(False)
    popt.SetExcludeEdgeLayer(True)
    popt.SetScale(1)
    popt.SetUseAuxOrigin(True)
    popt.SetNegative(False)
    popt.SetPlotReference(True)
    popt.SetPlotValue(True)
    popt.SetPlotInvisibleText(False)
    popt.SetSubtractMaskFromSilk(True)
    popt.SetMirror(False)
    popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)

    # TODO(kleinpa): Will JLCPCB accept file without this set?
    popt.SetUseGerberProtelExtensions(True)

    plot_plan = [("F_Cu", pcbnew.F_Cu, "Top layer"),
                 ("B_Cu", pcbnew.B_Cu, "Bottom layer"),
                 ("B_Mask", pcbnew.B_Mask, "Mask Bottom"),
                 ("F_Mask", pcbnew.F_Mask, "Mask top"),
                 ("B_Paste", pcbnew.B_Paste, "Paste Bottom"),
                 ("F_Paste", pcbnew.F_Paste, "Paste Top"),
                 ("F_SilkS", pcbnew.F_SilkS, "Silk Top"),
                 ("B_SilkS", pcbnew.B_SilkS, "Silk Bottom"),
                 ("Edge_Cuts", pcbnew.Edge_Cuts, "Edges")]

    for layer in range(1, board.GetCopperLayerCount() - 1):
        plot_plan += (f"inner{layer}", layer, "inner")

    with tempfile.TemporaryDirectory() as temp_path:
        popt.SetOutputDirectory(temp_path)

        # Plot layers
        for suffix, layer, description in plot_plan:
            pctl.SetLayer(layer)
            pctl.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, description)
            pctl.PlotLayer()
            pctl.ClosePlot()

        # Generate drill file
        drlwriter = pcbnew.EXCELLON_WRITER(board)
        drlwriter.SetMapFileFormat(aMapFmt=pcbnew.PLOT_FORMAT_GERBER)
        drlwriter.SetOptions(aMirror=False,
                             aMinimalHeader=False,
                             aOffset=pcbnew.wxPoint(0, 0),
                             aMerge_PTH_NPTH=True)
        formatMetric = True
        drlwriter.SetFormat(formatMetric)
        drlwriter.CreateDrillandMapFilesSet(aPlotDirectory=temp_path,
                                            aGenDrill=True,
                                            aGenMap=False)

        # Copy files from output directory to in-memory zip file
        fp = io.BytesIO()
        with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as z:
            for root, dirs, files in os.walk(temp_path):
                for file in files:
                    z.write(
                        os.path.join(root, file),
                        # TODO(kleinpa): Required for JLCPCB, any alternative?
                        file.replace("gm1", "gko"))
        fp.seek(0)
        return fp