summaryrefslogtreecommitdiff
path: root/gerber/am_statements.py
diff options
context:
space:
mode:
authorGarret Fick <garret@fickworkshop.com>2016-11-11 15:54:42 +0800
committerGitHub <noreply@github.com>2016-11-11 15:54:42 +0800
commit1e868763a1c4030bedd51553468cbe25f272bef9 (patch)
tree59cef68f1449a5be8d2a9a8ed352e3d9974a3edb /gerber/am_statements.py
parent5af19af190c1fb0f0c5be029d46d63e657dde4d9 (diff)
parent60d08dc8ad72f5bb0a14d4821451d7dce20b9639 (diff)
downloadgerbonara-1e868763a1c4030bedd51553468cbe25f272bef9.tar.gz
gerbonara-1e868763a1c4030bedd51553468cbe25f272bef9.tar.bz2
gerbonara-1e868763a1c4030bedd51553468cbe25f272bef9.zip
Merge pull request #5 from hamiltonkibbe/merge-curtacircuitos
Merge curtacircuitos
Diffstat (limited to 'gerber/am_statements.py')
-rw-r--r--gerber/am_statements.py152
1 files changed, 69 insertions, 83 deletions
diff --git a/gerber/am_statements.py b/gerber/am_statements.py
index 726df2f..31c0ae4 100644
--- a/gerber/am_statements.py
+++ b/gerber/am_statements.py
@@ -20,8 +20,6 @@ from math import asin
import math
from .primitives import *
-from .primitives import Circle, Line, Outline, Polygon, Rectangle
-from .utils import validate_coordinates, inch, metric
from .utils import validate_coordinates, inch, metric, rotate_point
@@ -75,7 +73,7 @@ class AMPrimitive(object):
def to_metric(self):
raise NotImplementedError('Subclass must implement `to-metric`')
-
+
@property
def _level_polarity(self):
if self.exposure == 'off':
@@ -190,9 +188,9 @@ class AMCirclePrimitive(AMPrimitive):
diameter = float(modifiers[2])
position = (float(modifiers[3]), float(modifiers[4]))
return cls(code, exposure, diameter, position)
-
+
@classmethod
- def from_primitive(cls, primitive):
+ def from_primitive(cls, primitive):
return cls(1, 'on', primitive.diameter, primitive.position)
def __init__(self, code, exposure, diameter, position):
@@ -262,11 +260,11 @@ class AMVectorLinePrimitive(AMPrimitive):
------
ValueError, TypeError
"""
-
+
@classmethod
def from_primitive(cls, primitive):
return cls(2, 'on', primitive.aperture.width, primitive.start, primitive.end, 0)
-
+
@classmethod
def from_gerber(cls, primitive):
modifiers = primitive.strip(' *').split(',')
@@ -310,27 +308,27 @@ class AMVectorLinePrimitive(AMPrimitive):
endy=self.end[1],
rotation=self.rotation)
return fmtstr.format(**data)
-
+
def to_primitive(self, units):
"""
Convert this to a primitive. We use the Outline to represent this (instead of Line)
because the behaviour of the end caps is different for aperture macros compared to Lines
when rotated.
"""
-
+
# Use a line to generate our vertices easily
line = Line(self.start, self.end, Rectangle(None, self.width, self.width))
vertices = line.vertices
-
+
aperture = Circle((0, 0), 0)
-
+
lines = []
prev_point = rotate_point(vertices[-1], self.rotation, (0, 0))
for point in vertices:
cur_point = rotate_point(point, self.rotation, (0, 0))
-
+
lines.append(Line(prev_point, cur_point, aperture))
-
+
return Outline(lines, units=units, level_polarity=self._level_polarity)
@@ -372,19 +370,19 @@ class AMOutlinePrimitive(AMPrimitive):
------
ValueError, TypeError
"""
-
+
@classmethod
def from_primitive(cls, primitive):
-
+
start_point = (round(primitive.primitives[0].start[0], 6), round(primitive.primitives[0].start[1], 6))
points = []
for prim in primitive.primitives:
points.append((round(prim.end[0], 6), round(prim.end[1], 6)))
-
+
rotation = 0.0
-
+
return cls(4, 'on', start_point, points, rotation)
-
+
@classmethod
def from_gerber(cls, primitive):
modifiers = primitive.strip(' *').split(",")
@@ -432,27 +430,26 @@ class AMOutlinePrimitive(AMPrimitive):
points=",\n".join(["%.6g,%.6g" % point for point in self.points]),
rotation=str(self.rotation)
)
- # TODO I removed a closing asterix - not sure if this works for items with multiple statements
- return "{code},{exposure},{n_points},{start_point},{points},\n{rotation}*".format(**data)
-
+ return "{code},{exposure},{n_points},{start_point},{points},{rotation}*".format(**data)
+
def to_primitive(self, units):
"""
Convert this to a drawable primitive. This uses the Outline instead of Line
primitive to handle differences in end caps when rotated.
"""
-
+
lines = []
prev_point = rotate_point(self.start_point, self.rotation)
for point in self.points:
cur_point = rotate_point(point, self.rotation)
-
+
lines.append(Line(prev_point, cur_point, Circle((0,0), 0)))
-
+
prev_point = cur_point
-
+
if lines[0].start != lines[-1].end:
raise ValueError('Outline must be closed')
-
+
return Outline(lines, units=units, level_polarity=self._level_polarity)
@@ -495,11 +492,11 @@ class AMPolygonPrimitive(AMPrimitive):
------
ValueError, TypeError
"""
-
+
@classmethod
def from_primitive(cls, primitive):
return cls(5, 'on', primitive.sides, primitive.position, primitive.diameter, primitive.rotation)
-
+
@classmethod
def from_gerber(cls, primitive):
modifiers = primitive.strip(' *').split(",")
@@ -548,7 +545,7 @@ class AMPolygonPrimitive(AMPrimitive):
)
fmt = "{code},{exposure},{vertices},{position},{diameter},{rotation}*"
return fmt.format(**data)
-
+
def to_primitive(self, units):
return Polygon(self.position, self.vertices, self.diameter / 2.0, 0, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity)
@@ -647,6 +644,7 @@ class AMMoirePrimitive(AMPrimitive):
self.crosshair_thickness = metric(self.crosshair_thickness)
self.crosshair_length = metric(self.crosshair_length)
+
def to_gerber(self, settings=None):
data = dict(
code=self.code,
@@ -663,7 +661,8 @@ class AMMoirePrimitive(AMPrimitive):
return fmt.format(**data)
def to_primitive(self, units):
- raise NotImplementedError()
+ #raise NotImplementedError()
+ return None
class AMThermalPrimitive(AMPrimitive):
@@ -743,77 +742,77 @@ class AMThermalPrimitive(AMPrimitive):
data = dict(
code=self.code,
position="%.4g,%.4g" % self.position,
- outer_diameter = self.outer_diameter,
- inner_diameter = self.inner_diameter,
- gap = self.gap,
- rotation = self.rotation
+ outer_diameter=self.outer_diameter,
+ inner_diameter=self.inner_diameter,
+ gap=self.gap,
+ rotation=self.rotation
)
fmt = "{code},{position},{outer_diameter},{inner_diameter},{gap},{rotation}*"
return fmt.format(**data)
-
+
def _approximate_arc_cw(self, start_angle, end_angle, radius, center):
"""
Get an arc as a series of points
-
+
Parameters
----------
start_angle : The start angle in radians
end_angle : The end angle in radians
radius`: Radius of the arc
center : The center point of the arc (x, y) tuple
-
+
Returns
-------
array of point tuples
"""
-
+
# The total sweep
sweep_angle = end_angle - start_angle
num_steps = 10
-
+
angle_step = sweep_angle / num_steps
-
+
radius = radius
center = center
-
+
points = []
-
+
for i in range(num_steps + 1):
current_angle = start_angle + (angle_step * i)
-
+
nextx = (center[0] + math.cos(current_angle) * radius)
nexty = (center[1] + math.sin(current_angle) * radius)
-
+
points.append((nextx, nexty))
-
+
return points
def to_primitive(self, units):
-
+
# We start with calculating the top right section, then duplicate it
-
+
inner_radius = self.inner_diameter / 2.0
outer_radius = self.outer_diameter / 2.0
-
+
# Calculate the start angle relative to the horizontal axis
inner_offset_angle = asin(self.gap / 2.0 / inner_radius)
outer_offset_angle = asin(self.gap / 2.0 / outer_radius)
-
+
rotation_rad = math.radians(self.rotation)
inner_start_angle = inner_offset_angle + rotation_rad
inner_end_angle = math.pi / 2 - inner_offset_angle + rotation_rad
-
+
outer_start_angle = outer_offset_angle + rotation_rad
outer_end_angle = math.pi / 2 - outer_offset_angle + rotation_rad
-
+
outlines = []
aperture = Circle((0, 0), 0)
-
+
points = (self._approximate_arc_cw(inner_start_angle, inner_end_angle, inner_radius, self.position)
+ list(reversed(self._approximate_arc_cw(outer_start_angle, outer_end_angle, outer_radius, self.position))))
# Add in the last point since outlines should be closed
points.append(points[0])
-
+
# There are four outlines at rotated sections
for rotation in [0, 90.0, 180.0, 270.0]:
@@ -821,11 +820,11 @@ class AMThermalPrimitive(AMPrimitive):
prev_point = rotate_point(points[0], rotation, self.position)
for point in points[1:]:
cur_point = rotate_point(point, rotation, self.position)
-
+
lines.append(Line(prev_point, cur_point, aperture))
-
+
prev_point = cur_point
-
+
outlines.append(Outline(lines, units=units, level_polarity=self._level_polarity))
return outlines
@@ -869,7 +868,7 @@ class AMCenterLinePrimitive(AMPrimitive):
------
ValueError, TypeError
"""
-
+
@classmethod
def from_primitive(cls, primitive):
width = primitive.width
@@ -912,9 +911,9 @@ class AMCenterLinePrimitive(AMPrimitive):
def to_gerber(self, settings=None):
data = dict(
code=self.code,
- exposure='1' if self.exposure == 'on' else '0',
- width=self.width,
- height=self.height,
+ exposure = '1' if self.exposure == 'on' else '0',
+ width = self.width,
+ height = self.height,
center="%.4g,%.4g" % self.center,
rotation=self.rotation
)
@@ -922,27 +921,27 @@ class AMCenterLinePrimitive(AMPrimitive):
return fmt.format(**data)
def to_primitive(self, units):
-
+
x = self.center[0]
y = self.center[1]
half_width = self.width / 2.0
half_height = self.height / 2.0
-
+
points = []
points.append((x - half_width, y + half_height))
points.append((x - half_width, y - half_height))
points.append((x + half_width, y - half_height))
points.append((x + half_width, y + half_height))
-
+
aperture = Circle((0, 0), 0)
-
+
lines = []
prev_point = rotate_point(points[3], self.rotation, self.center)
for point in points:
cur_point = rotate_point(point, self.rotation, self.center)
-
+
lines.append(Line(prev_point, cur_point, aperture))
-
+
return Outline(lines, units=units, level_polarity=self._level_polarity)
@@ -998,7 +997,7 @@ class AMLowerLeftLinePrimitive(AMPrimitive):
def __init__(self, code, exposure, width, height, lower_left, rotation):
if code != 22:
raise ValueError('LowerLeftLinePrimitive code is 22')
- super(AMLowerLeftLinePrimitive, self).__init__(code, exposure)
+ super (AMLowerLeftLinePrimitive, self).__init__(code, exposure)
self.width = width
self.height = height
validate_coordinates(lower_left)
@@ -1015,21 +1014,12 @@ class AMLowerLeftLinePrimitive(AMPrimitive):
self.width = metric(self.width)
self.height = metric(self.height)
- def to_primitive(self, units):
- # TODO I think I have merged this wrong
- # Offset the primitive from macro position
- position = tuple([pos + offset for pos, offset in
- zip(self.lower_left, (self.width/2, self.height/2))])
- # Return a renderable primitive
- return Rectangle(position, self.width, self.height,
- level_polarity=self._level_polarity, units=units)
-
def to_gerber(self, settings=None):
data = dict(
code=self.code,
- exposure='1' if self.exposure == 'on' else '0',
- width=self.width,
- height=self.height,
+ exposure = '1' if self.exposure == 'on' else '0',
+ width = self.width,
+ height = self.height,
lower_left="%.4g,%.4g" % self.lower_left,
rotation=self.rotation
)
@@ -1038,7 +1028,6 @@ class AMLowerLeftLinePrimitive(AMPrimitive):
class AMUnsupportPrimitive(AMPrimitive):
-
@classmethod
def from_gerber(cls, primitive):
return cls(primitive)
@@ -1055,6 +1044,3 @@ class AMUnsupportPrimitive(AMPrimitive):
def to_gerber(self, settings=None):
return self.primitive
-
- def to_primitive(self, units):
- return None \ No newline at end of file