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
+
\ 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