diff options
Diffstat (limited to 'gerbonara/cad/kicad/base_types.py')
-rw-r--r-- | gerbonara/cad/kicad/base_types.py | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/gerbonara/cad/kicad/base_types.py b/gerbonara/cad/kicad/base_types.py index a4eba70..d800a36 100644 --- a/gerbonara/cad/kicad/base_types.py +++ b/gerbonara/cad/kicad/base_types.py @@ -9,7 +9,8 @@ from itertools import cycle from .sexp import * from .sexp_mapper import * from ...newstroke import Newstroke -from ...utils import rotate_point, Tag, MM +from ...utils import rotate_point, sum_bounds, Tag, MM +from ...layers import LayerStack from ... import apertures as ap from ... import graphic_objects as go @@ -37,6 +38,16 @@ LAYER_MAP_K2G = { LAYER_MAP_G2K = {v: k for k, v in LAYER_MAP_K2G.items()} +class BBoxMixin: + def bounding_box(self, unit=MM): + if not hasattr(self, '_bounding_box'): + (min_x, min_y), (max_x, max_y) = sum_bounds(fe.bounding_box(unit) for fe in self.render()) + # Convert back from gerbonara's coordinates to kicad coordinates. + self._bounding_box = (min_x, -max_y), (max_x, -min_y) + + return self._bounding_box + + @sexp_type('uuid') class UUID: value: str = field(default_factory=uuid.uuid4) @@ -112,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: @@ -259,7 +278,14 @@ class XYCoord: @sexp_type('pts') class PointList: - xy : List(XYCoord) = field(default_factory=list) + @classmethod + def __map__(kls, obj, parent=None): + _tag, *values = obj + return [map_sexp(XYCoord, elem, parent=parent) for elem in values] + + @classmethod + def __sexp__(kls, value): + yield [kls.name_atom, *(e for elem in value for e in elem.__sexp__(elem))] @sexp_type('arc') @@ -281,6 +307,29 @@ class ArcPointList: yield [kls.name_atom, *(e for elem in value for e in elem.__sexp__(elem))] +@sexp_type('net') +class Net: + index: int = 0 + name: str = '' + + +class NetMixin: + def reset_net(self): + self.net = Net() + + @property + def net_index(self): + if self.net is None: + return 0 + return self.net.index + + @property + def net_name(self): + if self.net is None: + return '' + return self.net.name + + @sexp_type('xyz') class XYZCoord: x: float = 0 @@ -316,8 +365,8 @@ class FontSpec: face: Named(str) = None size: Rename(XYCoord) = field(default_factory=lambda: XYCoord(1.27, 1.27)) thickness: Named(float) = None - bold: OmitDefault(Named(YesNoAtom())) = False - italic: OmitDefault(Named(YesNoAtom())) = False + bold: OmitDefault(Named(LegacyCompatibleFlag())) = False + italic: OmitDefault(Named(LegacyCompatibleFlag())) = False line_spacing: Named(float) = None @@ -345,8 +394,8 @@ class Justify: @sexp_type('effects') class TextEffect: font: FontSpec = field(default_factory=FontSpec) - hide: OmitDefault(Named(YesNoAtom())) = False justify: OmitDefault(Justify) = field(default_factory=Justify) + hide: OmitDefault(Named(LegacyCompatibleFlag())) = False class TextMixin: @@ -523,13 +572,13 @@ class DrawnProperty(TextMixin): key: str = None value: str = None id: Named(int) = None - at: AtPos = field(default_factory=AtPos) - unlocked: Named(YesNoAtom()) = True + at: AtPos = None + unlocked: OmitDefault(Named(YesNoAtom())) = True layer: Named(str) = None - hide: Named(YesNoAtom()) = False - uuid: UUID = field(default_factory=UUID) + hide: OmitDefault(Named(YesNoAtom())) = False + uuid: UUID = None tstamp: Timestamp = None - effects: TextEffect = field(default_factory=TextEffect) + effects: OmitDefault(TextEffect) = field(default_factory=TextEffect) _ : SEXP_END = None parent: object = None |