From f439d10280df7544cfc4fe52bed98ab37d0a1171 Mon Sep 17 00:00:00 2001
From: jaseg <git@jaseg.de>
Date: Wed, 4 Oct 2023 17:14:46 +0200
Subject: Update for new, sparkling, generated footprints!

---
 footprint_generator.py |  61 +++++++++++++++++++++++++++++++++++++++++++++++++
 mesh_dialog.py         |  11 ++++-----
 mesh_footprints.tar.xz | Bin 0 -> 106300 bytes
 3 files changed, 66 insertions(+), 6 deletions(-)
 create mode 100755 footprint_generator.py
 create mode 100644 mesh_footprints.tar.xz

diff --git a/footprint_generator.py b/footprint_generator.py
new file mode 100755
index 0000000..731f6e8
--- /dev/null
+++ b/footprint_generator.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+from pathlib import Path
+import itertools
+
+import gerbonara.cad.kicad as kc
+from gerbonara.cad.kicad import footprints
+import gerbonara as gn
+from gerbonara.utils import MM
+
+import click
+
+@click.command()
+@click.option('-w', '--trace-width', default='0.15', help='Comma-separated list of trace widths [mm]')
+@click.option('-c', '--clearance', default='0.15', help='Comma-separated list of clearances to step through [mm]')
+@click.option('-n', '--conductors', default='2', help='Comma-separated list of numbers of conductors')
+@click.argument('output_dir', type=click.Path(dir_okay=True, file_okay=False, path_type=Path))
+def generate_footprints(output_dir, trace_width, clearance, conductors):
+    trace_widths = [float(x.strip()) for x in trace_width.split(',')]
+    clearances = [float(x.strip()) for x in clearance.split(',')]
+    conductors = [int(x.strip()) for x in conductors.split(',')]
+
+    if output_dir.suffix != '.pretty':
+        output_dir = output_dir.with_name(output_dir.name + '.pretty')
+
+    for trace, space, conductors in itertools.product(trace_widths, clearances, conductors):
+        pitch = trace + space
+
+        fp = footprints.Footprint(
+                name=f'MeshAnchor_{conductors}W_T{trace:.3f}mm_S{space:.3f}mm',
+                _version=20230620,
+                generator = footprints.Atom('kimesh_footprint_generator'),
+                descr=f'KiMesh mesh anchor footprint, {conductors} wires, {trace:.3f} mm trace width, {space:.3f} mm clearance',
+                tags='net tie',
+                attributes=footprints.Attribute(footprints.Atom.smd),
+                net_tie_pad_groups=[f'{i+1},{2*conductors-i},{2*conductors+1+i},{4*conductors-i}' for i in range(conductors)],
+                polygons=[footprints.Polygon(
+                    pts=footprints.PointList(xy=[
+                        footprints.XYCoord(-pitch/2, pitch * (conductors - i - 0.5) + trace/2),
+                        footprints.XYCoord(pitch/2, pitch * (conductors - i - 0.5) + trace/2),
+                        footprints.XYCoord(pitch/2, pitch * (conductors - i - 0.5) - trace/2),
+                        footprints.XYCoord(-pitch/2, pitch * (conductors - i - 0.5) - trace/2),
+                        ]),
+                    layer='F.Cu',
+                    fill=footprints.Atom.solid)
+                          for i in range(2*conductors)],
+                pads=[
+                    footprints.Pad(
+                        number=f'{i+1}',
+                        type=footprints.Atom.smd,
+                        shape=footprints.Atom.circle,
+                        at=footprints.AtPos(pitch * (i//(2*conductors) - 0.5), -pitch * (conductors - i%(2*conductors) - 0.5)),
+                        size=footprints.XYCoord(trace, trace),
+                        layers=['F.Cu'])
+                    for i in range(4*conductors)])
+        output_dir.mkdir(exist_ok=True)
+        fp.make_standard_properties()
+        fp.write(output_dir / f'{fp.name}.kicad_mod')
+
+if __name__ == '__main__':
+    generate_footprints()
diff --git a/mesh_dialog.py b/mesh_dialog.py
index c508608..0cce912 100644
--- a/mesh_dialog.py
+++ b/mesh_dialog.py
@@ -252,18 +252,17 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
             warn('Anchor {} has multiple outlines. Using first outline for trace start.')
         anchor_pads = list(sorted(anchor.Pads(), key=lambda pad: int(pad.GetNumber())))
 
-        mesh_angle = anchor.GetOrientationDegrees()
         trace_width = pcbnew.ToMM(anchor_pads[0].GetSize()[0])
         space_width = pcbnew.ToMM(math.dist(anchor_pads[0].GetPosition(), anchor_pads[1].GetPosition())) - trace_width
         num_traces = len(anchor_pads)
-        assert num_traces%2 == 0
-        num_traces //= 2
+        assert num_traces%4 == 0
+        num_traces //= 4
         nets = [f'{net_prefix}{i}' for i in range(num_traces)]
 
         width_per_trace = trace_width + space_width
         grid_cell_width = width_per_trace * num_traces * 2
 
-        x0, y0 = anchor_pads[0].GetPosition()
+        x0, y0 = anchor_pads[len(anchor_pads)//2].GetPosition()
         x0, y0 = pcbnew.ToMM(x0), pcbnew.ToMM(y0)
         xl, yl = anchor_pads[-1].GetPosition()
         xl, yl = pcbnew.ToMM(xl), pcbnew.ToMM(yl)
@@ -271,8 +270,8 @@ class MeshPluginMainDialog(mesh_plugin_dialog.MainDialog):
         mesh_angle = math.atan2(xl-x0, yl-y0)
         print('mesh angle is', math.degrees(mesh_angle))
         len_along = - width_per_trace/2
-        x0 += -trace_width/2 * math.cos(mesh_angle) + len_along * math.sin(mesh_angle)
-        y0 += -trace_width/2 * math.sin(mesh_angle) + len_along * math.cos(mesh_angle)
+        x0 += len_along * math.sin(mesh_angle)
+        y0 += len_along * math.cos(mesh_angle)
 
         mask_xformed = affinity.translate(mask, -x0, -y0)
         mask_xformed = affinity.rotate(mask_xformed, -mesh_angle, origin=(0, 0), use_radians=True)
diff --git a/mesh_footprints.tar.xz b/mesh_footprints.tar.xz
new file mode 100644
index 0000000..7695b8f
Binary files /dev/null and b/mesh_footprints.tar.xz differ
-- 
cgit