def main(): """ Entry point for readdxf.py. """ args = process_arguments() for f in ut.xpand(args.files): print('Filename: {}'.format(f)) try: data = dx.parse(f) if args.verbose: for d in data: pprint.pprint(d) entities = dx.entities(data) except Exception as ex: logging.info('skipping file {}: {}'.format(f, ex)) continue if not args.all: numbered = dx.numberedlayers(entities) bylayer = {nm: dx.fromlayer(entities, nm) for nm in numbered} entities = [] for layerent in bylayer.values(): entities += layerent num = len(entities) if num == 0: logging.warning('no entities found!') continue print('Contains: {} entities'.format(num)) if args.verbose: for e in entities: pprint.pprint(e) layers = dx.layernames(entities) for layer in layers: print('Layer: "{}"'.format(layer)) for e in dx.fromlayer(entities, layer): printent(e, args.verbose)
def main(): """ Entry point for dxf2nc.py. """ args = process_arguments() sorters = {'xy': utils.bbxykey, 'yx': utils.bbyxkey, 'dist': utils.distkey} sortkey = sorters[args.sort] lines.epsilon = args.dist for f in utils.xpand(args.files): logging.info('Starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='.nc') data = dx.parse(f) entities = dx.entities(data) except ValueError as ex: logging.info(str(ex)) fns = "error during processing. Skipping file '{}'." logging.error(fns.format(f)) continue except IOError as ex: logging.info(str(ex)) logging.error("i/o error in file '{}'. Skipping it.".format(f)) continue layers = dx.numberedlayers(entities) entities = [e for e in entities if dx.bycode(e, 8) in layers] num = len(entities) if num == 0: logging.info("no entities found! Skipping file '{}'.".format(f)) continue logging.info('{} entities found.'.format(num)) out = gerbernc.Writer(ofn) for layername in layers: out.newpiece() thislayer = dx.fromlayer(entities, layername) ls = '{} entities found in layer "{}".' logging.info(ls.format(len(thislayer), layername)) segments = lines.mksegments(thislayer) fs = '{} segments in layer "{}"' logging.info(fs.format(len(segments), layername)) if args.contours: cut_contours(segments, out, layername, sortkey) else: segments.sort(key=sortkey) cut_segments(segments, out) out.write()
def main(): """ Entry point for dxfgerber.py. """ args = process_arguments() sorters = {'xy': utils.bbxykey, 'yx': utils.bbyxkey, 'dist': utils.distkey} sortkey = sorters[args.sort] lines.epsilon = args.dist for f in utils.xpand(args.files): logging.info('starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='.dxf', addenum='_mod') data = dx.parse(f) entities = dx.entities(data) except ValueError as ex: logging.info(str(ex)) fns = "error during processing. Skipping file '{}'." logging.error(fns.format(f)) continue except IOError as ex: logging.info(str(ex)) logging.error("i/o error in file '{}'. Skipping it.".format(f)) continue layers = dx.numberedlayers(entities) entities = [e for e in entities if dx.bycode(e, 8) in layers] num = len(entities) if num == 0: logging.info("no entities found! Skipping file '{}'.".format(f)) continue logging.info('{} entities found.'.format(num)) with open(ofn, 'w') as out: out.write(dxfheader) for layername in layers: thislayer = dx.fromlayer(entities, layername) ls = '{} entities found in layer "{}".' logging.info(ls.format(num, layername)) segments = lines.mksegments(thislayer) fs = '{} segments in layer "{}"' logging.info(fs.format(len(segments), layername)) write_allseg(segments, out, layername, sortkey) out.write(dxffooter)
def main(): """ Entry point for dxf2pdf.py. """ args = process_arguments() for f in utils.xpand(args.files): logging.info('starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='.pdf', addenum='_dxf') data = dxf.parse(f) entities = dxf.entities(data) except ValueError as ex: logging.info(str(ex)) fns = "cannot construct output filename. Skipping file '{}'." logging.error(fns.format(f)) continue except IOError as ex: logging.info(str(ex)) logging.error("cannot open the file '{}'. Skipping it.".format(f)) continue output(f, ofn, entities, args)
def main(): """ Entry point for nc2pdf.py. """ args = process_arguments() for fn in utils.xpand(args.files): logging.info('starting file "{}"'.format(fn)) try: ofn = utils.outname(fn, extension='.pdf', addenum='_nc') cuts = list(gerbernc.segments(fn)) except ValueError as e: logging.info(str(e)) fns = "cannot construct output filename. Skipping file '{}'." logging.error(fns.format(fn)) continue except IOError as e: logging.info("cannot read file: {}".format(e)) logging.error("i/o error, skipping file '{}'".format(fn)) continue cnt = len(cuts) logging.info('got {} cuts'.format(cnt)) xvals = [pnt[0] for s in cuts for pnt in s] yvals = [pnt[1] for s in cuts for pnt in s] minx, maxx = min(xvals), max(xvals) miny, maxy = min(yvals), max(yvals) bs = '{} range from {:.1f} mm to {:.1f} mm' logging.info(bs.format('X', minx, maxx)) logging.info(bs.format('Y', miny, maxy)) logging.info('plotting the cuts') out, ctx = plot.setup(ofn, minx, miny, maxx, maxy) plot.grid(ctx, minx, miny, maxx, maxy) plot.lines(ctx, cuts) plot.title(ctx, 'nc2pdf', ofn, maxy - miny) out.show_page() logging.info('writing output file "{}"'.format(ofn)) out.finish() logging.info('file "{}" done.'.format(fn))
def main(argv): """Main program for the readnc utility. :param argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('files', nargs='*', help='one or more file names', metavar='file') pv = parser.parse_args(argv) if not pv.files: parser.print_help() sys.exit(0) for fn in utils.xpand(pv.files): try: rd = gerbernc.Reader(fn) except IOError as e: utils.skip(e, fn) continue except ValueError as e: utils.skip(e, fn) continue # print the file for cmd, _ in rd: print(cmd)
def main(argv): """Main program for the dxfgerber utility. :param argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) argtxt = """maximum distance between two points considered equal when searching for contours (defaults to 0.5 mm)""" parser.add_argument('-l', '--limit', nargs=1, help=argtxt, dest='limit', metavar='F', type=float, default=0.5) group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('-v', '--verbose', dest='verbose', action="store_true") parser.add_argument('files', nargs='*', help='one or more file names', metavar='file') pv = parser.parse_args(argv) msg = utils.Msg(pv.verbose) lim = pv.limit**2 if not pv.files: parser.print_help() sys.exit(0) for f in utils.xpand(pv.files): msg.say('Starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='.dxf', addenum='_mod') entities = dxf.reader(f) except Exception as ex: # pylint: disable=W0703 utils.skip(ex, f) continue num = len(entities) if num == 0: msg.say('No entities found!') continue if num > 1: msg.say('Contains {} entities'.format(num)) bbe = [e.bbox for e in entities] bb = bbox.merge(bbe) msg.say('Gathering connected entities into contours') contours, rement = ent.findcontours(entities, lim) ncon = 'Found {} contours, {} remaining single entities' msg.say(ncon.format(len(contours), len(rement))) entities = contours + rement msg.say('Sorting entities') entities.sort(key=lambda e: (e.bbox.minx, e.bbox.miny)) else: msg.say('Contains: 1 entity') bb = entities[0].bbox es = 'Original extents: {:.1f} ≤ x ≤ {:.1f} mm,' \ ' {:.1f} ≤ y ≤ {:.1f} mm' msg.say(es.format(bb.minx, bb.maxx, bb.miny, bb.maxy)) # move entities so that the bounding box begins at 0,0 if bb.minx != 0 or bb.miny != 0: ms = 'Moving all entities by ({:.1f}, {:.1f}) mm' msg.say(ms.format(-bb.minx, -bb.miny)) for e in entities: e.move(-bb.minx, -bb.miny) length = sum(e.length for e in entities) msg.say('Total length of entities: {:.0f} mm'.format(length)) msg.say('Writing output to "{}"'.format(ofn)) dxf.writer(ofn, 'dxfgerber', entities) msg.say('File "{}" done.'.format(f))
def main(argv): """Main program for the dxf2nc utility. :param argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) argtxt = """maximum distance between two points considered equal when searching for contours (defaults to 0.5 mm)""" argtxt2 = u"""minimum rotation angle in degrees where the knife needs to be lifted to prevent breaking (defaults to 60°)""" argtxt4 = "assemble connected lines into contours (off by default)" parser.add_argument('-l', '--limit', help=argtxt, dest='limit', metavar='F', type=float, default=0.5) parser.add_argument('-a', '--angle', help=argtxt2, dest='ang', metavar='F', type=float, default=60) parser.add_argument('-c', '--contours', help=argtxt4, dest='contours', action="store_true") group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('-v', '--verbose', dest='verbose', action="store_true") parser.add_argument('files', nargs='*', help='one or more file names', metavar='file') pv = parser.parse_args(argv) msg = utils.Msg(pv.verbose) lim = pv.limit**2 if not pv.files: parser.print_help() sys.exit(0) for f in utils.xpand(pv.files): parts = [] msg.say('Starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='') entities = dxf.reader(f) except Exception as ex: # pylint: disable=W0703 utils.skip(ex, f) continue # separate entities into parts according to their layers layers = {e.layer for e in entities} # Delete layer names that are not numbers layers = [la for la in layers if re.search('^[0-9]+', la)] layers.sort(key=lambda x: int(x)) # sort by integer value! # remove entities from unused layers. entities = [e for e in entities if e.layer in layers] num = len(entities) if num == 0: msg.say('No entities found!') continue if num > 1: msg.say('Contains {} entities'.format(num)) bbe = [e.bbox for e in entities] bb = bbox.merge(bbe) es = 'Original extents: {:.1f} ≤ x ≤ {:.1f} mm,' \ ' {:.1f} ≤ y ≤ {:.1f} mm' msg.say(es.format(bb.minx, bb.maxx, bb.miny, bb.maxy)) for layer in layers: msg.say('Found layer: "{}"'.format(layer)) le = [e for e in entities if e.layer == layer] if pv.contours: msg.say('Gathering connected entities into contours') contours, rement = ent.findcontours(le, lim) for c in contours: c.layer = layer ncon = 'Found {} contours, {} remaining single entities' msg.say(ncon.format(len(contours), len(rement))) le = contours + rement msg.say('Sorting entities') le.sort(key=lambda e: (e.bbox.minx, e.bbox.miny)) parts.append(le) msg.say('Sorting pieces') parts.sort(key=lambda p: bbox.merge([e.bbox for e in p]).minx) length = sum(e.length for e in entities) msg.say('Total length of entities: {:.0f} mm'.format(length)) msg.say('Writing output to "{}"'.format(ofn)) write_entities(ofn, parts, pv.ang) msg.say('File "{}" done.'.format(f))
def main(argv): """Main program for the readdxf utility. :param argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('-v', '--verbose', dest='verbose', action="store_true") parser.add_argument('files', nargs='*', help='one or more file names', metavar='file') pv = parser.parse_args(argv) msg = utils.Msg(pv.verbose) if not pv.files: parser.print_help() sys.exit(0) offset = 40 for f in utils.xpand(pv.files): msg.say('Starting file "{}"'.format(f)) try: ofn = utils.outname(f, extension='.pdf', addenum='_dxf') entities = dxf.reader(f) except ValueError as ex: msg.say(str(ex)) fns = "Cannot construct output filename. Skipping file '{}'." msg.say(fns.format(f)) continue except IOError as ex: msg.say(str(ex)) msg.say("Cannot open the file '{}'. Skipping it.".format(f)) continue # Output num = len(entities) if num == 0: msg.say('No entities found!') continue if num > 1: msg.say('Contains {} entities'.format(num)) bbx = [e.bbox for e in entities] bb = bbox.merge(bbx) else: msg.say('Contains: 1 entity') bb = entities[0].bbox w = bb.width + offset h = bb.height + offset xf = cairo.Matrix(xx=1.0, yy=-1.0, y0=h) out = cairo.PDFSurface(ofn, w, h) ctx = cairo.Context(out) ctx.set_matrix(xf) ctx.set_line_cap(cairo.LINE_CAP_ROUND) ctx.set_line_join(cairo.LINE_JOIN_ROUND) ctx.set_line_width(0.5) plot.plotgrid(ctx, w, h) colors = plot.crange(380, 650, len(entities)) msg.say('Plotting the entities') plot.plotentities(ctx, (offset / 2 - bb.minx, offset / 2 - bb.miny), entities, colors) # plot the color bar plot.plotcolorbar(ctx, w, len(entities), colors) # Plot the filename ctx.save() ctx.set_matrix(cairo.Matrix(xx=1.0, yy=1.0)) ctx.select_font_face('Sans') fh = min(10, h / 40) ctx.set_source_rgb(0.0, 0.0, 0.0) ctx.set_font_size(fh) ctx.move_to(5, fh + 5) txt = ' '.join([ 'Produced by: dxf2pdf', __version__, 'on', str(datetime.datetime.now())[:-10] ]) ctx.show_text(txt) ctx.stroke() fh = min(30, h / 20) ctx.move_to(5, h - 15) txt = 'File: "{}", last modified: {}' ctx.show_text(txt.format(f, time.ctime(os.path.getmtime(f)))) ctx.stroke() ctx.restore() # Finish the page. out.show_page() out.finish() msg.say('File "{}" done.'.format(f))
def main(argv): """Main program for the readdxf utility. :param argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) argtxt = """maximum distance between two points considered equal when searching for contours (defaults to 0.5 mm)""" parser.add_argument('-l', '--limit', nargs='?', help=argtxt, dest='limit', type=float, default=0.5) group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('files', metavar='file', nargs='*', help='one or more file names') pv = parser.parse_args(argv) msg = utils.Msg() lim = pv.limit**2 parts = [] if not pv.files: parser.print_help() sys.exit(0) for f in utils.xpand(pv.files): try: entities = dxf.reader(f) except Exception as ex: utils.skip(ex, f) continue num = len(entities) msg.say('Filename: {}'.format(f)) if num == 0: msg.say('No entities found!') sys.exit(1) if num > 1: msg.say('Contains: {} entities'.format(num)) bbe = [e.bbox for e in entities] bb = bbox.merge(bbe) layers = {e.layer for e in entities} for layer in layers: msg.say('Layer: "{}"'.format(layer)) le = [e for e in entities if e.layer == layer] contours, rement = ent.findcontours(le, lim) for c in contours: c.layer = layer ncon = 'Found {} contours, {} remaining single entities' msg.say(ncon.format(len(contours), len(rement))) le = contours + rement le.sort(key=lambda x: x.bbox.minx) parts.append(le) else: msg.say('Contains: 1 entity') msg.say('Layer: "{}"'.format(entities[0].layer)) bb = entities[0].bbox parts.append(entities) es = 'Extents: {:.1f} ≤ x ≤ {:.1f}, {:.1f} ≤ y ≤ {:.1f}' msg.say(es.format(bb.minx, bb.maxx, bb.miny, bb.maxy)) length = sum(e.length for e in entities) msg.say('Total length of entities: {:.0f} mm'.format(length)) for p in parts: msg.say('Layer: "{}"'.format(p[0].layer)) for e in p: msg.say(e) if isinstance(e, ent.Contour): for c in e.entities: msg.say('..', c)
def main(argv): """Main program for the nc2pdf utility. :argv: command line arguments """ parser = argparse.ArgumentParser(description=__doc__) group = parser.add_mutually_exclusive_group() group.add_argument('-L', '--license', action=LicenseAction, nargs=0, help="print the license") group.add_argument('-V', '--version', action='version', version=__version__) parser.add_argument('-v', '--verbose', dest='verbose', action="store_true") parser.add_argument('files', nargs='*', help='one or more file names', metavar='file') pv = parser.parse_args(argv) msg = utils.Msg(pv.verbose) offset = 40 if not pv.files: parser.print_help() sys.exit(0) for fn in utils.xpand(pv.files): msg.say('Starting file "{}"'.format(fn)) try: ofn = utils.outname(fn, extension='.pdf', addenum='_nc') rd = gerbernc.Reader(fn) except ValueError as e: msg.say(str(e)) fns = "Cannot construct output filename. Skipping file '{}'." msg.say(fns.format(fn)) continue except IOError as e: msg.say("Cannot read file: {}".format(e)) msg.say("Skipping file '{}'".format(fn)) continue cuts, xvals, yvals = getcuts(rd) cnt = len(cuts) msg.say('Got {} cuts'.format(cnt)) minx, maxx = min(xvals), max(xvals) miny, maxy = min(yvals), max(yvals) bs = '{} range from {:.1f} mm to {:.1f} mm' msg.say(bs.format('X', minx, maxx)) msg.say(bs.format('Y', miny, maxy)) w = maxx - minx + offset h = maxy - miny + offset msg.say('Plotting the cuts') # Produce PDF output. Scale factor is 1 mm real = # 1 PostScript point in the PDF file xf = cairo.Matrix(xx=1.0, yy=-1.0, y0=h) out = cairo.PDFSurface(ofn, w, h) ctx = cairo.Context(out) ctx.set_matrix(xf) ctx.set_line_cap(cairo.LINE_CAP_ROUND) ctx.set_line_join(cairo.LINE_JOIN_ROUND) ctx.set_line_width(0.5) # Plot a grid in red plot.plotgrid(ctx, w, h) # Plot the cutlines colors = plot.crange(380, 650, cnt) # Plot in colors ctx.save() ctx.translate(offset / 2 - minx, offset / 2 - miny) for section, (r, g, b) in zip(cuts, colors): x1, y1 = section.pop(0) ctx.move_to(x1, y1) ctx.set_source_rgb(r / 255.0, g / 255.0, b / 255.0) for x2, y2 in section: ctx.line_to(x2, y2) ctx.stroke() ctx.restore() # plot the color bar plot.plotcolorbar(ctx, w, cnt, colors) # Plot the filename ctx.save() ctx.set_matrix(cairo.Matrix(xx=1.0, yy=1.0)) ctx.select_font_face('Sans') fh = min(10, h / 40) ctx.set_source_rgb(0.0, 0.0, 0.0) ctx.set_font_size(fh) ctx.move_to(5, fh + 5) txt = ' '.join([ 'Produced by: nc2pdf', __version__, 'on', str(datetime.datetime.now())[:-10] ]) ctx.show_text(txt) ctx.stroke() fh = min(30, h / 20) ctx.move_to(5, h - 15) txt = 'File: "{}", last modified: {}' ctx.show_text(txt.format(fn, time.ctime(os.path.getmtime(fn)))) ctx.stroke() ctx.restore() # Finish the page. out.show_page() msg.say('Writing output file "{}"'.format(ofn)) out.finish() msg.say('File "{}" done.'.format(fn))