Mark low-current copper as polygons on user layers (dialog opt-in)
Build PCM package / build (push) Successful in 7s
tests / ubuntu-latest · py3.11 (push) Successful in 53s
tests / ubuntu-latest · py3.13 (push) Successful in 1m43s
tests / archlinux:latest (push) Successful in 39s
tests / debian:12 (push) Successful in 49s
tests / fedora:latest (push) Successful in 1m1s
tests / ubuntu:24.04 (push) Successful in 1m26s
tests / NixOS (FHS wrapper from docs/NIXOS.md) (push) Has been skipped
Build PCM package / build (push) Successful in 7s
tests / ubuntu-latest · py3.11 (push) Successful in 53s
tests / ubuntu-latest · py3.13 (push) Successful in 1m43s
tests / archlinux:latest (push) Successful in 39s
tests / debian:12 (push) Successful in 49s
tests / fedora:latest (push) Successful in 1m1s
tests / ubuntu:24.04 (push) Successful in 1m26s
tests / NixOS (FHS wrapper from docs/NIXOS.md) (push) Has been skipped
New EXPERIMENTAL dialog option (default off): after the solve, copper whose |J| is below a threshold (default 10% of the mean |J| over all solved copper cells - mean, not max, since contact-corner spikes would dwarf a max-relative threshold) is vectorized into filled graphic polygons on TRIM_LAYERS (User.5..User.8, configurable), one polygon per region so Edit > Convert can turn one into a rule area by hand. Areas are printed and the polygons saved to low_current_copper.json. The mask -> polygon step is the 0.5 contour of the binary field via contourpy (already in every venv as matplotlib dependency), padded so regions touching the raster edge close, simplified with Douglas-Peucker at 0.4 cells: staircase bevels collapse, one-cell-wide strips survive. Specks under TRIM_MIN_AREA_MM2 are dropped. Explicitly a suggestion, not a safe cut list (docstring, dialog and README all say so): copper carries little current BECAUSE the rest carries it, so removal redistributes |J| - the constant-density optimizer that iterates this to convergence is future work. board_io: the create/delete-with-status-surfaced helpers are now generic (_create_items_checked / _remove_items_checked) and shared between reference-image overlays and trim polygons. Tested on the dev stack (3.13) and the Python 3.9 mac-stack venv, 148 passed each; contourpy 1.3.x has identical API on both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,8 @@ class Selection:
|
||||
cap_max_drill_mm: float = 0.5
|
||||
adaptive: bool = True
|
||||
push_overlays: bool = False # EXPERIMENTAL in-KiCad |J| overlays
|
||||
trim_enabled: bool = False # EXPERIMENTAL low-current copper marking
|
||||
trim_pct: float = 10.0 # threshold as % of the mean |J|
|
||||
|
||||
|
||||
class _Dialog(QDialog):
|
||||
@@ -130,6 +132,19 @@ class _Dialog(QDialog):
|
||||
self.overlay_check.setChecked(config.PUSH_OVERLAYS)
|
||||
form.addRow("Overlays:", self.overlay_check)
|
||||
|
||||
tfirst, tlast = config.TRIM_LAYERS[0], config.TRIM_LAYERS[-1]
|
||||
self.trim_check = QCheckBox(
|
||||
f"experimental: mark copper below the threshold as polygons "
|
||||
f"on {tfirst}..{tlast} (replaces polygons there; a suggestion "
|
||||
f"only - removing copper shifts current elsewhere)")
|
||||
self.trim_check.setChecked(config.TRIM_ENABLED)
|
||||
form.addRow("Low-current copper:", self.trim_check)
|
||||
|
||||
self.trim_edit = QLineEdit(f"{config.TRIM_THRESHOLD_PCT:g}")
|
||||
self.trim_edit.setEnabled(config.TRIM_ENABLED)
|
||||
self.trim_check.toggled.connect(self.trim_edit.setEnabled)
|
||||
form.addRow("Threshold [% of mean |J|]:", self.trim_edit)
|
||||
|
||||
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
buttons.accepted.connect(self._try_accept)
|
||||
buttons.rejected.connect(self.reject)
|
||||
@@ -227,6 +242,12 @@ class _Dialog(QDialog):
|
||||
extra_cu = number(self.extracu_edit, "Extra Cu")
|
||||
if extra_cu < 0:
|
||||
raise ValueError("Extra Cu must be ≥ 0 µm.")
|
||||
trim_pct = config.TRIM_THRESHOLD_PCT
|
||||
if self.trim_check.isChecked():
|
||||
trim_pct = number(self.trim_edit, "Trim threshold")
|
||||
if not 0 < trim_pct < 100:
|
||||
raise ValueError("Trim threshold must be between 0 and "
|
||||
"100 (% of the mean |J|).")
|
||||
cap_max_drill = config.CAP_MAX_DRILL_MM
|
||||
if self.capped_check.isChecked():
|
||||
cap_max_drill = number(self.cap_drill_edit, "Capped up to drill")
|
||||
@@ -251,7 +272,9 @@ class _Dialog(QDialog):
|
||||
vias_capped=self.capped_check.isChecked(),
|
||||
cap_max_drill_mm=cap_max_drill,
|
||||
adaptive=self.adaptive_check.isChecked(),
|
||||
push_overlays=self.overlay_check.isChecked())
|
||||
push_overlays=self.overlay_check.isChecked(),
|
||||
trim_enabled=self.trim_check.isChecked(),
|
||||
trim_pct=trim_pct)
|
||||
|
||||
def _try_accept(self) -> None:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user