@tscircuit/capacity-autorouter 0.0.4 → 0.0.5
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 +353 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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,308 @@ ${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 (const edge of edges) {
|
|
4213
|
+
this.newConnections.push({
|
|
4214
|
+
pointsToConnect: [edge.from, edge.to],
|
|
4215
|
+
name: connection.name
|
|
4216
|
+
});
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
getNewSimpleRouteJson() {
|
|
4220
|
+
return {
|
|
4221
|
+
...this.ogSrj,
|
|
4222
|
+
connections: this.newConnections
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
4225
|
+
visualize() {
|
|
4226
|
+
const graphics = {
|
|
4227
|
+
lines: [],
|
|
4228
|
+
points: [],
|
|
4229
|
+
rects: [],
|
|
4230
|
+
circles: [],
|
|
4231
|
+
coordinateSystem: "cartesian",
|
|
4232
|
+
title: "Net To Point Pairs Visualization"
|
|
4233
|
+
};
|
|
4234
|
+
this.unprocessedConnections.forEach((connection) => {
|
|
4235
|
+
connection.pointsToConnect.forEach((point) => {
|
|
4236
|
+
graphics.points.push({
|
|
4237
|
+
x: point.x,
|
|
4238
|
+
y: point.y,
|
|
4239
|
+
color: "red",
|
|
4240
|
+
label: connection.name
|
|
4241
|
+
});
|
|
4242
|
+
});
|
|
4243
|
+
const fullyConnectedEdgeCount = connection.pointsToConnect.length ** 2;
|
|
4244
|
+
const random = seededRandom(0);
|
|
4245
|
+
const alreadyPlacedEdges = /* @__PURE__ */ new Set();
|
|
4246
|
+
for (let i = 0; i < Math.max(
|
|
4247
|
+
fullyConnectedEdgeCount,
|
|
4248
|
+
connection.pointsToConnect.length * 2
|
|
4249
|
+
); i++) {
|
|
4250
|
+
const a = Math.floor(random() * connection.pointsToConnect.length);
|
|
4251
|
+
const b = Math.floor(random() * connection.pointsToConnect.length);
|
|
4252
|
+
if (alreadyPlacedEdges.has(`${a}-${b}`)) continue;
|
|
4253
|
+
alreadyPlacedEdges.add(`${a}-${b}`);
|
|
4254
|
+
graphics.lines.push({
|
|
4255
|
+
points: [
|
|
4256
|
+
connection.pointsToConnect[a],
|
|
4257
|
+
connection.pointsToConnect[b]
|
|
4258
|
+
],
|
|
4259
|
+
strokeColor: "rgba(255,0,0,0.25)"
|
|
4260
|
+
});
|
|
4261
|
+
}
|
|
4262
|
+
});
|
|
4263
|
+
this.newConnections.forEach((connection) => {
|
|
4264
|
+
const color = this.colorMap?.[connection.name] || "blue";
|
|
4265
|
+
connection.pointsToConnect.forEach((point) => {
|
|
4266
|
+
graphics.points.push({
|
|
4267
|
+
x: point.x,
|
|
4268
|
+
y: point.y,
|
|
4269
|
+
color,
|
|
4270
|
+
label: connection.name
|
|
4271
|
+
});
|
|
4272
|
+
});
|
|
4273
|
+
for (let i = 0; i < connection.pointsToConnect.length - 1; i++) {
|
|
4274
|
+
for (let j = i + 1; j < connection.pointsToConnect.length; j++) {
|
|
4275
|
+
graphics.lines.push({
|
|
4276
|
+
points: [
|
|
4277
|
+
connection.pointsToConnect[i],
|
|
4278
|
+
connection.pointsToConnect[j]
|
|
4279
|
+
],
|
|
4280
|
+
strokeColor: color
|
|
4281
|
+
});
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
});
|
|
4285
|
+
return graphics;
|
|
4286
|
+
}
|
|
4287
|
+
};
|
|
4288
|
+
|
|
3967
4289
|
// lib/solvers/CapacityMeshSolver/CapacityMeshSolver.ts
|
|
3968
4290
|
var CapacityMeshSolver = class extends BaseSolver {
|
|
3969
4291
|
constructor(srj, opts = {}) {
|
|
@@ -3981,10 +4303,10 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
3981
4303
|
targetMinCapacity
|
|
3982
4304
|
);
|
|
3983
4305
|
}
|
|
3984
|
-
this.nodeSolver = new CapacityMeshNodeSolver(srj, this.opts);
|
|
3985
4306
|
this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
|
|
3986
4307
|
this.colorMap = getColorMap(srj, this.connMap);
|
|
3987
4308
|
}
|
|
4309
|
+
netToPointPairsSolver;
|
|
3988
4310
|
nodeSolver;
|
|
3989
4311
|
nodeTargetMerger;
|
|
3990
4312
|
edgeSolver;
|
|
@@ -4008,7 +4330,19 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4008
4330
|
}
|
|
4009
4331
|
return;
|
|
4010
4332
|
}
|
|
4011
|
-
if (!this.
|
|
4333
|
+
if (!this.netToPointPairsSolver) {
|
|
4334
|
+
this.netToPointPairsSolver = new NetToPointPairsSolver(
|
|
4335
|
+
this.srj,
|
|
4336
|
+
this.colorMap
|
|
4337
|
+
);
|
|
4338
|
+
this.activeSolver = this.netToPointPairsSolver;
|
|
4339
|
+
return;
|
|
4340
|
+
}
|
|
4341
|
+
if (!this.nodeSolver) {
|
|
4342
|
+
this.nodeSolver = new CapacityMeshNodeSolver(
|
|
4343
|
+
this.netToPointPairsSolver.getNewSimpleRouteJson(),
|
|
4344
|
+
this.opts
|
|
4345
|
+
);
|
|
4012
4346
|
this.activeSolver = this.nodeSolver;
|
|
4013
4347
|
return;
|
|
4014
4348
|
}
|
|
@@ -4029,7 +4363,7 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4029
4363
|
}
|
|
4030
4364
|
if (!this.pathingSolver) {
|
|
4031
4365
|
this.pathingSolver = new CapacityPathingSolver4_FlexibleNegativeCapacity({
|
|
4032
|
-
simpleRouteJson: this.
|
|
4366
|
+
simpleRouteJson: this.netToPointPairsSolver.getNewSimpleRouteJson(),
|
|
4033
4367
|
nodes,
|
|
4034
4368
|
edges: this.edgeSolver.edges,
|
|
4035
4369
|
colorMap: this.colorMap,
|
|
@@ -4086,7 +4420,8 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4086
4420
|
}
|
|
4087
4421
|
visualize() {
|
|
4088
4422
|
if (!this.solved && this.activeSolver) return this.activeSolver.visualize();
|
|
4089
|
-
const
|
|
4423
|
+
const netToPPSolver = this.netToPointPairsSolver?.visualize();
|
|
4424
|
+
const nodeViz = this.nodeSolver?.visualize();
|
|
4090
4425
|
const edgeViz = this.edgeSolver?.visualize();
|
|
4091
4426
|
const pathingViz = this.pathingSolver?.visualize();
|
|
4092
4427
|
const edgeToPortSegmentViz = this.edgeToPortSegmentSolver?.visualize();
|
|
@@ -4094,11 +4429,17 @@ var CapacityMeshSolver = class extends BaseSolver {
|
|
|
4094
4429
|
const segmentOptimizationViz = this.segmentToPointOptimizer?.visualize();
|
|
4095
4430
|
const highDensityViz = this.highDensityRouteSolver?.visualize();
|
|
4096
4431
|
const problemViz = {
|
|
4097
|
-
points: [...
|
|
4098
|
-
rects: [
|
|
4432
|
+
points: [...this.srj.connections.flatMap((c) => c.pointsToConnect)],
|
|
4433
|
+
rects: [
|
|
4434
|
+
...(this.srj.obstacles ?? []).map((o) => ({
|
|
4435
|
+
...o,
|
|
4436
|
+
fill: "rgba(255,0,0,0.25)"
|
|
4437
|
+
}))
|
|
4438
|
+
]
|
|
4099
4439
|
};
|
|
4100
4440
|
const visualizations = [
|
|
4101
4441
|
problemViz,
|
|
4442
|
+
netToPPSolver,
|
|
4102
4443
|
nodeViz,
|
|
4103
4444
|
edgeViz,
|
|
4104
4445
|
pathingViz,
|