From 3fb26e6940b5ae752308d8a33f2608d266795153 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 29 Dec 2021 19:58:20 +0100 Subject: Basic round-trip works --- gerbonara/gerber/apertures.py | 64 +++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'gerbonara/gerber/apertures.py') diff --git a/gerbonara/gerber/apertures.py b/gerbonara/gerber/apertures.py index 2c03a37..b478ad9 100644 --- a/gerbonara/gerber/apertures.py +++ b/gerbonara/gerber/apertures.py @@ -1,9 +1,11 @@ import math -from dataclasses import dataclass, replace -from aperture_macros.parse import GenericMacros +from dataclasses import dataclass, replace, astuple + +from .aperture_macros.parse import GenericMacros + +from . import graphic_primitives as gp -import graphic_primitives as gp def _flash_hole(self, x, y): if self.hole_rect_h is not None: @@ -11,6 +13,13 @@ def _flash_hole(self, x, y): else: return self.primitives(x, y), Circle((x, y), self.hole_dia, polarity_dark=False) +def strip_right(*args): + args = list(args) + while args and args[-1] is None: + args.pop() + return args + + class Aperture: @property def hole_shape(self): @@ -25,12 +34,12 @@ class Aperture: @property def params(self): - return dataclasses.astuple(self) + return astuple(self) def flash(self, x, y): return self.primitives(x, y) - @parameter + @property def equivalent_width(self): raise ValueError('Non-circular aperture used in interpolation statement, line width is not properly defined.') @@ -39,8 +48,8 @@ class Aperture: # we emulate this parameter. Our circle, rectangle and oblong classes below have a rotation parameter. Only at # export time during to_gerber, this parameter is evaluated. actual_inst = self._rotated() - params = 'X'.join(f'{par:.4}' for par in actual_inst.params) - return f'{actual_inst.aperture.gerber_shape_code},{params}' + params = 'X'.join(f'{float(par):.4}' for par in actual_inst.params if par is not None) + return f'{actual_inst.gerber_shape_code},{params}' def __eq__(self, other): return hasattr(other, to_gerber) and self.to_gerber() == other.to_gerber() @@ -57,7 +66,7 @@ class CircleAperture(Aperture): gerber_shape_code = 'C' human_readable_shape = 'circle' diameter : float - hole_dia : float = 0 + hole_dia : float = None hole_rect_h : float = None rotation : float = 0 # radians; for rectangular hole; see hack in Aperture.to_gerber @@ -69,12 +78,12 @@ class CircleAperture(Aperture): flash = _flash_hole - @parameter + @property def equivalent_width(self): return self.diameter - def rotated(self): - if math.isclose(rotation % (2*math.pi), 0) or self.hole_rect_h is None: + def _rotated(self): + if math.isclose(self.rotation % (2*math.pi), 0) or self.hole_rect_h is None: return self else: return self.to_macro(self.rotation) @@ -82,6 +91,10 @@ class CircleAperture(Aperture): def to_macro(self): return ApertureMacroInstance(GenericMacros.circle, *self.params) + @property + def params(self): + return strip_right(self.diameter, self.hole_dia, self.hole_rect_h) + @dataclass(frozen=True) class RectangleAperture(Aperture): @@ -89,7 +102,7 @@ class RectangleAperture(Aperture): human_readable_shape = 'rect' w : float h : float - hole_dia : float = 0 + hole_dia : float = None hole_rect_h : float = None rotation : float = 0 # radians @@ -101,7 +114,7 @@ class RectangleAperture(Aperture): flash = _flash_hole - @parameter + @property def equivalent_width(self): return math.sqrt(self.w**2 + self.h**2) @@ -116,6 +129,10 @@ class RectangleAperture(Aperture): def to_macro(self): return ApertureMacroInstance(GenericMacros.rect, *self.params) + @property + def params(self): + return strip_right(self.w, self.h, self.hole_dia, self.hole_rect_h) + @dataclass(frozen=True) class ObroundAperture(Aperture): @@ -123,7 +140,7 @@ class ObroundAperture(Aperture): human_readable_shape = 'obround' w : float h : float - hole_dia : float = 0 + hole_dia : float = None hole_rect_h : float = None rotation : float = 0 @@ -148,6 +165,10 @@ class ObroundAperture(Aperture): inst = self if self.w > self.h else replace(self, w=self.h, h=self.w, **_rotate_hole_90(self)) return ApertureMacroInstance(GenericMacros.obround, *inst.params) + @property + def params(self): + return strip_right(self.w, self.h, self.hole_dia, self.hole_rect_h) + @dataclass(frozen=True) class PolygonAperture(Aperture): @@ -155,7 +176,7 @@ class PolygonAperture(Aperture): diameter : float n_vertices : int rotation : float = 0 - hole_dia : float = 0 + hole_dia : float = None def primitives(self, x, y): return [ gp.RegularPolygon(x, y, diameter, n_vertices, rotation=self.rotation) ] @@ -172,6 +193,15 @@ class PolygonAperture(Aperture): def to_macro(self): return ApertureMacroInstance(GenericMacros.polygon, *self.params) + @property + def params(self): + if self.hole_dia is not None: + return self.diameter, self.n_vertices, self.rotation, self.hole_dia + elif self.rotation: + return self.diameter, self.n_vertices, self.rotation + else: + return self.diameter, self.n_vertices + class ApertureMacroInstance(Aperture): params : [float] @@ -204,4 +234,8 @@ class ApertureMacroInstance(Aperture): hasattr(other, 'params') and self.params == other.params and \ hasattr(other, 'rotation') and self.rotation == other.rotation + @property + def params(self): + return astuple(self)[:-1] + -- cgit