Add support for polygon apertures

This commit is contained in:
Garret Fick 2016-06-25 16:46:44 +08:00
parent efcb221fc7
commit ccb6eb7a76
6 changed files with 61 additions and 12 deletions

View file

@ -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):

View file

@ -285,9 +285,14 @@ 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, '')

View file

@ -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 = []

View file

@ -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)

View file

@ -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')

View file

@ -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)