summaryrefslogtreecommitdiff
path: root/gerbonara/cad
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-04-20 00:46:30 +0200
committerjaseg <git@jaseg.de>2023-04-20 00:46:30 +0200
commit5ce88e4d1b06dcc846c94ec614fb00f64e85c125 (patch)
tree30cacf1ffb500c1deebc6b30e8c98d7ec474559a /gerbonara/cad
parent240e5569aa7521aed321b2607f78d198c36ed8b8 (diff)
downloadgerbonara-5ce88e4d1b06dcc846c94ec614fb00f64e85c125.tar.gz
gerbonara-5ce88e4d1b06dcc846c94ec614fb00f64e85c125.tar.bz2
gerbonara-5ce88e4d1b06dcc846c94ec614fb00f64e85c125.zip
Fix a bunch of bugs on the way to electroniceel's protoboard layout
Diffstat (limited to 'gerbonara/cad')
-rw-r--r--gerbonara/cad/kicad/footprints.py10
-rw-r--r--gerbonara/cad/kicad/graphical_primitives.py14
-rw-r--r--gerbonara/cad/protoboard.py22
3 files changed, 33 insertions, 13 deletions
diff --git a/gerbonara/cad/kicad/footprints.py b/gerbonara/cad/kicad/footprints.py
index 4b95d4e..8377961 100644
--- a/gerbonara/cad/kicad/footprints.py
+++ b/gerbonara/cad/kicad/footprints.py
@@ -22,7 +22,7 @@ from ... import graphic_primitives as gp
from ... import graphic_objects as go
from ... import apertures as ap
from ...utils import MM
-from ...aperture_macros.parse import GenericMacros
+from ...aperture_macros.parse import GenericMacros, ApertureMacro
@sexp_type('property')
@@ -376,7 +376,7 @@ class Pad:
dx, dy = self.rect_delta.x, self.rect_delta.y
# Note: KiCad already uses MM units, so no conversion needed here.
- return ApertureMacroInstance(GenericMacros.isosceles_trapezoid,
+ return ap.ApertureMacroInstance(GenericMacros.isosceles_trapezoid,
[x+dx, y+dy,
2*max(dx, dy),
0, 0, # no hole
@@ -385,7 +385,7 @@ class Pad:
elif self.shape == Atom.roundrect:
x, y = self.size.x, self.size.y
r = min(x, y) * self.roundrect_rratio
- return ApertureMacroInstance(GenericMacros.rounded_rect,
+ return ap.ApertureMacroInstance(GenericMacros.rounded_rect,
[x, y,
r,
0, 0, # no hole
@@ -398,7 +398,7 @@ class Pad:
for gn_obj in obj.render():
primitives += gn_obj._aperture_macro_primitives() # todo: precision params
macro = ApertureMacro(primitives=primitives)
- return ApertureMacroInstance(macro)
+ return ap.ApertureMacroInstance(macro)
def render_drill(self):
if not self.drill:
@@ -548,6 +548,8 @@ class Footprint:
for fe in obj.render():
fe.rotate(rotation)
fe.offset(x, y, MM)
+ if isinstance(fe, go.Flash) and fe.aperture:
+ fe.aperture = fe.aperture.rotated(rotation)
layer_stack[layer_map[layer]].objects.append(fe)
for obj in self.pads:
diff --git a/gerbonara/cad/kicad/graphical_primitives.py b/gerbonara/cad/kicad/graphical_primitives.py
index ed40c96..0760342 100644
--- a/gerbonara/cad/kicad/graphical_primitives.py
+++ b/gerbonara/cad/kicad/graphical_primitives.py
@@ -8,7 +8,7 @@ from .primitives import *
from ... import graphic_objects as go
from ... import apertures as ap
from ...newstroke import Newstroke
-from ...utils import rotate_point
+from ...utils import rotate_point, MM
@sexp_type('layer')
class TextLayer:
@@ -84,7 +84,7 @@ class TextBox:
if self.stroke.type not in (None, Atom.default, Atom.solid):
raise ValueError('Dashed strokes are not supported on vector text')
- yield from reg.outline_objects(aperture=CircleAperture(self.stroke.width, unit=MM))
+ yield from reg.outline_objects(aperture=ap.CircleAperture(self.stroke.width, unit=MM))
yield reg
@@ -137,7 +137,7 @@ class Rectangle:
yield rect
if self.width:
- yield from rect.outline_objects(aperture=CircleAperture(self.width, unit=MM))
+ yield from rect.outline_objects(aperture=ap.CircleAperture(self.width, unit=MM))
@sexp_type('gr_circle')
@@ -177,7 +177,7 @@ class Arc:
arc = go.Arc(x1, y1, x2, y2, cx-x1, cy-y1, unit=MM)
if self.width:
- arc.aperture = CircleAperture(self.width, unit=MM)
+ arc.aperture = ap.CircleAperture(self.width, unit=MM)
yield arc
if self.fill:
@@ -189,14 +189,14 @@ class Polygon:
pts: PointList = field(default_factory=PointList)
layer: Named(str) = None
width: Named(float) = None
- fill: FillMode= False
+ fill: FillMode = True
tstamp: Timestamp = None
def render(self):
reg = go.Region([(pt.x, pt.y) for pt in self.pts.xy], unit=MM)
- if width:
- yield from reg.outline_objects(aperture=CircleAperture(self.width, unit=MM))
+ if self.width and self.width >= 0.005:
+ yield from reg.outline_objects(aperture=ap.CircleAperture(self.width, unit=MM))
if self.fill:
yield reg
diff --git a/gerbonara/cad/protoboard.py b/gerbonara/cad/protoboard.py
index 3c523bc..9c3fbd7 100644
--- a/gerbonara/cad/protoboard.py
+++ b/gerbonara/cad/protoboard.py
@@ -6,10 +6,13 @@ import string
import itertools
from copy import copy, deepcopy
import warnings
+import importlib.resources
from .primitives import *
from ..graphic_objects import Region
from ..apertures import RectangleAperture, CircleAperture
+from .kicad import footprints as kfp
+from . import data as package_data
class ProtoBoard(Board):
@@ -468,6 +471,21 @@ class PoweredProto(ObjectGroup):
return unit.convert_bounds_from(self.unit, ((x-p, y-p), (x+p, y+p)))
+class SpikyProto(ObjectGroup):
+ def __init__(self, pitch=None, drill=None, clearance=None, power_pad_dia=None, via_size=None, trace_width=None, unit=MM):
+ super().__init__(0, 0)
+ res = importlib.resources.files(package_data)
+
+ self.fp_center = kfp.Footprint.load(res.joinpath('center-pad-spikes.kicad_mod').read_text(encoding='utf-8'))
+ self.objects.append(kfp.FootprintInstance(1.27, 1.27, self.fp_center, unit=MM))
+
+ self.fp_between = kfp.Footprint.load(res.joinpath('pad-between-spiked.kicad_mod').read_text(encoding='utf-8'))
+ self.objects.append(kfp.FootprintInstance(1.27, 0, self.fp_between, unit=MM))
+ self.objects.append(kfp.FootprintInstance(0, 1.27, self.fp_between, rotation=math.pi/2, unit=MM))
+
+ self.pad = kfp.Footprint.load(res.joinpath('tht-0.8.kicad_mod').read_text(encoding='utf-8'))
+ self.objects.append(kfp.FootprintInstance(0, 0, self.pad, unit=MM))
+
def convert_to_mm(value, unit):
unitl = unit.lower()
if unitl == 'mm':
@@ -498,7 +516,7 @@ def eval_value(value, total_length=None):
def _demo():
#pattern1 = PatternProtoArea(2.54, obj=THTPad.circle(0, 0, 0.9, 1.8, paste=False))
- pattern1 = PatternProtoArea(2.54, 3.84, obj=THTPad.obround(0, 0, 0.9, 1.8, 2.5, paste=False))
+ pattern1 = PatternProtoArea(2.54, 2.54, obj=SpikyProto())
pattern2 = PatternProtoArea(1.2, 2.0, obj=SMDPad.rect(0, 0, 1.0, 1.8, paste=False))
pattern3 = PatternProtoArea(2.54, 1.27, obj=SMDPad.rect(0, 0, 2.3, 1.0, paste=False))
#pattern3 = EmptyProtoArea(copper_fill=True)
@@ -511,7 +529,7 @@ def _demo():
#pattern = PatternProtoArea(2.54*1.5, obj=THTFlowerProto())
#pattern = PatternProtoArea(2.54, obj=THTPad.circle(0, 0, 0.9, 1.8, paste=False))
#pattern = PatternProtoArea(2.54, obj=PoweredProto())
- pb = ProtoBoard(100, 80, pattern, mounting_hole_dia=3.2, mounting_hole_offset=5)
+ pb = ProtoBoard(30, 30, pattern1, mounting_hole_dia=3.2, mounting_hole_offset=5)
print(pb.pretty_svg())
pb.layer_stack().save_to_directory('/tmp/testdir')