summaryrefslogtreecommitdiff
path: root/gerber/rs274x.py
diff options
context:
space:
mode:
authorHamilton Kibbe <hamilton.kibbe@gmail.com>2016-01-21 03:57:44 -0500
committerHamilton Kibbe <hamilton.kibbe@gmail.com>2016-01-21 03:57:44 -0500
commit5476da8aa3f4ee424f56f4f2491e7af1c4b7b758 (patch)
tree427dafda78ee21a1846a2b9c9747dd96afe7e8a3 /gerber/rs274x.py
parent7a532514631384dbfc9d7fc2002cbbfe52433c9f (diff)
downloadgerbonara-5476da8aa3f4ee424f56f4f2491e7af1c4b7b758.tar.gz
gerbonara-5476da8aa3f4ee424f56f4f2491e7af1c4b7b758.tar.bz2
gerbonara-5476da8aa3f4ee424f56f4f2491e7af1c4b7b758.zip
Fix a bunch of rendering bugs.
- 'clear' polarity primitives no longer erase background - Added aperture macro support for polygons - Added aperture macro rendring support - Renderer now creates a new surface for each layer and merges them instead of working directly on a single surface - Updated examples accordingly
Diffstat (limited to 'gerber/rs274x.py')
-rw-r--r--gerber/rs274x.py74
1 files changed, 54 insertions, 20 deletions
diff --git a/gerber/rs274x.py b/gerber/rs274x.py
index 319d58f..b19913b 100644
--- a/gerber/rs274x.py
+++ b/gerber/rs274x.py
@@ -93,6 +93,7 @@ class GerberFile(CamFile):
`bounds` is stored as ((min x, max x), (min y, max y))
"""
+
def __init__(self, statements, settings, primitives, filename=None):
super(GerberFile, self).__init__(statements, settings, primitives, filename)
@@ -181,7 +182,8 @@ class GerberParser(object):
DEPRECATED_FORMAT = re.compile(r'(?P<format>G9[01])\*')
# end deprecated
- PARAMS = (FS, MO, LP, AD_CIRCLE, AD_RECT, AD_OBROUND, AD_POLY, AD_MACRO, AM, AS, IN, IP, IR, MI, OF, SF, LN)
+ PARAMS = (FS, MO, LP, AD_CIRCLE, AD_RECT, AD_OBROUND, AD_POLY,
+ AD_MACRO, AM, AS, IN, IP, IR, MI, OF, SF, LN)
PARAM_STMT = [re.compile(r"%?{0}\*%?".format(p)) for p in PARAMS]
@@ -362,7 +364,8 @@ class GerberParser(object):
# deprecated codes
(deprecated_unit, r) = _match_one(self.DEPRECATED_UNIT, line)
if deprecated_unit:
- stmt = MOParamStmt(param="MO", mo="inch" if "G70" in deprecated_unit["mode"] else "metric")
+ stmt = MOParamStmt(param="MO", mo="inch" if "G70" in
+ deprecated_unit["mode"] else "metric")
self.settings.units = stmt.mode
yield stmt
line = r
@@ -436,8 +439,9 @@ class GerberParser(object):
height = modifiers[0][1]
aperture = Obround(position=None, width=width, height=height)
elif shape == 'P':
- # FIXME: not supported yet?
- pass
+ diameter = modifiers[0][0]
+ sides = modifiers[0][1]
+ aperture = Polygon(position=None, radius=diameter/2.0, sides=sides)
else:
aperture = self.macros[shape].build(modifiers)
@@ -446,7 +450,8 @@ class GerberParser(object):
def _evaluate_mode(self, stmt):
if stmt.type == 'RegionMode':
if self.region_mode == 'on' and stmt.mode == 'off':
- self.primitives.append(Region(self.current_region, level_polarity=self.level_polarity))
+ self.primitives.append(Region(self.current_region,
+ level_polarity=self.level_polarity))
self.current_region = None
self.region_mode = stmt.mode
elif stmt.type == 'QuadrantMode':
@@ -476,7 +481,8 @@ class GerberParser(object):
self.interpolation = 'linear'
elif stmt.function in ('G02', 'G2', 'G03', 'G3'):
self.interpolation = 'arc'
- self.direction = ('clockwise' if stmt.function in ('G02', 'G2') else 'counterclockwise')
+ self.direction = ('clockwise' if stmt.function in
+ ('G02', 'G2') else 'counterclockwise')
if stmt.op:
self.op = stmt.op
@@ -490,43 +496,71 @@ class GerberParser(object):
if self.interpolation == 'linear':
if self.region_mode == 'off':
- self.primitives.append(Line(start, end, self.apertures[self.aperture], level_polarity=self.level_polarity, units=self.settings.units))
+ self.primitives.append(Line(start, end,
+ self.apertures[self.aperture],
+ level_polarity=self.level_polarity,
+ units=self.settings.units))
else:
# from gerber spec revision J3, Section 4.5, page 55:
# The segments are not graphics objects in themselves; segments are part of region which is the graphics object. The segments have no thickness.
- # The current aperture is associated with the region. This has no graphical effect, but allows all its attributes to be applied to the region.
+ # The current aperture is associated with the region. This
+ # has no graphical effect, but allows all its attributes to
+ # be applied to the region.
if self.current_region is None:
- self.current_region = [Line(start, end, self.apertures.get(self.aperture, Circle((0,0), 0)), level_polarity=self.level_polarity, units=self.settings.units),]
- else:
- self.current_region.append(Line(start, end, self.apertures.get(self.aperture, Circle((0,0), 0)), level_polarity=self.level_polarity, units=self.settings.units))
+ self.current_region = [Line(start, end,
+ self.apertures.get(self.aperture,
+ Circle((0, 0), 0)),
+ level_polarity=self.level_polarity,
+ units=self.settings.units), ]
+ else:
+ self.current_region.append(Line(start, end,
+ self.apertures.get(self.aperture,
+ Circle((0, 0), 0)),
+ level_polarity=self.level_polarity,
+ units=self.settings.units))
else:
i = 0 if stmt.i is None else stmt.i
j = 0 if stmt.j is None else stmt.j
center = (start[0] + i, start[1] + j)
if self.region_mode == 'off':
- self.primitives.append(Arc(start, end, center, self.direction, self.apertures[self.aperture], level_polarity=self.level_polarity, units=self.settings.units))
+ self.primitives.append(Arc(start, end, center, self.direction,
+ self.apertures[self.aperture],
+ level_polarity=self.level_polarity,
+ units=self.settings.units))
else:
if self.current_region is None:
- self.current_region = [Arc(start, end, center, self.direction, self.apertures[self.aperture], level_polarity=self.level_polarity, units=self.settings.units),]
+ self.current_region = [Arc(start, end, center, self.direction,
+ self.apertures[self.aperture],
+ level_polarity=self.level_polarity,
+ units=self.settings.units), ]
else:
- self.current_region.append(Arc(start, end, center, self.direction, self.apertures[self.aperture], level_polarity=self.level_polarity, units=self.settings.units))
+ self.current_region.append(Arc(start, end, center, self.direction,
+ self.apertures[self.aperture],
+ level_polarity=self.level_polarity,
+ units=self.settings.units))
elif self.op == "D02":
pass
elif self.op == "D03":
primitive = copy.deepcopy(self.apertures[self.aperture])
- # XXX: temporary fix because there are no primitives for Macros and Polygon
+
+
if primitive is not None:
- # XXX: just to make it easy to spot
- if isinstance(primitive, type([])):
- print(primitive[0].to_gerber())
- else:
+
+ if not isinstance(primitive, AMParamStmt):
primitive.position = (x, y)
primitive.level_polarity = self.level_polarity
primitive.units = self.settings.units
self.primitives.append(primitive)
-
+ else:
+ # Aperture Macro
+ for am_prim in primitive.primitives:
+ renderable = am_prim.to_primitive((x, y),
+ self.level_polarity,
+ self.settings.units)
+ if renderable is not None:
+ self.primitives.append(renderable)
self.x, self.y = x, y
def _evaluate_aperture(self, stmt):