summaryrefslogtreecommitdiff
path: root/gerbonara/cad/kicad/primitives.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerbonara/cad/kicad/primitives.py')
-rw-r--r--gerbonara/cad/kicad/primitives.py32
1 files changed, 25 insertions, 7 deletions
diff --git a/gerbonara/cad/kicad/primitives.py b/gerbonara/cad/kicad/primitives.py
index 65566d0..ad1cc90 100644
--- a/gerbonara/cad/kicad/primitives.py
+++ b/gerbonara/cad/kicad/primitives.py
@@ -38,7 +38,7 @@ def layer_mask(layers):
case 'B.Cu':
mask |= 1<<31
case _:
- if (m := re.match(f'In([0-9]+)\.Cu', layer)):
+ if (m := re.match(fr'In([0-9]+)\.Cu', layer)):
mask |= 1<<int(m.group(1))
return mask
@@ -62,6 +62,8 @@ def center_arc_to_kicad_mid(center, start, end):
def kicad_mid_to_center_arc(mid, start, end):
""" Convert kicad's slightly insane midpoint notation to standrad center/p1/p2 notation.
+ returns a ((center_x, center_y), radius, clockwise) tuple in KiCad coordinates.
+
Returns the center and radius of the circle passing the given 3 points.
In case the 3 points form a line, raises a ValueError.
"""
@@ -81,7 +83,7 @@ def kicad_mid_to_center_arc(mid, start, end):
cy = ((p1[0] - p2[0]) * cd - (p2[0] - p3[0]) * bc) / det
radius = math.sqrt((cx - p1[0])**2 + (cy - p1[1])**2)
- return (cx, cy), radius
+ return (cx, cy), radius, det < 0
@sexp_type('hatch')
@@ -92,7 +94,7 @@ class Hatch:
@sexp_type('connect_pads')
class PadConnection:
- type: AtomChoice(Atom.thru_hole_only, Atom.full, Atom.no) = None
+ type: AtomChoice(Atom.yes, Atom.thru_hole_only, Atom.full, Atom.no) = None
clearance: Named(float) = 0
@@ -133,18 +135,18 @@ class ZoneFill:
class FillPolygon:
layer: Named(str) = ""
island: Wrap(Flag()) = False
- pts: PointList = field(default_factory=PointList)
+ pts: PointList = field(default_factory=list)
@sexp_type('fill_segments')
class FillSegment:
layer: Named(str) = ""
- pts: PointList = field(default_factory=PointList)
+ pts: PointList = field(default_factory=list)
@sexp_type('polygon')
class ZonePolygon:
- pts: PointList = field(default_factory=PointList)
+ pts: PointList = field(default_factory=list)
@sexp_type('zone')
@@ -178,10 +180,26 @@ class Zone:
self.fill_polygons = []
self.fill_segments = []
+ def rotate(self, angle, cx=None, cy=None):
+ self.unfill()
+ self.polygon.pts = [pt.with_rotation(angle, cx, cy) for pt in self.polygon.pts]
+
+ def offset(self, x=0, y=0):
+ self.unfill()
+ self.polygon.pts = [pt.with_offset(x, y) for pt in self.polygon.pts]
+
+
+ def bounding_box(self):
+ min_x = min(pt.x for pt in self.polygon.pts)
+ min_y = min(pt.y for pt in self.polygon.pts)
+ max_x = max(pt.x for pt in self.polygon.pts)
+ max_y = max(pt.y for pt in self.polygon.pts)
+ return (min_x, min_y), (max_x, max_y)
+
@sexp_type('polygon')
class RenderCachePolygon:
- pts: PointList = field(default_factory=PointList)
+ pts: PointList = field(default_factory=list)
@sexp_type('render_cache')