#!/usr/bin/python # -*- coding: utf-8 -*- # ## kicadpcb2dxf.py # creates DXF file of selected kicad pcb board # using r12writer from ezdxf modules included # this is a part of kicad StepUp tools; please refer to kicad StepUp tools # for the full licence # ### Copyright (c) 2015 Maurice easyw@katamail.com #**************************************************************************** ## done: # gr_line, gr_circle, gr_arc # add footprint support fp_line, fp_circle, fp_arc # add text support (mirror & alignement not supported) # add multiline text support ## todo: # add quote support # add rotation for module arcs # Purpose: fast & simple but restricted DXF R12 writer, with no in-memory drawing, and without dependencies to other # ezdxf modules. The created DXF file contains no HEADER, TABLES or BLOCKS section only the ENTITIES section is present. # Created: 14.04.2016 # Copyright (C) 2016, Manfred Moitzi # License: MIT License #import pcbnew;pcbnew.GetWizardsBackTrace() from __future__ import unicode_literals dxf_parser="r12writer from ezdxf 0.7.6" __author__ = "mozman " script_name="kicadpcb2dxf" __author_script__="easyw Maurice" ___version___="3.8.2" from contextlib import contextmanager def rnd(x): # adjust output precision of floats by changing 'ndigits' return round(x, ndigits=6) TEXT_ALIGN_FLAGS = { 'LEFT': (0, 0), 'CENTER': (1, 0), 'RIGHT': (2, 0), 'BOTTOM_LEFT': (0, 1), 'BOTTOM_CENTER': (1, 1), 'BOTTOM_RIGHT': (2, 1), 'MIDDLE_LEFT': (0, 2), 'MIDDLE_CENTER': (1, 2), 'MIDDLE_RIGHT': (2, 2), 'TOP_LEFT': (0, 3), 'TOP_CENTER': (1, 3), 'TOP_RIGHT': (2, 3), } @contextmanager def r12writer(stream, fixed_tables=False): if hasattr(stream, 'write'): writer = R12FastStreamWriter(stream, fixed_tables) yield writer writer.close() else: with open(stream, 'wt') as stream: writer = R12FastStreamWriter(stream, fixed_tables) yield writer writer.close() class R12FastStreamWriter(object): def __init__(self, stream, fixed_tables=False): self.stream = stream if fixed_tables: stream.write(PREFACE) stream.write("0\nSECTION\n2\nENTITIES\n") # write header def close(self): self.stream.write("0\nENDSEC\n0\nEOF\n") # write tail def add_line(self, start, end, layer="0", color=None, linetype=None): dxf = ["0\nLINE\n"] dxf.append(dxf_attribs(layer, color, linetype)) dxf.append(dxf_vertex(start, code=10)) dxf.append(dxf_vertex(end, code=11)) self.stream.write(''.join(dxf)) def add_circle(self, center, radius, layer="0", color=None, linetype=None): dxf = ["0\nCIRCLE\n"] dxf.append(dxf_attribs(layer, color, linetype)) dxf.append(dxf_vertex(center)) dxf.append(dxf_tag(40, str(rnd(radius)))) self.stream.write(''.join(dxf)) def add_arc(self, center, radius, start=0, end=360, layer="0", color=None, linetype=None): dxf = ["0\nARC\n"] dxf.append(dxf_attribs(layer, color, linetype)) dxf.append(dxf_vertex(center)) dxf.append(dxf_tag(40, str(rnd(radius)))) dxf.append(dxf_tag(50, str(rnd(start)))) dxf.append(dxf_tag(51, str(rnd(end)))) self.stream.write(''.join(dxf)) def add_point(self, location, layer="0", color=None, linetype=None): dxf = ["0\nPOINT\n"] dxf.append(dxf_attribs(layer, color, linetype)) dxf.append(dxf_vertex(location)) self.stream.write(''.join(dxf)) def add_3dface(self, vertices, invisible=0, layer="0", color=None, linetype=None): self._add_quadrilateral('3DFACE', vertices, invisible, layer, color, linetype) def add_solid(self, vertices, layer="0", color=None, linetype=None): self._add_quadrilateral('SOLID', vertices, 0, layer, color, linetype) def _add_quadrilateral(self, dxftype, vertices, flags, layer, color, linetype): dxf = ["0\n%s\n" % dxftype] dxf.append(dxf_attribs(layer, color, linetype)) vertices = list(vertices) if len(vertices) < 3: raise ValueError("%s needs 3 ot 4 vertices." % dxftype) elif len(vertices) == 3: vertices.append(vertices[-1]) # double last vertex dxf.extend(dxf_vertex(vertex, code) for code, vertex in enumerate(vertices, start=10)) if flags: dxf.append(dxf_tag(70, str(flags))) self.stream.write(''.join(dxf)) def add_polyline(self, vertices, layer="0", color=None, linetype=None): def write_polyline(flags): dxf = ["0\nPOLYLINE\n"] dxf.append(dxf_attribs(layer, color, linetype)) dxf.append(dxf_tag(66, "1")) # entities follow dxf.append(dxf_tag(70, flags)) self.stream.write(''.join(dxf)) polyline_flags, vertex_flags = None, None for vertex in vertices: if polyline_flags is None: # first vertex if len(vertex) == 3: # 3d polyline polyline_flags, vertex_flags = ('8', '32') else: # 2d polyline polyline_flags, vertex_flags = ('0', '0') write_polyline(polyline_flags) dxf = ["0\nVERTEX\n"] dxf.append(dxf_attribs(layer)) dxf.append(dxf_tag(70, vertex_flags)) dxf.append(dxf_vertex(vertex)) self.stream.write(''.join(dxf)) if polyline_flags is not None: self.stream.write("0\nSEQEND\n") def add_text(self, text, insert=(0, 0), height=1., width=1., align="LEFT", rotation=0., oblique=0., style='STANDARD', layer="0", color=None): # text style is always STANDARD without a TABLES section dxf = ["0\nTEXT\n"] dxf.append(dxf_attribs(layer, color)) dxf.append(dxf_vertex(insert, code=10)) dxf.append(dxf_tag(1, str(text))) dxf.append(dxf_tag(40, str(rnd(height)))) if width != 1.: dxf.append(dxf_tag(41, str(rnd(width)))) if rotation != 0.: dxf.append(dxf_tag(50, str(rnd(rotation)))) if oblique != 0.: dxf.append(dxf_tag(51, str(rnd(oblique)))) if style != "STANDARD": dxf.append(dxf_tag(7, str(style))) halign, valign = TEXT_ALIGN_FLAGS[align.upper()] dxf.append(dxf_tag(72, str(halign))) dxf.append(dxf_tag(73, str(valign))) dxf.append(dxf_vertex(insert, code=11)) # align point self.stream.write(''.join(dxf)) def dxf_attribs(layer, color=None, linetype=None): dxf = ["8\n%s\n" % layer] # layer is required if linetype is not None: dxf.append("6\n%s\n" % linetype) if color is not None: if 0 <= int(color) < 257: dxf.append("62\n%d\n" % color) else: raise ValueError("color has to be an integer in the range from 0 to 256.") return "".join(dxf) def dxf_vertex(vertex, code=10): dxf = [] for c in vertex: dxf.append("%d\n%s\n" % (code, str(rnd(c)))) code += 10 return "".join(dxf) def dxf_tag(code, value): return "%d\n%s\n" % (code, value) ################################################################### ##real python code easyw import sys if sys.version_info[0] == 2: #if py2: reload(sys) sys.setdefaultencoding('utf8') #to accept utf8 chars #else: # import importlib # importlib.reload(sys) import re, os from math import sqrt, atan2, degrees, sin, cos, radians import wx import pcbnew from pcbnew import * class pcb2dxf( pcbnew.ActionPlugin ): """ export technical layers of kicad PCB to DXF """ def defaults( self ): """ Method defaults must be redefined self.name should be the menu label to use self.category should be the category (not yet used) self.description should be a comprehensive description of the plugin """ self.name = "Export pcb technical layers to DXF \nversion "+___version___ self.category = "export PCB" self.description = "export technical layers of pcb to DXF (saved board)" self.show_toolbar_button = True self.icon_file_name = os.path.join(os.path.dirname(__file__), './dxf_icon.png') def Run( self ): fileName = GetBoard().GetFileName() if len(fileName)==0: wx.LogMessage("a board needs to be saved/loaded!") else: dirpath = os.path.abspath(os.path.expanduser(fileName)) path, fname = os.path.split(dirpath) ext = os.path.splitext(os.path.basename(fileName))[1] name = os.path.splitext(os.path.basename(fileName))[0] LogMsg="reading from "+ dirpath out_filename=path+os.sep+name+".dxf" LogMsg+="writing to "+out_filename content=[] txtFile = open(fileName,"r") content = txtFile.readlines() content.append(" ") txtFile.close() #wx.MessageDialog(None, 'This is a message box. ONLY TEST!', 'Test', wx.OK | wx.ICON_INFORMATION).ShowModal() #wx.MessageDialog(None, 'This is a message box. ONLY TEST!', content, wx.OK | wx.ICON_INFORMATION).ShowModal() #found_selected=False #board = pcbnew.GetBoard() dlg=wx.MessageBox( 'Exporting technical layers of pcb to DXF\nOnly SAVED board file will be exported to DXF file\n\nversion '+___version___, 'Confirm', wx.OK | wx.CANCEL | wx.ICON_INFORMATION ) if dlg == wx.OK: if os.path.isfile(out_filename): dlg=wx.MessageBox( 'Overwrite DXF file?', 'Confirm', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION ) if dlg == wx.YES: export_dxf(content, out_filename) else: export_dxf(content, out_filename) def export_dxf(content,out_filename): # quote_layer True to move all quote on special layer quote_layer=False align="LEFT" with r12writer(out_filename) as dxf: data=[];createTxt=0;quote_color=127;dimension=0 for line in content: if line.strip().startswith("(at ") and not "(at (xyz" in line: pos=line.split('(at ',1)[-1] plcmt=pos.split(" ") if len (plcmt)<=2: plcmt[1]=plcmt[1].split(')')[0] else: plcmt[2]=plcmt[2].split(')')[0] #say("getting fp offset") #say (plcmt) #say (plcmt[0]+" x off");say (plcmt[1]+" y off") create=0 if "fp_line" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]+" "+layer) #say(coords) if len (plcmt)<=2: xs=float(coords[2])+float(plcmt[0]);ys=-float(coords[3].split(')')[0])-float(plcmt[1]) xe=float(coords[5])+float(plcmt[0]);ye=-float(coords[6].split(')')[0])-float(plcmt[1]) else: rot_angle=float(plcmt[2]) crx=float(plcmt[0]);cry=-float(plcmt[1]) xs1=float(coords[2])+float(plcmt[0]);ys1=-float(coords[3].split(')')[0])-float(plcmt[1]) xe1=float(coords[5])+float(plcmt[0]);ye1=-float(coords[6].split(')')[0])-float(plcmt[1]) r1=sqrt((crx-xs1)**2+(cry-ys1)**2) base_angle1=degrees(atan2(ys1-cry, xs1-crx)) #say(str(rot_angle)+ " rot angle") #say(str(base_angle1)+ " angle1") r2=sqrt((crx-xe1)**2+(cry-ye1)**2) base_angle2=degrees(atan2(ye1-cry, xe1-crx)) #say(str(base_angle2)+ " angle2") #say(str(r1)+ " r1");say(str(r2)+ " r2") #say(str(cx)+ " cx");say(str(cy)+ " cy") #say (rot_angle);say (cx); say(cy) xs=crx-r1*cos(radians(-rot_angle+base_angle1));ys=cry-r1*sin(radians(-rot_angle+base_angle1)) xe=crx-r2*cos(radians(-rot_angle+base_angle2));ye=cry-r2*sin(radians(-rot_angle+base_angle2)) #say(str(xs)+" xs "+str(ys)+" ys "+str(xe)+" xe "+str(ye)+" ye"); #xs=float(coords[4]);ys=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) #say (plcmt[0]+" x off") #say (str(float(plcmt[0]))+" x off") #say(str(xs)+";"+str(ys)+" module") #data.append(str(xs)+";"+str(ys)) dxf.add_line((xs,ys), (xe,ye), layer, color, linetype=None) create=0 if "fp_circle" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]) if len (plcmt)<=2: cx=float(coords[2])+float(plcmt[0]);cy=-float(coords[3].split(')')[0])-float(plcmt[1]) xe=float(coords[5])+float(plcmt[0]);ye=-float(coords[6].split(')')[0])-float(plcmt[1]) data.append(str(cx)+";"+str(cy)) r=sqrt((cx-xe)**2+(cy-ye)**2) dxf.add_circle((cx, cy), r, layer, color, linetype=None) else: rot_angle=float(plcmt[2]) crx=float(plcmt[0]);cry=-float(plcmt[1]) #rotation point ocx=float(coords[2])+float(plcmt[0]);ocy=-float(coords[3].split(')')[0])-float(plcmt[1]) #center of circle xe=float(coords[5])+float(plcmt[0]);ye=-float(coords[6].split(')')[0])-float(plcmt[1]) r1=sqrt((crx-ocx)**2+(cry-ocy)**2) base_angle1=degrees(atan2(cry-ocy, crx-ocx)) #say(str(rot_angle)+ " rot angle") #say(str(base_angle1)+ " angle1") #say(str(r1)+ " r1");say(str(r2)+ " r2") #say(str(cx)+ " cx");say(str(cy)+ " cy") #say (rot_angle);say (cx); say(cy) ncx=crx+r1*cos(radians(-rot_angle+base_angle1));ncy=cry+r1*sin(radians(-rot_angle+base_angle1)) data.append(str(ncx)+";"+str(ncy)) r=sqrt((ocx-xe)**2+(ocy-ye)**2) dxf.add_circle((ncx, ncy), r, layer, color, linetype=None) #say(str(xs)+" xs "+str(ys)+" ys "+str(xe)+" xe "+str(ye)+" ye"); #cx=float(coords[4]);cy=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) # data.append(str(cx)+";"+str(cy)) # r=sqrt((cx-xe)**2+(cy-ye)**2) #dxf.add_circle((cx, cy), r, layer, color, linetype=None) create=0 if "fp_arc" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]) cx=float(coords[2])+float(plcmt[0]);cy=-float(coords[3].split(')')[0])-float(plcmt[1]) xe=float(coords[5])+float(plcmt[0]);ye=-float(coords[6].split(')')[0])-float(plcmt[1]) #cx=float(coords[4]);cy=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) arc_angle=float(coords[8].split(')')[0]) #arc_angle=float(coords[10][:-1]) #endAngle = degrees(atan2(ye-cy, xe-cx)) #startAngle = (endAngle-arc_angle) if arc_angle<0: startAngle = degrees(atan2(ye-cy, xe-cx)) endAngle = (startAngle-arc_angle) else: endAngle = degrees(atan2(ye-cy, xe-cx)) startAngle = (endAngle-arc_angle) center = (cx, cy, 0) # int or float r = sqrt((cx-xe)**2+(cy-ye)**2) #say(str(startAngle)+";"+str(endAngle)) if len (plcmt)<=2: data.append(str(cx)+";"+str(cy)) dxf.add_arc(center, r, startAngle, endAngle, layer, color, linetype=None) else: rot_angle=float(plcmt[2]) crx=float(plcmt[0]);cry=-float(plcmt[1]) #rotation point ocx=cx; ocy=cy #center of circle r1=sqrt((crx-ocx)**2+(cry-ocy)**2) base_angle1=degrees(atan2(cry-ocy, crx-ocx)) #say(str(rot_angle)+ " rot angle") #say(str(base_angle1)+ " angle1") #say(str(r1)+ " r1");say(str(r2)+ " r2") #say(str(cx)+ " cx");say(str(cy)+ " cy") #say (rot_angle);say (cx); say(cy) ncx=crx+r1*cos(radians(-rot_angle+base_angle1));ncy=cry+r1*sin(radians(-rot_angle+base_angle1)) data.append(str(ncx)+";"+str(ncy)) center = (ncx, ncy, 0) # int or float r2=sqrt((crx-xe)**2+(cry-ye)**2) base_angle2=degrees(atan2(cry-ye, crx-xe)) xe2=crx-r2*cos(radians(-rot_angle+base_angle2));ye2=cry-r2*sin(radians(-rot_angle+base_angle2)) if arc_angle+rot_angle>0: startAngle = degrees(atan2(ye2-ncy, xe2-ncx)) endAngle = (startAngle-arc_angle) else: endAngle = degrees(atan2(ye2-ncy, xe2-ncx)) startAngle = (endAngle-arc_angle) #r=sqrt((ocx-xe)**2+(ocy-ye)**2) dxf.add_arc(center, r, startAngle, endAngle, layer, color, linetype=None) #say(str(xs)+" xs "+str(ys)+" ys "+str(xe)+" xe "+str(ye)+" ye"); create=0 if "gr_line" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]+" "+layer) #say(coords) xs=float(coords[2]);ys=-float(coords[3].split(')')[0]) xe=float(coords[5]);ye=-float(coords[6].split(')')[0]) #xs=float(coords[4]);ys=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) #data.append(str(xs)+";"+str(ys)) dxf.add_line((xs,ys), (xe,ye), layer, color, linetype=None) create=0 if "gr_circle" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]) cx=float(coords[2]);cy=-float(coords[3].split(')')[0]) xe=float(coords[5]);ye=-float(coords[6].split(')')[0]) #cx=float(coords[4]);cy=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) data.append(str(cx)+";"+str(cy)) r=sqrt((cx-xe)**2+(cy-ye)**2) dxf.add_circle((cx, cy), r, layer, color, linetype=None) create=0 if "gr_arc" in line: if "Dwgs" in line: layer=0; color=None; create=1 if "Cmts" in line: layer="Cmts"; color=1; create=1 if "Edge" in line: layer="Edge"; color=2; create=1 if "Eco1" in line: layer="Eco1"; color=3; create=1 if "Eco2" in line: layer="Eco2"; color=4; create=1 if "F.Fab" in line: layer="FFab"; color=5; create=1 if "B.Fab" in line: layer="BFab"; color=6; create=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; create=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; create=1 if "Margin" in line: layer="Margin"; color=9; create=1 if create==1: coords=line.split('(',1)[-1] coords=coords.split(" ") #say(coords[4]+";"+coords[5][:-1]) cx=float(coords[2]);cy=-float(coords[3].split(')')[0]) xe=float(coords[5]);ye=-float(coords[6].split(')')[0]) #cx=float(coords[4]);cy=-float(coords[5][:-1]) #xe=float(coords[7]);ye=-float(coords[8][:-1]) arc_angle=float(coords[8].split(')')[0]) #say(arc_angle) #arc_angle=float(coords[10][:-1]) data.append(str(cx)+";"+str(cy)) #endAngle = degrees(atan2(ye-cy, xe-cx)) #startAngle = (endAngle-arc_angle) if arc_angle<0: startAngle = degrees(atan2(ye-cy, xe-cx)) endAngle = (startAngle-arc_angle) else: endAngle = degrees(atan2(ye-cy, xe-cx)) startAngle = (endAngle-arc_angle) center = (cx, cy, 0) # int or float r = sqrt((cx-xe)**2+(cy-ye)**2) #say(str(startAngle)+";"+str(endAngle)) dxf.add_arc(center, r, startAngle, endAngle, layer, color, linetype=None) #createTxt=0 if "gr_text" in line: if "Dwgs" in line: layer=0; color=None; createTxt=1 if "Cmts" in line: layer="Cmts"; color=1; createTxt=1 if "Edge" in line: layer="Edge"; color=2; createTxt=1 if "Eco1" in line: layer="Eco1"; color=3; createTxt=1 if "Eco2" in line: layer="Eco2"; color=4; createTxt=1 if "F.Fab" in line: layer="FFab"; color=5; createTxt=1 if "B.Fab" in line: layer="BFab"; color=6; createTxt=1 if "F.CrtYd" in line: layer="FCrtYd"; color=7; createTxt=1 if "B.CrtYd" in line: layer="BCrtYd"; color=8; createTxt=1 if "Margin" in line: layer="Margin"; color=9; createTxt=1 if createTxt==1: #(gr_text Rotate (at 325.374 52.705 15) (layer Eco2.User) line=line.strip().split("(gr_text ")[1].split("(at") text=line[0].replace("\"", "").replace("\'", "") #say(line[1].split(" ")) px=line[1].split(" ")[1];py=line[1].split(" ")[2].replace(")", "") if "layer" not in line[1].split(" ")[3]: rot=line[1].split(" ")[3].replace(")", "") else: rot="0" #say(line);say(text);say(px+";"+py+";"+rot) if "(effects" in line and createTxt==1: createTxt=0 size=(line.split("(size ")[1].split(" ")) #say (line) #sizeX=int(round(float(size[0]))) #sizeY=int(round(float(size[1].replace(")", "")))) sizeX=(float(size[0])) sizeY=(float(size[1].replace(")", ""))) #say(sizeX);say(sizeY) text1=text.split("\\n") #say (text1) #say (len(text1)) posY=-float(py) # multiline support if dimension==1 and quote_layer: color=quote_color layer="Quote" dimension=0 for txt in text1: dxf.add_text(txt,(float(px),posY),sizeX,sizeY,align,float(rot),0.,'SIMPLEX',layer,color) posY=posY-sizeY*1.3 align="LEFT" # dxf.add_text(text,(float(px),-float(py)),sizeX,sizeY,"LEFT",float(rot),0.,'STANDARD',layer,color) if "(dimension" in line: dimension=1;align="MIDDLE_CENTER" if "(feature" in line or "(crossbar" in line or "(arrow" in line: dimension_bar=line.split("(xy") #say(dimension_bar) dsx=float(dimension_bar[1].split(" ")[1]) dsy=float(dimension_bar[1].split(" ")[2].replace(")","")) dex=float(dimension_bar[2].split(" ")[1]) dey=float(dimension_bar[2].split(" ")[2].replace(")","")) #say(str(dsx)+";"+str(dsy)+";;"+str(dex)+";"+str(dey)) dxf.add_line((dsx,-dsy), (dex,-dey), layer, color, linetype=None) #say (data) wx.MessageDialog(None, "SAVED board to dxf --> "+out_filename+" written\n\n'pcb2dxf' version: "+___version___, 'DXF exported', wx.OK | wx.ICON_INFORMATION).ShowModal() ### end export_dxf pcb2dxf().register() PREFACE = """ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1009 9 $DWGCODEPAGE 3 ANSI_1252 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 LTYPE 5 431 70 20 0 LTYPE 5 40F 2 CONTINUOUS 70 0 3 Solid line 72 65 73 0 40 0.0 0 LTYPE 5 410 2 CENTER 70 0 3 Center ____ _ ____ _ ____ _ ____ _ ____ _ ____ 72 65 73 4 40 2.0 49 1.25 49 -0.25 49 0.25 49 -0.25 0 LTYPE 5 411 2 DASHED 70 0 3 Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _ 72 65 73 2 40 0.75 49 0.5 49 -0.25 0 LTYPE 5 412 2 PHANTOM 70 0 3 Phantom ______ __ __ ______ __ __ ______ 72 65 73 6 40 2.5 49 1.25 49 -0.25 49 0.25 49 -0.25 49 0.25 49 -0.25 0 LTYPE 5 413 2 HIDDEN 70 0 3 Hidden __ __ __ __ __ __ __ __ __ __ __ __ __ __ 72 65 73 2 40 9.525 49 6.345 49 -3.175 0 LTYPE 5 43B 2 CENTERX2 70 0 3 Center (2x) ________ __ ________ __ ________ 72 65 73 4 40 3.5 49 2.5 49 -0.25 49 0.5 49 -0.25 0 LTYPE 5 43C 2 CENTER2 70 0 3 Center (.5x) ____ _ ____ _ ____ _ ____ _ ____ 72 65 73 4 40 1.0 49 0.625 49 -0.125 49 0.125 49 -0.125 0 LTYPE 5 43D 2 DASHEDX2 70 0 3 Dashed (2x) ____ ____ ____ ____ ____ ____ 72 65 73 2 40 1.2 49 1.0 49 -0.2 0 LTYPE 5 43E 2 DASHED2 70 0 3 Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ 72 65 73 2 40 0.3 49 0.25 49 -0.05 0 LTYPE 5 43F 2 PHANTOMX2 70 0 3 Phantom (2x)____________ ____ ____ ____________ 72 65 73 6 40 4.25 49 2.5 49 -0.25 49 0.5 49 -0.25 49 0.5 49 -0.25 0 LTYPE 5 440 2 PHANTOM2 70 0 3 Phantom (.5x) ___ _ _ ___ _ _ ___ _ _ ___ _ _ ___ 72 65 73 6 40 1.25 49 0.625 49 -0.125 49 0.125 49 -0.125 49 0.125 49 -0.125 0 LTYPE 5 441 2 DASHDOT 70 0 3 Dash dot __ . __ . __ . __ . __ . __ . __ . __ 72 65 73 4 40 1.4 49 1.0 49 -0.2 49 0.0 49 -0.2 0 LTYPE 5 442 2 DASHDOTX2 70 0 3 Dash dot (2x) ____ . ____ . ____ . ____ 72 65 73 4 40 2.4 49 2.0 49 -0.2 49 0.0 49 -0.2 0 LTYPE 5 443 2 DASHDOT2 70 0 3 Dash dot (.5x) _ . _ . _ . _ . _ . _ . _ . _ 72 65 73 4 40 0.7 49 0.5 49 -0.1 49 0.0 49 -0.1 0 LTYPE 5 444 2 DOT 70 0 3 Dot . . . . . . . . . . . . . . . . 72 65 73 2 40 0.2 49 0.0 49 -0.2 0 LTYPE 5 445 2 DOTX2 70 0 3 Dot (2x) . . . . . . . . 72 65 73 2 40 0.4 49 0.0 49 -0.4 0 LTYPE 5 446 2 DOT2 70 0 3 Dot (.5) . . . . . . . . . . . . . . . . . . . 72 65 73 2 40 0.1 49 0.0 49 -0.1 0 LTYPE 5 447 2 DIVIDE 70 0 3 Divide __ . . __ . . __ . . __ . . __ . . __ 72 65 73 6 40 1.6 49 1.0 49 -0.2 49 0.0 49 -0.2 49 0.0 49 -0.2 0 LTYPE 5 448 2 DIVIDEX2 70 0 3 Divide (2x) ____ . . ____ . . ____ . . ____ 72 65 73 6 40 2.6 49 2.0 49 -0.2 49 0.0 49 -0.2 49 0.0 49 -0.2 0 LTYPE 5 449 2 DIVIDE2 70 0 3 Divide(.5x) _ . _ . _ . _ . _ . _ . _ . _ 72 65 73 6 40 0.8 49 0.5 49 -0.1 49 0.0 49 -0.1 49 0.0 49 -0.1 0 ENDTAB 0 TABLE 2 STYLE 5 433 70 18 0 STYLE 5 417 2 STANDARD 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 0 STYLE 5 44A 2 ARIAL 70 0 40 0.0 41 1.0 50 0.0 71 0 42 1.0 3 arial.ttf 4 0 STYLE 5 44F 2 ARIAL_NARROW 70 0 40 0.0 41 1.0 50 0.0 71 0 42 1.0 3 arialn.ttf 4 0 STYLE 5 453 2 ISOCPEUR 70 0 40 0.0 41 1.0 50 0.0 71 0 42 1.0 3 isocpeur.ttf 4 0 STYLE 5 455 2 TIMES 70 0 40 0.0 41 1.0 50 0.0 71 0 42 1.0 3 times.ttf 4 0 ENDTAB 0 TABLE 2 VIEW 5 434 70 0 0 ENDTAB 0 ENDSEC """