From 8d5403260b72115cfd9f401289dfd0f894e272ea Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 29 Apr 2023 11:28:38 +0200 Subject: Fix aperture macro rotation issue and add missing data files --- gerbonara/aperture_macros/expression.py | 2 +- gerbonara/aperture_macros/parse.py | 4 ++-- gerbonara/aperture_macros/primitive.py | 18 +++++++++++++++--- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'gerbonara/aperture_macros') diff --git a/gerbonara/aperture_macros/expression.py b/gerbonara/aperture_macros/expression.py index 63f1e42..44abf51 100644 --- a/gerbonara/aperture_macros/expression.py +++ b/gerbonara/aperture_macros/expression.py @@ -123,7 +123,7 @@ class UnitExpression(Expression): raise ValueError('Unit mismatch: Can only add/subtract UnitExpression from UnitExpression, not scalar.') def __sub__(self, other): - return (self + (-other)).optimize() + return (self + (-other)).optimized() def __rsub__(self, other): # see __radd__ above diff --git a/gerbonara/aperture_macros/parse.py b/gerbonara/aperture_macros/parse.py index 72703ae..b8970ff 100644 --- a/gerbonara/aperture_macros/parse.py +++ b/gerbonara/aperture_macros/parse.py @@ -55,9 +55,9 @@ class ApertureMacro: comments: tuple = () def __post_init__(self): - if self.name is None: + if self.name is None or re.match(r'GNX[0-9A-F]{16}', self.name): # We can't use field(default_factory=...) here because that factory doesn't get a reference to the instance. - object.__setattr__(self, 'name', f'gn_{hash(self):x}') + object.__setattr__(self, 'name', f'GNX{hash(self)&0xffffffffffffffff:016X}') @classmethod def parse_macro(cls, name, body, unit): diff --git a/gerbonara/aperture_macros/primitive.py b/gerbonara/aperture_macros/primitive.py index 5700743..356da9f 100644 --- a/gerbonara/aperture_macros/primitive.py +++ b/gerbonara/aperture_macros/primitive.py @@ -13,7 +13,7 @@ from .expression import Expression, UnitExpression, ConstantExpression, expr from .. import graphic_primitives as gp from .. import graphic_objects as go -from ..utils import rotate_point, LengthUnit +from ..utils import rotate_point, LengthUnit, MM def point_distance(a, b): @@ -277,8 +277,20 @@ class Outline(Primitive): return f'' def to_gerber(self, unit=None): - coords = ','.join(coord.to_gerber(unit) for coord in self.coords) - return f'{self.code},{self.exposure.to_gerber()},{len(self.coords)-1},{coords},{self.rotation.to_gerber()}' + # Calculate out rotation since at least gerbv mis-renders Outlines with rotation other than zero. + rotation = self.rotation.optimized() + coords = self.coords + if isinstance(rotation, ConstantExpression): + rotation = math.radians(rotation.value) + # This will work even with variables in x and y, we just need to pass in cx and cy as UnitExpressions + unit_zero = UnitExpression(expr(0), MM) + coords = [ rotate_point(x, y, -rotation, cx=unit_zero, cy=unit_zero) for x, y in self.points ] + coords = [ e for point in coords for e in point ] + + rotation = ConstantExpression(0) + + coords = ','.join(coord.to_gerber(unit) for coord in coords) + return f'{self.code},{self.exposure.to_gerber()},{len(self.coords)-1},{coords},{rotation.to_gerber()}' def to_graphic_primitives(self, offset, rotation, variable_binding={}, unit=None, polarity_dark=True): with self.Calculator(self, variable_binding, unit) as calc: -- cgit