kicad-sch-api 0.2.0__py3-none-any.whl → 0.2.1__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.
- kicad_sch_api/__init__.py +6 -2
- kicad_sch_api/cli.py +67 -62
- kicad_sch_api/core/component_bounds.py +477 -0
- kicad_sch_api/core/components.py +22 -10
- kicad_sch_api/core/config.py +127 -0
- kicad_sch_api/core/formatter.py +183 -23
- kicad_sch_api/core/geometry.py +111 -0
- kicad_sch_api/core/ic_manager.py +43 -37
- kicad_sch_api/core/junctions.py +17 -22
- kicad_sch_api/core/manhattan_routing.py +430 -0
- kicad_sch_api/core/parser.py +495 -196
- kicad_sch_api/core/pin_utils.py +149 -0
- kicad_sch_api/core/schematic.py +630 -207
- kicad_sch_api/core/simple_manhattan.py +228 -0
- kicad_sch_api/core/types.py +9 -4
- kicad_sch_api/core/wire_routing.py +380 -0
- kicad_sch_api/core/wires.py +29 -25
- kicad_sch_api/discovery/__init__.py +1 -1
- kicad_sch_api/discovery/search_index.py +142 -107
- kicad_sch_api/library/cache.py +70 -62
- {kicad_sch_api-0.2.0.dist-info → kicad_sch_api-0.2.1.dist-info}/METADATA +212 -40
- kicad_sch_api-0.2.1.dist-info/RECORD +31 -0
- kicad_sch_api-0.2.0.dist-info/RECORD +0 -24
- {kicad_sch_api-0.2.0.dist-info → kicad_sch_api-0.2.1.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.2.0.dist-info → kicad_sch_api-0.2.1.dist-info}/entry_points.txt +0 -0
- {kicad_sch_api-0.2.0.dist-info → kicad_sch_api-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {kicad_sch_api-0.2.0.dist-info → kicad_sch_api-0.2.1.dist-info}/top_level.txt +0 -0
|
@@ -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
|