/
brdParser.py
148 lines (118 loc) · 5.37 KB
/
brdParser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from xml.parsers.expat import ParserCreate
class boardParser:
__slots__=('myDict','tree','polygonHolder','polygonIndex','lastPolygonHolder','textHolder','lastTextHolder','textIndex','addTo')
def __init__(self):
self.myDict={}
self.tree=[]
self.polygonIndex=-1
self.polygonHolder=''
self.lastPolygonHolder=''
self.textHolder=''
self.lastTextHolder=''
self.textIndex=-1
self.addTo=self.myDict
def start_element(self,name,attrs):
self.addTo=self.myDict
if name=='autorouter' or name=='designrules' or self.tree.__contains__('designrules') or self.tree.__contains__('autorouter'):
self.tree.append(name)
return None
if len(self.tree)>0:
for unit in self.tree:
self.addTo=self.addTo[unit]
if name=='setting':
for key in attrs:
self.addTo[key]=attrs[key]
else:
if name=='layer':
name=attrs['number']
self.addTo[name]=attrs
elif name=='element' or name=='signal' or name=='library' or name=='class' or name=='package' or name=='attribute':
name=attrs['name']
self.addTo[name]=attrs
elif name=='smd' or name=='pad':
if self.addTo.get(name)==None:
self.addTo[name]={}
pname=attrs['name']
self.addTo[name][pname]=attrs
elif name=='contactref':
if self.addTo.get('contactref')==None:
self.addTo['contactref']={}
name=attrs['element']+':'+attrs['pad']
self.addTo['contactref'][name]=attrs
elif name=='wire' or name=='circle' or name=='rectangle' or name=='polygon' or name=='via':
if name=='polygon':
self.polygonHolder=self.tree[-1]
if not self.polygonHolder == self.lastPolygonHolder:
self.polygonIndex=-1
self.lastPolygonHolder=self.polygonHolder
self.polygonIndex+=1
if self.addTo.get(name)==None:
self.addTo[name]=[]
self.addTo[name].append(attrs)
elif name=='vertex':
#vertexs lie within polygon... therefore self.addTo will be a list of dictionaries see above
#we must add the vertex to the correct dictionary
if self.addTo[self.polygonIndex].get('vertex')==None: #makes sure there is a vertex list in the polygon
self.addTo[self.polygonIndex]['vertex']=[]
self.addTo[self.polygonIndex]['vertex'].append(attrs)
elif name=='text':
self.textHolder=self.tree[-1]
if not self.textHolder == self.lastTextHolder:
self.textIndex=-1
self.lastTextHolder=self.textHolder
self.textIndex+=1
if self.addTo.get(name)==None:
self.addTo[name]=[]
self.addTo[name].append(attrs)
else:
self.addTo[name]=attrs
self.tree.append(name)
def end_element(self,name):
self.tree.pop()
def char_data(self,data):
if self.tree[-1]=='text':
if self.addTo['text'][self.textIndex].get('txtData')==None:
self.addTo['text'][self.textIndex]['txtData']=''
self.addTo['text'][self.textIndex]['txtData']+=data
def parse(self,inFile):
encoding='utf-8'
p=ParserCreate(encoding)
p.StartElementHandler = self.start_element
p.EndElementHandler = self.end_element
p.CharacterDataHandler = self.char_data
contents=''
for line in inFile:
contents+=line.strip()
p.Parse(contents)
self.myDict['border']=self.getBorder()
return self.myDict
def getBorder(self):
"""
Gets the bounding box of the entire Board based on the board outline layer
Returns:
a dictionary containing info about the bounding box
keys= left, right, top, bottom, cX, cY
Preconditions:
The board must have an edge Layer to get the bounds from
"""
left=float('inf')
right=float('-inf')
top=float('-inf')
bottom=float('inf')
wires=self.myDict['eagle']['drawing']['board']['plain']['wire']
for wire in wires:
if wire.get('layer')=='20':
xs=(float(wire['x1']),float(wire['x2']))
ys=(float(wire['y1']),float(wire['y2']))
if max(xs)>right:
right=max(xs)
if min(xs)<left:
left=min(xs)
if max(ys)>top:
top=max(ys)
if min(ys)<bottom:
bottom=min(ys)
cX=(right-left)/2
cY=(top-bottom)/2
border={'left':str(left),'right':str(right),'top':str(top),'bottom':str(bottom),'cX':str(cX),'cY':str(cY)}
return border