-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPCB_parser.py
156 lines (127 loc) · 5.42 KB
/
PCB_parser.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
149
150
151
152
153
154
155
156
import json
# class PCB():
# __init__(self,data):
# shapeData = data.["shape"]
# self.tracks = self.getTracks(shapeData)
# def parseShapeData
def getFeatures(shapeData):
shapeTypes = set()
for shape in shapeData:
shapeType = shape.split("~")[0]
if shapeType == "LIB":
subshapes = shape.split("#@$")[1:]
inlib =getFeatures(subshapes)
shapeTypes = shapeTypes.union(inlib)
shapeTypes.add(shapeType)
return shapeTypes
def parsePoints(pointText):
points = []
coordList = pointText.split()
xcoords = coordList[0::2]
ycoords = coordList[1::2]
for pair in zip(xcoords, ycoords):
points.append((float(pair[0]), float(pair[1])))
if points == []:
print('A track contained no point information. Returning []. Check for [] to handle exception')
return points
def casteAttributeData(shapeData):
intAttributes = ["layer"]
for intAttrbute in intAttributes:
if intAttrbute in shapeData:
shapeData[intAttrbute] = int(shapeData[intAttrbute])
floatAttributes = ["x", "y", "width", "height", "rot"]
for floatAttribute in floatAttributes:
if floatAttribute in shapeData:
try:
shapeData[floatAttribute] = float(shapeData[floatAttribute])
except ValueError:
shapeData[floatAttribute] = 0.0
print("For ", floatAttribute, ": ", shapeData[floatAttribute], "was not decimal")
return shapeData
def createDictForAttributes(shape):
shapeTypes = {'F', 'SOLIDREGION', 'R', 'A', 'LIB', 'HOLE', 'PL', 'COPPERAREA', 'ARC', 'PLANEZONE', 'T', 'SVGNODE', 'DIMENSION', 'W', 'RECT', 'VIA', 'TRACK', 'TEXT', 'N', 'P', 'PG', 'SHEET', 'PAD', 'PROTRACTOR', 'E', 'CIRCLE', 'J'}
attributeData = None
if "TRACK" in shape:
attributes = shape["TRACK"].split("~")
attributeData = dict()
attributeData["width"] = attributes[0]
attributeData["layer"] = attributes[1]
attributeData["net"] = attributes[2]
attributeData["points"] = parsePoints(attributes[3])
attributeData["id"] = attributes[4]
if "VIA" in shape:
attributes = shape["VIA"].split("~")
attributeData = dict()
attributeData["x"] = attributes[0]
attributeData["y"] = attributes[1]
attributeData["diameter"] = attributes[2]
attributeData["net"] = attributes[3]
attributeData["holeRadius"] = attributes[4]
attributeData["id"] = attributes[5]
if "HOLE" in shape:
attributes = shape["HOLE"].split("~")
attributeData = dict()
attributeData["x"] = attributes[0]
attributeData["y"] = attributes[1]
attributeData["diameter"] = attributes[2]
attributeData["id"] = attributes[3]
if "PAD" in shape:
attributes = shape["PAD"].split("~")
attributeData = dict()
attributeData["type"] = attributes[0]
attributeData["x"] = attributes[1]
attributeData["y"] = attributes[2]
attributeData["width"] = attributes[3]
attributeData["height"] = attributes[4]
attributeData["layer"] = attributes[5]
attributeData["net"] = attributes[6]
attributeData["rot"] = attributes[10]
attributeData["id"] = attributes[11]
if attributeData["type"] == "ELLIPSE":
# attributeData["points"] = parsePoints(attributes[9])
attributeData["id"] = attributes[11]
elif attributeData["type"] == "RECT":
# attributeData["points"] = parsePoints(attributes[9])
attributeData["id"] = attributes[11]
elif attributeData["type"] == "OVAL":
attributeData["net"] = attributes[6]
# attributeData["loci"] = parsePoints(attributes[9])
attributeData["id"] = attributes[11]
elif attributeData["type"] == "POLYGON":
attributeData["net"] = attributes[6]
# attributeData["points"] = parsePoints(attributes[9])
attributeData["id"] = attributes[11]
if "LIB" in shape:
attributes = shape["LIB"].split("~")
attributeData = dict()
attributeData["x"] = attributes[0]
attributeData["y"] = attributes[1]
if attributes[3] == '': # non rotation for lib is left empty
attributeData["rot"] = '0'
else:
attributeData["rot"] = attributes[3]
attributeData["id"] = attributes[5]
if attributeData == None:
for key in shape.keys():
if key not in shapeTypes:
print(key," is not a known shape type")
return attributeData
else:
return casteAttributeData(attributeData)
def createDictForShapes(shapeDatas):
pcbParsed = []
for shape in shapeDatas:
[shapeType, rawShapeData] = shape.split("~", maxsplit=1)
shapeData = createDictForAttributes({shapeType:rawShapeData})
if shapeType == "TRACK" and shapeData['points'] == []: #Some tracks have zeros points #TODO investigate why
break
if shapeType == "LIB":
subshapes = shape.split("#@$")[1:]
if subshapes != ['']:
tmp = createDictForShapes(subshapes)
pcbParsed.append({shapeType:tmp})
else:
pcbParsed.append({shapeType:shapeData})
return pcbParsed
def convertPCBcompressedToJSON(pcb):
return createDictForShapes(pcb["result"]["dataStr"]["shape"])