fix: schematic pin connection reliability
- add_schematic_net_label: warn in description that coords must be exact pin endpoints; recommend connect_to_net instead - connect_to_net: stub wire direction now follows pin angle (was hardcoded +X) - pin_locator.py: add get_pin_angle() and _get_lib_id() helpers - new tool: get_schematic_pin_locations(schematicPath, reference) → returns exact x/y of every pin endpoint, so Claude can place labels correctly
This commit is contained in:
@@ -179,6 +179,63 @@ class PinLocator:
|
||||
|
||||
return (rotated_x, rotated_y)
|
||||
|
||||
def _get_lib_id(self, schematic_path: Path, symbol_reference: str) -> Optional[str]:
|
||||
"""Helper: return the lib_id string for a placed symbol"""
|
||||
try:
|
||||
sch_key = str(schematic_path)
|
||||
if sch_key not in self._schematic_cache:
|
||||
self._schematic_cache[sch_key] = Schematic(sch_key)
|
||||
sch = self._schematic_cache[sch_key]
|
||||
for symbol in sch.symbol:
|
||||
if symbol.property.Reference.value == symbol_reference:
|
||||
return symbol.lib_id.value if hasattr(symbol, "lib_id") else None
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_pin_angle(
|
||||
self, schematic_path: Path, symbol_reference: str, pin_number: str
|
||||
) -> Optional[float]:
|
||||
"""
|
||||
Get the outward angle of a pin endpoint in degrees (0=right, 90=up, 180=left, 270=down).
|
||||
This is the direction a wire stub must extend to stay connected to the pin.
|
||||
|
||||
Returns angle in degrees, or None if pin not found.
|
||||
"""
|
||||
try:
|
||||
sch_key = str(schematic_path)
|
||||
if sch_key not in self._schematic_cache:
|
||||
self._schematic_cache[sch_key] = Schematic(sch_key)
|
||||
sch = self._schematic_cache[sch_key]
|
||||
|
||||
target_symbol = None
|
||||
for symbol in sch.symbol:
|
||||
if symbol.property.Reference.value == symbol_reference:
|
||||
target_symbol = symbol
|
||||
break
|
||||
|
||||
if not target_symbol:
|
||||
return None
|
||||
|
||||
symbol_at = target_symbol.at.value
|
||||
symbol_rotation = float(symbol_at[2]) if len(symbol_at) > 2 else 0.0
|
||||
|
||||
lib_id = target_symbol.lib_id.value if hasattr(target_symbol, "lib_id") else None
|
||||
if not lib_id:
|
||||
return None
|
||||
|
||||
pins = self.get_symbol_pins(schematic_path, lib_id)
|
||||
if pin_number not in pins:
|
||||
return None
|
||||
|
||||
# Pin definition angle + symbol rotation = absolute outward direction
|
||||
pin_def_angle = pins[pin_number].get("angle", 0)
|
||||
absolute_angle = (pin_def_angle + symbol_rotation) % 360
|
||||
return absolute_angle
|
||||
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def get_pin_location(
|
||||
self, schematic_path: Path, symbol_reference: str, pin_number: str
|
||||
) -> Optional[List[float]]:
|
||||
|
||||
Reference in New Issue
Block a user