@tscircuit/capacity-autorouter 0.0.39 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -3
- package/dist/index.js +98 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -259,6 +259,7 @@ declare class CapacityPathingSolver extends BaseSolver {
|
|
|
259
259
|
connection: SimpleRouteConnection;
|
|
260
260
|
nodes: CapacityMeshNode[];
|
|
261
261
|
path?: CapacityMeshNode[];
|
|
262
|
+
straightLineDistance: number;
|
|
262
263
|
}>;
|
|
263
264
|
usedNodeCapacityMap: Map<CapacityMeshNodeId, number>;
|
|
264
265
|
simpleRouteJson: SimpleRouteJson;
|
|
@@ -291,6 +292,7 @@ declare class CapacityPathingSolver extends BaseSolver {
|
|
|
291
292
|
connection: SimpleRouteConnection;
|
|
292
293
|
nodes: CapacityMeshNode[];
|
|
293
294
|
pathFound: boolean;
|
|
295
|
+
straightLineDistance: number;
|
|
294
296
|
}[];
|
|
295
297
|
connectionNameToGoalNodeIds: Map<string, string[]>;
|
|
296
298
|
};
|
|
@@ -1420,10 +1422,10 @@ interface CapacityMeshSolverOptions {
|
|
|
1420
1422
|
type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
|
|
1421
1423
|
solverName: string;
|
|
1422
1424
|
solverClass: T;
|
|
1423
|
-
getConstructorParams: (instance:
|
|
1424
|
-
onSolved?: (instance:
|
|
1425
|
+
getConstructorParams: (instance: AutoroutingPipelineSolver) => ConstructorParameters<T>;
|
|
1426
|
+
onSolved?: (instance: AutoroutingPipelineSolver) => void;
|
|
1425
1427
|
};
|
|
1426
|
-
declare class
|
|
1428
|
+
declare class AutoroutingPipelineSolver extends BaseSolver {
|
|
1427
1429
|
srj: SimpleRouteJson;
|
|
1428
1430
|
opts: CapacityMeshSolverOptions;
|
|
1429
1431
|
netToPointPairsSolver?: NetToPointPairsSolver;
|
|
@@ -1452,6 +1454,7 @@ declare class CapacityMeshSolver extends BaseSolver {
|
|
|
1452
1454
|
constructor(srj: SimpleRouteJson, opts?: CapacityMeshSolverOptions);
|
|
1453
1455
|
currentPipelineStepIndex: number;
|
|
1454
1456
|
_step(): void;
|
|
1457
|
+
solveUntilPhase(phase: string): void;
|
|
1455
1458
|
getCurrentPhase(): string;
|
|
1456
1459
|
visualize(): GraphicsObject;
|
|
1457
1460
|
/**
|
|
@@ -1477,6 +1480,9 @@ declare class CapacityMeshSolver extends BaseSolver {
|
|
|
1477
1480
|
getOutputSimplifiedPcbTraces(): SimplifiedPcbTraces;
|
|
1478
1481
|
getOutputSimpleRouteJson(): SimpleRouteJson;
|
|
1479
1482
|
}
|
|
1483
|
+
/** @deprecated Use AutoroutingPipelineSolver instead */
|
|
1484
|
+
declare const CapacityMeshSolver: typeof AutoroutingPipelineSolver;
|
|
1485
|
+
type CapacityMeshSolver = AutoroutingPipelineSolver;
|
|
1480
1486
|
|
|
1481
1487
|
/**
|
|
1482
1488
|
* Calculate the capacity of a node based on its width
|
package/dist/index.js
CHANGED
|
@@ -5122,47 +5122,72 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
5122
5122
|
const Bmutable = this.unravelSection.mutableSegmentIds.has(B.segmentId);
|
|
5123
5123
|
const Cmutable = this.unravelSection.mutableSegmentIds.has(C.segmentId);
|
|
5124
5124
|
const Dmutable = this.unravelSection.mutableSegmentIds.has(D.segmentId);
|
|
5125
|
+
const aSegment = this.dedupedSegmentMap.get(A.segmentId);
|
|
5126
|
+
const bSegment = this.dedupedSegmentMap.get(B.segmentId);
|
|
5127
|
+
const cSegment = this.dedupedSegmentMap.get(C.segmentId);
|
|
5128
|
+
const dSegment = this.dedupedSegmentMap.get(D.segmentId);
|
|
5129
|
+
const isNewZAvailableForAll = (segmentObjects, newZ) => {
|
|
5130
|
+
return segmentObjects.every((seg) => seg.availableZ.includes(newZ));
|
|
5131
|
+
};
|
|
5125
5132
|
if (Amutable && Bmutable) {
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5133
|
+
const newZ = A.z === 0 ? 1 : 0;
|
|
5134
|
+
if (isNewZAvailableForAll([aSegment, bSegment], newZ)) {
|
|
5135
|
+
operations.push({
|
|
5136
|
+
type: "change_layer",
|
|
5137
|
+
newZ,
|
|
5138
|
+
segmentPointIds: [APointId, BPointId]
|
|
5139
|
+
});
|
|
5140
|
+
}
|
|
5131
5141
|
}
|
|
5132
5142
|
if (Cmutable && Dmutable) {
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5143
|
+
const newZ = C.z === 0 ? 1 : 0;
|
|
5144
|
+
if (isNewZAvailableForAll([cSegment, dSegment], newZ)) {
|
|
5145
|
+
operations.push({
|
|
5146
|
+
type: "change_layer",
|
|
5147
|
+
newZ,
|
|
5148
|
+
segmentPointIds: [CPointId, DPointId]
|
|
5149
|
+
});
|
|
5150
|
+
}
|
|
5138
5151
|
}
|
|
5139
5152
|
if (Amutable) {
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5153
|
+
const newZ = A.z === 0 ? 1 : 0;
|
|
5154
|
+
if (aSegment.availableZ.includes(newZ)) {
|
|
5155
|
+
operations.push({
|
|
5156
|
+
type: "change_layer",
|
|
5157
|
+
newZ,
|
|
5158
|
+
segmentPointIds: [APointId]
|
|
5159
|
+
});
|
|
5160
|
+
}
|
|
5145
5161
|
}
|
|
5146
5162
|
if (Bmutable) {
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5163
|
+
const newZ = B.z === 0 ? 1 : 0;
|
|
5164
|
+
if (bSegment.availableZ.includes(newZ)) {
|
|
5165
|
+
operations.push({
|
|
5166
|
+
type: "change_layer",
|
|
5167
|
+
newZ,
|
|
5168
|
+
segmentPointIds: [BPointId]
|
|
5169
|
+
});
|
|
5170
|
+
}
|
|
5152
5171
|
}
|
|
5153
5172
|
if (Cmutable) {
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5173
|
+
const newZ = C.z === 0 ? 1 : 0;
|
|
5174
|
+
if (cSegment.availableZ.includes(newZ)) {
|
|
5175
|
+
operations.push({
|
|
5176
|
+
type: "change_layer",
|
|
5177
|
+
newZ,
|
|
5178
|
+
segmentPointIds: [CPointId]
|
|
5179
|
+
});
|
|
5180
|
+
}
|
|
5159
5181
|
}
|
|
5160
5182
|
if (Dmutable) {
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5183
|
+
const newZ = D.z === 0 ? 1 : 0;
|
|
5184
|
+
if (dSegment.availableZ.includes(newZ)) {
|
|
5185
|
+
operations.push({
|
|
5186
|
+
type: "change_layer",
|
|
5187
|
+
newZ,
|
|
5188
|
+
segmentPointIds: [DPointId]
|
|
5189
|
+
});
|
|
5190
|
+
}
|
|
5166
5191
|
}
|
|
5167
5192
|
}
|
|
5168
5193
|
return operations;
|
|
@@ -5851,6 +5876,7 @@ var createRectFromCapacityNode = (node, opts = {}) => {
|
|
|
5851
5876
|
"0": "rgba(0,200,200, 0.1)",
|
|
5852
5877
|
"1": "rgba(0,0,200, 0.1)"
|
|
5853
5878
|
}[node.availableZ.join(",")] ?? "rgba(0,200,200,0.1)",
|
|
5879
|
+
layer: `z${node.availableZ.join(",")}`,
|
|
5854
5880
|
label: [
|
|
5855
5881
|
node.capacityMeshNodeId,
|
|
5856
5882
|
`availableZ: ${node.availableZ.join(",")}`,
|
|
@@ -5942,9 +5968,16 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
5942
5968
|
connectionsWithNodes.push({
|
|
5943
5969
|
connection,
|
|
5944
5970
|
nodes: nodesForConnection,
|
|
5945
|
-
pathFound: false
|
|
5971
|
+
pathFound: false,
|
|
5972
|
+
straightLineDistance: distance(
|
|
5973
|
+
nodesForConnection[0].center,
|
|
5974
|
+
nodesForConnection[nodesForConnection.length - 1].center
|
|
5975
|
+
)
|
|
5946
5976
|
});
|
|
5947
5977
|
}
|
|
5978
|
+
connectionsWithNodes.sort(
|
|
5979
|
+
(a, b) => a.straightLineDistance - b.straightLineDistance
|
|
5980
|
+
);
|
|
5948
5981
|
return { connectionsWithNodes, connectionNameToGoalNodeIds };
|
|
5949
5982
|
}
|
|
5950
5983
|
currentConnectionIndex = 0;
|
|
@@ -6040,6 +6073,7 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
6040
6073
|
this.currentConnectionIndex++;
|
|
6041
6074
|
this.candidates = null;
|
|
6042
6075
|
this.visitedNodes = null;
|
|
6076
|
+
this.failed = true;
|
|
6043
6077
|
return;
|
|
6044
6078
|
}
|
|
6045
6079
|
if (this.isConnectedToEndGoal(currentCandidate.node, end)) {
|
|
@@ -6098,11 +6132,14 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
6098
6132
|
for (let i = 0; i < this.connectionsWithNodes.length; i++) {
|
|
6099
6133
|
const conn = this.connectionsWithNodes[i];
|
|
6100
6134
|
if (conn.path && conn.path.length > 0) {
|
|
6101
|
-
const pathPoints = conn.path.map(
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6135
|
+
const pathPoints = conn.path.map(
|
|
6136
|
+
({ center: { x, y }, width, availableZ }) => ({
|
|
6137
|
+
// slight offset to allow viewing overlapping paths
|
|
6138
|
+
x: x + (i % 10 + i % 19) * (5e-3 * width),
|
|
6139
|
+
y: y + (i % 10 + i % 19) * (5e-3 * width),
|
|
6140
|
+
availableZ
|
|
6141
|
+
})
|
|
6142
|
+
);
|
|
6106
6143
|
graphics.lines.push({
|
|
6107
6144
|
points: pathPoints,
|
|
6108
6145
|
strokeColor: this.colorMap[conn.connection.name]
|
|
@@ -6114,7 +6151,8 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
6114
6151
|
y: point.y,
|
|
6115
6152
|
label: [
|
|
6116
6153
|
`conn: ${conn.connection.name}`,
|
|
6117
|
-
`node: ${conn.path[u].capacityMeshNodeId}
|
|
6154
|
+
`node: ${conn.path[u].capacityMeshNodeId}`,
|
|
6155
|
+
`z: ${point.availableZ.join(",")}`
|
|
6118
6156
|
].join("\n")
|
|
6119
6157
|
});
|
|
6120
6158
|
}
|
|
@@ -6201,7 +6239,20 @@ var CapacityPathingSolver5 = class extends CapacityPathingSolver {
|
|
|
6201
6239
|
* Penalty you pay for using this node
|
|
6202
6240
|
*/
|
|
6203
6241
|
getNodeCapacityPenalty(node) {
|
|
6204
|
-
|
|
6242
|
+
const MAX_PENALTY = node.width + node.height;
|
|
6243
|
+
const MIN_PENALTY = 0.05;
|
|
6244
|
+
const START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW = 2;
|
|
6245
|
+
const totalCapacity = this.getTotalCapacity(node);
|
|
6246
|
+
const usedCapacity = this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0;
|
|
6247
|
+
const remainingCapacity = totalCapacity - usedCapacity;
|
|
6248
|
+
if (remainingCapacity > START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW) {
|
|
6249
|
+
return MIN_PENALTY;
|
|
6250
|
+
}
|
|
6251
|
+
const penalty = (MAX_PENALTY - MIN_PENALTY) * Math.max(
|
|
6252
|
+
1,
|
|
6253
|
+
(START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW - remainingCapacity) / (MAX_PENALTY - MIN_PENALTY)
|
|
6254
|
+
) + MIN_PENALTY;
|
|
6255
|
+
return penalty;
|
|
6205
6256
|
}
|
|
6206
6257
|
/**
|
|
6207
6258
|
* We're rewarding travel into big nodes.
|
|
@@ -6217,7 +6268,7 @@ var CapacityPathingSolver5 = class extends CapacityPathingSolver {
|
|
|
6217
6268
|
return prevCandidate.g + this.getDistanceBetweenNodes(prevCandidate.node, node) + this.getNodeCapacityPenalty(node);
|
|
6218
6269
|
}
|
|
6219
6270
|
computeH(prevCandidate, node, endGoal) {
|
|
6220
|
-
return this.getDistanceBetweenNodes(node, endGoal);
|
|
6271
|
+
return this.getDistanceBetweenNodes(node, endGoal) + this.getNodeCapacityPenalty(node);
|
|
6221
6272
|
}
|
|
6222
6273
|
};
|
|
6223
6274
|
|
|
@@ -6362,7 +6413,7 @@ var StrawSolver = class extends BaseSolver {
|
|
|
6362
6413
|
this.solved = true;
|
|
6363
6414
|
return;
|
|
6364
6415
|
}
|
|
6365
|
-
if (rootNode.width < this.strawSize
|
|
6416
|
+
if (rootNode.width < this.strawSize && rootNode.height < this.strawSize) {
|
|
6366
6417
|
this.skippedNodes.push(rootNode);
|
|
6367
6418
|
return;
|
|
6368
6419
|
}
|
|
@@ -7796,7 +7847,7 @@ function definePipelineStep(solverName, solverClass, getConstructorParams, opts
|
|
|
7796
7847
|
onSolved: opts.onSolved
|
|
7797
7848
|
};
|
|
7798
7849
|
}
|
|
7799
|
-
var
|
|
7850
|
+
var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
7800
7851
|
constructor(srj, opts = {}) {
|
|
7801
7852
|
super();
|
|
7802
7853
|
this.srj = srj;
|
|
@@ -8028,6 +8079,11 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
8028
8079
|
this.timeSpentOnPhase[pipelineStepDef.solverName] = 0;
|
|
8029
8080
|
this.startTimeOfPhase[pipelineStepDef.solverName] = performance.now();
|
|
8030
8081
|
}
|
|
8082
|
+
solveUntilPhase(phase) {
|
|
8083
|
+
while (this.getCurrentPhase() !== phase) {
|
|
8084
|
+
this.step();
|
|
8085
|
+
}
|
|
8086
|
+
}
|
|
8031
8087
|
getCurrentPhase() {
|
|
8032
8088
|
return this.pipelineDef[this.currentPipelineStepIndex]?.solverName ?? "none";
|
|
8033
8089
|
}
|
|
@@ -8198,6 +8254,7 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
8198
8254
|
};
|
|
8199
8255
|
}
|
|
8200
8256
|
};
|
|
8257
|
+
var CapacityMeshSolver = AutoroutingPipelineSolver;
|
|
8201
8258
|
export {
|
|
8202
8259
|
CapacityMeshSolver,
|
|
8203
8260
|
calculateOptimalCapacityDepth,
|