summaryrefslogtreecommitdiff
path: root/gerbonara/cad/primitives.py
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-06-12 18:39:33 +0200
committerjaseg <git@jaseg.de>2023-06-12 18:39:33 +0200
commit35618179036409c71c87746c32a27238260a02a4 (patch)
tree5982cc2556eb110a37ef03288dfe13d7bef841b3 /gerbonara/cad/primitives.py
parent03f2ec0a307a33fd9be1da1a65b1dcb569cfcffd (diff)
downloadgerbonara-35618179036409c71c87746c32a27238260a02a4.tar.gz
gerbonara-35618179036409c71c87746c32a27238260a02a4.tar.bz2
gerbonara-35618179036409c71c87746c32a27238260a02a4.zip
Add basic KiCad PCB file format support
Diffstat (limited to 'gerbonara/cad/primitives.py')
-rw-r--r--gerbonara/cad/primitives.py58
1 files changed, 48 insertions, 10 deletions
diff --git a/gerbonara/cad/primitives.py b/gerbonara/cad/primitives.py
index 472cb32..2b7c209 100644
--- a/gerbonara/cad/primitives.py
+++ b/gerbonara/cad/primitives.py
@@ -173,6 +173,44 @@ class Positioned:
return True
+# The dataclass API is slightly idiotic here, so we have to duplicate the entire thing.
+@dataclass(frozen=True)
+class FrozenPositioned:
+ x: float
+ y: float
+ _: KW_ONLY
+ rotation: float = 0.0
+ flip: bool = False
+ unit: LengthUnit = MM
+ parent: object = None
+
+ @property
+ def abs_pos(self):
+ if self.parent is None:
+ px, py, pa, pf = 0, 0, 0, False
+ else:
+ px, py, pa, pf = self.parent.abs_pos
+
+ return self.x+px, self.y+py, self.rotation+pa, (bool(self.flip) != bool(pf))
+
+ def bounding_box(self, unit=MM):
+ stack = LayerStack()
+ self.render(stack)
+ objects = chain(*(l.objects for l in stack.graphic_layers.values()),
+ stack.drill_pth.objects, stack.drill_npth.objects)
+ objects = list(objects)
+ #print('foo', type(self).__name__,
+ # [(type(obj).__name__, [prim.bounding_box() for prim in obj.to_primitives(unit)]) for obj in objects], file=sys.stderr)
+ return sum_bounds(prim.bounding_box() for obj in objects for prim in obj.to_primitives(unit))
+
+ def overlaps(self, bbox, unit=MM):
+ return bbox_intersect(self.bounding_box(unit), bbox)
+
+ @property
+ def single_sided(self):
+ return True
+
+
@dataclass
class Graphics(Positioned):
top_copper: list = field(default_factory=list)
@@ -336,15 +374,6 @@ class Text(Positioned):
return (self.x+x0, self.y+y0), (self.x+x0+approx_w, self.y+y0+approx_h)
-@dataclass
-class Pad(Positioned):
- pad_stack: PadStack
-
- @property
- def single_sided(self):
- return self.pad_stack.single_sided
-
-
@dataclass(frozen=True, slots=True)
class PadStackAperture:
aperture: Aperture
@@ -493,7 +522,7 @@ class ThroughViaStack(PadStack):
@dataclass(frozen=True, slots=True)
-class Via(Positioned):
+class Via(FrozenPositioned):
pad_stack: PadStack
def render(self, layer_stack, cache=None):
@@ -506,6 +535,15 @@ class Via(Positioned):
@dataclass
+class Pad(Positioned):
+ pad_stack: PadStack
+
+ @property
+ def single_sided(self):
+ return self.pad_stack.single_sided
+
+
+@dataclass
class Trace:
width: float
start: object = None