diff options
Diffstat (limited to 'gerber/gerber_statements.py')
-rw-r--r-- | gerber/gerber_statements.py | 109 |
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() |