From 4a815bf25ddd1d378ec6ad5af008e5bbcd362b51 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Wed, 30 Dec 2015 14:05:00 +0800 Subject: First time any macro renders --- gerber/am_statements.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 38f4d71..0e4f5f4 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -16,7 +16,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from math import pi from .utils import validate_coordinates, inch, metric +from .primitives import Circle, Line, Rectangle # TODO: Add support for aperture macro variables @@ -67,6 +69,12 @@ class AMPrimitive(object): def to_metric(self): raise NotImplementedError('Subclass must implement `to-metric`') + + def to_primitive(self, units): + """ + Convert to a primitive, as defines the primitives module (for drawing) + """ + raise NotImplementedError('Subclass must implement `to-primitive`') def __eq__(self, other): return self.__dict__ == other.__dict__ @@ -120,6 +128,12 @@ class AMCommentPrimitive(AMPrimitive): def to_gerber(self, settings=None): return '0 %s *' % self.comment + def to_primitive(self, units): + """ + Returns None - has not primitive representation + """ + return None + def __str__(self): return '' % self.comment @@ -189,6 +203,9 @@ class AMCirclePrimitive(AMPrimitive): y = self.position[1]) return '{code},{exposure},{diameter},{x},{y}*'.format(**data) + def to_primitive(self, units): + return Circle((self.position), self.diameter, units=units) + class AMVectorLinePrimitive(AMPrimitive): """ Aperture Macro Vector Line primitive. Code 2 or 20. @@ -273,6 +290,9 @@ class AMVectorLinePrimitive(AMPrimitive): endy = self.end[1], rotation = self.rotation) return fmtstr.format(**data) + + def to_primitive(self, units): + return Line(self.start, self.end, Rectangle(None, self.width, self.width), units=units) class AMOutlinePrimitive(AMPrimitive): @@ -360,6 +380,9 @@ class AMOutlinePrimitive(AMPrimitive): rotation=str(self.rotation) ) return "{code},{exposure},{n_points},{start_point},{points},{rotation}*".format(**data) + + def to_primitive(self, units): + raise NotImplementedError() class AMPolygonPrimitive(AMPrimitive): @@ -450,6 +473,9 @@ class AMPolygonPrimitive(AMPrimitive): ) fmt = "{code},{exposure},{vertices},{position},{diameter},{rotation}*" return fmt.format(**data) + + def to_primitive(self, units): + raise NotImplementedError() class AMMoirePrimitive(AMPrimitive): @@ -562,6 +588,9 @@ class AMMoirePrimitive(AMPrimitive): fmt = "{code},{position},{diameter},{ring_thickness},{gap},{max_rings},{crosshair_thickness},{crosshair_length},{rotation}*" return fmt.format(**data) + def to_primitive(self, units): + raise NotImplementedError() + class AMThermalPrimitive(AMPrimitive): """ Aperture Macro Thermal primitive. Code 7. @@ -646,6 +675,9 @@ class AMThermalPrimitive(AMPrimitive): fmt = "{code},{position},{outer_diameter},{inner_diameter},{gap}*" return fmt.format(**data) + def to_primitive(self, units): + raise NotImplementedError() + class AMCenterLinePrimitive(AMPrimitive): """ Aperture Macro Center Line primitive. Code 21. @@ -729,6 +761,9 @@ class AMCenterLinePrimitive(AMPrimitive): fmt = "{code},{exposure},{width},{height},{center},{rotation}*" return fmt.format(**data) + def to_primitive(self, units): + return Rectangle(self.center, self.width, self.height, rotation=self.rotation * pi / 180.0, units=units) + class AMLowerLeftLinePrimitive(AMPrimitive): """ Aperture Macro Lower Left Line primitive. Code 22. @@ -811,6 +846,9 @@ class AMLowerLeftLinePrimitive(AMPrimitive): fmt = "{code},{exposure},{width},{height},{lower_left},{rotation}*" return fmt.format(**data) + def to_primitive(self, units): + raise NotImplementedError() + class AMUnsupportPrimitive(AMPrimitive): @classmethod @@ -829,3 +867,6 @@ 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 -- cgit From 96692b22216fdfe11f2ded104ac0bdba3b7866a5 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Wed, 30 Dec 2015 15:32:44 +0800 Subject: Render primitives for some aperture macros --- gerber/am_statements.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 0e4f5f4..599d19d 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -16,9 +16,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from math import pi -from .utils import validate_coordinates, inch, metric -from .primitives import Circle, Line, Rectangle +import math +from .utils import validate_coordinates, inch, metric, rotate_point +from .primitives import Circle, Line, Outline, Rectangle # TODO: Add support for aperture macro variables @@ -382,7 +382,15 @@ class AMOutlinePrimitive(AMPrimitive): return "{code},{exposure},{n_points},{start_point},{points},{rotation}*".format(**data) def to_primitive(self, units): - raise NotImplementedError() + + lines = [] + prev_point = rotate_point(self.points[0], self.rotation) + for point in self.points[1:]: + cur_point = rotate_point(self.points[0], self.rotation) + + lines.append(Line(prev_point, cur_point, Circle((0,0), 0))) + + return Outline(lines, units=units) class AMPolygonPrimitive(AMPrimitive): @@ -762,7 +770,7 @@ class AMCenterLinePrimitive(AMPrimitive): return fmt.format(**data) def to_primitive(self, units): - return Rectangle(self.center, self.width, self.height, rotation=self.rotation * pi / 180.0, units=units) + return Rectangle(self.center, self.width, self.height, rotation=math.radians(self.rotation), units=units) class AMLowerLeftLinePrimitive(AMPrimitive): -- cgit From f61eee807f87c329f6f88645ecdb48f01b887c52 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Wed, 30 Dec 2015 18:44:07 +0800 Subject: Render polygon flashes --- gerber/am_statements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 599d19d..e484b10 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -18,7 +18,7 @@ import math from .utils import validate_coordinates, inch, metric, rotate_point -from .primitives import Circle, Line, Outline, Rectangle +from .primitives import Circle, Line, Outline, Polygon, Rectangle # TODO: Add support for aperture macro variables @@ -483,7 +483,7 @@ class AMPolygonPrimitive(AMPrimitive): return fmt.format(**data) def to_primitive(self, units): - raise NotImplementedError() + return Polygon(self.position, self.vertices, self.diameter / 2.0, rotation=math.radians(self.rotation), units=units) class AMMoirePrimitive(AMPrimitive): -- cgit From 6a993594130c42adffa9e2d58757b66b48755aad Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 16 Jan 2016 12:28:46 +0800 Subject: Fix converting polygons to outlines for macros --- gerber/am_statements.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index e484b10..b448139 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -386,9 +386,11 @@ class AMOutlinePrimitive(AMPrimitive): lines = [] prev_point = rotate_point(self.points[0], self.rotation) for point in self.points[1:]: - cur_point = rotate_point(self.points[0], self.rotation) + cur_point = rotate_point(point, self.rotation) lines.append(Line(prev_point, cur_point, Circle((0,0), 0))) + + prev_point = cur_point return Outline(lines, units=units) -- cgit From 5b93db47cd29e384ead918db1893f4cf58326f82 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Tue, 2 Feb 2016 00:11:55 +0800 Subject: Draw thermal aperture macros (as approximation) --- gerber/am_statements.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index b448139..2bca6e6 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -19,6 +19,7 @@ import math from .utils import validate_coordinates, inch, metric, rotate_point from .primitives import Circle, Line, Outline, Polygon, Rectangle +from math import asin # TODO: Add support for aperture macro variables @@ -649,9 +650,10 @@ class AMThermalPrimitive(AMPrimitive): outer_diameter = float(modifiers[3]) inner_diameter= float(modifiers[4]) gap = float(modifiers[5]) - return cls(code, position, outer_diameter, inner_diameter, gap) + rotation = float(modifiers[6]) + return cls(code, position, outer_diameter, inner_diameter, gap, rotation) - def __init__(self, code, position, outer_diameter, inner_diameter, gap): + def __init__(self, code, position, outer_diameter, inner_diameter, gap, rotation): if code != 7: raise ValueError('ThermalPrimitive code is 7') super(AMThermalPrimitive, self).__init__(code, 'on') @@ -660,6 +662,7 @@ class AMThermalPrimitive(AMPrimitive): self.outer_diameter = outer_diameter self.inner_diameter = inner_diameter self.gap = gap + self.rotation = rotation def to_inch(self): self.position = tuple([inch(x) for x in self.position]) @@ -684,9 +687,83 @@ class AMThermalPrimitive(AMPrimitive): ) fmt = "{code},{position},{outer_diameter},{inner_diameter},{gap}*" 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): - raise NotImplementedError() + + # 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)))) + + # There are four outlines at rotated sections + for rotation in [0, 90.0, 180.0, 270.0]: + + lines = [] + 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)) + + return outlines class AMCenterLinePrimitive(AMPrimitive): -- cgit From 223a010831f0d9dae4bd6d2e626a603a78eb0b1d Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 27 Feb 2016 18:18:04 +0800 Subject: Fix critical issue with rotatin points (when the angle is zero the y would be flipped). Render AM with outline to gerber --- gerber/am_statements.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 2bca6e6..05ebd9d 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -334,6 +334,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(",") @@ -376,17 +389,18 @@ class AMOutlinePrimitive(AMPrimitive): code=self.code, exposure="1" if self.exposure == "on" else "0", n_points=len(self.points), - start_point="%.4g,%.4g" % self.start_point, - points=",".join(["%.4g,%.4g" % point for point in self.points]), + start_point="%.6g,%.6g" % self.start_point, + points=",\n".join(["%.6g,%.6g" % point for point in self.points]), rotation=str(self.rotation) ) - return "{code},{exposure},{n_points},{start_point},{points},{rotation}*".format(**data) + # 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) def to_primitive(self, units): lines = [] - prev_point = rotate_point(self.points[0], self.rotation) - for point in self.points[1:]: + 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))) -- cgit From 20a9af279ac2217a39b73903ff94b916a3025be2 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Tue, 1 Mar 2016 00:06:14 +0800 Subject: More rendering of AMGroup to statements --- gerber/am_statements.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 05ebd9d..084439c 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -179,6 +179,10 @@ 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): + return cls(1, 'on', primitive.diameter, primitive.position) def __init__(self, code, exposure, diameter, position): validate_coordinates(position) @@ -247,6 +251,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(',') @@ -406,6 +415,9 @@ class AMOutlinePrimitive(AMPrimitive): 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) @@ -762,6 +774,8 @@ class AMThermalPrimitive(AMPrimitive): 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]: @@ -818,6 +832,14 @@ class AMCenterLinePrimitive(AMPrimitive): ------ ValueError, TypeError """ + + @classmethod + def from_primitive(cls, primitive): + width = primitive.width + height = primitive.height + center = primitive.position + rotation = math.degrees(primitive.rotation) + return cls(21, 'on', width, height, center, rotation) @classmethod def from_gerber(cls, primitive): -- cgit From 7f47aea332ee1df45c87baa304d95ed03cc59865 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 5 Mar 2016 10:04:58 +0800 Subject: Write polygons to macros --- gerber/am_statements.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 084439c..faaed05 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -461,6 +461,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(",") -- cgit From 3fc296918e7d0d343840c5daa08eb6d564660a29 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 28 May 2016 13:06:08 +0800 Subject: Use the known macro statement to render. Fix thermal not setting rotation --- gerber/am_statements.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index faaed05..c3229ba 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -715,8 +715,9 @@ class AMThermalPrimitive(AMPrimitive): outer_diameter = self.outer_diameter, inner_diameter = self.inner_diameter, gap = self.gap, + rotation = self.rotation ) - fmt = "{code},{position},{outer_diameter},{inner_diameter},{gap}*" + fmt = "{code},{position},{outer_diameter},{inner_diameter},{gap},{rotation}*" return fmt.format(**data) def _approximate_arc_cw(self, start_angle, end_angle, radius, center): -- cgit From b01c4822b6da6b7be37becb73c58f60621f6366f Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 25 Jun 2016 12:27:28 +0800 Subject: Render aperture macros with clear regions --- gerber/am_statements.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index c3229ba..f5330a5 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -76,6 +76,12 @@ class AMPrimitive(object): Convert to a primitive, as defines the primitives module (for drawing) """ raise NotImplementedError('Subclass must implement `to-primitive`') + + @property + def _level_polarity(self): + if self.exposure == 'off': + return 'clear' + return 'dark' def __eq__(self, other): return self.__dict__ == other.__dict__ @@ -209,7 +215,7 @@ class AMCirclePrimitive(AMPrimitive): return '{code},{exposure},{diameter},{x},{y}*'.format(**data) def to_primitive(self, units): - return Circle((self.position), self.diameter, units=units) + return Circle((self.position), self.diameter, units=units, level_polarity=self._level_polarity) class AMVectorLinePrimitive(AMPrimitive): @@ -302,7 +308,7 @@ class AMVectorLinePrimitive(AMPrimitive): return fmtstr.format(**data) def to_primitive(self, units): - return Line(self.start, self.end, Rectangle(None, self.width, self.width), units=units) + return Line(self.start, self.end, Rectangle(None, self.width, self.width), units=units, level_polarity=self._level_polarity) class AMOutlinePrimitive(AMPrimitive): @@ -419,7 +425,7 @@ class AMOutlinePrimitive(AMPrimitive): if lines[0].start != lines[-1].end: raise ValueError('Outline must be closed') - return Outline(lines, units=units) + return Outline(lines, units=units, level_polarity=self._level_polarity) class AMPolygonPrimitive(AMPrimitive): @@ -517,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) + return Polygon(self.position, self.vertices, self.diameter / 2.0, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) class AMMoirePrimitive(AMPrimitive): @@ -795,7 +801,7 @@ class AMThermalPrimitive(AMPrimitive): prev_point = cur_point - outlines.append(Outline(lines, units=units)) + outlines.append(Outline(lines, units=units, level_polarity=self._level_polarity)) return outlines @@ -891,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) + return Rectangle(self.center, self.width, self.height, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) class AMLowerLeftLinePrimitive(AMPrimitive): -- cgit From efcb221fc7bd8dae583357e6c4e1c2d3fc9e9df6 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 25 Jun 2016 16:00:46 +0800 Subject: Missing * in writing aperture macro --- gerber/am_statements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index f5330a5..a58f1dd 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -409,7 +409,7 @@ class AMOutlinePrimitive(AMPrimitive): 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},\n{rotation}*".format(**data) def to_primitive(self, units): -- cgit From ccb6eb7a766bd6edf314978f3ec4fc0dcd61652d Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 25 Jun 2016 16:46:44 +0800 Subject: Add support for polygon apertures --- gerber/am_statements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gerber/am_statements.py') 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): -- cgit From b140f5e4767912110f69cbda8417a8e076345b70 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Tue, 28 Jun 2016 23:15:20 +0800 Subject: Don't flash G03-only commands --- gerber/am_statements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 0d92a8c..a58f1dd 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, hole_radius=0, rotation=self.rotation, units=units, level_polarity=self._level_polarity) + return Polygon(self.position, self.vertices, self.diameter / 2.0, rotation=math.radians(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=self.rotation, units=units, level_polarity=self._level_polarity) + return Rectangle(self.center, self.width, self.height, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) class AMLowerLeftLinePrimitive(AMPrimitive): -- cgit From efb3703df4a9205a9476b682cd1e09e241ab8459 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Thu, 30 Jun 2016 22:46:20 +0800 Subject: Fix rotation of center line --- gerber/am_statements.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index a58f1dd..6ece68e 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -897,7 +897,28 @@ 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) + + 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) class AMLowerLeftLinePrimitive(AMPrimitive): -- cgit From 14747494b89178372c65aad1e6ef8fa431e7f24c Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Thu, 30 Jun 2016 23:08:51 +0800 Subject: Rotate vector line --- gerber/am_statements.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 6ece68e..6cb90dc 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -308,7 +308,20 @@ class AMVectorLinePrimitive(AMPrimitive): return fmtstr.format(**data) def to_primitive(self, units): - return Line(self.start, self.end, Rectangle(None, self.width, self.width), units=units, level_polarity=self._level_polarity) + + 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) class AMOutlinePrimitive(AMPrimitive): -- cgit From 0107d159b5a04c282478ceb4c51fdd03af3bd8c9 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 2 Jul 2016 12:34:35 +0800 Subject: Fix crash with polygon aperture macros --- gerber/am_statements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 6cb90dc..ed9f71e 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -536,7 +536,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, 0, rotation=math.radians(self.rotation), units=units, level_polarity=self._level_polarity) class AMMoirePrimitive(AMPrimitive): -- cgit From 8cd842a41a55ab3d8f558a2e3e198beba7da58a1 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 21 Jan 2016 03:57:44 -0500 Subject: Manually mere rendering changes --- gerber/am_statements.py | 113 ++++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 48 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index ed9f71e..248542d 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -16,14 +16,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from math import asin import math -from .utils import validate_coordinates, inch, metric, rotate_point + from .primitives import Circle, Line, Outline, Polygon, Rectangle -from math import asin +from .utils import validate_coordinates, inch, metric, rotate_point # TODO: Add support for aperture macro variables - __all__ = ['AMPrimitive', 'AMCommentPrimitive', 'AMCirclePrimitive', 'AMVectorLinePrimitive', 'AMOutlinePrimitive', 'AMPolygonPrimitive', 'AMMoirePrimitive', 'AMThermalPrimitive', 'AMCenterLinePrimitive', @@ -54,12 +54,14 @@ class AMPrimitive(object): ------ TypeError, ValueError """ + def __init__(self, code, exposure=None): VALID_CODES = (0, 1, 2, 4, 5, 6, 7, 20, 21, 22, 9999) if not isinstance(code, int): raise TypeError('Aperture Macro Primitive code must be an integer') elif code not in VALID_CODES: - raise ValueError('Invalid Code. Valid codes are %s.' % ', '.join(map(str, VALID_CODES))) + raise ValueError('Invalid Code. Valid codes are %s.' % + ', '.join(map(str, VALID_CODES))) if exposure is not None and exposure.lower() not in ('on', 'off'): raise ValueError('Exposure must be either on or off') self.code = code @@ -71,21 +73,21 @@ class AMPrimitive(object): def to_metric(self): raise NotImplementedError('Subclass must implement `to-metric`') - def to_primitive(self, units): - """ - Convert to a primitive, as defines the primitives module (for drawing) - """ - raise NotImplementedError('Subclass must implement `to-primitive`') - @property def _level_polarity(self): if self.exposure == 'off': return 'clear' return 'dark' + def to_primitive(self, units): + """ Return a Primitive instance based on the specified macro params. + """ + print('Rendering {}s is not supported yet.'.format(str(self.__class__))) + def __eq__(self, other): return self.__dict__ == other.__dict__ + class AMCommentPrimitive(AMPrimitive): """ Aperture Macro Comment primitive. Code 0 @@ -207,11 +209,11 @@ class AMCirclePrimitive(AMPrimitive): self.position = tuple([metric(x) for x in self.position]) def to_gerber(self, settings=None): - data = dict(code = self.code, - exposure = '1' if self.exposure == 'on' else 0, - diameter = self.diameter, - x = self.position[0], - y = self.position[1]) + data = dict(code=self.code, + exposure='1' if self.exposure == 'on' else 0, + diameter=self.diameter, + x=self.position[0], + y=self.position[1]) return '{code},{exposure},{diameter},{x},{y}*'.format(**data) def to_primitive(self, units): @@ -294,21 +296,26 @@ class AMVectorLinePrimitive(AMPrimitive): self.start = tuple([metric(x) for x in self.start]) self.end = tuple([metric(x) for x in self.end]) - def to_gerber(self, settings=None): fmtstr = '{code},{exp},{width},{startx},{starty},{endx},{endy},{rotation}*' - data = dict(code = self.code, - exp = 1 if self.exposure == 'on' else 0, - width = self.width, - startx = self.start[0], - starty = self.start[1], - endx = self.end[0], - endy = self.end[1], - rotation = self.rotation) + data = dict(code=self.code, + exp=1 if self.exposure == 'on' else 0, + width=self.width, + startx=self.start[0], + starty=self.start[1], + endx=self.end[0], + 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 @@ -385,7 +392,8 @@ class AMOutlinePrimitive(AMPrimitive): start_point = (float(modifiers[3]), float(modifiers[4])) points = [] for i in range(n): - points.append((float(modifiers[5 + i*2]), float(modifiers[5 + i*2 + 1]))) + points.append((float(modifiers[5 + i * 2]), + float(modifiers[5 + i * 2 + 1]))) rotation = float(modifiers[-1]) return cls(code, exposure, start_point, points, rotation) @@ -425,6 +433,10 @@ class AMOutlinePrimitive(AMPrimitive): return "{code},{exposure},{n_points},{start_point},{points},\n{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) @@ -500,7 +512,6 @@ class AMPolygonPrimitive(AMPrimitive): rotation = float(modifiers[6]) return cls(code, exposure, vertices, position, diameter, rotation) - def __init__(self, code, exposure, vertices, position, diameter, rotation): """ Initialize AMPolygonPrimitive """ @@ -529,7 +540,7 @@ class AMPolygonPrimitive(AMPrimitive): exposure="1" if self.exposure == "on" else "0", vertices=self.vertices, position="%.4g,%.4g" % self.position, - diameter = '%.4g' % self.diameter, + diameter='%.4g' % self.diameter, rotation=str(self.rotation) ) fmt = "{code},{exposure},{vertices},{position},{diameter},{rotation}*" @@ -633,17 +644,16 @@ 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, position="%.4g,%.4g" % self.position, - diameter = self.diameter, - ring_thickness = self.ring_thickness, - gap = self.gap, - max_rings = self.max_rings, - crosshair_thickness = self.crosshair_thickness, - crosshair_length = self.crosshair_length, + diameter=self.diameter, + ring_thickness=self.ring_thickness, + gap=self.gap, + max_rings=self.max_rings, + crosshair_thickness=self.crosshair_thickness, + crosshair_length=self.crosshair_length, rotation=self.rotation ) fmt = "{code},{position},{diameter},{ring_thickness},{gap},{max_rings},{crosshair_thickness},{crosshair_length},{rotation}*" @@ -698,7 +708,7 @@ class AMThermalPrimitive(AMPrimitive): code = int(modifiers[0]) position = (float(modifiers[1]), float(modifiers[2])) outer_diameter = float(modifiers[3]) - inner_diameter= float(modifiers[4]) + inner_diameter = float(modifiers[4]) gap = float(modifiers[5]) rotation = float(modifiers[6]) return cls(code, position, outer_diameter, inner_diameter, gap, rotation) @@ -720,7 +730,6 @@ class AMThermalPrimitive(AMPrimitive): self.inner_diameter = inch(self.inner_diameter) self.gap = inch(self.gap) - def to_metric(self): self.position = tuple([metric(x) for x in self.position]) self.outer_diameter = metric(self.outer_diameter) @@ -873,14 +882,14 @@ class AMCenterLinePrimitive(AMPrimitive): exposure = 'on' if float(modifiers[1]) == 1 else 'off' width = float(modifiers[2]) height = float(modifiers[3]) - center= (float(modifiers[4]), float(modifiers[5])) + center = (float(modifiers[4]), float(modifiers[5])) rotation = float(modifiers[6]) return cls(code, exposure, width, height, center, rotation) def __init__(self, code, exposure, width, height, center, rotation): if code != 21: raise ValueError('CenterLinePrimitive code is 21') - super (AMCenterLinePrimitive, self).__init__(code, exposure) + super(AMCenterLinePrimitive, self).__init__(code, exposure) self.width = width self.height = height validate_coordinates(center) @@ -900,9 +909,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 ) @@ -986,7 +995,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) @@ -1003,23 +1012,31 @@ 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([a + b for a , b in zip (position, self.lower_left)]) + position = tuple([pos + offset for pos, offset in + zip(position, (self.width/2, self.height/2))]) + # Return a renderable primitive + return Rectangle(self.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 ) fmt = "{code},{exposure},{width},{height},{lower_left},{rotation}*" return fmt.format(**data) - def to_primitive(self, units): - raise NotImplementedError() - class AMUnsupportPrimitive(AMPrimitive): + @classmethod def from_gerber(cls, primitive): return cls(primitive) -- cgit From 8d5e782ccf220d77f0aad5a4e5605dc5cbe0f410 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 6 Aug 2016 09:51:58 +0800 Subject: Fix multiple problems with the merge. There are still errors, but I will intentionally leave them because future merges might resolve them --- gerber/am_statements.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 248542d..9c09085 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -1015,11 +1015,10 @@ class AMLowerLeftLinePrimitive(AMPrimitive): def to_primitive(self, units): # TODO I think I have merged this wrong # Offset the primitive from macro position - position = tuple([a + b for a , b in zip (position, self.lower_left)]) position = tuple([pos + offset for pos, offset in - zip(position, (self.width/2, self.height/2))]) + zip(self.lower_left, (self.width/2, self.height/2))]) # Return a renderable primitive - return Rectangle(self.position, self.width, self.height, + return Rectangle(position, self.width, self.height, level_polarity=self._level_polarity, units=units) def to_gerber(self, settings=None): -- cgit From 5af19af190c1fb0f0c5be029d46d63e657dde4d9 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 21 Jan 2016 03:57:44 -0500 Subject: Commit partial merge so I can work on the plane --- gerber/am_statements.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 9c09085..726df2f 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -19,10 +19,13 @@ 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 + # TODO: Add support for aperture macro variables __all__ = ['AMPrimitive', 'AMCommentPrimitive', 'AMCirclePrimitive', 'AMVectorLinePrimitive', 'AMOutlinePrimitive', 'AMPolygonPrimitive', -- cgit From 724c2b3bced319ed0b50c4302fed9b0e1aa9ce9c Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sat, 5 Nov 2016 20:56:47 -0400 Subject: Finish Merge, most tests passing --- gerber/am_statements.py | 113 ++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 56 deletions(-) (limited to 'gerber/am_statements.py') diff --git a/gerber/am_statements.py b/gerber/am_statements.py index 726df2f..2e3fe3d 100644 --- a/gerber/am_statements.py +++ b/gerber/am_statements.py @@ -75,7 +75,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 +190,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 +262,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 +310,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 +372,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(",") @@ -434,25 +434,25 @@ class AMOutlinePrimitive(AMPrimitive): ) # 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) - + 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 +495,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 +548,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) @@ -663,7 +663,8 @@ class AMMoirePrimitive(AMPrimitive): return fmt.format(**data) def to_primitive(self, units): - raise NotImplementedError() + #raise NotImplementedError() + return None class AMThermalPrimitive(AMPrimitive): @@ -750,70 +751,70 @@ class AMThermalPrimitive(AMPrimitive): ) 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 +822,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 +870,7 @@ class AMCenterLinePrimitive(AMPrimitive): ------ ValueError, TypeError """ - + @classmethod def from_primitive(cls, primitive): width = primitive.width @@ -922,27 +923,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) @@ -1057,4 +1058,4 @@ class AMUnsupportPrimitive(AMPrimitive): return self.primitive def to_primitive(self, units): - return None \ No newline at end of file + return None -- cgit