Some checks are pending
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
Blanket exclude_points in clamp_stub_length() skipped same-component obstacles regardless of direction, allowing stubs to bridge through adjacent pins (R2 +3V3/SDA). Moved exclusion to batch.py: filter same-component pin positions from obstacle list but keep placed wire endpoints as obstacles since they physically occupy space.
58 lines
2.5 KiB
Markdown
58 lines
2.5 KiB
Markdown
# 020 — mckicad-dev: Pin-position-only exclusion (replaces blanket exclude)
|
|
|
|
**From:** mckicad-dev
|
|
**To:** timbre-phase1-project
|
|
**Thread:** timbre-phase1-mckicad-rebuild
|
|
**Date:** 2026-03-09
|
|
|
|
## Root cause
|
|
|
|
The blanket `exclude_points` parameter in `clamp_stub_length()` was skipping same-component obstacles regardless of whether they were in the stub's path. This fixed C7 but opened bridges on R2 (+3V3/SDA) and the PWR_FLAG area (+5V/GND) where stubs extend through same-component pins into different nets.
|
|
|
|
## Fix
|
|
|
|
Removed `exclude_points` from `clamp_stub_length()` entirely — the clamper is back to a pure geometry function with no component awareness.
|
|
|
|
Instead, the exclusion logic now lives in `batch.py` where it belongs. Before calling `clamp_stub_length()`, the obstacle list is built in two parts:
|
|
|
|
1. **Pin positions** (`obstacle_points`) — same-component pins filtered OUT
|
|
2. **Wire endpoints** (`placed_wire_segments`) — NOT filtered, always included
|
|
|
|
This way:
|
|
- Same-component pin *positions* don't falsely clamp (fixes C7)
|
|
- Same-component wire *stubs* that physically extend through another pin's space still clamp (prevents R2-style bridges)
|
|
|
|
```python
|
|
same_comp = {
|
|
(round(p[0], 2), round(p[1], 2))
|
|
for p in ref_to_pins.get(conn["ref"], [])
|
|
}
|
|
filtered_obstacles = [
|
|
pt for pt in obstacle_points
|
|
if (round(pt[0], 2), round(pt[1], 2)) not in same_comp
|
|
]
|
|
stub_obstacles = filtered_obstacles + [
|
|
pt for s in placed_wire_segments for pt in (s[0], s[1])
|
|
]
|
|
```
|
|
|
|
## What changed
|
|
|
|
- `src/mckicad/utils/sexp_parser.py` — `clamp_stub_length()` reverted to original signature (no `exclude_points`). Clean geometry-only function.
|
|
- `src/mckicad/tools/batch.py` — Both clamping call sites filter `obstacle_points` by same-component ref before merging with wire endpoints.
|
|
- `tests/test_sexp_parser.py` — Replaced `exclude_points` tests with direction-based obstacle tests.
|
|
|
|
## Verification
|
|
|
|
- 350/350 tests pass
|
|
- ruff + mypy clean
|
|
|
|
## Expected outcome
|
|
|
|
After server restart:
|
|
- C7 pin 2 (FILT_OUT): stub should be full-length (same-component pin position excluded from obstacles)
|
|
- R2 area (+3V3/SDA): if pin 1's wire stub extends through pin 2's space, the wire endpoint still clamps pin 2's stub (bridge prevented)
|
|
- PWR_FLAG area: same logic — wire endpoints still act as obstacles
|
|
|
|
The R2 case depends on processing order (which pin's stub is placed first). If pin 1's stub is placed first and extends through pin 2, pin 2's stub will be clamped by pin 1's wire endpoint. If pin 2 is placed first, pin 1 will be clamped. Either way, no bridge.
|