ba754d49e3a7e7f77ffaa9b2c014cb46cab7b9d8
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

1) """
2) Exporting of GNU PCB files to DXF.
3) """
4) 
5) import ezdxf
6) import sys
7) 
8) import pcb_types
9) 
10) 
11) class DxfFootprintWriter():
12)     """
13)     Writer for DXF files from GNU PCB footprints.
14)     """
15) 
16)     def __init__(self):
17)         self._doc = ezdxf.new('R12')
18)         self._msp = self._doc.modelspace()
19)         self._layers = {}
20)         self._addLayer('clearance', 8)  # gray
21)         self._addLayer('hole_drill', 3)  # green
22)         self._addLayer('mask', 16)  # dark red
23)         self._addLayer('name', 7)  # white
24)         self._addLayer('number', 7)  # white
25)         self._addLayer('pin_copper', 1)  # red
26)         self._addLayer('pin_drill', 5)  # blue
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

27)         self._addLayer('silk_center', 2)  # yellow
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

28) 
29)     def _addCircle(self, x: pcb_types.Coordinate, y: pcb_types.Coordinate,
30)                    d: pcb_types.Coordinate, layer_name: str):
31)         self._msp.add_circle((x.mm, -y.mm),
32)                              radius=d.mm / 2,
33)                              dxfattribs={'layer': layer_name})
34) 
35)     def _addOctagon(self, cx: pcb_types.Coordinate, cy: pcb_types.Coordinate,
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

36)                     size: pcb_types.Coordinate, layer_name: str):
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

37)         l = size.mm / 2
38)         s = l / (1 + 2**.5)
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

39)         points = [(cx.mm - s, -cy.mm - l), (cx.mm + s, -cy.mm - l),
40)                   (cx.mm + l, -cy.mm - s), (cx.mm + l, -cy.mm + s),
41)                   (cx.mm + s, -cy.mm + l), (cx.mm - s, -cy.mm + l),
42)                   (cx.mm - l, -cy.mm + s), (cx.mm - l, -cy.mm - s),
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

43)                   (cx.mm - s, -cy.mm - l)]
44)         self._msp.add_polyline2d(points, dxfattribs={'layer': layer_name})
45) 
46)     def _addSquare(self, cx: pcb_types.Coordinate, cy: pcb_types.Coordinate,
47)                    size: pcb_types.Coordinate, layer_name: str):
48)         points = [(cx.mm - size.mm / 2, -cy.mm - size.mm / 2),
49)                   (cx.mm + size.mm / 2, -cy.mm - size.mm / 2),
50)                   (cx.mm + size.mm / 2, -cy.mm + size.mm / 2),
51)                   (cx.mm - size.mm / 2, -cy.mm + size.mm / 2),
52)                   (cx.mm - size.mm / 2, -cy.mm - size.mm / 2)]
53)         self._msp.add_polyline2d(points, dxfattribs={'layer': layer_name})
54) 
55)     def _addLayer(self, name: str, color: int = 7):
56)         if name in self._layers:
57)             return
58)         self._layers[name] = self._doc.layers.new(name=name,
59)                                                   dxfattribs={
60)                                                       'linetype': 'Continuous',
61)                                                       'color': color
62)                                                   })
63) 
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

64)     def _addLine(self, x1: pcb_types.Coordinate, y1: pcb_types.Coordinate,
65)                  x2: pcb_types.Coordinate, y2: pcb_types.Coordinate,
66)                  layer_name: str):
67)         self._msp.add_line((x1.mm, -y1.mm), (x2.mm, -y2.mm),
68)                            dxfattribs={'layer': layer_name})
69) 
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

70)     def _addText(self,
71)                  x: pcb_types.Coordinate,
72)                  y: pcb_types.Coordinate,
73)                  t: str,
74)                  layer_name: str,
75)                  height: pcb_types.Coordinate = None,
76)                  align: str = None):
77)         dxfattribs = {'layer': layer_name}
78)         if height is not None:
79)             dxfattribs['height'] = height.mm
80)         text = self._msp.add_text(t, dxfattribs=dxfattribs)
81)         kwargs = {}
82)         if align is not None:
83)             kwargs['align'] = align
84)         text.set_pos((x.mm, -y.mm), **kwargs)
85) 
86)     def _drawHole(self, pin: pcb_types.Pin):
87)         self._addCircle(pin.r_x, pin.r_y, pin.drill, 'hole_drill')
88)         self._addCircle(pin.r_x, pin.r_y, pin.thickness + pin.clearance,
89)                         'clearance')
90)         self._addCircle(pin.r_x, pin.r_y, pin.mask, 'mask')
91)         self._drawNameNumber(pin.r_x,
92)                              pin.r_y,
93)                              pin.name,
94)                              pin.number,
95)                              height=pin.drill / 2)
96) 
97)     def _drawNameNumber(self,
98)                         x: pcb_types.Coordinate,
99)                         y: pcb_types.Coordinate,
100)                         name: str,
101)                         number: str,
102)                         height: pcb_types.Coordinate = None):
103)         self._addText(x, y, name, 'name', height=height, align='BOTTOM_CENTER')
104)         self._addText(x,
105)                       y,
106)                       number,
107)                       'number',
108)                       height=height,
109)                       align='TOP_CENTER')
110) 
111)     def _drawPinOctagon(self, pin: pcb_types.Pin):
112)         self._addOctagon(pin.r_x, pin.r_y, pin.thickness, 'pin_copper')
113)         self._addCircle(pin.r_x, pin.r_y, pin.drill, 'pin_drill')
114)         self._addOctagon(pin.r_x, pin.r_y, pin.thickness + pin.clearance,
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

115)                          'clearance')
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

116)         self._addOctagon(pin.r_x, pin.r_y, pin.mask, 'mask')
117)         self._drawNameNumber(pin.r_x,
118)                              pin.r_y,
119)                              pin.name,
120)                              pin.number,
121)                              height=pin.drill / 2)
122) 
123)     def _drawPinRound(self, pin: pcb_types.Pin):
124)         self._addCircle(pin.r_x, pin.r_y, pin.thickness, 'pin_copper')
125)         self._addCircle(pin.r_x, pin.r_y, pin.drill, 'pin_drill')
126)         self._addCircle(pin.r_x, pin.r_y, pin.thickness + pin.clearance,
127)                         'clearance')
128)         self._addCircle(pin.r_x, pin.r_y, pin.mask, 'mask')
129)         self._drawNameNumber(pin.r_x,
130)                              pin.r_y,
131)                              pin.name,
132)                              pin.number,
133)                              height=pin.drill / 2)
134) 
135)     def _drawPinSquare(self, pin: pcb_types.Pin):
136)         self._addSquare(pin.r_x, pin.r_y, pin.thickness, 'pin_copper')
137)         self._addCircle(pin.r_x, pin.r_y, pin.drill, 'pin_drill')
138)         self._addSquare(pin.r_x, pin.r_y, pin.thickness + pin.clearance,
139)                         'clearance')
140)         self._addSquare(pin.r_x, pin.r_y, pin.mask, 'mask')
141)         self._drawNameNumber(pin.r_x,
142)                              pin.r_y,
143)                              pin.name,
144)                              pin.number,
145)                              height=pin.drill / 2)
146) 
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

147)     def drawElementLine(self, element_line: pcb_types.ElementLine):
148)         """
149)         Draw element line to DXF.
150)         """
151)         self._addLine(element_line.r_x1, element_line.r_y1, element_line.r_x2,
152)                       element_line.r_y2, 'silk_center')
153)         # TODO element_line.thickness
154)         # TODO element_line.s_flags onsolder
155) 
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

156)     def drawFootprint(self, fp: pcb_types.Element):
157)         """
158)         Draw footprint to DXF.
159)         """
160)         # draw entities in header
161)         # TODO
162)         # draw entities in body
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

163)         type2method = {
164)             pcb_types.ElementLine: self.drawElementLine,
165)             pcb_types.Pin: self.drawPin
166)         }
Stefan Schuermans DXF export of pins + holes

Stefan Schuermans authored 3 years ago

167)         for entity in fp.body:
168)             try:
169)                 method = type2method[type(entity)]
170)                 method(entity)
171)             except KeyError:
172)                 # TODO
173)                 print(
174)                     'warning: ignoring unknown entity of'
175)                     f' type {type(entity).__name__:s}',
176)                     file=sys.stderr)
177) 
178)     def drawPin(self, pin: pcb_types.Pin):
Stefan Schuermans begin DXF export of element...

Stefan Schuermans authored 3 years ago

179)         """
180)         Draw pin to DXF.
181)         """