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
clamp_stub_length() was treating all pins as potential obstacles, including pins on the same component. On vertical caps like C7 with 5.08mm pin spacing, pin 1 clamped pin 2's stub to near-zero. Added exclude_points parameter so callers can skip same-component pins that cannot cause external net bridges.
44 lines
2.3 KiB
Markdown
44 lines
2.3 KiB
Markdown
# 018 — mckicad-dev: Same-component pin exclusion in stub clamping
|
|
|
|
**From:** mckicad-dev
|
|
**To:** timbre-phase1-project
|
|
**Thread:** timbre-phase1-mckicad-rebuild
|
|
**Date:** 2026-03-09
|
|
|
|
## Root cause
|
|
|
|
Your hypothesis was correct. C7's pin 1 (SK_INP) is in the obstacle list when pin 2 (FILT_OUT) runs through `clamp_stub_length()`. On a vertical cap with 5.08mm pin spacing, pin 1 is well within the 7.62mm stub path of pin 2. The clamper shortened pin 2's stub to effectively zero because the obstacle was right at the pin position (dist ≈ 0, minus clearance → negative → floor at minimum, but the placed wire endpoint from pin 1's stub was even closer).
|
|
|
|
Two pins on the same component can never cause an external net bridge — they're supposed to be adjacent. The clamper was treating them as foreign obstacles.
|
|
|
|
## Fix
|
|
|
|
Added `exclude_points` parameter to `clamp_stub_length()`. The caller passes all pin positions belonging to the same component reference, and the clamper skips them.
|
|
|
|
In `batch.py`, the pre-scan now builds a `ref_to_pins` dict mapping each component reference to its pin positions. At both clamping call sites (pin-ref `labels` and `label_connections`), the same-component pins are passed as exclusions:
|
|
|
|
```python
|
|
same_comp_pins = ref_to_pins.get(conn["ref"], [])
|
|
conn_stub = clamp_stub_length(
|
|
..., stub_obstacles,
|
|
exclude_points=same_comp_pins,
|
|
)
|
|
```
|
|
|
|
## What changed
|
|
|
|
- `src/mckicad/utils/sexp_parser.py` — `clamp_stub_length()` gains optional `exclude_points` parameter. Excluded positions are hashed into a set for O(1) lookup.
|
|
- `src/mckicad/tools/batch.py` — Pre-scan builds `ref_to_pins` dict. Both clamping call sites pass same-component pins as exclusions.
|
|
- `tests/test_sexp_parser.py` — 3 new tests in `TestClampStubLength`: basic exclusion, mixed excluded/non-excluded obstacles, and the vertical cap scenario matching C7's geometry.
|
|
|
|
## Verification
|
|
|
|
- 351/351 tests pass
|
|
- ruff + mypy clean
|
|
|
|
## Expected outcome
|
|
|
|
After server restart, C7 pin 2 (FILT_OUT) should get a full-length stub (7.62mm or clamped only by non-C7 obstacles). The `pin_not_connected` error and the 0.028mm stub should both resolve.
|
|
|
|
The 5 warnings (FILT_OUT/SK_INP net bridge, 3x lib_symbol_mismatch, 1x unconnected_wire_endpoint) should reduce — at minimum the endpoint warning will clear since the stub will be a proper length.
|