From e42b7462c971830367586bc886bcc3225edfc678 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 19 Jul 2024 19:18:55 +0200 Subject: kicad: Add nicer width access This commit straightens up the mess a bit with kicad's two conflicting "width" fields in different file format versions. The new variant is preferred when saving, but the old variant is accepted as API --- gerbonara/cad/kicad/base_types.py | 8 ++++++++ gerbonara/cad/kicad/graphical_primitives.py | 31 +++++++++++++++-------------- 2 files changed, 24 insertions(+), 15 deletions(-) (limited to 'gerbonara/cad') diff --git a/gerbonara/cad/kicad/base_types.py b/gerbonara/cad/kicad/base_types.py index 0060980..358aab7 100644 --- a/gerbonara/cad/kicad/base_types.py +++ b/gerbonara/cad/kicad/base_types.py @@ -123,6 +123,14 @@ class Stroke: return attrs +class WidthMixin: + def __post_init__(self): + if self.width is None: + self.width = self.stroke.width + else: + self.stroke = Stroke(self.width) + + class Dasher: def __init__(self, obj): if obj.stroke: diff --git a/gerbonara/cad/kicad/graphical_primitives.py b/gerbonara/cad/kicad/graphical_primitives.py index 8911639..1583e04 100644 --- a/gerbonara/cad/kicad/graphical_primitives.py +++ b/gerbonara/cad/kicad/graphical_primitives.py @@ -71,7 +71,7 @@ class TextBox(BBoxMixin): @sexp_type('gr_line') -class Line: +class Line(WidthMixin): start: Rename(XYCoord) = None end: Rename(XYCoord) = None angle: Named(float) = None # wat @@ -122,7 +122,7 @@ class FillMode: yield [Atom.fill, Atom.solid if value else Atom.none] @sexp_type('gr_rect') -class Rectangle(BBoxMixin): +class Rectangle(BBoxMixin, WidthMixin): start: Rename(XYCoord) = None end: Rename(XYCoord) = None layer: Named(str) = None @@ -140,9 +140,9 @@ class Rectangle(BBoxMixin): if self.fill: yield rect - if self.width: + if (w := self.stroke.width if self.stroke else self.width): # FIXME stroke support - yield from rect.outline_objects(aperture=ap.CircleAperture(self.width, unit=MM)) + yield from rect.outline_objects(aperture=ap.CircleAperture(w, unit=MM)) @property def top_left(self): @@ -155,7 +155,7 @@ class Rectangle(BBoxMixin): @sexp_type('gr_circle') -class Circle(BBoxMixin): +class Circle(BBoxMixin, WidthMixin): center: Rename(XYCoord) = None end: Rename(XYCoord) = None layer: Named(str) = None @@ -167,10 +167,11 @@ class Circle(BBoxMixin): def render(self, variables=None): r = math.dist((self.center.x, -self.center.y), (self.end.x, -self.end.y)) - aperture = ap.CircleAperture(self.width or 0, unit=MM) + w = self.stroke.width if self.stroke else self.width + aperture = ap.CircleAperture(w or 0, unit=MM) arc = go.Arc.from_circle(self.center.x, -self.center.y, r, aperture=aperture, unit=MM) - if self.width: + if w: # FIXME stroke support yield arc @@ -183,7 +184,7 @@ class Circle(BBoxMixin): @sexp_type('gr_arc') -class Arc(BBoxMixin): +class Arc(WidthMixin, BBoxMixin): start: Rename(XYCoord) = None mid: Rename(XYCoord) = None end: Rename(XYCoord) = None @@ -210,11 +211,10 @@ class Arc(BBoxMixin): self.end.x, self.end.y = rotate_point(self.end.x, self.end.y, angle, cx, cy) def render(self, variables=None): - # FIXME stroke support - if not self.width: + if not (w := self.stroke.width if self.stroke else self.width): return - aperture = ap.CircleAperture(self.width, unit=MM) + aperture = ap.CircleAperture(w, unit=MM) x1, y1 = self.start.x, self.start.y x2, y2 = self.end.x, self.end.y (cx, cy), _r, clockwise = kicad_mid_to_center_arc(self.mid, self.start, self.end) @@ -227,7 +227,7 @@ class Arc(BBoxMixin): @sexp_type('gr_poly') -class Polygon(BBoxMixin): +class Polygon(BBoxMixin, WidthMixin): pts: ArcPointList = field(default_factory=list) layer: Named(str) = None width: Named(float) = None @@ -255,9 +255,10 @@ class Polygon(BBoxMixin): reg = go.Region(points, centers, unit=MM) reg.close() + w = self.stroke.width if self.stroke else self.width # FIXME stroke support - if self.width and self.width >= 0.005 or self.stroke.width and self.stroke.width > 0.005: - yield from reg.outline_objects(aperture=ap.CircleAperture(self.width, unit=MM)) + if w and w >= 0.005: + yield from reg.outline_objects(aperture=ap.CircleAperture(w, unit=MM)) if self.fill: yield reg @@ -267,7 +268,7 @@ class Polygon(BBoxMixin): @sexp_type('gr_curve') -class Curve(BBoxMixin): +class Curve(BBoxMixin, WidthMixin): pts: PointList = field(default_factory=list) layer: Named(str) = None width: Named(float) = None -- cgit