diff options
Diffstat (limited to 'gerber')
-rw-r--r-- | gerber/am_statements.py | 4 | ||||
-rw-r--r-- | gerber/gerber_statements.py | 7 | ||||
-rw-r--r-- | gerber/primitives.py | 7 | ||||
-rw-r--r-- | gerber/render/cairo_backend.py | 15 | ||||
-rw-r--r-- | gerber/render/rs274x_backend.py | 26 | ||||
-rw-r--r-- | gerber/rs274x.py | 14 |
6 files changed, 61 insertions, 12 deletions
diff --git a/gerber/am_statements.py b/gerber/am_statements.py index a58f1dd..0d92a8c 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -523,7 +523,7 @@ class AMPolygonPrimitive(AMPrimitive): return fmt.format(**data) def to_primitive(self, units): - return Polygon(self.position, self.vertices, self.diameter / 2.0, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) + return Polygon(self.position, self.vertices, self.diameter / 2.0, hole_radius=0, rotation=self.rotation, units=units, level_polarity=self._level_polarity) class AMMoirePrimitive(AMPrimitive): @@ -897,7 +897,7 @@ class AMCenterLinePrimitive(AMPrimitive): return fmt.format(**data) def to_primitive(self, units): - return Rectangle(self.center, self.width, self.height, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) + return Rectangle(self.center, self.width, self.height, rotation=self.rotation, units=units, level_polarity=self._level_polarity) class AMLowerLeftLinePrimitive(AMPrimitive): diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py index 725febf..234952e 100644 --- a/gerber/gerber_statements.py +++ b/gerber/gerber_statements.py @@ -285,10 +285,15 @@ class ADParamStmt(ParamStmt): @classmethod def obround(cls, dcode, width, height): - '''Create an obrou d aperture definition statement''' + '''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, '') diff --git a/gerber/primitives.py b/gerber/primitives.py index aa6e661..211acb8 100644 --- a/gerber/primitives.py +++ b/gerber/primitives.py @@ -721,14 +721,15 @@ class Obround(Primitive): class Polygon(Primitive):
"""
- Polygon flash defined by a set number of sized.
+ Polygon flash defined by a set number of sides.
"""
- def __init__(self, position, sides, radius, **kwargs):
+ def __init__(self, position, sides, radius, hole_radius, **kwargs):
super(Polygon, self).__init__(**kwargs)
validate_coordinates(position)
self.position = position
self.sides = sides
self.radius = radius
+ self.hole_radius = hole_radius
self._to_convert = ['position', 'radius']
@property
@@ -753,7 +754,7 @@ class Polygon(Primitive): @property
def vertices(self):
- offset = math.degrees(self.rotation)
+ offset = self.rotation
da = 360.0 / self.sides
points = []
diff --git a/gerber/render/cairo_backend.py b/gerber/render/cairo_backend.py index c1bd60c..2b7c2ff 100644 --- a/gerber/render/cairo_backend.py +++ b/gerber/render/cairo_backend.py @@ -159,6 +159,9 @@ class GerberCairoContext(GerberContext): self._render_rectangle(obround.subshapes['rectangle'], color)
def _render_polygon(self, polygon, color):
+ if polygon.hole_radius > 0:
+ self.ctx.push_group()
+
vertices = polygon.vertices
self.ctx.set_source_rgba(color[0], color[1], color[2], self.alpha)
@@ -172,6 +175,18 @@ class GerberCairoContext(GerberContext): self.ctx.line_to(*map(mul, v, self.scale))
self.ctx.fill()
+
+ if polygon.hole_radius > 0:
+ # Render the center clear
+ center = tuple(map(mul, polygon.position, self.scale))
+ self.ctx.set_source_rgba(color[0], color[1], color[2], self.alpha)
+ self.ctx.set_operator(cairo.OPERATOR_CLEAR)
+ self.ctx.set_line_width(0)
+ self.ctx.arc(center[0], center[1], polygon.hole_radius * self.scale[0], 0, 2 * math.pi)
+ self.ctx.fill()
+
+ self.ctx.pop_group_to_source()
+ self.ctx.paint_with_alpha(1)
def _render_drill(self, circle, color):
self._render_circle(circle, color)
diff --git a/gerber/render/rs274x_backend.py b/gerber/render/rs274x_backend.py index bb784b1..c37529e 100644 --- a/gerber/render/rs274x_backend.py +++ b/gerber/render/rs274x_backend.py @@ -310,7 +310,7 @@ class Rs274xContext(GerberContext): self._next_dcode = max(dcode + 1, self._next_dcode) aper = ADParamStmt.obround(dcode, width, height) - self._obrounds[(width, height)] = aper + self._obrounds[key] = aper self.header.append(aper) return aper @@ -320,10 +320,28 @@ class Rs274xContext(GerberContext): aper = self._get_obround(obround.width, obround.height) self._render_flash(obround, aper) - pass - def _render_polygon(self, polygon, color): - raise ValueError('Polygons can only exist in the context of aperture macro') + + aper = self._get_polygon(polygon.radius, polygon.sides, polygon.rotation, polygon.hole_radius) + self._render_flash(polygon, aper) + + def _get_polygon(self, radius, num_vertices, rotation, hole_radius, dcode = None): + + key = (radius, num_vertices, rotation, hole_radius) + aper = self._polygons.get(key, None) + + if not aper: + if not dcode: + dcode = self._next_dcode + self._next_dcode += 1 + else: + self._next_dcode = max(dcode + 1, self._next_dcode) + + aper = ADParamStmt.polygon(dcode, radius * 2, num_vertices, rotation, hole_radius * 2) + self._polygons[key] = aper + self.header.append(aper) + + return aper def _render_drill(self, drill, color): raise ValueError('Drills are not valid in RS274X files') diff --git a/gerber/rs274x.py b/gerber/rs274x.py index 7eba1c2..ffac66d 100644 --- a/gerber/rs274x.py +++ b/gerber/rs274x.py @@ -483,8 +483,18 @@ class GerberParser(object): height = modifiers[0][1] aperture = Obround(position=None, width=width, height=height, units=self.settings.units) elif shape == 'P': - # FIXME: not supported yet? - pass + outer_diameter = modifiers[0][0] + number_vertices = int(modifiers[0][1]) + if len(modifiers[0]) > 2: + rotation = modifiers[0][2] + else: + rotation = 0 + + if len(modifiers[0]) > 3: + hole_diameter = modifiers[0][3] + else: + hole_diameter = 0 + aperture = Polygon(position=None, sides=number_vertices, radius=outer_diameter/2.0, hole_radius=hole_diameter/2.0, rotation=rotation) else: aperture = self.macros[shape].build(modifiers) |