Route automatic breakout exits toward external endpoints - #3381
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const isInsideRegionBounds = | ||
| pcbPort.x >= region.bounds.minX && | ||
| pcbPort.x <= region.bounds.maxX && | ||
| pcbPort.y >= region.bounds.minY && | ||
| pcbPort.y <= region.bounds.maxY | ||
| if (isInsideRegion) continue | ||
| externalPcbPorts.set(pcbPort.pcb_port_id, { | ||
| if (!isInsideRegionBounds) { | ||
| aggregateExternalTargetsByPcbPortId.set(pcbPort.pcb_port_id, { | ||
| x: pcbPort.x, | ||
| y: pcbPort.y, | ||
| }) | ||
| } | ||
| const targets = | ||
| externalTargetsByConnectionId.get(sourceTrace.source_trace_id) ?? [] | ||
| targets.push({ | ||
| x: pcbPort.x, | ||
| y: pcbPort.y, | ||
| }) | ||
| externalTargetsByConnectionId.set(sourceTrace.source_trace_id, targets) |
There was a problem hiding this comment.
Critical bug: externalTargetsByConnectionId is being populated with ALL targets (both internal and external) but should only contain external targets. After the isInsideRegionBounds check determines a target is NOT inside bounds (line 326), it correctly adds to aggregateExternalTargetsByPcbPortId. However, lines 332-338 unconditionally add ALL pcb ports to externalTargetsByConnectionId regardless of whether they're inside or outside the region bounds.
Fix:
if (!isInsideRegionBounds) {
aggregateExternalTargetsByPcbPortId.set(pcbPort.pcb_port_id, {
x: pcbPort.x,
y: pcbPort.y,
})
const targets =
externalTargetsByConnectionId.get(sourceTrace.source_trace_id) ?? []
targets.push({
x: pcbPort.x,
y: pcbPort.y,
})
externalTargetsByConnectionId.set(sourceTrace.source_trace_id, targets)
}This will cause incorrect routing decisions since internal targets will be included when computing preferred edges and center points for external routing.
| const isInsideRegionBounds = | |
| pcbPort.x >= region.bounds.minX && | |
| pcbPort.x <= region.bounds.maxX && | |
| pcbPort.y >= region.bounds.minY && | |
| pcbPort.y <= region.bounds.maxY | |
| if (isInsideRegion) continue | |
| externalPcbPorts.set(pcbPort.pcb_port_id, { | |
| if (!isInsideRegionBounds) { | |
| aggregateExternalTargetsByPcbPortId.set(pcbPort.pcb_port_id, { | |
| x: pcbPort.x, | |
| y: pcbPort.y, | |
| }) | |
| } | |
| const targets = | |
| externalTargetsByConnectionId.get(sourceTrace.source_trace_id) ?? [] | |
| targets.push({ | |
| x: pcbPort.x, | |
| y: pcbPort.y, | |
| }) | |
| externalTargetsByConnectionId.set(sourceTrace.source_trace_id, targets) | |
| const isInsideRegionBounds = | |
| pcbPort.x >= region.bounds.minX && | |
| pcbPort.x <= region.bounds.maxX && | |
| pcbPort.y >= region.bounds.minY && | |
| pcbPort.y <= region.bounds.maxY | |
| if (!isInsideRegionBounds) { | |
| aggregateExternalTargetsByPcbPortId.set(pcbPort.pcb_port_id, { | |
| x: pcbPort.x, | |
| y: pcbPort.y, | |
| }) | |
| const targets = | |
| externalTargetsByConnectionId.get(sourceTrace.source_trace_id) ?? [] | |
| targets.push({ | |
| x: pcbPort.x, | |
| y: pcbPort.y, | |
| }) | |
| externalTargetsByConnectionId.set(sourceTrace.source_trace_id, targets) | |
| } | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
|
Superseded by the properly split implementation: winding solver behavior in tscircuit/winding-breakout-point-solver#6, the public endpoint contract in tscircuit/props#809, and Core integration/snapshots in #3382. Closing this Core-owned solver workaround in favor of the winding-owned fix. |
Summary
Why
The routing-quality regression surfaced in #3378 because every connection in the single breakout region was forced through the aggregate right edge. The RESET/R1 connection has its external endpoint on the left, so that start/end choice created a long cross-region escape and unnecessary layer changes. The right-side header exits were also centered on the internal pads instead of the external header endpoints.
This keeps the original winding solve as the baseline feasibility check and only splits ungrouped singleton outliers when at least two routes remain on the original edge. Custom solvers and multi-region breakouts are unchanged.
The affected Pipeline9 fixture goes from 3 vias to 0.
Testing
Related to #3378.