diff --git a/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts b/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts index 31e0df39..662a0685 100644 --- a/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts +++ b/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts @@ -56,6 +56,16 @@ export class LongDistancePairSolver extends BaseSolver { primaryConnectedPinIds.add(pair.pins[1].pinId) } + // Build helpers to skip nets handled by net labels only (mirrors the same + // logic added to MspConnectionPairSolver for issue #79). + const directlyWiredPinIds = new Set() + for (const dc of inputProblem.directConnections) { + for (const pid of dc.pinIds) directlyWiredPinIds.add(pid) + } + const netLabelOrientedNets = new Set( + Object.keys(inputProblem.availableNetLabelOrientations ?? {}), + ) + const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem) this.netConnMap = netConnMap const pinMap = new Map() @@ -76,8 +86,18 @@ export class LongDistancePairSolver extends BaseSolver { const allPinIdsInNet = netConnMap.getIdsConnectedToNet(netId) if (allPinIdsInNet.length < 2) continue + // Skip nets that are represented by net labels only — they have no direct + // wire connections and have a configured label orientation. + const hasDirect = allPinIdsInNet.some((id: string) => + directlyWiredPinIds.has(id), + ) + const hasLabel = allPinIdsInNet.some((id: string) => + netLabelOrientedNets.has(id), + ) + if (!hasDirect && hasLabel) continue + const unconnectedPinIds = allPinIdsInNet.filter( - (pinId) => !primaryConnectedPinIds.has(pinId), + (pinId: string) => !primaryConnectedPinIds.has(pinId), ) for (const unconnectedPinId of unconnectedPinIds) { diff --git a/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts b/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts index 48b46c90..20616803 100644 --- a/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts +++ b/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts @@ -74,7 +74,27 @@ export class MspConnectionPairSolver extends BaseSolver { } } - this.queuedDcNetIds = Object.keys(netConnMap.netMap) + // Only queue nets that need wire traces. + // Nets that are handled exclusively via netConnections with a configured + // net-label orientation should be represented by net labels only — routing + // a wire trace on top of them produces the spurious extra lines in #79. + const directlyWiredPinIds = new Set() + for (const dc of inputProblem.directConnections) { + for (const pid of dc.pinIds) { + directlyWiredPinIds.add(pid) + } + } + const netLabelOrientedNets = new Set( + Object.keys(inputProblem.availableNetLabelOrientations ?? {}), + ) + this.queuedDcNetIds = Object.keys(netConnMap.netMap).filter((netId) => { + const connectedIds = netConnMap.getIdsConnectedToNet(netId) as string[] + // Always route if any pin has a direct wire connection. + if (connectedIds.some((id) => directlyWiredPinIds.has(id))) return true + // Skip nets that have a label orientation and no direct connections — + // NetLabelPlacementSolver will place the label instead. + return !connectedIds.some((id) => netLabelOrientedNets.has(id)) + }) } override getConstructorParams(): ConstructorParameters< diff --git a/tests/examples/__snapshots__/example01.snap.svg b/tests/examples/__snapshots__/example01.snap.svg index 293bf05a..b596f082 100644 --- a/tests/examples/__snapshots__/example01.snap.svg +++ b/tests/examples/__snapshots__/example01.snap.svg @@ -2,97 +2,103 @@ +x-" data-x="-0.8" data-y="0.2" cx="422.5742574257426" cy="289.44950495049505" r="3" fill="hsl(319, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="0" cx="422.5742574257426" cy="311.62772277227725" r="3" fill="hsl(320, 100%, 50%, 0.8)" /> +x-" data-x="-0.8" data-y="-0.2" cx="422.5742574257426" cy="333.80594059405945" r="3" fill="hsl(321, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="-0.2" cx="600" cy="333.80594059405945" r="3" fill="hsl(322, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0" cx="600" cy="311.62772277227725" r="3" fill="hsl(323, 100%, 50%, 0.8)" /> +x+" data-x="0.8" data-y="0.2" cx="600" cy="289.44950495049505" r="3" fill="hsl(324, 100%, 50%, 0.8)" /> +y+" data-x="-2" data-y="0.5" cx="289.50495049504957" cy="256.1821782178218" r="3" fill="hsl(121, 100%, 50%, 0.8)" /> +y-" data-x="-2" data-y="-0.5" cx="289.50495049504957" cy="367.0732673267327" r="3" fill="hsl(122, 100%, 50%, 0.8)" /> +y+" data-x="-4" data-y="0.5" cx="67.72277227722776" cy="256.1821782178218" r="3" fill="hsl(2, 100%, 50%, 0.8)" /> +y-" data-x="-4" data-y="-0.5" cx="67.72277227722776" cy="367.0732673267327" r="3" fill="hsl(3, 100%, 50%, 0.8)" /> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + +