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.py109
1 files changed, 107 insertions, 2 deletions
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 74b3e54..7322b3c 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):
@@ -96,6 +97,11 @@ class FSParamStmt(ParamStmt):
"""
@classmethod
+ def from_settings(cls, settings):
+
+ return cls('FS', settings.zero_suppression, settings.notation, settings.format)
+
+ @classmethod
def from_dict(cls, stmt_dict):
"""
"""
@@ -169,6 +175,10 @@ class MOParamStmt(ParamStmt):
"""
@classmethod
+ def from_units(cls, units):
+ return cls(None, units)
+
+ @classmethod
def from_dict(cls, stmt_dict):
param = stmt_dict.get('param')
if stmt_dict.get('mo') is None:
@@ -226,6 +236,11 @@ class LPParamStmt(ParamStmt):
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
@@ -259,6 +274,33 @@ class ADParamStmt(ParamStmt):
"""
@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, hole_diameter):
+ '''Create a circular aperture definition statement'''
+
+ if hole_diameter != None:
+ return cls('AD', dcode, 'C', ([diameter, hole_diameter],))
+ 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')
d = int(stmt_dict.get('d'))
@@ -292,7 +334,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:
@@ -393,7 +437,8 @@ class AMParamStmt(ParamStmt):
else:
self.primitives.append(
AMUnsupportPrimitive.from_gerber(primitive))
- return self
+
+ return AMGroup(self.primitives, stmt=self, units=self.units)
def to_inch(self):
if self.units == 'metric':
@@ -820,6 +865,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']
@@ -843,6 +896,32 @@ class CoordStmt(Statement):
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
@@ -966,6 +1045,16 @@ class CoordStmt(Statement):
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):
""" Aperture Statement
@@ -1018,6 +1107,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):
if 'G74' not in line and 'G75' not in line:
raise ValueError('%s is not a valid quadrant mode statement'
@@ -1045,6 +1142,14 @@ class RegionModeStmt(Statement):
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')
mode = mode.lower()