def vertex(): x, y = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) outs = ' VERTEX at ({:.2f}, {:.2f})'.format(x, y) if 42 in e: v = math.degrees(math.atan(float(dx.bycode(e, 42))) * 4) outs += ', curve angle {:.1f}°'.format(v) print(outs)
def arc(): xc, yc, R = (float(dx.bycode(e, 10)), float(dx.bycode(e, 20)), float(dx.bycode(e, 40))) sa, ea = float(dx.bycode(e, 50)), float(dx.bycode(e, 51)) sar, ear = math.radians(sa), math.radians(ea) xs, ys = xc + R * math.cos(sar), yc + R * math.sin(sar) xe, ye = xc + R * math.cos(ear), yc + R * math.sin(ear) outs = ' ARC from ({:.2f}, {:.2f}) to ({:.2f}, {:.2f})' print(outs.format(xs, ys, xe, ye)) outs = ' centered at ({:.2f}, {:.2f}), ' \ 'radius {:.2f}, from {:.1f}° to {:.1f}°' print(outs.format(xc, yc, R, sa, ea))
def arc(e): cx, cy = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) R = fr(dx.bycode(e, 40)) sa, ea = (math.radians(float(dx.bycode(e, 50))), math.radians(float(dx.bycode(e, 51)))) if ea > sa: da = ea - sa else: da = 2 * math.pi - sa + ea if DEVLIM > R: cnt = 1 else: maxstep = 2 * math.acos(1 - DEVLIM / R) if da < 0: maxstep = -maxstep cnt = math.ceil(da / maxstep) step = da / cnt angs = [sa + i * step for i in range(cnt + 1)] pnts = [(fr(cx + R * math.cos(a)), fr(cy + R * math.sin(a))) for a in angs] return pnts
def printent(e, v): """Print a DXF entity""" def line(): xs, ys = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) xe, ye = float(dx.bycode(e, 11)), float(dx.bycode(e, 21)) outs = ' LINE from ({:.2f}, {:.2f}) to ({:.2f}, {:.2f})' print(outs.format(xs, ys, xe, ye)) def arc(): xc, yc, R = (float(dx.bycode(e, 10)), float(dx.bycode(e, 20)), float(dx.bycode(e, 40))) sa, ea = float(dx.bycode(e, 50)), float(dx.bycode(e, 51)) sar, ear = math.radians(sa), math.radians(ea) xs, ys = xc + R * math.cos(sar), yc + R * math.sin(sar) xe, ye = xc + R * math.cos(ear), yc + R * math.sin(ear) outs = ' ARC from ({:.2f}, {:.2f}) to ({:.2f}, {:.2f})' print(outs.format(xs, ys, xe, ye)) outs = ' centered at ({:.2f}, {:.2f}), ' \ 'radius {:.2f}, from {:.1f}° to {:.1f}°' print(outs.format(xc, yc, R, sa, ea)) def polyline(): print(' POLYLINE') def vertex(): x, y = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) outs = ' VERTEX at ({:.2f}, {:.2f})'.format(x, y) if 42 in e: v = math.degrees(math.atan(float(dx.bycode(e, 42))) * 4) outs += ', curve angle {:.1f}°'.format(v) print(outs) def endseq(): print(' ENDSEQ') printdict = { 'LINE': line, 'ARC': arc, 'POLYLINE': polyline, 'VERTEX': vertex, 'SEQEND': endseq } k = dx.bycode(e, 0) try: printdict[k]() except KeyError: if v: print(' {} entity: {}'.format(k, e)) else: print(' {} entity'.format(k))
def output(ifn, ofn, entities, args): opts = [] if args.contours: opts = ['contours'] if args.markers: opts.append('markers') sorters = {'xy': utils.bbxykey, 'yx': utils.bbyxkey, 'dist': utils.distkey} sortkey = sorters[args.sort] if not args.alllayers: layers = dxf.numberedlayers(entities) entities = [e for e in entities if dxf.bycode(e, 8) in layers] else: layers = dxf.layernames(entities) num = len(entities) if num == 0: logging.info("no entities found! Skipping file '{}'.".format(ifn)) return logging.info('{} entities found'.format(num)) allsegments = lines.mksegments(entities) bboxes = [lines.bbox(s) for s in allsegments] minx, miny, maxx, maxy = lines.merge_bbox(bboxes) out, ctx = plot.setup(ofn, minx, miny, maxx, maxy) plot.grid(ctx, minx, miny, maxx, maxy) for layername in layers: thislayer = dxf.fromlayer(entities, layername) segments = lines.mksegments(thislayer) ls = '{} entities found in layer "{}".' logging.info(ls.format(len(thislayer), layername)) logging.info('plotting the entities') if args.contours: closedseg, openseg = lines.combine_segments(segments) fs = '{} {} segments in layer "{}"' for a, b in (('closed', closedseg), ('open', openseg)): logging.info(fs.format(len(b), a, layername)) openseg.sort(key=sortkey) plot.lines(ctx, openseg, marks=args.markers) closedseg.sort(key=sortkey) plot.lines(ctx, closedseg, marks=args.markers) else: fs = '{} segments in layer "{}"' logging.info(fs.format(len(segments), layername)) plot.lines(ctx, segments, marks=args.markers) plot.title(ctx, 'dxf2pdf', ofn, maxy - miny, options=opts) out.show_page() logging.info('writing output file "{}"'.format(ofn)) out.finish() logging.info('file "{}" done.'.format(ifn))
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 line(e): return [(fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))), (fr(dx.bycode(e, 11)), fr(dx.bycode(e, 21)))]
def line(): xs, ys = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) xe, ye = float(dx.bycode(e, 11)), float(dx.bycode(e, 21)) outs = ' LINE from ({:.2f}, {:.2f}) to ({:.2f}, {:.2f})' print(outs.format(xs, ys, xe, ye))
def line(e): return [ (fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))), (fr(dx.bycode(e, 11)), fr(dx.bycode(e, 21))) ]
def mksegments(entities, ndigits=3): """ Convert an iterable of entities to a list of line segments. Arguments: entities: An iterable if dictionaries, each containing a DXF entity. ndigits: Rounds to ndigits after the decimal point. Returns: A list of line segments. Line segments are lists of ≥2 (x,y) tuples. """ def fr(n): return round(float(n), ndigits) def line(e): return [ (fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))), (fr(dx.bycode(e, 11)), fr(dx.bycode(e, 21))) ] def arc(e): cx, cy = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) R = fr(dx.bycode(e, 40)) sa, ea = (math.radians(float(dx.bycode(e, 50))), math.radians(float(dx.bycode(e, 51)))) if ea > sa: da = ea - sa else: da = 2 * math.pi - sa + ea if DEVLIM > R: cnt = 1 else: maxstep = 2 * math.acos(1 - DEVLIM / R) if da < 0: maxstep = -maxstep cnt = math.ceil(da / maxstep) step = da / cnt angs = [sa + i * step for i in range(cnt + 1)] pnts = [(fr(cx + R * math.cos(a)), fr(cy + R * math.sin(a))) for a in angs] return pnts # Convert lines lines = [line(e) for e in entities if dx.bycode(e, 0) == 'LINE'] # Convert arcs lines += [arc(e) for e in entities if dx.bycode(e, 0) == 'ARC'] # Convert polylines pi = [n for n, e in enumerate(entities) if dx.bycode(e, 0) == 'POLYLINE'] se = [n for n, e in enumerate(entities) if dx.bycode(e, 0) == 'SEQEND'] for start in pi: end = [n for n in se if n > start][0] poly = entities[start:end] points = [(fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))) for e in poly[1:]] angles = [math.atan(float(dx.bycode(e, 42))) * 4 if 42 in e else None for e in poly[1:]] if 70 in poly[0] and (int(dx.bycode(poly[0], 70)) & 1): # closed points.append(points[0]) ends = zip(points, points[1:], angles) addition = [points[0]] for sp, ep, a in ends: if a: arcent = _arcdata(sp, ep, a) addition += arc(arcent)[1:] else: addition.append(ep) lines += [addition] # Convert lwpolylines return lines
def mksegments(entities, ndigits=3): """ Convert an iterable of entities to a list of line segments. Arguments: entities: An iterable if dictionaries, each containing a DXF entity. ndigits: Rounds to ndigits after the decimal point. Returns: A list of line segments. Line segments are lists of ≥2 (x,y) tuples. """ def fr(n): return round(float(n), ndigits) def line(e): return [(fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))), (fr(dx.bycode(e, 11)), fr(dx.bycode(e, 21)))] def arc(e): cx, cy = float(dx.bycode(e, 10)), float(dx.bycode(e, 20)) R = fr(dx.bycode(e, 40)) sa, ea = (math.radians(float(dx.bycode(e, 50))), math.radians(float(dx.bycode(e, 51)))) if ea > sa: da = ea - sa else: da = 2 * math.pi - sa + ea if DEVLIM > R: cnt = 1 else: maxstep = 2 * math.acos(1 - DEVLIM / R) if da < 0: maxstep = -maxstep cnt = math.ceil(da / maxstep) step = da / cnt angs = [sa + i * step for i in range(cnt + 1)] pnts = [(fr(cx + R * math.cos(a)), fr(cy + R * math.sin(a))) for a in angs] return pnts # Convert lines lines = [line(e) for e in entities if dx.bycode(e, 0) == 'LINE'] # Convert arcs lines += [arc(e) for e in entities if dx.bycode(e, 0) == 'ARC'] # Convert polylines pi = [n for n, e in enumerate(entities) if dx.bycode(e, 0) == 'POLYLINE'] se = [n for n, e in enumerate(entities) if dx.bycode(e, 0) == 'SEQEND'] for start in pi: end = [n for n in se if n > start][0] poly = entities[start:end] points = [(fr(dx.bycode(e, 10)), fr(dx.bycode(e, 20))) for e in poly[1:]] angles = [ math.atan(float(dx.bycode(e, 42))) * 4 if 42 in e else None for e in poly[1:] ] if 70 in poly[0] and (int(dx.bycode(poly[0], 70)) & 1): # closed points.append(points[0]) ends = zip(points, points[1:], angles) addition = [points[0]] for sp, ep, a in ends: if a: arcent = _arcdata(sp, ep, a) addition += arc(arcent)[1:] else: addition.append(ep) lines += [addition] # Convert lwpolylines return lines