diff --git a/lib/check-traces-are-contiguous/check-traces-are-contiguous.ts b/lib/check-traces-are-contiguous/check-traces-are-contiguous.ts index b75e32f..3d5fcc5 100644 --- a/lib/check-traces-are-contiguous/check-traces-are-contiguous.ts +++ b/lib/check-traces-are-contiguous/check-traces-are-contiguous.ts @@ -52,7 +52,7 @@ function routePointConnectsToAnotherExpectedPort( const expectedPads = padMap.get(expectedPort.pcb_port_id) return ( expectedPads?.some((pad) => - isPointInPad({ x: point.x, y: point.y }, pad), + isPointInPad({ x: point.x, y: point.y }, pad, point.layer), ) ?? false ) }) @@ -273,13 +273,21 @@ function checkTracesAreContiguous( const isFirstPointConnected = firstPoint.route_type === "wire" && pads.some((pad) => - isPointInPad({ x: firstPoint.x, y: firstPoint.y }, pad), + isPointInPad( + { x: firstPoint.x, y: firstPoint.y }, + pad, + firstPoint.layer, + ), ) const isLastPointConnected = lastPoint.route_type === "wire" && pads.some((pad) => - isPointInPad({ x: lastPoint.x, y: lastPoint.y }, pad), + isPointInPad( + { x: lastPoint.x, y: lastPoint.y }, + pad, + lastPoint.layer, + ), ) if (!isFirstPointConnected && !isLastPointConnected) { @@ -326,7 +334,11 @@ function checkTracesAreContiguous( if ( firstPoint.route_type === "wire" && pads.some((pad) => - isPointInPad({ x: firstPoint.x, y: firstPoint.y }, pad), + isPointInPad( + { x: firstPoint.x, y: firstPoint.y }, + pad, + firstPoint.layer, + ), ) ) { firstConnectsToAnyPad = true @@ -334,7 +346,11 @@ function checkTracesAreContiguous( if ( lastPoint.route_type === "wire" && pads.some((pad) => - isPointInPad({ x: lastPoint.x, y: lastPoint.y }, pad), + isPointInPad( + { x: lastPoint.x, y: lastPoint.y }, + pad, + lastPoint.layer, + ), ) ) { lastConnectsToAnyPad = true diff --git a/lib/check-traces-are-contiguous/is-point-in-pad.ts b/lib/check-traces-are-contiguous/is-point-in-pad.ts index e786e83..4ec84c3 100644 --- a/lib/check-traces-are-contiguous/is-point-in-pad.ts +++ b/lib/check-traces-are-contiguous/is-point-in-pad.ts @@ -34,7 +34,18 @@ function isPointOnSegment( export function isPointInPad( point: { x: number; y: number }, pad: PcbSmtPad | PcbPlatedHole, + layer?: string, ): boolean { + // A trace endpoint only connects to a pad on the same layer (a top-layer + // wire can't land on a bottom-layer smt pad without a via). + if (layer !== undefined) { + const padIsOnLayer = + pad.type === "pcb_smtpad" + ? pad.layer === layer + : pad.layers.some((padLayer) => padLayer === layer) + if (!padIsOnLayer) return false + } + if (pad.type === "pcb_smtpad") { if (pad.shape === "circle") { return getDistanceBetweenPoints(point, pad) <= pad.radius diff --git a/tests/lib/__snapshots__/trace-endpoint-on-different-layer.snap.svg b/tests/lib/__snapshots__/trace-endpoint-on-different-layer.snap.svg index 41cbce8..baf4829 100644 --- a/tests/lib/__snapshots__/trace-endpoint-on-different-layer.snap.svg +++ b/tests/lib/__snapshots__/trace-endpoint-on-different-layer.snap.svg @@ -1 +1 @@ - \ No newline at end of file +Trace [trace[t1]] is missing a connection to smtpad[#pp2] \ No newline at end of file diff --git a/tests/lib/check-traces-are-contiguous.test.ts b/tests/lib/check-traces-are-contiguous.test.ts index 6af8b7e..539426f 100644 --- a/tests/lib/check-traces-are-contiguous.test.ts +++ b/tests/lib/check-traces-are-contiguous.test.ts @@ -410,7 +410,7 @@ test("still reports a source-trace branch that does not reach a required port", ) }) -test.failing( +test( "errors when a trace endpoint touches a pad on a different layer", () => { // A top-layer wire endpoint at (1,0) coincides with a BOTTOM-layer pad. @@ -475,7 +475,7 @@ test.failing( }, ) -test.failing( +test( "draws an error where a trace endpoint touches a pad on a different layer", () => { // Same scenario rendered with shouldDrawErrors: a top-layer wire ends on