Skip to content

Commit 8fb55d7

Browse files
committed
Add EasyEda file parser
Issue #95
1 parent 2a836c0 commit 8fb55d7

File tree

6 files changed

+607
-19
lines changed

6 files changed

+607
-19
lines changed

InteractiveHtmlBom/core/ibom.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ def main(parser, config, logger):
239239
# type: (EcadParser, Config, Logger) -> None
240240
global log
241241
log = logger
242-
pcb_file_name = parser.file_name
242+
pcb_file_name = os.path.basename(parser.file_name)
243+
pcb_file_dir = os.path.dirname(parser.file_name)
244+
243245
# Get extra field data
244246
extra_fields = None
245247
if config.netlist_file and os.path.isfile(config.netlist_file):
@@ -266,9 +268,10 @@ def main(parser, config, logger):
266268

267269
extra_fields = extra_fields[1] if extra_fields else None
268270

269-
pcb_file_dir = os.path.dirname(pcb_file_name)
270-
271271
pcbdata, components = parser.parse()
272+
if not pcbdata or not components:
273+
logger.error('Parsing failed.')
274+
exit(1)
272275
pcbdata["bom"]["both"] = generate_bom(components, config, extra_fields)
273276

274277
# build BOM

InteractiveHtmlBom/ecad/__init__.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1-
def get_kicad_parser(file_name, logger, board):
1+
import os
2+
3+
4+
def get_parser_by_extension(file_name, logger):
5+
ext = os.path.splitext(file_name)[1]
6+
if ext == '.kicad_pcb':
7+
return get_kicad_parser(file_name, logger)
8+
elif ext == '.json':
9+
return get_easyeda_parser(file_name, logger)
10+
else:
11+
return None
12+
13+
14+
def get_kicad_parser(file_name, logger, board=None):
215
from .kicad import PcbnewParser
316
return PcbnewParser(file_name, logger, board)
17+
18+
19+
def get_easyeda_parser(file_name, logger):
20+
from .easyeda import EasyEdaParser
21+
return EasyEdaParser(file_name, logger)

InteractiveHtmlBom/ecad/common.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import math
2+
3+
14
class EcadParser(object):
25

36
def __init__(self, file_name, logger):
@@ -30,3 +33,94 @@ def __init__(self, ref, val, footprint, layer, attr=None):
3033
self.footprint = footprint
3134
self.layer = layer
3235
self.attr = attr
36+
37+
38+
class BoundingBox(object):
39+
"""Geometry util to calculate and compound bounding box of simple shapes."""
40+
41+
def __init__(self):
42+
self._x0 = None
43+
self._y0 = None
44+
self._x1 = None
45+
self._y1 = None
46+
47+
def to_dict(self):
48+
# type: () -> dict
49+
return {
50+
"minx": self._x0,
51+
"miny": self._y0,
52+
"maxx": self._x1,
53+
"maxy": self._y1,
54+
}
55+
56+
def to_component_dict(self):
57+
# type: () -> dict
58+
return {
59+
"pos": [self._x0, self._y0],
60+
"size": [self._x1 - self._x0, self._y1 - self._y0],
61+
}
62+
63+
def add(self, other):
64+
"""Add another bounding box.
65+
:type other: BoundingBox
66+
"""
67+
if other._x0 is not None:
68+
self.add_point(other._x0, other._y0)
69+
self.add_point(other._x1, other._y1)
70+
return self
71+
72+
@staticmethod
73+
def _rotate(x, y, rx, ry, angle):
74+
sin = math.sin(math.radians(angle))
75+
cos = math.cos(math.radians(angle))
76+
new_x = rx + (x - rx) * cos - (y - ry) * sin
77+
new_y = ry + (x - rx) * sin + (y - ry) * cos
78+
return new_x, new_y
79+
80+
def add_point(self, x, y, rx=0, ry=0, angle=0):
81+
x, y = self._rotate(x, y, rx, ry, angle)
82+
if self._x0 is None:
83+
self._x0 = x
84+
self._y0 = y
85+
self._x1 = x
86+
self._y1 = y
87+
else:
88+
self._x0 = min(self._x0, x)
89+
self._y0 = min(self._y0, y)
90+
self._x1 = max(self._x1, x)
91+
self._y1 = max(self._y1, y)
92+
return self
93+
94+
def add_segment(self, x0, y0, x1, y1, r):
95+
self.add_circle(x0, y0, r)
96+
self.add_circle(x1, y1, r)
97+
return self
98+
99+
def add_rectangle(self, x, y, w, h, angle=0):
100+
self.add_point(x - w / 2, y - h / 2, x, y, angle)
101+
self.add_point(x + w / 2, y - h / 2, x, y, angle)
102+
self.add_point(x - w / 2, y + h / 2, x, y, angle)
103+
self.add_point(x + w / 2, y + h / 2, x, y, angle)
104+
return self
105+
106+
def add_circle(self, x, y, r):
107+
self.add_point(x - r, y)
108+
self.add_point(x, y - r)
109+
self.add_point(x + r, y)
110+
self.add_point(x, y + r)
111+
return self
112+
113+
def add_arc(self):
114+
# TODO
115+
pass
116+
117+
def pad(self, amount):
118+
"""Add small padding to the box."""
119+
if self._x0 is not None:
120+
self._x0 -= amount
121+
self._y0 -= amount
122+
self._x1 += amount
123+
self._y1 += amount
124+
125+
def initialized(self):
126+
return self._x0 is not None

0 commit comments

Comments
 (0)