@tscircuit/matchpack 0.0.17 → 0.0.18

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 CHANGED
@@ -238,7 +238,9 @@ declare class PartitionPackingSolver extends BaseSolver {
238
238
  finalLayout: OutputLayout | null;
239
239
  packSolver2: PackSolver2 | null;
240
240
  constructor(input: PartitionPackingSolverInput);
241
+ private partitionHasFixedChip;
241
242
  _step(): void;
243
+ private buildConnectivityMap;
242
244
  private organizePackedPartitions;
243
245
  private createPackInput;
244
246
  private applyPackingResult;
package/dist/index.js CHANGED
@@ -823,9 +823,12 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
823
823
  }
824
824
  _step() {
825
825
  if (!this.activeSubSolver) {
826
- const packInput = this.createPackInput();
826
+ const pinToNetworkMap = createFilteredNetworkMapping({
827
+ inputProblem: this.partitionInputProblem,
828
+ pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
829
+ }).pinToNetworkMap;
830
+ const packInput = this.createPackInput(pinToNetworkMap);
827
831
  this.activeSubSolver = new PackSolver2(packInput);
828
- this.activeSubSolver = this.activeSubSolver;
829
832
  }
830
833
  this.activeSubSolver.step();
831
834
  if (this.activeSubSolver.failed) {
@@ -841,11 +844,7 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
841
844
  this.activeSubSolver = null;
842
845
  }
843
846
  }
844
- createPackInput() {
845
- const pinToNetworkMap = createFilteredNetworkMapping({
846
- inputProblem: this.partitionInputProblem,
847
- pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
848
- }).pinToNetworkMap;
847
+ createPackInput(pinToNetworkMap) {
849
848
  const packComponents = Object.entries(
850
849
  this.partitionInputProblem.chipMap
851
850
  ).map(([chipId, chip]) => {
@@ -860,7 +859,6 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
860
859
  type: "rect",
861
860
  offset: { x: pin.offset.x, y: pin.offset.y },
862
861
  size: { x: PIN_SIZE, y: PIN_SIZE }
863
- // Small size for pins
864
862
  });
865
863
  }
866
864
  const padsBoundingBox = getPadsBoundingBox(pads);
@@ -878,10 +876,16 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
878
876
  y: Math.max(padsBoundingBoxSize.y, chip.size.y)
879
877
  }
880
878
  });
879
+ const fixedRotation = chip.availableRotations?.[0] ?? 0;
881
880
  return {
882
881
  componentId: chipId,
883
882
  pads,
884
- availableRotationDegrees: chip.availableRotations || [0, 90, 180, 270]
883
+ availableRotationDegrees: chip.availableRotations ?? [0, 90, 180, 270],
884
+ ...chip.fixedPosition && {
885
+ isStatic: true,
886
+ center: chip.fixedPosition,
887
+ ccwRotationOffset: fixedRotation
888
+ }
885
889
  };
886
890
  });
887
891
  let minGap = this.partitionInputProblem.chipGap;
@@ -902,7 +906,7 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
902
906
  chipPlacements[chipId] = {
903
907
  x: packedComponent.center.x,
904
908
  y: packedComponent.center.y,
905
- ccwRotationDegrees: packedComponent.ccwRotationOffset || packedComponent.ccwRotationDegrees || 0
909
+ ccwRotationDegrees: packedComponent.ccwRotationDegrees ?? packedComponent.ccwRotationOffset ?? 0
906
910
  };
907
911
  }
908
912
  return {
@@ -1007,13 +1011,17 @@ var PartitionPackingSolver = class extends BaseSolver {
1007
1011
  this.packedPartitions = input.packedPartitions;
1008
1012
  this.inputProblem = input.inputProblem;
1009
1013
  }
1014
+ partitionHasFixedChip(partitionIndex) {
1015
+ const packedPartition = this.packedPartitions[partitionIndex];
1016
+ if (!packedPartition) return false;
1017
+ return Object.values(packedPartition.inputProblem.chipMap).some(
1018
+ (chip) => chip.fixedPosition !== void 0
1019
+ );
1020
+ }
1010
1021
  _step() {
1011
1022
  try {
1012
1023
  if (this.packedPartitions.length === 0) {
1013
- this.finalLayout = {
1014
- chipPlacements: {},
1015
- groupPlacements: {}
1016
- };
1024
+ this.finalLayout = { chipPlacements: {}, groupPlacements: {} };
1017
1025
  this.solved = true;
1018
1026
  return;
1019
1027
  }
@@ -1048,6 +1056,35 @@ var PartitionPackingSolver = class extends BaseSolver {
1048
1056
  this.error = `Failed to pack partitions: ${error}`;
1049
1057
  }
1050
1058
  }
1059
+ buildConnectivityMap() {
1060
+ const pinToNetworkMap = /* @__PURE__ */ new Map();
1061
+ for (const packedPartition of this.packedPartitions) {
1062
+ for (const [connKey, connected] of Object.entries(
1063
+ packedPartition.inputProblem.netConnMap
1064
+ )) {
1065
+ if (!connected) continue;
1066
+ const [pinId, netId] = connKey.split("-");
1067
+ if (pinId && netId) pinToNetworkMap.set(pinId, netId);
1068
+ }
1069
+ for (const [connKey, connected] of Object.entries(
1070
+ packedPartition.inputProblem.pinStrongConnMap
1071
+ )) {
1072
+ if (!connected) continue;
1073
+ const pins = connKey.split("-");
1074
+ if (pins.length === 2 && pins[0] && pins[1]) {
1075
+ const existingNet = pinToNetworkMap.get(pins[0]) || pinToNetworkMap.get(pins[1]);
1076
+ if (existingNet) {
1077
+ pinToNetworkMap.set(pins[0], existingNet);
1078
+ pinToNetworkMap.set(pins[1], existingNet);
1079
+ } else {
1080
+ pinToNetworkMap.set(pins[0], connKey);
1081
+ pinToNetworkMap.set(pins[1], connKey);
1082
+ }
1083
+ }
1084
+ }
1085
+ }
1086
+ return pinToNetworkMap;
1087
+ }
1051
1088
  organizePackedPartitions() {
1052
1089
  const partitionGroups = [];
1053
1090
  for (let i = 0; i < this.packedPartitions.length; i++) {
@@ -1078,47 +1115,20 @@ var PartitionPackingSolver = class extends BaseSolver {
1078
1115
  minY = Math.min(minY, chipMinY);
1079
1116
  maxY = Math.max(maxY, chipMaxY);
1080
1117
  }
1081
- const bounds = { minX, maxX, minY, maxY };
1082
1118
  partitionGroups.push({
1083
1119
  partitionIndex: i,
1084
1120
  chipIds: partitionChipIds,
1085
- bounds
1121
+ bounds: { minX, maxX, minY, maxY }
1086
1122
  });
1087
1123
  }
1088
1124
  }
1089
1125
  return partitionGroups;
1090
1126
  }
1091
- createPackInput(partitionGroups) {
1092
- const pinToNetworkMap = /* @__PURE__ */ new Map();
1093
- for (const packedPartition of this.packedPartitions) {
1094
- for (const [connKey, connected] of Object.entries(
1095
- packedPartition.inputProblem.netConnMap
1096
- )) {
1097
- if (!connected) continue;
1098
- const [pinId, netId] = connKey.split("-");
1099
- if (pinId && netId) {
1100
- pinToNetworkMap.set(pinId, netId);
1101
- }
1102
- }
1103
- for (const [connKey, connected] of Object.entries(
1104
- packedPartition.inputProblem.pinStrongConnMap
1105
- )) {
1106
- if (!connected) continue;
1107
- const pins = connKey.split("-");
1108
- if (pins.length === 2 && pins[0] && pins[1]) {
1109
- const existingNet = pinToNetworkMap.get(pins[0]) || pinToNetworkMap.get(pins[1]);
1110
- if (existingNet) {
1111
- pinToNetworkMap.set(pins[0], existingNet);
1112
- pinToNetworkMap.set(pins[1], existingNet);
1113
- } else {
1114
- pinToNetworkMap.set(pins[0], connKey);
1115
- pinToNetworkMap.set(pins[1], connKey);
1116
- }
1117
- }
1118
- }
1119
- }
1120
- const packComponents = partitionGroups.map((group) => {
1127
+ createPackInput(groups) {
1128
+ const pinToNetworkMap = this.buildConnectivityMap();
1129
+ const packComponents = groups.map((group) => {
1121
1130
  const packedPartition = this.packedPartitions[group.partitionIndex];
1131
+ const isFixed = this.partitionHasFixedChip(group.partitionIndex);
1122
1132
  const partitionWidth = group.bounds.maxX - group.bounds.minX;
1123
1133
  const partitionHeight = group.bounds.maxY - group.bounds.minY;
1124
1134
  const centerX = (group.bounds.minX + group.bounds.maxX) / 2;
@@ -1136,37 +1146,32 @@ var PartitionPackingSolver = class extends BaseSolver {
1136
1146
  }
1137
1147
  ];
1138
1148
  const addedNetworks = /* @__PURE__ */ new Set();
1139
- const pinPositions = /* @__PURE__ */ new Map();
1140
1149
  for (const chipId of group.chipIds) {
1141
1150
  const chipPlacement = packedPartition.layout.chipPlacements[chipId];
1142
1151
  const chip = packedPartition.inputProblem.chipMap[chipId];
1143
1152
  for (const pinId of chip.pins) {
1144
1153
  const chipPin = packedPartition.inputProblem.chipPinMap[pinId];
1145
1154
  if (!chipPin) continue;
1146
- let transformedOffset = { x: chipPin.offset.x, y: chipPin.offset.y };
1147
- const rotation = chipPlacement.ccwRotationDegrees || 0;
1148
- if (rotation === 90) {
1149
- transformedOffset = { x: -chipPin.offset.y, y: chipPin.offset.x };
1150
- } else if (rotation === 180) {
1151
- transformedOffset = { x: -chipPin.offset.x, y: -chipPin.offset.y };
1152
- } else if (rotation === 270) {
1153
- transformedOffset = { x: chipPin.offset.y, y: -chipPin.offset.x };
1155
+ let rotatedPinOffset = { x: chipPin.offset.x, y: chipPin.offset.y };
1156
+ const chipRotationDeg = chipPlacement.ccwRotationDegrees ?? 0;
1157
+ if (chipRotationDeg === 90) {
1158
+ rotatedPinOffset = { x: -chipPin.offset.y, y: chipPin.offset.x };
1159
+ } else if (chipRotationDeg === 180) {
1160
+ rotatedPinOffset = { x: -chipPin.offset.x, y: -chipPin.offset.y };
1161
+ } else if (chipRotationDeg === 270) {
1162
+ rotatedPinOffset = { x: chipPin.offset.y, y: -chipPin.offset.x };
1154
1163
  }
1155
- const absolutePinX = chipPlacement.x + transformedOffset.x;
1156
- const absolutePinY = chipPlacement.y + transformedOffset.y;
1157
- pinPositions.set(pinId, { x: absolutePinX, y: absolutePinY });
1158
- const networkId = pinToNetworkMap.get(pinId) || `${pinId}_disconnected`;
1164
+ const absolutePinX = chipPlacement.x + rotatedPinOffset.x;
1165
+ const absolutePinY = chipPlacement.y + rotatedPinOffset.y;
1166
+ const networkId = pinToNetworkMap.get(pinId) ?? `${pinId}_disconnected`;
1159
1167
  if (!addedNetworks.has(networkId)) {
1160
1168
  addedNetworks.add(networkId);
1161
- const padOffsetX = absolutePinX - centerX;
1162
- const padOffsetY = absolutePinY - centerY;
1163
1169
  pads.push({
1164
1170
  padId: `${group.partitionIndex}_pin_${pinId}`,
1165
1171
  networkId,
1166
1172
  type: "rect",
1167
- offset: { x: padOffsetX, y: padOffsetY },
1173
+ offset: { x: absolutePinX - centerX, y: absolutePinY - centerY },
1168
1174
  size: { x: 0.01, y: 0.01 }
1169
- // Small pin pad
1170
1175
  });
1171
1176
  }
1172
1177
  }
@@ -1174,14 +1179,17 @@ var PartitionPackingSolver = class extends BaseSolver {
1174
1179
  return {
1175
1180
  componentId: `partition_${group.partitionIndex}`,
1176
1181
  pads,
1177
- availableRotationDegrees: [0]
1178
- // Keep partitions unrotated
1182
+ availableRotationDegrees: [0],
1183
+ ...isFixed && {
1184
+ isStatic: true,
1185
+ center: { x: centerX, y: centerY },
1186
+ ccwRotationOffset: 0
1187
+ }
1179
1188
  };
1180
1189
  });
1181
1190
  return {
1182
1191
  components: packComponents,
1183
1192
  minGap: this.inputProblem.partitionGap,
1184
- // Use partitionGap from input problem
1185
1193
  packOrderStrategy: "largest_to_smallest",
1186
1194
  packPlacementStrategy: "minimum_sum_squared_distance_to_network"
1187
1195
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/matchpack",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.17",
5
+ "version": "0.0.18",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
@@ -14,21 +14,21 @@
14
14
  "build:site": "cosmos-export"
15
15
  },
16
16
  "devDependencies": {
17
- "@biomejs/biome": "^2.1.3",
17
+ "@biomejs/biome": "^2.4.16",
18
18
  "@react-hook/resize-observer": "^2.0.2",
19
- "@tscircuit/circuit-json-util": "^0.0.64",
20
- "@tscircuit/math-utils": "^0.0.19",
21
- "@tscircuit/schematic-viewer": "^2.0.26",
22
- "@types/bun": "latest",
19
+ "@tscircuit/circuit-json-util": "^0.0.95",
20
+ "@tscircuit/math-utils": "^0.0.36",
21
+ "@tscircuit/schematic-viewer": "^2.0.61",
22
+ "@types/bun": "^1.3.14",
23
23
  "bpc-graph": "^0.0.66",
24
- "calculate-packing": "^0.0.31",
25
- "circuit-json": "^0.0.226",
26
- "graphics-debug": "^0.0.64",
27
- "react-cosmos": "^7.0.0",
28
- "react-cosmos-plugin-vite": "^7.0.0",
29
- "tscircuit": "^0.0.593",
30
- "tsup": "^8.5.0",
31
- "circuit-to-svg": "^0.0.350"
24
+ "calculate-packing": "^0.0.74",
25
+ "circuit-json": "^0.0.432",
26
+ "graphics-debug": "^0.0.95",
27
+ "react-cosmos": "^7.3.0",
28
+ "react-cosmos-plugin-vite": "^7.3.0",
29
+ "tscircuit": "^0.0.1819",
30
+ "tsup": "^8.5.1",
31
+ "circuit-to-svg": "^0.0.351"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "typescript": "^5"