@tscircuit/capacity-autorouter 0.0.4 → 0.0.6
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 +27 -1
- package/dist/index.js +354 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -213,6 +213,7 @@ declare class CapacityPathingSolver extends BaseSolver {
|
|
|
213
213
|
reduceCapacityAlongPath(nextConnection: {
|
|
214
214
|
path?: CapacityMeshNode[];
|
|
215
215
|
}): void;
|
|
216
|
+
isConnectedToEndGoal(node: CapacityMeshNode, endGoal: CapacityMeshNode): boolean;
|
|
216
217
|
_step(): void;
|
|
217
218
|
visualize(): GraphicsObject;
|
|
218
219
|
}
|
|
@@ -771,6 +772,30 @@ declare class CapacitySegmentPointOptimizer extends BaseSolver {
|
|
|
771
772
|
visualize(): GraphicsObject;
|
|
772
773
|
}
|
|
773
774
|
|
|
775
|
+
/**
|
|
776
|
+
* Converts a net containing many points to connect into an array of point pair
|
|
777
|
+
* connections.
|
|
778
|
+
*
|
|
779
|
+
* For example, a connection with 3 pointsToConnect could be turned into 2
|
|
780
|
+
* connections of 2 points each.
|
|
781
|
+
*
|
|
782
|
+
* Where we create the minimum number of pairs, we're using a minimum spanning
|
|
783
|
+
* tree (MST).
|
|
784
|
+
*
|
|
785
|
+
* Sometimes it can be used to add additional traces to help make sure we
|
|
786
|
+
* distribute load effectively. In this version we don't do that!
|
|
787
|
+
*/
|
|
788
|
+
declare class NetToPointPairsSolver extends BaseSolver {
|
|
789
|
+
ogSrj: SimpleRouteJson;
|
|
790
|
+
colorMap: Record<string, string>;
|
|
791
|
+
unprocessedConnections: Array<SimpleRouteConnection>;
|
|
792
|
+
newConnections: Array<SimpleRouteConnection>;
|
|
793
|
+
constructor(ogSrj: SimpleRouteJson, colorMap?: Record<string, string>);
|
|
794
|
+
_step(): void;
|
|
795
|
+
getNewSimpleRouteJson(): SimpleRouteJson;
|
|
796
|
+
visualize(): GraphicsObject;
|
|
797
|
+
}
|
|
798
|
+
|
|
774
799
|
interface CapacityMeshSolverOptions {
|
|
775
800
|
capacityDepth?: number;
|
|
776
801
|
targetMinCapacity?: number;
|
|
@@ -778,7 +803,8 @@ interface CapacityMeshSolverOptions {
|
|
|
778
803
|
declare class CapacityMeshSolver extends BaseSolver {
|
|
779
804
|
srj: SimpleRouteJson;
|
|
780
805
|
opts: CapacityMeshSolverOptions;
|
|
781
|
-
|
|
806
|
+
netToPointPairsSolver?: NetToPointPairsSolver;
|
|
807
|
+
nodeSolver?: CapacityMeshNodeSolver;
|
|
782
808
|
nodeTargetMerger?: CapacityNodeTargetMerger;
|
|
783
809
|
edgeSolver?: CapacityMeshEdgeSolver;
|
|
784
810
|
pathingSolver?: CapacityPathingSolver;
|
package/dist/index.js
CHANGED
|
@@ -2896,6 +2896,9 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
2896
2896
|
);
|
|
2897
2897
|
}
|
|
2898
2898
|
}
|
|
2899
|
+
isConnectedToEndGoal(node, endGoal) {
|
|
2900
|
+
return this.nodeEdgeMap.get(node.capacityMeshNodeId).some((edge) => edge.nodeIds.includes(endGoal.capacityMeshNodeId));
|
|
2901
|
+
}
|
|
2899
2902
|
_step() {
|
|
2900
2903
|
const nextConnection = this.connectionsWithNodes[this.currentConnectionIndex];
|
|
2901
2904
|
if (!nextConnection) {
|
|
@@ -2922,8 +2925,14 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
2922
2925
|
this.visitedNodes = null;
|
|
2923
2926
|
return;
|
|
2924
2927
|
}
|
|
2925
|
-
if (currentCandidate.node
|
|
2926
|
-
nextConnection.path = this.getBacktrackedPath(
|
|
2928
|
+
if (this.isConnectedToEndGoal(currentCandidate.node, end)) {
|
|
2929
|
+
nextConnection.path = this.getBacktrackedPath({
|
|
2930
|
+
prevCandidate: currentCandidate,
|
|
2931
|
+
node: end,
|
|
2932
|
+
f: 0,
|
|
2933
|
+
g: 0,
|
|
2934
|
+
h: 0
|
|
2935
|
+
});
|
|
2927
2936
|
this.reduceCapacityAlongPath(nextConnection);
|
|
2928
2937
|
this.currentConnectionIndex++;
|
|
2929
2938
|
this.candidates = null;
|
|
@@ -3002,19 +3011,30 @@ ${node.width.toFixed(2)}x${node.height.toFixed(2)}`
|
|
|
3002
3011
|
}
|
|
3003
3012
|
}
|
|
3004
3013
|
}
|
|
3014
|
+
const nextConnection = this.connectionsWithNodes[this.currentConnectionIndex];
|
|
3015
|
+
if (nextConnection) {
|
|
3016
|
+
const [start, end] = nextConnection.connection.pointsToConnect;
|
|
3017
|
+
graphics.lines.push({
|
|
3018
|
+
points: [
|
|
3019
|
+
{ x: start.x, y: start.y },
|
|
3020
|
+
{ x: end.x, y: end.y }
|
|
3021
|
+
],
|
|
3022
|
+
strokeColor: "red",
|
|
3023
|
+
strokeDash: "10 5"
|
|
3024
|
+
});
|
|
3025
|
+
}
|
|
3005
3026
|
if (this.candidates) {
|
|
3006
|
-
const topCandidates = this.candidates.slice(0,
|
|
3027
|
+
const topCandidates = this.candidates.slice(0, 5);
|
|
3007
3028
|
const connectionName = this.connectionsWithNodes[this.currentConnectionIndex].connection.name;
|
|
3008
3029
|
topCandidates.forEach((candidate, index) => {
|
|
3009
|
-
const opacity = 0.
|
|
3030
|
+
const opacity = 0.5 * (1 - index / 5);
|
|
3010
3031
|
const backtrackedPath = this.getBacktrackedPath(candidate);
|
|
3011
3032
|
graphics.lines.push({
|
|
3012
3033
|
points: backtrackedPath.map(({ center: { x, y } }) => ({ x, y })),
|
|
3013
3034
|
strokeColor: safeTransparentize(
|
|
3014
3035
|
this.colorMap[connectionName] ?? "red",
|
|
3015
3036
|
1 - opacity
|
|
3016
|
-
)
|
|
3017
|
-
strokeWidth: 0.5
|
|
3037
|
+
)
|
|
3018
3038
|
});
|
|
3019
3039
|
});
|
|
3020
3040
|
}
|
|
@@ -3964,6 +3984,309 @@ ${segment.nodePortSegmentId}`
|
|
|
3964
3984
|
}
|
|
3965
3985
|
};
|
|
3966
3986
|
|
|
3987
|
+
// lib/solvers/NetToPointPairsSolver/buildMinimumSpanningTree.ts
|
|
3988
|
+
var KDNode = class {
|
|
3989
|
+
point;
|
|
3990
|
+
left = null;
|
|
3991
|
+
right = null;
|
|
3992
|
+
constructor(point) {
|
|
3993
|
+
this.point = point;
|
|
3994
|
+
}
|
|
3995
|
+
};
|
|
3996
|
+
var KDTree = class {
|
|
3997
|
+
root = null;
|
|
3998
|
+
constructor(points) {
|
|
3999
|
+
if (points.length > 0) {
|
|
4000
|
+
this.root = this.buildTree(points, 0);
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
buildTree(points, depth) {
|
|
4004
|
+
const axis = depth % 2 === 0 ? "x" : "y";
|
|
4005
|
+
points.sort((a, b) => a[axis] - b[axis]);
|
|
4006
|
+
const medianIndex = Math.floor(points.length / 2);
|
|
4007
|
+
const node = new KDNode(points[medianIndex]);
|
|
4008
|
+
if (medianIndex > 0) {
|
|
4009
|
+
node.left = this.buildTree(points.slice(0, medianIndex), depth + 1);
|
|
4010
|
+
}
|
|
4011
|
+
if (medianIndex < points.length - 1) {
|
|
4012
|
+
node.right = this.buildTree(points.slice(medianIndex + 1), depth + 1);
|
|
4013
|
+
}
|
|
4014
|
+
return node;
|
|
4015
|
+
}
|
|
4016
|
+
// Find the nearest neighbor to a query point
|
|
4017
|
+
findNearestNeighbor(queryPoint) {
|
|
4018
|
+
if (!this.root) {
|
|
4019
|
+
throw new Error("Tree is empty");
|
|
4020
|
+
}
|
|
4021
|
+
const best = this.root.point;
|
|
4022
|
+
const bestDistance = this.distance(queryPoint, best);
|
|
4023
|
+
this.nearestNeighborSearch(this.root, queryPoint, 0, best, bestDistance);
|
|
4024
|
+
return best;
|
|
4025
|
+
}
|
|
4026
|
+
nearestNeighborSearch(node, queryPoint, depth, best, bestDistance) {
|
|
4027
|
+
if (!node) {
|
|
4028
|
+
return best;
|
|
4029
|
+
}
|
|
4030
|
+
const axis = depth % 2 ? "x" : "y";
|
|
4031
|
+
const currentDistance = this.distance(queryPoint, node.point);
|
|
4032
|
+
if (currentDistance < bestDistance) {
|
|
4033
|
+
best = node.point;
|
|
4034
|
+
bestDistance = currentDistance;
|
|
4035
|
+
}
|
|
4036
|
+
const axisDiff = queryPoint[axis] - node.point[axis];
|
|
4037
|
+
const firstBranch = axisDiff <= 0 ? node.left : node.right;
|
|
4038
|
+
const secondBranch = axisDiff <= 0 ? node.right : node.left;
|
|
4039
|
+
best = this.nearestNeighborSearch(
|
|
4040
|
+
firstBranch,
|
|
4041
|
+
queryPoint,
|
|
4042
|
+
depth + 1,
|
|
4043
|
+
best,
|
|
4044
|
+
bestDistance
|
|
4045
|
+
);
|
|
4046
|
+
bestDistance = this.distance(queryPoint, best);
|
|
4047
|
+
if (Math.abs(axisDiff) < bestDistance) {
|
|
4048
|
+
best = this.nearestNeighborSearch(
|
|
4049
|
+
secondBranch,
|
|
4050
|
+
queryPoint,
|
|
4051
|
+
depth + 1,
|
|
4052
|
+
best,
|
|
4053
|
+
bestDistance
|
|
4054
|
+
);
|
|
4055
|
+
}
|
|
4056
|
+
return best;
|
|
4057
|
+
}
|
|
4058
|
+
// Find k nearest neighbors
|
|
4059
|
+
findKNearestNeighbors(queryPoint, k) {
|
|
4060
|
+
if (!this.root) {
|
|
4061
|
+
return [];
|
|
4062
|
+
}
|
|
4063
|
+
const neighbors = [];
|
|
4064
|
+
this.kNearestNeighborSearch(this.root, queryPoint, 0, neighbors, k);
|
|
4065
|
+
return neighbors.sort((a, b) => a.distance - b.distance).slice(0, k).map((n) => n.point);
|
|
4066
|
+
}
|
|
4067
|
+
kNearestNeighborSearch(node, queryPoint, depth, neighbors, k) {
|
|
4068
|
+
if (!node) {
|
|
4069
|
+
return;
|
|
4070
|
+
}
|
|
4071
|
+
const axis = depth % 2 ? "x" : "y";
|
|
4072
|
+
const currentDistance = this.distance(queryPoint, node.point);
|
|
4073
|
+
neighbors.push({ point: node.point, distance: currentDistance });
|
|
4074
|
+
const axisDiff = queryPoint[axis] - node.point[axis];
|
|
4075
|
+
const firstBranch = axisDiff <= 0 ? node.left : node.right;
|
|
4076
|
+
const secondBranch = axisDiff <= 0 ? node.right : node.left;
|
|
4077
|
+
this.kNearestNeighborSearch(
|
|
4078
|
+
firstBranch,
|
|
4079
|
+
queryPoint,
|
|
4080
|
+
depth + 1,
|
|
4081
|
+
neighbors,
|
|
4082
|
+
k
|
|
4083
|
+
);
|
|
4084
|
+
let kthDistance = Infinity;
|
|
4085
|
+
if (neighbors.length >= k) {
|
|
4086
|
+
neighbors.sort((a, b) => a.distance - b.distance);
|
|
4087
|
+
kthDistance = neighbors[k - 1]?.distance || Infinity;
|
|
4088
|
+
}
|
|
4089
|
+
if (Math.abs(axisDiff) < kthDistance || neighbors.length < k) {
|
|
4090
|
+
this.kNearestNeighborSearch(
|
|
4091
|
+
secondBranch,
|
|
4092
|
+
queryPoint,
|
|
4093
|
+
depth + 1,
|
|
4094
|
+
neighbors,
|
|
4095
|
+
k
|
|
4096
|
+
);
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
// Calculate Euclidean distance between two points
|
|
4100
|
+
distance(a, b) {
|
|
4101
|
+
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
|
|
4102
|
+
}
|
|
4103
|
+
};
|
|
4104
|
+
var DisjointSet = class {
|
|
4105
|
+
parent = /* @__PURE__ */ new Map();
|
|
4106
|
+
rank = /* @__PURE__ */ new Map();
|
|
4107
|
+
constructor(points) {
|
|
4108
|
+
for (const point of points) {
|
|
4109
|
+
const key = this.pointToKey(point);
|
|
4110
|
+
this.parent.set(key, key);
|
|
4111
|
+
this.rank.set(key, 0);
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
pointToKey(point) {
|
|
4115
|
+
return `${point.x},${point.y}`;
|
|
4116
|
+
}
|
|
4117
|
+
find(point) {
|
|
4118
|
+
const key = this.pointToKey(point);
|
|
4119
|
+
if (!this.parent.has(key)) {
|
|
4120
|
+
throw new Error(`Point ${key} not found in DisjointSet`);
|
|
4121
|
+
}
|
|
4122
|
+
let root = key;
|
|
4123
|
+
while (root !== this.parent.get(root)) {
|
|
4124
|
+
root = this.parent.get(root);
|
|
4125
|
+
}
|
|
4126
|
+
let current = key;
|
|
4127
|
+
while (current !== root) {
|
|
4128
|
+
const next = this.parent.get(current);
|
|
4129
|
+
this.parent.set(current, root);
|
|
4130
|
+
current = next;
|
|
4131
|
+
}
|
|
4132
|
+
return root;
|
|
4133
|
+
}
|
|
4134
|
+
union(pointA, pointB) {
|
|
4135
|
+
const rootA = this.find(pointA);
|
|
4136
|
+
const rootB = this.find(pointB);
|
|
4137
|
+
if (rootA === rootB) {
|
|
4138
|
+
return false;
|
|
4139
|
+
}
|
|
4140
|
+
const rankA = this.rank.get(rootA) || 0;
|
|
4141
|
+
const rankB = this.rank.get(rootB) || 0;
|
|
4142
|
+
if (rankA < rankB) {
|
|
4143
|
+
this.parent.set(rootA, rootB);
|
|
4144
|
+
} else if (rankA > rankB) {
|
|
4145
|
+
this.parent.set(rootB, rootA);
|
|
4146
|
+
} else {
|
|
4147
|
+
this.parent.set(rootB, rootA);
|
|
4148
|
+
this.rank.set(rootA, rankA + 1);
|
|
4149
|
+
}
|
|
4150
|
+
return true;
|
|
4151
|
+
}
|
|
4152
|
+
};
|
|
4153
|
+
function buildMinimumSpanningTree(points) {
|
|
4154
|
+
if (points.length <= 1) {
|
|
4155
|
+
return [];
|
|
4156
|
+
}
|
|
4157
|
+
const kdTree = new KDTree(points);
|
|
4158
|
+
const edges = [];
|
|
4159
|
+
const k = Math.min(10, points.length - 1);
|
|
4160
|
+
for (const point of points) {
|
|
4161
|
+
const neighbors = kdTree.findKNearestNeighbors(point, k + 1);
|
|
4162
|
+
for (const neighbor of neighbors) {
|
|
4163
|
+
if (point.x === neighbor.x && point.y === neighbor.y) {
|
|
4164
|
+
continue;
|
|
4165
|
+
}
|
|
4166
|
+
const distance3 = Math.sqrt(
|
|
4167
|
+
(point.x - neighbor.x) ** 2 + (point.y - neighbor.y) ** 2
|
|
4168
|
+
);
|
|
4169
|
+
edges.push({
|
|
4170
|
+
from: point,
|
|
4171
|
+
to: neighbor,
|
|
4172
|
+
weight: distance3
|
|
4173
|
+
});
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
edges.sort((a, b) => a.weight - b.weight);
|
|
4177
|
+
const disjointSet = new DisjointSet(points);
|
|
4178
|
+
const mstEdges = [];
|
|
4179
|
+
for (const edge of edges) {
|
|
4180
|
+
if (disjointSet.union(edge.from, edge.to)) {
|
|
4181
|
+
mstEdges.push(edge);
|
|
4182
|
+
if (mstEdges.length === points.length - 1) {
|
|
4183
|
+
break;
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
return mstEdges;
|
|
4188
|
+
}
|
|
4189
|
+
|
|
4190
|
+
// lib/solvers/NetToPointPairsSolver/NetToPointPairsSolver.ts
|
|
4191
|
+
var NetToPointPairsSolver = class extends BaseSolver {
|
|
4192
|
+
constructor(ogSrj, colorMap = {}) {
|
|
4193
|
+
super();
|
|
4194
|
+
this.ogSrj = ogSrj;
|
|
4195
|
+
this.colorMap = colorMap;
|
|
4196
|
+
this.unprocessedConnections = ogSrj.connections;
|
|
4197
|
+
this.newConnections = [];
|
|
4198
|
+
}
|
|
4199
|
+
unprocessedConnections;
|
|
4200
|
+
newConnections;
|
|
4201
|
+
_step() {
|
|
4202
|
+
if (this.unprocessedConnections.length === 0) {
|
|
4203
|
+
this.solved = true;
|
|
4204
|
+
return;
|
|
4205
|
+
}
|
|
4206
|
+
const connection = this.unprocessedConnections.pop();
|
|
4207
|
+
if (connection.pointsToConnect.length === 2) {
|
|
4208
|
+
this.newConnections.push(connection);
|
|
4209
|
+
return;
|
|
4210
|
+
}
|
|
4211
|
+
const edges = buildMinimumSpanningTree(connection.pointsToConnect);
|
|
4212
|
+
for (let i = 0; i < edges.length; i++) {
|
|
4213
|
+
const edge = edges[i];
|
|
4214
|
+
this.newConnections.push({
|
|
4215
|
+
pointsToConnect: [edge.from, edge.to],
|
|
4216
|
+
name: `${connection.name}_mst${i}`
|
|
4217
|
+
});
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
getNewSimpleRouteJson() {
|
|
4221
|
+
return {
|
|
4222
|
+
...this.ogSrj,
|
|
4223
|
+
connections: this.newConnections
|
|
4224
|
+
};
|
|
4225
|
+
}
|
|
4226
|
+
visualize() {
|
|
4227
|
+
const graphics = {
|
|
4228
|
+
lines: [],
|
|
4229
|
+
points: [],
|
|
4230
|
+
rects: [],
|
|
4231
|
+
circles: [],
|
|
4232
|
+
coordinateSystem: "cartesian",
|
|
4233
|
+
title: "Net To Point Pairs Visualization"
|
|
4234
|
+
};
|
|
4235
|
+
this.unprocessedConnections.forEach((connection) => {
|
|
4236
|
+
connection.pointsToConnect.forEach((point) => {
|
|
4237
|
+
graphics.points.push({
|
|
4238
|
+
x: point.x,
|
|
4239
|
+
y: point.y,
|
|
4240
|
+
color: "red",
|
|
4241
|
+
label: connection.name
|
|
4242
|
+
});
|
|
4243
|
+
});
|
|
4244
|
+
const fullyConnectedEdgeCount = connection.pointsToConnect.length ** 2;
|
|
4245
|
+
const random = seededRandom(0);
|
|
4246
|
+
const alreadyPlacedEdges = /* @__PURE__ */ new Set();
|
|
4247
|
+
for (let i = 0; i < Math.max(
|
|
4248
|
+
fullyConnectedEdgeCount,
|
|
4249
|
+
connection.pointsToConnect.length * 2
|
|
4250
|
+
); i++) {
|
|
4251
|
+
const a = Math.floor(random() * connection.pointsToConnect.length);
|
|
4252
|
+
const b = Math.floor(random() * connection.pointsToConnect.length);
|
|
4253
|
+
if (alreadyPlacedEdges.has(`${a}-${b}`)) continue;
|
|
4254
|
+
alreadyPlacedEdges.add(`${a}-${b}`);
|
|
4255
|
+
graphics.lines.push({
|
|
4256
|
+
points: [
|
|
4257
|
+
connection.pointsToConnect[a],
|
|
4258
|
+
connection.pointsToConnect[b]
|
|
4259
|
+
],
|
|
4260
|
+
strokeColor: "rgba(255,0,0,0.25)"
|
|
4261
|
+
});
|
|
4262
|
+
}
|
|
4263
|
+
});
|
|
4264
|
+
this.newConnections.forEach((connection) => {
|
|
4265
|
+
const color = this.colorMap?.[connection.name] || "blue";
|
|
4266
|
+
connection.pointsToConnect.forEach((point) => {
|
|
4267
|
+
graphics.points.push({
|
|
4268
|
+
x: point.x,
|
|
4269
|
+
y: point.y,
|
|
4270
|
+
color,
|
|
4271
|
+
label: connection.name
|
|
4272
|
+
});
|
|
4273
|
+
});
|
|
4274
|
+
for (let i = 0; i < connection.pointsToConnect.length - 1; i++) {
|
|
4275
|
+
for (let j = i + 1; j < connection.pointsToConnect.length; j++) {
|
|
4276
|
+
graphics.lines.push({
|
|
4277
|
+
points: [
|
|
4278
|
+
connection.pointsToConnect[i],
|
|
4279
|
+
connection.pointsToConnect[j]
|
|
4280
|
+
],
|
|
4281
|
+
strokeColor: color
|
|
4282
|
+
});
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
});
|
|
4286
|
+
return graphics;
|
|
4287
|
+
}
|
|
4288
|
+
};
|
|
4289
|
+
|
|
3967
4290
|
// lib/solvers/CapacityMeshSolver/CapacityMeshSolver.ts
|
|
3968
4291
|
var CapacityMeshSolver = class extends BaseSolver {
|
|
3969
4292
|
constructor(srj, opts = {}) {
|
|
@@ -3981,10 +4304,10 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
3981
4304
|
targetMinCapacity
|
|
3982
4305
|
);
|
|
3983
4306
|
}
|
|
3984
|
-
this.nodeSolver = new CapacityMeshNodeSolver(srj, this.opts);
|
|
3985
4307
|
this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
|
|
3986
4308
|
this.colorMap = getColorMap(srj, this.connMap);
|
|
3987
4309
|
}
|
|
4310
|
+
netToPointPairsSolver;
|
|
3988
4311
|
nodeSolver;
|
|
3989
4312
|
nodeTargetMerger;
|
|
3990
4313
|
edgeSolver;
|
|
@@ -4008,7 +4331,19 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4008
4331
|
}
|
|
4009
4332
|
return;
|
|
4010
4333
|
}
|
|
4011
|
-
if (!this.
|
|
4334
|
+
if (!this.netToPointPairsSolver) {
|
|
4335
|
+
this.netToPointPairsSolver = new NetToPointPairsSolver(
|
|
4336
|
+
this.srj,
|
|
4337
|
+
this.colorMap
|
|
4338
|
+
);
|
|
4339
|
+
this.activeSolver = this.netToPointPairsSolver;
|
|
4340
|
+
return;
|
|
4341
|
+
}
|
|
4342
|
+
if (!this.nodeSolver) {
|
|
4343
|
+
const newSrj = this.netToPointPairsSolver.getNewSimpleRouteJson();
|
|
4344
|
+
this.connMap = getConnectivityMapFromSimpleRouteJson(newSrj);
|
|
4345
|
+
this.colorMap = getColorMap(newSrj, this.connMap);
|
|
4346
|
+
this.nodeSolver = new CapacityMeshNodeSolver(newSrj, this.opts);
|
|
4012
4347
|
this.activeSolver = this.nodeSolver;
|
|
4013
4348
|
return;
|
|
4014
4349
|
}
|
|
@@ -4029,7 +4364,7 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4029
4364
|
}
|
|
4030
4365
|
if (!this.pathingSolver) {
|
|
4031
4366
|
this.pathingSolver = new CapacityPathingSolver4_FlexibleNegativeCapacity({
|
|
4032
|
-
simpleRouteJson: this.
|
|
4367
|
+
simpleRouteJson: this.netToPointPairsSolver.getNewSimpleRouteJson(),
|
|
4033
4368
|
nodes,
|
|
4034
4369
|
edges: this.edgeSolver.edges,
|
|
4035
4370
|
colorMap: this.colorMap,
|
|
@@ -4086,7 +4421,8 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4086
4421
|
}
|
|
4087
4422
|
visualize() {
|
|
4088
4423
|
if (!this.solved && this.activeSolver) return this.activeSolver.visualize();
|
|
4089
|
-
const
|
|
4424
|
+
const netToPPSolver = this.netToPointPairsSolver?.visualize();
|
|
4425
|
+
const nodeViz = this.nodeSolver?.visualize();
|
|
4090
4426
|
const edgeViz = this.edgeSolver?.visualize();
|
|
4091
4427
|
const pathingViz = this.pathingSolver?.visualize();
|
|
4092
4428
|
const edgeToPortSegmentViz = this.edgeToPortSegmentSolver?.visualize();
|
|
@@ -4094,11 +4430,17 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4094
4430
|
const segmentOptimizationViz = this.segmentToPointOptimizer?.visualize();
|
|
4095
4431
|
const highDensityViz = this.highDensityRouteSolver?.visualize();
|
|
4096
4432
|
const problemViz = {
|
|
4097
|
-
points: [...
|
|
4098
|
-
rects: [
|
|
4433
|
+
points: [...this.srj.connections.flatMap((c) => c.pointsToConnect)],
|
|
4434
|
+
rects: [
|
|
4435
|
+
...(this.srj.obstacles ?? []).map((o) => ({
|
|
4436
|
+
...o,
|
|
4437
|
+
fill: "rgba(255,0,0,0.25)"
|
|
4438
|
+
}))
|
|
4439
|
+
]
|
|
4099
4440
|
};
|
|
4100
4441
|
const visualizations = [
|
|
4101
4442
|
problemViz,
|
|
4443
|
+
netToPPSolver,
|
|
4102
4444
|
nodeViz,
|
|
4103
4445
|
edgeViz,
|
|
4104
4446
|
pathingViz,
|