kicad-sch-api 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kicad-sch-api might be problematic. Click here for more details.

@@ -0,0 +1,149 @@
1
+ """
2
+ Pin positioning utilities for KiCAD schematic manipulation.
3
+
4
+ Provides accurate pin position calculation with component transformations,
5
+ migrated and improved from circuit-synth.
6
+ """
7
+
8
+ import logging
9
+ from typing import List, Optional, Tuple
10
+
11
+ from ..library.cache import get_symbol_cache
12
+ from .geometry import apply_transformation
13
+ from .types import Point, SchematicSymbol
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ def get_component_pin_position(component: SchematicSymbol, pin_number: str) -> Optional[Point]:
19
+ """
20
+ Get the absolute position of a component pin.
21
+
22
+ Migrated from circuit-synth with enhanced logging for verification.
23
+
24
+ Args:
25
+ component: Component containing the pin
26
+ pin_number: Pin number to find
27
+
28
+ Returns:
29
+ Absolute position of the pin, or None if not found
30
+ """
31
+ logger.info(f"Getting position for {component.reference} pin {pin_number}")
32
+ logger.info(f" Component position: ({component.position.x}, {component.position.y})")
33
+ logger.info(f" Component rotation: {getattr(component, 'rotation', 0)}°")
34
+ logger.info(f" Component mirror: {getattr(component, 'mirror', None)}")
35
+
36
+ # First check if pin is already in component data
37
+ for pin in component.pins:
38
+ if pin.number == pin_number:
39
+ logger.info(f" Found pin {pin_number} in component data")
40
+ logger.info(f" Pin relative position: ({pin.position.x}, {pin.position.y})")
41
+
42
+ # Apply component transformations
43
+ absolute_pos = apply_transformation(
44
+ (pin.position.x, pin.position.y),
45
+ component.position,
46
+ getattr(component, "rotation", 0),
47
+ getattr(component, "mirror", None),
48
+ )
49
+
50
+ result = Point(absolute_pos[0], absolute_pos[1])
51
+ logger.info(f" Final absolute position: ({result.x}, {result.y})")
52
+ return result
53
+
54
+ # If not in component data, try to get from symbol library
55
+ logger.info(f" Pin {pin_number} not in component data, checking symbol library")
56
+
57
+ try:
58
+ symbol_cache = get_symbol_cache()
59
+ symbol_def = symbol_cache.get_symbol(component.lib_id)
60
+
61
+ if not symbol_def:
62
+ logger.warning(f" Symbol definition not found for {component.lib_id}")
63
+ return None
64
+
65
+ logger.info(f" Found symbol definition for {component.lib_id}")
66
+
67
+ # Look for pin in symbol definition
68
+ pins_found = []
69
+ for pin_def in symbol_def.get("pins", []):
70
+ pins_found.append(pin_def.get("number", "unknown"))
71
+ if pin_def.get("number") == pin_number:
72
+ logger.info(f" Found pin {pin_number} in symbol definition")
73
+
74
+ # Get pin position from definition
75
+ pin_x = pin_def.get("x", 0)
76
+ pin_y = pin_def.get("y", 0)
77
+ logger.info(f" Symbol pin position: ({pin_x}, {pin_y})")
78
+
79
+ # Apply component transformations
80
+ absolute_pos = apply_transformation(
81
+ (pin_x, pin_y),
82
+ component.position,
83
+ getattr(component, "rotation", 0),
84
+ getattr(component, "mirror", None),
85
+ )
86
+
87
+ result = Point(absolute_pos[0], absolute_pos[1])
88
+ logger.info(f" Final absolute position: ({result.x}, {result.y})")
89
+ return result
90
+
91
+ logger.warning(f" Pin {pin_number} not found in symbol. Available pins: {pins_found}")
92
+
93
+ except Exception as e:
94
+ logger.error(f" Error accessing symbol cache: {e}")
95
+
96
+ return None
97
+
98
+
99
+ def list_component_pins(component: SchematicSymbol) -> List[Tuple[str, Point]]:
100
+ """
101
+ List all pins for a component with their absolute positions.
102
+
103
+ Args:
104
+ component: Component to analyze
105
+
106
+ Returns:
107
+ List of (pin_number, absolute_position) tuples
108
+ """
109
+ logger.info(f"Listing pins for component {component.reference}")
110
+
111
+ pins = []
112
+
113
+ # Check component data first
114
+ for pin in component.pins:
115
+ absolute_pos = apply_transformation(
116
+ (pin.position.x, pin.position.y),
117
+ component.position,
118
+ getattr(component, "rotation", 0),
119
+ getattr(component, "mirror", None),
120
+ )
121
+ pins.append((pin.number, Point(absolute_pos[0], absolute_pos[1])))
122
+
123
+ # If no pins in component data, try symbol library
124
+ if not pins:
125
+ try:
126
+ symbol_cache = get_symbol_cache()
127
+ symbol_def = symbol_cache.get_symbol(component.lib_id)
128
+
129
+ if symbol_def:
130
+ for pin_def in symbol_def.get("pins", []):
131
+ pin_number = pin_def.get("number")
132
+ pin_x = pin_def.get("x", 0)
133
+ pin_y = pin_def.get("y", 0)
134
+
135
+ absolute_pos = apply_transformation(
136
+ (pin_x, pin_y),
137
+ component.position,
138
+ getattr(component, "rotation", 0),
139
+ getattr(component, "mirror", None),
140
+ )
141
+ pins.append((pin_number, Point(absolute_pos[0], absolute_pos[1])))
142
+ except Exception as e:
143
+ logger.error(f"Error getting pins from symbol library: {e}")
144
+
145
+ logger.info(f"Found {len(pins)} pins for {component.reference}")
146
+ for pin_num, pos in pins:
147
+ logger.info(f" Pin {pin_num}: ({pos.x}, {pos.y})")
148
+
149
+ return pins