summaryrefslogtreecommitdiff
path: root/gerbonara/cad/kicad/base_types.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerbonara/cad/kicad/base_types.py')
-rw-r--r--gerbonara/cad/kicad/base_types.py69
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