summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Henrique Silva <ph.silva@gmail.com>2015-01-14 03:15:52 -0200
committerPaulo Henrique Silva <ph.silva@gmail.com>2015-01-14 03:15:52 -0200
commitcbb662491c273e97cfceed94b29a77ce865244dd (patch)
tree7ec54a045d07a2e89d9f0bc705f1b9ca81ec8bc1
parent53ee7566097b5a26cd3a1dab1d730f9606d767e6 (diff)
downloadgerbonara-cbb662491c273e97cfceed94b29a77ce865244dd.tar.gz
gerbonara-cbb662491c273e97cfceed94b29a77ce865244dd.tar.bz2
gerbonara-cbb662491c273e97cfceed94b29a77ce865244dd.zip
Refactor AM aperture handling and add unit conversion support
* Add support to convert between metric/impertial * AM primitives are now properly created and can be converted between metric/imperial. (only Outline primitive is supported, no rendering yet)
-rw-r--r--gerber/gerber_statements.py128
-rw-r--r--gerber/rs274x.py10
2 files changed, 129 insertions, 9 deletions
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 1a6f646..f799f5a 100644
--- a/gerber/gerber_statements.py
+++ b/gerber/gerber_statements.py
@@ -259,13 +259,19 @@ class ADParamStmt(ParamStmt):
self.d = d
self.shape = shape
if modifiers is not None:
- self.modifiers = [[x for x in m.split("X")] for m in modifiers.split(",") if len(m)]
+ self.modifiers = [[float(x) for x in m.split("X")] for m in modifiers.split(",") if len(m)]
else:
self.modifiers = []
+ def to_inch(self):
+ self.modifiers = [[x / 25.4 for x in modifier] for modifier in self.modifiers]
+
+ def to_metric(self):
+ self.modifiers = [[x * 25.4 for x in modifier] for modifier in self.modifiers]
+
def to_gerber(self, settings=None):
if len(self.modifiers):
- return '%ADD{0}{1},{2}*%'.format(self.d, self.shape, ','.join(['X'.join(e) for e in self.modifiers]))
+ return '%ADD{0}{1},{2}*%'.format(self.d, self.shape, ','.join(['X'.join(["%.4f" % x for x in modifier]) for modifier in self.modifiers]))
else:
return '%ADD{0}{1}*%'.format(self.d, self.shape)
@@ -282,6 +288,77 @@ class ADParamStmt(ParamStmt):
return '<Aperture Definition: %d: %s>' % (self.d, shape)
+class AMPrimitive(object):
+
+ def __init__(self, code, exposure):
+ self.code = code
+ self.exposure = exposure
+
+ def to_inch(self):
+ pass
+
+ def to_metric(self):
+ pass
+
+
+class AMOutlinePrimitive(AMPrimitive):
+
+ @classmethod
+ def from_gerber(cls, primitive):
+ modifiers = primitive.split(",")
+
+ code = int(modifiers[0])
+ exposure = "on" if modifiers[1] == "1" else "off"
+ n = int(modifiers[2])
+ start_point = (float(modifiers[3]), float(modifiers[4]))
+ points = []
+
+ for i in range(n):
+ points.append((float(modifiers[5 + i*2]), float(modifiers[5 + i*2 + 1])))
+
+ rotation = float(modifiers[-1])
+
+ return cls(code, exposure, start_point, points, rotation)
+
+ def __init__(self, code, exposure, start_point, points, rotation):
+ super(AMOutlinePrimitive, self).__init__(code, exposure)
+
+ self.start_point = start_point
+ self.points = points
+ self.rotation = rotation
+
+ def to_inch(self):
+ self.start_point = tuple([x / 25.4 for x in self.start_point])
+ self.points = tuple([(x / 25.4, y / 25.4) for x, y in self.points])
+
+ def to_metric(self):
+ self.start_point = tuple([x * 25.4 for x in self.start_point])
+ self.points = tuple([(x * 25.4, y * 25.4) for x, y in self.points])
+
+ def to_gerber(self, settings=None):
+ data = dict(
+ code=self.code,
+ exposure="1" if self.exposure == "on" else "0",
+ n_points=len(self.points),
+ start_point="%.4f,%.4f" % self.start_point,
+ points=",".join(["%.4f,%.4f" % point for point in self.points]),
+ rotation=str(self.rotation)
+ )
+ return "{code},{exposure},{n_points},{start_point},{points},{rotation}".format(**data)
+
+
+class AMUnsupportPrimitive:
+ @classmethod
+ def from_gerber(cls, primitive):
+ return cls(primitive)
+
+ def __init__(self, primitive):
+ self.primitive = primitive
+
+ def to_gerber(self, settings=None):
+ return self.primitive
+
+
class AMParamStmt(ParamStmt):
""" AM - Aperture Macro Statement
"""
@@ -312,10 +389,29 @@ class AMParamStmt(ParamStmt):
"""
ParamStmt.__init__(self, param)
self.name = name
- self.macro = macro
+ self.primitives = self._parsePrimitives(macro)
+
+ def _parsePrimitives(self, macro):
+ primitives = []
+
+ for primitive in macro.split("*"):
+ if primitive[0] == "4":
+ primitives.append(AMOutlinePrimitive.from_gerber(primitive))
+ else:
+ primitives.append(AMUnsupportPrimitive.from_gerber(primitive))
+
+ return primitives
+
+ def to_inch(self):
+ for primitive in self.primitives:
+ primitive.to_inch()
+
+ def to_metric(self):
+ for primitive in self.primitives:
+ primitive.to_metric()
def to_gerber(self, settings=None):
- return '%AM{0}*{1}*%'.format(self.name, self.macro)
+ return '%AM{0}*{1}*%'.format(self.name, "".join([primitive.to_gerber(settings) for primitive in self.primitives]))
def __str__(self):
return '<Aperture Macro %s: %s>' % (self.name, self.macro)
@@ -726,6 +822,30 @@ class CoordStmt(Statement):
ret += self.op
return ret + '*'
+ def to_inch(self):
+ if self.x is not None:
+ self.x = self.x / 25.4
+ if self.y is not None:
+ self.y = self.y / 25.4
+ if self.i is not None:
+ self.i = self.i / 25.4
+ if self.j is not None:
+ self.j = self.j / 25.4
+ if self.function == "G71":
+ self.function = "G70"
+
+ def to_metric(self):
+ if self.x is not None:
+ self.x = self.x * 25.4
+ if self.y is not None:
+ self.y = self.y * 25.4
+ if self.i is not None:
+ self.i = self.i * 25.4
+ if self.j is not None:
+ self.j = self.j * 25.4
+ if self.function == "G70":
+ self.function = "G71"
+
def __str__(self):
coord_str = ''
if self.function:
diff --git a/gerber/rs274x.py b/gerber/rs274x.py
index 3ec7429..2e5a3ec 100644
--- a/gerber/rs274x.py
+++ b/gerber/rs274x.py
@@ -361,15 +361,15 @@ class GerberParser(object):
def _define_aperture(self, d, shape, modifiers):
aperture = None
if shape == 'C':
- diameter = float(modifiers[0][0])
+ diameter = modifiers[0][0]
aperture = Circle(position=None, diameter=diameter)
elif shape == 'R':
- width = float(modifiers[0][0])
- height = float(modifiers[0][1])
+ width = modifiers[0][0]
+ height = modifiers[0][1]
aperture = Rectangle(position=None, width=width, height=height)
elif shape == 'O':
- width = float(modifiers[0][0])
- height = float(modifiers[0][1])
+ width = modifiers[0][0]
+ height = modifiers[0][1]
aperture = Obround(position=None, width=width, height=height)
self.apertures[d] = aperture