fix: apply unannotated-reference fix to find_unconnected_pins and get_elements_in_region

The same reference-lookup bug fixed in check_wire_collisions (where
PinLocator.get_all_symbol_pins always resolves to the first symbol
with a given reference) also affected:

- find_unconnected_pins: would check wrong pin positions for all
  unannotated components after the first, producing false connected/
  unconnected reports.
- get_elements_in_region: would return wrong pin coordinates for
  unannotated components in the queried region.

Both now use _compute_pin_positions_direct (fetching pin defs by
lib_id and applying each symbol's own position/rotation/mirror),
matching the fix already applied to check_wire_collisions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Eugene Mikhantyev
2026-03-15 11:06:08 +00:00
parent 53564cbc58
commit 1bfa608729

View File

@@ -293,11 +293,13 @@ def find_unconnected_pins(schematic_path: Path) -> List[Dict[str, Any]]:
if sym["is_power"] or ref.startswith("_TEMPLATE") or not ref:
continue
pin_positions = locator.get_all_symbol_pins(schematic_path, ref)
if not pin_positions:
pin_defs = locator.get_symbol_pins(schematic_path, sym["lib_id"])
if not pin_defs:
continue
pin_defs = None
pin_positions = _compute_pin_positions_direct(sym, pin_defs)
if not pin_positions:
continue
for pin_num, pos in pin_positions.items():
px, py = pos[0], pos[1]
@@ -307,9 +309,6 @@ def find_unconnected_pins(schematic_path: Path) -> List[Dict[str, Any]]:
if is_connected(px, py):
continue
if pin_defs is None:
pin_defs = locator.get_symbol_pins(schematic_path, sym["lib_id"])
pin_name = pin_defs.get(pin_num, {}).get("name", pin_num)
unconnected.append({
"reference": ref,
@@ -482,13 +481,15 @@ def get_elements_in_region(
"position": {"x": sym["x"], "y": sym["y"]},
"isPower": sym["is_power"],
}
# Include pin positions
pin_positions = locator.get_all_symbol_pins(schematic_path, sym["reference"])
if pin_positions:
entry["pins"] = {
pn: {"x": round(pos[0], 4), "y": round(pos[1], 4)}
for pn, pos in pin_positions.items()
}
# Include pin positions (compute directly to handle unannotated duplicates)
pin_defs = locator.get_symbol_pins(schematic_path, sym["lib_id"])
if pin_defs:
pin_positions = _compute_pin_positions_direct(sym, pin_defs)
if pin_positions:
entry["pins"] = {
pn: {"x": round(pos[0], 4), "y": round(pos[1], 4)}
for pn, pos in pin_positions.items()
}
region_symbols.append(entry)
# Wires: include if ANY endpoint is within bounds