summaryrefslogtreecommitdiff
path: root/gerber/gerber_statements.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerber/gerber_statements.py')
-rw-r--r--gerber/gerber_statements.py107
1 files changed, 105 insertions, 2 deletions
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 9931acf..52e7ac3 100644
--- a/gerber/gerber_statements.py
+++ b/gerber/gerber_statements.py
@@ -26,6 +26,7 @@ from .utils import (parse_gerber_value, write_gerber_value, decimal_string,
from .am_statements import *
from .am_read import read_macro
from .am_eval import eval_macro
+from .primitives import AMGroup
class Statement(object):
@@ -92,6 +93,11 @@ class ParamStmt(Statement):
class FSParamStmt(ParamStmt):
""" FS - Gerber Format Specification Statement
"""
+
+ @classmethod
+ def from_settings(cls, settings):
+
+ return cls('FS', settings.zero_suppression, settings.notation, settings.format)
@classmethod
def from_dict(cls, stmt_dict):
@@ -167,6 +173,10 @@ class FSParamStmt(ParamStmt):
class MOParamStmt(ParamStmt):
""" MO - Gerber Mode (measurement units) Statement.
"""
+
+ @classmethod
+ def from_units(cls, units):
+ return cls(None, units)
@classmethod
def from_dict(cls, stmt_dict):
@@ -225,6 +235,11 @@ class LPParamStmt(ParamStmt):
param = stmt_dict['param']
lp = 'clear' if stmt_dict.get('lp') == 'C' else 'dark'
return cls(param, lp)
+
+ @classmethod
+ def from_region(cls, region):
+ #todo what is the first param?
+ return cls(None, region.level_polarity)
def __init__(self, param, lp):
""" Initialize LPParamStmt class
@@ -257,7 +272,31 @@ class LPParamStmt(ParamStmt):
class ADParamStmt(ParamStmt):
""" AD - Gerber Aperture Definition Statement
"""
-
+
+ @classmethod
+ def rect(cls, dcode, width, height):
+ '''Create a rectangular aperture definition statement'''
+ return cls('AD', dcode, 'R', ([width, height],))
+
+ @classmethod
+ def circle(cls, dcode, diameter):
+ '''Create a circular aperture definition statement'''
+ return cls('AD', dcode, 'C', ([diameter],))
+
+ @classmethod
+ def obround(cls, dcode, width, height):
+ '''Create an obround aperture definition statement'''
+ return cls('AD', dcode, 'O', ([width, height],))
+
+ @classmethod
+ def polygon(cls, dcode, diameter, num_vertices, rotation, hole_diameter):
+ '''Create a polygon aperture definition statement'''
+ return cls('AD', dcode, 'P', ([diameter, num_vertices, rotation, hole_diameter],))
+
+ @classmethod
+ def macro(cls, dcode, name):
+ return cls('AD', dcode, name, '')
+
@classmethod
def from_dict(cls, stmt_dict):
param = stmt_dict.get('param')
@@ -292,7 +331,9 @@ class ADParamStmt(ParamStmt):
ParamStmt.__init__(self, param)
self.d = d
self.shape = shape
- if modifiers:
+ if isinstance(modifiers, tuple):
+ self.modifiers = modifiers
+ elif modifiers:
self.modifiers = [tuple([float(x) for x in m.split("X") if len(x)]) for m in modifiers.split(",") if len(m)]
else:
self.modifiers = [tuple()]
@@ -388,6 +429,8 @@ class AMParamStmt(ParamStmt):
self.primitives.append(AMThermalPrimitive.from_gerber(primitive))
else:
self.primitives.append(AMUnsupportPrimitive.from_gerber(primitive))
+
+ return AMGroup(self.primitives, stmt=self, units=self.units)
def to_inch(self):
if self.units == 'metric':
@@ -814,6 +857,14 @@ class CoordStmt(Statement):
""" Coordinate Data Block
"""
+ OP_DRAW = 'D01'
+ OP_MOVE = 'D02'
+ OP_FLASH = 'D03'
+
+ FUNC_LINEAR = 'G01'
+ FUNC_ARC_CW = 'G02'
+ FUNC_ARC_CCW = 'G03'
+
@classmethod
def from_dict(cls, stmt_dict, settings):
function = stmt_dict['function']
@@ -832,6 +883,32 @@ class CoordStmt(Statement):
if j is not None:
j = parse_gerber_value(stmt_dict.get('j'), settings.format, settings.zero_suppression)
return cls(function, x, y, i, j, op, settings)
+
+ @classmethod
+ def move(cls, func, point):
+ if point:
+ return cls(func, point[0], point[1], None, None, CoordStmt.OP_MOVE, None)
+ # No point specified, so just write the function. This is normally for ending a region (D02*)
+ return cls(func, None, None, None, None, CoordStmt.OP_MOVE, None)
+
+ @classmethod
+ def line(cls, func, point):
+ return cls(func, point[0], point[1], None, None, CoordStmt.OP_DRAW, None)
+
+ @classmethod
+ def mode(cls, func):
+ return cls(func, None, None, None, None, None, None)
+
+ @classmethod
+ def arc(cls, func, point, center):
+ return cls(func, point[0], point[1], center[0], center[1], CoordStmt.OP_DRAW, None)
+
+ @classmethod
+ def flash(cls, point):
+ if point:
+ return cls(None, point[0], point[1], None, None, CoordStmt.OP_FLASH, None)
+ else:
+ return cls(None, None, None, None, None, CoordStmt.OP_FLASH, None)
def __init__(self, function, x, y, i, j, op, settings):
""" Initialize CoordStmt class
@@ -951,6 +1028,16 @@ class CoordStmt(Statement):
coord_str += 'Op: %s' % op
return '<Coordinate Statement: %s>' % coord_str
+
+ @property
+ def only_function(self):
+ """
+ Returns if the statement only set the function.
+ """
+
+ # TODO I would like to refactor this so that the function is handled separately and then
+ # TODO this isn't required
+ return self.function != None and self.op == None and self.x == None and self.y == None and self.i == None and self.j == None
class ApertureStmt(Statement):
@@ -1000,6 +1087,14 @@ class EofStmt(Statement):
class QuadrantModeStmt(Statement):
+
+ @classmethod
+ def single(cls):
+ return cls('single-quadrant')
+
+ @classmethod
+ def multi(cls):
+ return cls('multi-quadrant')
@classmethod
def from_gerber(cls, line):
@@ -1028,6 +1123,14 @@ class RegionModeStmt(Statement):
if 'G36' not in line and 'G37' not in line:
raise ValueError('%s is not a valid region mode statement' % line)
return (cls('on') if line[:3] == 'G36' else cls('off'))
+
+ @classmethod
+ def on(cls):
+ return cls('on')
+
+ @classmethod
+ def off(cls):
+ return cls('off')
def __init__(self, mode):
super(RegionModeStmt, self).__init__('RegionMode')