fix: route_pad_to_pad auto-inserts via when pads are on different copper layers

- Detects F.Cu<->B.Cu layer mismatch in route_pad_to_pad
- Splits route into: trace on start layer + via at midpoint + trace on end layer
- route_trace description warns: use route_pad_to_pad for cross-layer routing
- route_pad_to_pad description highlights automatic via insertion
This commit is contained in:
Tom
2026-03-07 15:46:54 +01:00
parent 9d344c95a5
commit 3e329cbf6b
2 changed files with 54 additions and 30 deletions

View File

@@ -144,40 +144,64 @@ class RoutingCommands:
if not net:
net = start_pad.GetNetname() or end_pad.GetNetname() or ""
# Delegate to route_trace
result = self.route_trace(
{
"start": {
"x": start_pos.x / scale,
"y": start_pos.y / scale,
"unit": "mm",
},
"end": {
"x": end_pos.x / scale,
"y": end_pos.y / scale,
"unit": "mm",
},
"layer": layer,
"width": width,
"net": net,
}
# Detect if pads are on different copper layers → need via
start_layer = start_pad.GetLayerName()
end_layer = end_pad.GetLayerName()
copper_layers = {"F.Cu", "B.Cu"}
needs_via = (
start_layer in copper_layers
and end_layer in copper_layers
and start_layer != end_layer
)
if needs_via:
# Place via at midpoint between the two pads
via_x = (start_pos.x + end_pos.x) / 2 / scale
via_y = (start_pos.y + end_pos.y) / 2 / scale
# Trace on start layer: start_pad → via
r1 = self.route_trace({
"start": {"x": start_pos.x / scale, "y": start_pos.y / scale, "unit": "mm"},
"end": {"x": via_x, "y": via_y, "unit": "mm"},
"layer": start_layer, "width": width, "net": net,
})
# Via connecting both layers
self.add_via({
"position": {"x": via_x, "y": via_y, "unit": "mm"},
"net": net,
"from_layer": start_layer,
"to_layer": end_layer,
})
# Trace on end layer: via → end_pad
r2 = self.route_trace({
"start": {"x": via_x, "y": via_y, "unit": "mm"},
"end": {"x": end_pos.x / scale, "y": end_pos.y / scale, "unit": "mm"},
"layer": end_layer, "width": width, "net": net,
})
success = r1.get("success") and r2.get("success")
result = {
"success": success,
"message": f"Routed {from_ref}.{from_pad} → via → {to_ref}.{to_pad} (net: {net}, via at {via_x:.2f},{via_y:.2f})",
"via_added": True,
"via_position": {"x": via_x, "y": via_y},
}
else:
# Same layer — direct trace
result = self.route_trace({
"start": {"x": start_pos.x / scale, "y": start_pos.y / scale, "unit": "mm"},
"end": {"x": end_pos.x / scale, "y": end_pos.y / scale, "unit": "mm"},
"layer": layer if layer else start_layer,
"width": width, "net": net,
})
if result.get("success"):
result["message"] = (
f"Routed {from_ref}.{from_pad}{to_ref}.{to_pad} (net: {net or 'none'})"
)
result["fromPad"] = {
"ref": from_ref,
"pad": from_pad,
"x": start_pos.x / scale,
"y": start_pos.y / scale,
"ref": from_ref, "pad": from_pad,
"x": start_pos.x / scale, "y": start_pos.y / scale,
}
result["toPad"] = {
"ref": to_ref,
"pad": to_pad,
"x": end_pos.x / scale,
"y": end_pos.y / scale,
"ref": to_ref, "pad": to_pad,
"x": end_pos.x / scale, "y": end_pos.y / scale,
}
return result