diff --git a/lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/SingleTransitionCrossingRouteSolver.ts b/lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/SingleTransitionCrossingRouteSolver.ts index 70cc6440..d7340395 100644 --- a/lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/SingleTransitionCrossingRouteSolver.ts +++ b/lib/solvers/HighDensitySolver/TwoRouteHighDensitySolver/SingleTransitionCrossingRouteSolver.ts @@ -171,7 +171,7 @@ export class SingleTransitionCrossingRouteSolver extends BaseSolver { const C = flatRoute.B const turnDirection = computeTurnDirection(A, B, C, this.bounds) - // const turnDirection = computeTurnDirection(A, B, C, this.bounds) + console.debug("turnDirection", turnDirection) const sideTraversal = calculateTraversalPercentages( A, B, @@ -179,30 +179,31 @@ export class SingleTransitionCrossingRouteSolver extends BaseSolver { this.bounds, turnDirection, ) + console.debug("sideTraversal", sideTraversal) // console.log({ sideTraversal, turnDirection }) const viaBounds = { minX: this.bounds.minX + - (sideTraversal.left > 0.5 - ? marginFromBorderWithTrace - : marginFromBorderWithoutTrace), + (sideTraversal.left > 0.75 + ? marginFromBorderWithoutTrace + : marginFromBorderWithTrace), minY: this.bounds.minY + - (sideTraversal.bottom > 0.5 - ? marginFromBorderWithTrace - : marginFromBorderWithoutTrace), + (sideTraversal.bottom > 0.75 + ? marginFromBorderWithoutTrace + : marginFromBorderWithTrace), maxX: this.bounds.maxX - - (sideTraversal.right > 0.5 - ? marginFromBorderWithTrace - : marginFromBorderWithoutTrace), + (sideTraversal.right > 0.75 + ? marginFromBorderWithoutTrace + : marginFromBorderWithTrace), maxY: this.bounds.maxY - - (sideTraversal.top > 0.5 - ? marginFromBorderWithTrace - : marginFromBorderWithoutTrace), + (sideTraversal.top > 0.75 + ? marginFromBorderWithoutTrace + : marginFromBorderWithTrace), } if (viaBounds.maxY < viaBounds.minY) { @@ -215,13 +216,15 @@ export class SingleTransitionCrossingRouteSolver extends BaseSolver { viaBounds.maxX = viaBounds.minX } - return findClosestPointToABCWithinBounds( + let via = findClosestPointToABCWithinBounds( A, B, C, marginFromBorderWithTrace, viaBounds, ) + via = { x: viaBounds.minX, y: viaBounds.maxY } + return via } /** * Create a single transition route with properly placed via @@ -302,12 +305,10 @@ export class SingleTransitionCrossingRouteSolver extends BaseSolver { const minDistFromViaToTrace = this.viaDiameter / 2 + this.traceThickness / 2 + this.obstacleMargin - const p2 = middleWithMargin( - via, - this.viaDiameter, - otherRouteStart.z !== flatStart.z ? otherRouteStart : otherRouteEnd, - this.traceThickness, - ) + const p2 = { + x: via.x - minDistFromViaToTrace * 1.2, + y: via.y, + } const viaCircle = { center: { x: via.x, y: via.y }, radius: minDistFromViaToTrace, @@ -363,6 +364,7 @@ export class SingleTransitionCrossingRouteSolver extends BaseSolver { const flatRoute = routeAHasTransition ? routeB : routeA const viaPosition = this.calculateViaPosition(transitionRoute, flatRoute) + console.debug("viaPosition", viaPosition) if (viaPosition) { this.debugViaPositions.push({ via: viaPosition }) } else { diff --git a/lib/testing/utils/convertToCircuitJson.ts b/lib/testing/utils/convertToCircuitJson.ts index bcd6b8e9..7d1de75f 100644 --- a/lib/testing/utils/convertToCircuitJson.ts +++ b/lib/testing/utils/convertToCircuitJson.ts @@ -215,41 +215,46 @@ function extractViasFromRoutes( }) }) } else { - // Extract vias from HighDensityRoutes by looking for layer changes - ;(routes as HighDensityRoute[]).forEach((route) => { - for (let i = 1; i < route.route.length; i++) { - const prevPoint = route.route[i - 1] - const currPoint = route.route[i] + // HighDensityRoutes will be processed later when converting each trace + // This function intentionally does nothing for that case + } + } - // If z-coordinate changes, we have a via - if ( - prevPoint.z !== currPoint.z && - Math.abs(prevPoint.x - currPoint.x) < 0.01 && - Math.abs(prevPoint.y - currPoint.y) < 0.01 - ) { - const fromLayer = mapZToLayerName(prevPoint.z, 2) - const toLayer = mapZToLayerName(currPoint.z, 2) - const locationKey = `${currPoint.x},${currPoint.y},${fromLayer},${toLayer}` + return vias +} - if (!viaLocations.has(locationKey)) { - vias.push({ - type: "pcb_via", - pcb_via_id: `via_${vias.length}`, - x: currPoint.x, - y: currPoint.y, - outer_diameter: minViaDiameter, - hole_diameter: minViaDiameter * 0.5, - layers: [fromLayer, toLayer] as LayerName[], - }) - viaLocations.add(locationKey) - } - } - } +function extractViasFromHdRoute( + route: HighDensityRoute, + pcbTraceId: string, + viaIdStart: number, + minViaDiameter = 0.6, +): { vias: PcbVia[]; nextViaId: number } { + const vias: PcbVia[] = [] + let counter = viaIdStart + for (let i = 1; i < route.route.length; i++) { + const prevPoint = route.route[i - 1] + const currPoint = route.route[i] + + if ( + prevPoint.z !== currPoint.z && + Math.abs(prevPoint.x - currPoint.x) < 0.01 && + Math.abs(prevPoint.y - currPoint.y) < 0.01 + ) { + const fromLayer = mapZToLayerName(prevPoint.z, 2) + const toLayer = mapZToLayerName(currPoint.z, 2) + vias.push({ + type: "pcb_via", + pcb_via_id: `via_${counter++}`, + pcb_trace_id: pcbTraceId, + x: currPoint.x, + y: currPoint.y, + outer_diameter: minViaDiameter, + hole_diameter: minViaDiameter * 0.5, + layers: [fromLayer, toLayer] as LayerName[], }) } } - - return vias + return { vias, nextViaId: counter } } /** @@ -267,6 +272,7 @@ export function convertToCircuitJson( ): AnyCircuitElement[] { // Start with empty circuit JSON const circuitJson: AnyCircuitElement[] = [] + let viaCounter = 0 // Add source traces from connection information circuitJson.push(...createSourceTraces(srjWithPointPairs, routes)) @@ -274,8 +280,10 @@ export function convertToCircuitJson( // Add PCB ports for connection points circuitJson.push(...createPcbPorts(srjWithPointPairs)) - // Extract and add vias as independent pcb_via elements - circuitJson.push(...extractViasFromRoutes(routes, minViaDiameter)) + // Extract and add vias as independent pcb_via elements for simple traces + const preExtractedVias = extractViasFromRoutes(routes, minViaDiameter) + viaCounter += preExtractedVias.length + circuitJson.push(...preExtractedVias) // Build a map of connection names to simplify lookups const connectionMap = new Map() @@ -301,14 +309,23 @@ export function convertToCircuitJson( // Handle HighDensityRoutes ;(routes as HighDensityRoute[]).forEach((route, index) => { const connectionName = route.connectionName + const traceId = `trace_${index}` circuitJson.push( convertHdRouteToCircuitJson( route, - `trace_${index}`, + traceId, connectionMap.get(connectionName) || connectionName, minTraceWidth, ) as AnyCircuitElement, ) + const { vias, nextViaId } = extractViasFromHdRoute( + route, + traceId, + viaCounter, + minViaDiameter, + ) + viaCounter = nextViaId + circuitJson.push(...vias) }) } } diff --git a/tests/bugs/__snapshots__/repro01-highdensity-drc-failure.snap.svg b/tests/bugs/__snapshots__/repro01-highdensity-drc-failure.snap.svg index 4db94451..374c00ba 100644 --- a/tests/bugs/__snapshots__/repro01-highdensity-drc-failure.snap.svg +++ b/tests/bugs/__snapshots__/repro01-highdensity-drc-failure.snap.svg @@ -1,34 +1,34 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +