예제 #1
0
    def plot_drill(self):
        board_name = os.path.splitext(
            os.path.basename(self.board.GetFileName()))[0]
        logger.info('Plotting drill file')
        drill_writer = pcbnew.EXCELLON_WRITER(self.board)
        drill_writer.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)

        mirror = False
        minimalHeader = False
        offset = pcbnew.wxPoint(0, 0)
        merge_npth = True
        drill_writer.SetOptions(mirror, minimalHeader, offset, merge_npth)

        metric_format = True
        drill_writer.SetFormat(metric_format)

        generate_drill = True
        generate_map = True
        drill_writer.CreateDrillandMapFilesSet(self.build_directory,
                                               generate_drill, generate_map)

        drill_file_name = os.path.join(self.build_directory,
                                       '%s.drl' % (board_name, ))

        map_file_name = os.path.join(self.build_directory,
                                     '%s-drl_map.pdf' % (board_name, ))
        return drill_file_name, map_file_name
예제 #2
0
def plotDrill(
        board,
        gerberDirPath,
        boardProjectName,
        excellonFormat,
        useAuxOrigin,
        drillMinimalHeader,
        drillMergeNpth,
        drillExtensionRenameTo,
):
    ew = pcbnew.EXCELLON_WRITER(board)
    ew.SetFormat(True, excellonFormat, 3, 3)
    offset = pcbnew.wxPoint(0,0)
    if useAuxOrigin:
        offset = board.GetAuxOrigin()
    ew.SetOptions(False, drillMinimalHeader, offset, drillMergeNpth)
    ew.CreateDrillandMapFilesSet(gerberDirPath,True,False)
    if drillExtensionRenameTo is not None:
        if drillMergeNpth:
            renameFileIfExists('%s/%s.drl' % (gerberDirPath, boardProjectName),
                               '%s/%s.%s' % (gerberDirPath, boardProjectName, drillExtensionRenameTo))
        else:
            renameFileIfExists('%s/%s-PTH.drl' % (gerberDirPath, boardProjectName),
                               '%s/%s-PTH.%s' % (gerberDirPath, boardProjectName, drillExtensionRenameTo))
            renameFileIfExists('%s/%s-NPTH.drl' % (gerberDirPath, boardProjectName),
                               '%s/%s-NPTH.%s' % (gerberDirPath, boardProjectName, drillExtensionRenameTo))
예제 #3
0
def get_drill_file(drill_output_dir):

    create_dir_if_not_exist(drill_output_dir)

    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 = False
    drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

    metricFmt = True
    drlwriter.SetFormat(metricFmt)

    genDrl = True
    genMap = True
    print('create drill and map files in %s' % drill_output_dir)
    drlwriter.CreateDrillandMapFilesSet(drill_output_dir, genDrl, genMap)

    # One can create a text file to report drill statistics
    rptfn = os.path.join(drill_output_dir, 'drill_report.rpt')
    print('report: %s' % rptfn)
    drlwriter.GenDrillReportFile(rptfn)
예제 #4
0
    def genDrill(self, board, path, filename):

        drlwriter = pcbnew.EXCELLON_WRITER(board)
        drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)
        mirror = False
        minimalHeader = False
        mergeNPTH = True
        offset = pcbnew.wxPoint(0, 0)
        drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)
        drlwriter.SetRouteModeForOvalHoles(False)  # G85 for oval shapes
        metricFmt = False
        drlwriter.SetFormat(metricFmt, drlwriter.KEEP_ZEROS)
        genDrl = True
        genMap = True

        drlwriter.CreateDrillandMapFilesSet(path, genDrl, genMap)

        # convert to DOS format when run on Linux
        if platform.system() == 'Linux':
            f = open(path + '/' + filename + '.drl', 'r')
            content = f.read()
            content = self.toDOS(content)
            f = open(path + '/' + filename + '.drl', 'w')
            f.write(content)
            f.close()

        # One can create a text file to report drill statistics
        drlwriter.GenDrillReportFile(path + '/' + filename + '_drill_stat.txt')

        logging.info('Drill file done')
예제 #5
0
파일: __init__.py 프로젝트: ohmtech/kcgen
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)
예제 #6
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()
예제 #7
0
 def export_drills(self):
     ''' Generate EXCELLON drill file '''
     print('> ' + self.f_name.replace('.kicad_pcb', '.drl'))
     drill_writer = pcbnew.EXCELLON_WRITER(self.board)
     drill_writer.SetOptions(aMirror=False,
                             aMinimalHeader=False,
                             aMerge_PTH_NPTH=False,
                             aOffset=pcbnew.wxPoint(0, 0))
     drill_writer.SetFormat(True)  # Metric format
     drill_writer.CreateDrillandMapFilesSet(aPlotDirectory=self.plot_dir,
                                            aGenDrill=True,
                                            aGenMap=False)
def generate_drillmap(name, output_dir):
    board = pcbnew.LoadBoard(name)
    writer = pcbnew.EXCELLON_WRITER(board)

    writer.SetFormat(False)
    writer.SetOptions(aMirror=False,
                      aMinimalHeader=False,
                      aOffset=writer.GetOffset(),
                      aMerge_PTH_NPTH=True)
    writer.CreateDrillandMapFilesSet(output_dir,
                                     aGenDrill=True,
                                     aGenMap=False,
                                     aReporter=None)
예제 #9
0
def generate_drill_files(args):
    """ Generates the drill files for a KiCAD design, including a drill
    report. The options/arguments consumed by this function are all provided
    by the argument parser. Returns 0 if everything was successful, or 1
    otherwise. """

    pcb_file = sanitize(args.pcb_file)
    output_dir = sanitize(args.output_dir)

    file_base = os.path.splitext(os.path.basename(pcb_file))[0]
    drill_report_file = "%s-drill_report.txt" % file_base
    drill_report_file = os.path.join(args.tempdir, drill_report_file)

    board = pcbnew.LoadBoard(pcb_file)
    origin_point = board.GetAuxOrigin()

    writer = pcbnew.EXCELLON_WRITER(board)
    writer.SetMapFileFormat(pcbnew.PLOT_FORMAT_GERBER)
    writer.SetFormat(args.metric, pcbnew.EXCELLON_WRITER.DECIMAL_FORMAT)
    writer.SetOptions(False, False, origin_point, False)

    writer.GenDrillReportFile(drill_report_file)
    writer.CreateDrillandMapFilesSet(args.tempdir, True, True)

    if args.check != "":
        drills_ok = check_drills(sanitize(args.check), drill_report_file,
                                 args.metric)
        if drills_ok is False:
            return 1

    if args.no_slots:
        drill_report_data = open(drill_report_file, 'r').readlines()
        for line in drill_report_data:
            if re.findall("with [1-9][0-9]* slot", line) != []:
                sys.stderr.write("Error: One or more slots reported in ")
                sys.stderr.write("design.\n%s" % line)
                return 1

    if not os.path.isdir(output_dir):
        try:
            os.mkdir(output_dir)
        except OSError:
            err_msg = "Error: Couldn't make output directory [%s]" % output_dir
            sys.stderr.write(err_msg + "\n")
            return 1

    for filename in os.listdir(args.tempdir):
        filename = os.path.join(args.tempdir, filename)
        shutil.copy(filename, output_dir)

    return 0
예제 #10
0
    def _configure_excellon_drill_writer(self, board, offset, options):

        drill_writer = pcbnew.EXCELLON_WRITER(board)

        to = options.type_options

        mirror_y = to.mirror_y_axis
        minimal_header = to.minimal_header

        merge_npth = to.pth_and_npth_single_file
        zeros_format = pcbnew.EXCELLON_WRITER.DECIMAL_FORMAT

        drill_writer.SetOptions(mirror_y, minimal_header, offset, merge_npth)
        drill_writer.SetFormat(to.metric_units, zeros_format)

        return drill_writer
예제 #11
0
파일: board.py 프로젝트: ekettenburg/kifab
    def drill(
        self,
        dest,
        global_suffix='',
        merge_npth=False,
        extension=None,
        mirror=False,
        aux_origin=True,
        minimal_header=False,
        metric=True,
    ):

        dctl = pcbnew.EXCELLON_WRITER(self._board)
        if aux_origin:
            offset = self._board.GetAuxOrigin()
        else:
            offset = pcbnew.wxPoint(0, 0)
        dctl.SetOptions(mirror, minimal_header, offset, merge_npth)
        dctl.SetFormat(metric)
        dctl.CreateDrillandMapFilesSet(dest, aGenDrill=True, aGenMap=False)

        oldname = os.path.join(dest, self._name)
        if len(global_suffix):
            newname = os.path.join(dest, self._name + '-' + global_suffix)
        else:
            newname = oldname

        oldext = '.drl'
        if extension is not None:
            newext = extension
        else:
            newext = oldext

        if newname != oldname or newext != oldext:
            if merge_npth:
                os.rename(oldname + oldext, newname + newext)
            else:
                for s in ['-PTH', '-NPTH']:
                    os.rename(oldname + s + oldext, newname + s + newext)
예제 #12
0
          (pcbnew.Edge_Cuts, "Edge_Cuts")]

for l in layers:
    # Set current layer
    pc.SetLayer(l[0])

    # Plot layer to file
    pc.OpenPlotfile(l[1], pcbnew.PLOT_FORMAT_GERBER, l[1])
    print("Plotting to " + pc.GetPlotFileName())
    pc.PlotLayer()

pc.ClosePlot()

# Generate drill files

drlwriter = pcbnew.EXCELLON_WRITER(board)
drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_POST)

mirror = False
minimalHeader = False
offset = board.GetAuxOrigin()
mergeNPTH = False
drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

metricFmt = True
drlwriter.SetFormat(metricFmt)

genDrl = True
genMap = False
drlwriter.CreateDrillandMapFilesSet(os.path.dirname(sys.argv[1]), genDrl,
                                    genMap)
예제 #13
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
예제 #14
0
def gen_gerbers(filename, plot_folder):
    board = PN.LoadBoard(filename)

    pc = PN.PLOT_CONTROLLER(board)
    po = pc.GetPlotOptions()
    po.SetOutputDirectory(plot_folder)

    # Set some important plot options:
    po.SetPlotFrameRef(False)
    po.SetLineWidth(PN.FromMM(0.15))
    po.SetAutoScale(False)
    po.SetScale(1)
    po.SetMirror(False)
    po.SetUseGerberAttributes(False)
    po.SetUseGerberProtelExtensions(True)
    po.SetExcludeEdgeLayer(True)
    po.SetScale(1)
    po.SetUseAuxOrigin(False)
    po.SetSubtractMaskFromSilk(
        True
    )  #Without this if part outline silkscreen on top of pad, we are screwed.
    po.SetPlotReference(True)
    po.SetPlotValue(False)

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

    for layer_prefix, layer_id, layer_info in layers:
        pc.SetLayer(layer_id)
        pc.OpenPlotfile(layer_prefix, PN.PLOT_FORMAT_GERBER, layer_info)
        print('Plot %s' % os.path.basename(pc.GetPlotFileName()))
        if pc.PlotLayer() == False:
            print("Plot error while generating %s" % layer_info)
            sys.exit(1)
    pc.ClosePlot()

    # Generate the drill file
    drl = PN.EXCELLON_WRITER(board)
    drl.SetMapFileFormat(PN.PLOT_FORMAT_GERBER)
    mirror = False
    minimal_header = False
    offset = PN.wxPoint(0, 0)
    mergeNPTH = True
    drl.SetOptions(mirror, minimal_header, offset, mergeNPTH)
    metric_fmt = False
    zeros_fmt = PN.EXCELLON_WRITER.SUPPRESS_LEADING
    left_digits = 2
    right_digits = 4
    drl.SetFormat(metric_fmt, zeros_fmt, left_digits, right_digits)
    generate_drl = True
    generate_map = True
    print("Create drill and map files")
    drl.CreateDrillandMapFilesSet(pc.GetPlotDirName(), generate_drl,
                                  generate_map)
예제 #15
0
    pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER, layer_info[2])
    pctl.PlotLayer()
    pctl.ClosePlot()

##############################
# export drill

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 = True
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(gerber_dir, DRILL_FILE, MAP_FILE,
                                       REPORTER)

####################
# Create gerber zip
shutil.make_archive("{}/gerbers".format(output_dir),
                    'zip',
                    root_dir=gerber_dir)
예제 #16
0
def plotGerbers():

    board = pcbnew.GetBoard()

    pctl = pcbnew.PLOT_CONTROLLER(board)

    popt = pctl.GetPlotOptions()

    popt.SetOutputDirectory("gerbers/")

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

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

    # This by gerbers only (also the name is truly horrid!)
    popt.SetSubtractMaskFromSilk(False)

    # 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
    plot_plan = [
        ("CuTop", pcbnew.F_Cu, "Top layer"),
        ("CuBottom", pcbnew.B_Cu, "Bottom layer"),
        ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"),
        ("PasteTop", pcbnew.F_Paste, "Paste top"),
        ("SilkTop", pcbnew.F_SilkS, "Silk top"),
        ("SilkBottom", pcbnew.B_SilkS, "Silk top"),
        ("MaskBottom", pcbnew.B_Mask, "Mask bottom"),
        ("MaskTop", pcbnew.F_Mask, "Mask top"),
        ("EdgeCuts", pcbnew.Edge_Cuts, "Edges"),
    ]

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

    # 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)

    # Generate drill file
    genDrl = True
    genMap = False
    drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), genDrl, genMap)
    return pctl.GetPlotDirName()
예제 #17
0
def OutputFab(board=None,
              output_dir=defaults['output_dir'],
              overwrite=False,
              protel_ext=False,
              output_log=sys.stdout):

    ret = {}
    ret['warn'] = []

    if board == None:
        board = pcbnew.GetBoard()
    if not board:
        raise Exception('Error: Invalid board')

    os.makedirs(output_dir)

    out_file_prefix = os.path.splitext(os.path.basename(
        board.GetFileName()))[0]

    # TODO run DRC

    pctl = pcbnew.PLOT_CONTROLLER(board)
    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(output_dir)

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

    popt.SetAutoScale(False)  #do not change it
    popt.SetScale(1)  #do not change it
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(
        False)  # disable verbose header in gerber files
    popt.SetUseGerberProtelExtensions(protel_ext)
    popt.SetExcludeEdgeLayer(True)
    popt.SetUseAuxOrigin(True)

    popt.SetSubtractMaskFromSilk(True)
    popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)

    plot_plan = [
        # fname_suffix     layer_id             comment
        ("CuTop", pcbnew.F_Cu, "Top layer"),
        ("CuBottom", pcbnew.B_Cu, "Bottom layer"),
        ("PasteTop", pcbnew.F_Paste, "Paste top"),
        ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"),
        ("SilkTop", pcbnew.F_SilkS, "Silk top"),
        ("SilkBottom", pcbnew.B_SilkS, "Silk bottom"),
        ("MaskTop", pcbnew.F_Mask, "Mask top"),
        ("MaskBottom", pcbnew.B_Mask, "Mask bottom"),
        ("EdgeCuts", pcbnew.Edge_Cuts, "Edges"),
    ]

    # add inner layers if present
    for inner_layer in range(1, board.GetCopperLayerCount() - 1):
        layer_name = "Int%d" % inner_layer
        plot_plan.append((layer_name, inner_layer, "Layer %s" % layer_name))

    # now do the plot
    for layer_info in plot_plan:
        pctl.SetLayer(layer_info[1])
        pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER,
                          layer_info[2])
        output_log.write('Ploting %s\n' % pctl.GetPlotFileName())
        if pctl.PlotLayer() == False:
            raise Exception("Plot error")

    # Plot the FAB notes and drill legend
    popt.SetUseAuxOrigin(False)
    # Color plotting does not work from the python interface
    # Might need to export each layer separatelly and combine them with external tools
    pctl.SetColorMode(True)
    pctl.OpenPlotfile("FabDrawing", pcbnew.PLOT_FORMAT_PDF, "Fab Drawing")
    output_log.write('Ploting %s\n' % pctl.GetPlotFileName())
    #popt.SetColor(pcbnew.GREEN)  # kicad 4.0
    #popt.SetColor(pcbnew.COLOR4D(0.050, 0.050, 0.050, 0.1)) # kicad 5.0
    pctl.SetLayer(pcbnew.Edge_Cuts)
    pctl.PlotLayer()
    pctl.SetLayer(pcbnew.Cmts_User)
    pctl.PlotLayer()
    pctl.SetLayer(pcbnew.Eco1_User)
    pctl.PlotLayer()

    # Generate drill files
    mirror = False
    minimalHeader = False
    offset = board.GetAuxOrigin()
    mergeNPTH = True

    drlwriter = pcbnew.EXCELLON_WRITER(board)
    drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)
    drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_PDF)

    metricFmt = True
    drlwriter.SetFormat(metricFmt)

    genDrl = True
    genMap = True
    output_log.write('Create drill and map files\n')
    drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), genDrl, genMap)

    report_filename = pctl.GetPlotDirName(
    ) + out_file_prefix + '_DrillReport.rpt'
    output_log.write('Create drill report in %s\n' % report_filename)
    drlwriter.GenDrillReportFile(report_filename)

    pctl.ClosePlot()

    output_log.write('Create zip file')
    os.chdir(pctl.GetPlotDirName())
    cmd = 'zip -j {0}.zip {0}*.g?? {0}*.g? {0}-FabDrawing.pdf {0}.drl '.format(
        out_file_prefix)
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
    stdout, stderr = p.communicate()
    output_log.write(stdout)
    output_log.write(stderr)

    # TODO IPC-D-356 (it's not exposed in the python interface)
    ret['warn'].append(
        'Please create manually the IPC-D-356 file from the File->Fabrication Outputs menu'
    )

    return ret
예제 #18
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)
예제 #19
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)
예제 #20
0
파일: export_pcb.py 프로젝트: Pokour/kicad
def plot(brd, args):
    pctl = pcbnew.PLOT_CONTROLLER(brd)
    popt = pctl.GetPlotOptions()
    popt.SetOutputDirectory(args.output_dir)

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

    popt.SetAutoScale(False)
    popt.SetScale(1)
    popt.SetMirror(False)
    popt.SetUseGerberAttributes(True)
    popt.SetExcludeEdgeLayer(True)
    popt.SetUseGerberProtelExtensions(
        True)  # instead of .gbr use protel extensions
    if args.values:
        popt.SetPlotReference(False)
        popt.SetPlotValue(True)
    else:
        popt.SetPlotReference(True)
        popt.SetPlotValue(False)


#        popt.SetUseAuxOrigin(True)

# This by gerbers only (also the name is truly horrid!) - what is this?
    popt.SetSubtractMaskFromSilk(False)

    pctl.SetColorMode(True)
    plot_plan = [
        # filename      layer               description     outline svg     gerb
        ("MaskBottom", pcbnew.B_Mask, "Mask bottom", True, False, True),
        ("MaskTop", pcbnew.F_Mask, "Mask top", True, True, True),
        ("CuBottom", pcbnew.B_Cu, "Bottom layer", True, True, True),
        ("CuTop", pcbnew.F_Cu, "Top layer", True, True, True),
        ("SilkTop", pcbnew.F_SilkS, "Silk top", False, True, True),
        ("SilkBottom", pcbnew.B_SilkS, "Silk bottom", False, False, True),
        ("EdgeCuts", pcbnew.Edge_Cuts, "Edges", False, True, True),
        ("User", pcbnew.Cmts_User, "User", False, True, False),
    ]

    if config.get('board', 'layers') == '4':
        plot_plan += [("CuLayer2", pcbnew.In1_Cu, "Layer 2", True, True, True),
                      ("CuLayer3", pcbnew.In2_Cu, "Layer 3", True, True, True)]

    # https://github.com/KiCad/kicad-source-mirror/blob/0af5695e51733445c0f246eb688c98201601cd76/pcbnew/plot_board_layers.cpp#L226
    for layer_info in plot_plan:
        print(layer_info)
        pctl.SetLayer(layer_info[1])
        popt.SetUseGerberAttributes(
            False)  # gerbv lists lots of errors if this is True
        if layer_info[5]:
            pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER,
                              layer_info[2])
            pctl.PlotLayer()

    # drill
    # https://github.com/KiCad/kicad-source-mirror/blob/afe92c7bfc9d02d551b2cfa675e73d18b956f010/pcbnew/dialogs/dialog_gendrill.cpp#L403
    drill = pcbnew.EXCELLON_WRITER(brd)
    # older kicad doesn't know about MergeOption
    drill.SetMergeOption(True)
    drill.SetFormat(True, drill.DECIMAL_FORMAT, 0, 0)
    drill.CreateDrillandMapFilesSet(args.output_dir, True, False)

    # make an SVG overview
    pctl.OpenPlotfile("overview", pcbnew.PLOT_FORMAT_SVG, "Overview")
    pctl.SetColorMode(True)
    for layer_info in plot_plan:
        pctl.SetLayer(layer_info[1])
        if layer_info[4]:
            pctl.PlotLayer()

    pctl.ClosePlot()

    out_name = get_board_name()
    print("convert svg to png")
    os.system(
        "inkscape -f %s/%s-overview.svg -z --export-dpi=%d --export-area-drawing --export-png=%s/%s-overview.png"
        % (args.output_dir, out_name, args.dpi, args.output_dir, out_name))
    os.remove("%s/%s-overview.svg" %
              (args.output_dir, out_name))  # remove the svg as it's quite big
예제 #21
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)
예제 #22
0
    def Run(self):
        Print_Board_Dimensions().Run()

        board = pcbnew.GetBoard()
        design_settings = board.GetDesignSettings()

        ff = board.GetFileName().replace("\\", "/")
        while ("//" in r"%r" % ff):
            ff = ff.replace("//", "/")

        fdir = ff.rsplit("/", 1)[0:-1][0] + "/"
        fname = (ff.rsplit(".", 1)[0]).rsplit("/", 1)[-1]

        fabdir = fdir + "fabrication/"
        dokudir = fdir + "documentation/"
        mapfiledir = dokudir + "drillmaps/"

        if not (os.path.isdir(fabdir)):
            os.mkdir(fabdir)
        if not (os.path.isdir(dokudir)):
            os.mkdir(dokudir)
        if not (os.path.isdir(mapfiledir)):
            os.mkdir(mapfiledir)

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

        # Set some important plot options:
        popt.SetPlotFrameRef(False)
        popt.SetSketchPadLineWidth(pcbnew.FromMM(0.05))

        popt.SetAutoScale(False)
        popt.SetScale(1)
        popt.SetMirror(False)
        popt.SetUseGerberAttributes(True)
        popt.SetGerberPrecision(6)
        popt.SetExcludeEdgeLayer(True)
        popt.SetSubtractMaskFromSilk(True)
        popt.SetUseAuxOrigin(True)
        popt.SetUseGerberX2format(True)
        popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)

        popt.SetOutputDirectory(fabdir)

        # 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
        rename_necessary = False

        plot_plan = [
            ("TopLayer", pcbnew.F_Cu, "Top layer"),
            ("BottomLayer", pcbnew.B_Cu, "Bottom layer"),
            ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"),
            ("PasteTop", pcbnew.F_Paste, "Paste top"),
            ("SilkTop", pcbnew.F_SilkS, "Silk top"),
            ("SilkBottom", pcbnew.B_SilkS, "Silk top"),
            ("MaskBottom", pcbnew.B_Mask, "Mask bottom"),
            ("MaskTop", pcbnew.F_Mask, "Mask top"),
            ("Mechanical", pcbnew.Edge_Cuts, "Mechanical"),
        ]

        popt.SetUseGerberProtelExtensions(True)

        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("", pcbnew.PLOT_FORMAT_GERBER, layer_info[2])
            filpn = pctl.GetPlotFileName().rsplit('.', 1)[0:-1][0]
            extn = pctl.GetPlotFileName().rsplit('.', 1)[-1]
            pctl.PlotLayer()

            if extn == 'gm1':
                rename_necessary = True
                sysstrng = (filpn + ".gm1")
                newname = (filpn + ".gml")

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

        for innerlyr in range(1, lyrcnt - 1):
            pctl.SetLayer(innerlyr)
            lyrname = 'inner%s' % innerlyr
            pctl.OpenPlotfile(lyrname, pcbnew.PLOT_FORMAT_GERBER, "inner")
            pctl.PlotLayer()

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

        if rename_necessary:
            if os.path.isfile(newname):
                os.remove(newname)
            os.rename(sysstrng, newname)
            rename_necessary = False

        # 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 = design_settings.m_AuxOrigin
        # False to generate 2 separate drill files (one for plated holes, one for non plated holes)
        # True to generate only one drill file
        mergeNPTH = False
        drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)

        metricFmt = True
        drlwriter.SetFormat(metricFmt,
                            pcbnew.GENDRILL_WRITER_BASE.SUPPRESS_LEADING, 3, 3)

        drlwriter.SetRouteModeForOvalHoles(True)

        drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), True, False)
        drlwriter.CreateDrillandMapFilesSet(mapfiledir, False, True)

        # Rename drill files to .txt
        if os.path.isfile(fabdir + fname + "-PTH.drl"):
            if os.path.isfile(fabdir + fname + "-PTH.txt"):
                os.remove(fabdir + fname + "-PTH.txt")
            os.rename(fabdir + fname + "-PTH.drl", fabdir + fname + "-PTH.txt")
        if os.path.isfile(fabdir + fname + "-NPTH.drl"):
            if os.path.isfile(fabdir + fname + "-NPTH.txt"):
                os.remove(fabdir + fname + "-NPTH.txt")
            os.rename(fabdir + fname + "-NPTH.drl",
                      fabdir + fname + "-NPTH.txt")

        os.system("zip -j " + fabdir + fname + ".zip " + fabdir + "*")

        #######################################################################################################

        popt.SetA4Output(True)
        popt.SetSketchPadLineWidth(pcbnew.FromMM(0.1))
        # popt.SetAutoScale(True)

        # Switching the output directory
        popt.SetOutputDirectory(dokudir)

        ########################################################################################################

        # Our fabricators want two additional gerbers:
        # An assembly with no silk trim and all and only the references
        # (you'll see that even holes have designators, obviously)
        # popt.SetSubtractMaskFromSilk(False)
        popt.SetPlotReference(True)
        popt.SetPlotValue(False)
        popt.SetPlotInvisibleText(False)
        popt.SetPlotReference(True)
        popt.SetPlotValue(True)
        popt.SetPlotInvisibleText(False)

        # Remember that the frame is always in color 0 (BLACK) and should be requested
        # before opening the plot
        popt.SetPlotFrameRef(False)

        popt.SetFineScaleAdjustX(1.000)
        popt.SetFineScaleAdjustY(1.000)

        pctl.OpenPlotfile("Layout", pcbnew.PLOT_FORMAT_PDF, "General layout")
        popt.SetTextMode(pcbnew.PLOT_TEXT_MODE_STROKE)

        pctl.SetLayer(pcbnew.Edge_Cuts)
        pctl.PlotLayer()

        popt.SetPlotMode(pcbnew.SKETCH)
        pctl.SetLayer(pcbnew.F_Mask)
        pctl.PlotLayer()

        popt.SetPlotMode(pcbnew.FILLED)
        pctl.SetLayer(pcbnew.F_SilkS)
        pctl.PlotLayer()

        pctl.ClosePlot()

        ################################################################################################################

        pctl.OpenPlotfile("Assembly", pcbnew.PLOT_FORMAT_SVG,
                          "Master Assembly")
        pctl.SetColorMode(True)

        # We want *everything*
        popt.SetPlotReference(True)
        popt.SetPlotValue(True)
        popt.SetPlotInvisibleText(False)

        # Remember than the DXF driver assigns colours to layers. This means that
        # we will be able to turn references on and off simply using their layers
        # Also most of the layer are now plotted in 'line' mode, because DXF handles
        # fill mode almost like sketch mode (this is to keep compatibility with
        # most CAD programs; most of the advanced primitive attributes required are
        # handled only by recent autocads...); also the entry level cads (qcad
        # and derivatives) simply don't handle polyline widths...

        pctl.SetLayer(pcbnew.B_SilkS)
        pctl.PlotLayer()
        pctl.SetLayer(pcbnew.F_SilkS)
        pctl.PlotLayer()
        popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.SMALL_DRILL_SHAPE)
        pctl.SetLayer(pcbnew.B_Mask)
        pctl.PlotLayer()
        pctl.SetLayer(pcbnew.F_Mask)
        pctl.PlotLayer()
        pctl.SetLayer(pcbnew.B_Paste)
        pctl.PlotLayer()
        pctl.SetLayer(pcbnew.F_Paste)
        pctl.PlotLayer()
        pctl.SetLayer(pcbnew.Edge_Cuts)
        pctl.PlotLayer()

        # Export the copper layers too... exporting one of them in filled mode with
        # drill marks will put the marks in the WHITE later (since it tries to blank
        # the pads...); these will be obviously great reference points for snap
        # and stuff in the cad. A pctl function to only plot them would be
        # better anyway...

        #pctl.SetLayer(pcbnew.B_Cu)
        #pctl.PlotLayer()
        #popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE)
        #pctl.SetLayer(pcbnew.F_Cu)
        #pctl.PlotLayer()

        # At the end you have to close the last plot, otherwise you don't know when
        # the object will be recycled!
        pctl.ClosePlot()
예제 #23
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)
예제 #24
0
def plot(args):
    board = pcbnew.LoadBoard(args.brd + '.kicad_pcb')

    # Load board and initialize plot controller
    pc = pcbnew.PLOT_CONTROLLER(board)
    po = pc.GetPlotOptions()
    po.SetPlotFrameRef(False)
    po.SetExcludeEdgeLayer(True)
    po.SetOutputDirectory(args.dir)
    po.SetUseGerberProtelExtensions(args.protel)

    # Load board and initialize excellon writter
    er = pcbnew.EXCELLON_WRITER(board)
    mirror = False
    minimalHeader = False
    offset = pcbnew.wxPoint(0, 0)
    merge_npth = not args.splitth
    er.SetOptions(mirror, minimalHeader, offset, merge_npth)
    metric_format = True
    er.SetFormat(metric_format)
    generate_drill = True
    generate_map = False

    if (args.drl or args.all):
        if (args.splitth):
            print('Plotting to ' +
                  os.path.join(args.dir, os.path.basename(args.brd)) +
                  '-PTH.drl')
            print('Plotting to ' +
                  os.path.join(args.dir, os.path.basename(args.brd)) +
                  '-NPTH.drl')
        else:
            print('Plotting to ' +
                  os.path.join(args.dir, os.path.basename(args.brd)) + '.drl')
        er.CreateDrillandMapFilesSet(args.dir, generate_drill, generate_map)

    if (args.fcu or args.all):
        suffix = 'F.Cu'
        if (args.protel):
            suffix = ''
        # Set current layer
        pc.SetLayer(pcbnew.F_Cu)
        # Plot single layer to file
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GTL')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.bcu or args.all):
        suffix = 'B.Cu'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.B_Cu)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GBL')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.fmask or args.all):
        suffix = 'F.Mask'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.F_Mask)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GTS')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.bmask or args.all):
        suffix = 'B.Mask'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.B_Mask)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GBS')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.fsilks or args.all):
        suffix = 'F.SilkS'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.F_SilkS)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GTO')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.bsilks or args.all):
        suffix = 'B.SilkS'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.B_SilkS)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GBO')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    if (args.edgecuts or args.all):
        suffix = 'Edge.Cuts'
        if (args.protel):
            suffix = ''
        pc.SetLayer(pcbnew.Edge_Cuts)
        pc.OpenPlotfile(suffix, pcbnew.PLOT_FORMAT_GERBER, 'GML')
        print('Plotting to ' + pc.GetPlotFileName())
        pc.PlotLayer()

    pc.ClosePlot()