calculate-packing 0.0.27 → 0.0.29

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
@@ -171,6 +171,7 @@ declare class PhasedPackSolver extends BaseSolver {
171
171
 
172
172
  declare const convertCircuitJsonToPackOutput: (circuitJson: CircuitJson, opts?: {
173
173
  source_group_id?: string;
174
+ shouldAddInnerObstacles?: boolean;
174
175
  }) => PackOutput;
175
176
 
176
177
  declare const getGraphicsFromPackOutput: (packOutput: PackOutput) => GraphicsObject;
@@ -233,6 +234,9 @@ interface Point {
233
234
  x: number;
234
235
  y: number;
235
236
  }
237
+ interface PointWithNetworkId extends Point {
238
+ networkId?: string;
239
+ }
236
240
  interface OffsetPadPoint {
237
241
  id: string;
238
242
  offsetX: number;
@@ -265,7 +269,7 @@ interface MultiOffsetIrlsSolverParams {
265
269
  */
266
270
  declare class MultiOffsetIrlsSolver extends BaseSolver {
267
271
  offsetPadPoints: OffsetPadPoint[];
268
- targetPointMap: Map<string, Point[]>;
272
+ targetPointMap: Map<string, PointWithNetworkId[]>;
269
273
  currentPosition: Point;
270
274
  constraintFn?: (point: Point) => Point;
271
275
  epsilon: number;
@@ -405,6 +409,9 @@ declare class SingleComponentPackSolver extends BaseSolver {
405
409
  currentRotationIndex: number;
406
410
  activeSubSolver?: OutlineSegmentCandidatePointSolver | null;
407
411
  candidateResults: CandidateResult[];
412
+ rejectedCandidates: Array<CandidateResult & {
413
+ gapDistance: number;
414
+ }>;
408
415
  bestCandidate?: CandidateResult;
409
416
  outputPackedComponent?: PackedComponent;
410
417
  constructor(params: {
package/dist/index.js CHANGED
@@ -23,12 +23,17 @@ function checkOverlapWithPackedComponents({
23
23
  newComponentPadBox,
24
24
  packedPadBox
25
25
  );
26
- if (boxDist < minGap) {
27
- return true;
26
+ if (boxDist + 1e-6 < minGap) {
27
+ return {
28
+ hasOverlap: true,
29
+ gapDistance: boxDist
30
+ };
28
31
  }
29
32
  }
30
33
  }
31
- return false;
34
+ return {
35
+ hasOverlap: false
36
+ };
32
37
  }
33
38
 
34
39
  // lib/math/computeNearestPointOnSegmentForSegmentSet.ts
@@ -1408,7 +1413,7 @@ var PhasedPackSolver = class extends BaseSolver {
1408
1413
  component,
1409
1414
  packedComponents: this.packedComponents,
1410
1415
  minGap: this.packInput.minGap ?? 0
1411
- });
1416
+ }).hasOverlap;
1412
1417
  }
1413
1418
  };
1414
1419
 
@@ -1552,7 +1557,7 @@ var extractPadInfos = (pcbComponent, db, getNetworkId) => {
1552
1557
  };
1553
1558
 
1554
1559
  // lib/plumbing/convertCircuitJsonToPackOutput.ts
1555
- var buildPackedComponent = (pcbComponents, componentId, db, getNetworkId) => {
1560
+ var buildPackedComponent = (pcbComponents, componentId, db, getNetworkId, shouldAddInnerObstacles) => {
1556
1561
  const padInfos = pcbComponents.flatMap(
1557
1562
  (pc) => extractPadInfos(pc, db, getNetworkId)
1558
1563
  );
@@ -1578,6 +1583,17 @@ var buildPackedComponent = (pcbComponents, componentId, db, getNetworkId) => {
1578
1583
  y: p.absoluteCenter.y - center.y
1579
1584
  }
1580
1585
  }));
1586
+ if (shouldAddInnerObstacles) {
1587
+ const innerPad = {
1588
+ padId: `${componentId}-inner`,
1589
+ networkId: `${componentId}-inner`,
1590
+ type: "rect",
1591
+ size: { x: maxX - minX, y: maxY - minY },
1592
+ absoluteCenter: center,
1593
+ offset: { x: 0, y: 0 }
1594
+ };
1595
+ pads.push(innerPad);
1596
+ }
1581
1597
  return {
1582
1598
  componentId,
1583
1599
  center,
@@ -1628,7 +1644,8 @@ var convertCircuitJsonToPackOutput = (circuitJson, opts = {}) => {
1628
1644
  [pcbComponent],
1629
1645
  pcbComponent.pcb_component_id,
1630
1646
  db,
1631
- getNetworkId
1647
+ getNetworkId,
1648
+ opts.shouldAddInnerObstacles
1632
1649
  )
1633
1650
  );
1634
1651
  } else if (node.nodeType === "group") {
@@ -2451,7 +2468,10 @@ var OutlineSegmentCandidatePointSolver = class extends BaseSolver {
2451
2468
  for (const packedComponent of this.packedComponents) {
2452
2469
  for (const packedPad of packedComponent.pads) {
2453
2470
  if (packedPad.networkId === pad.networkId) {
2454
- targetPoints.push(packedPad.absoluteCenter);
2471
+ targetPoints.push({
2472
+ ...packedPad.absoluteCenter,
2473
+ networkId: packedPad.networkId
2474
+ });
2455
2475
  }
2456
2476
  }
2457
2477
  }
@@ -2726,6 +2746,7 @@ var SingleComponentPackSolver = class extends BaseSolver {
2726
2746
  currentRotationIndex = 0;
2727
2747
  activeSubSolver = null;
2728
2748
  candidateResults = [];
2749
+ rejectedCandidates = [];
2729
2750
  bestCandidate;
2730
2751
  outputPackedComponent;
2731
2752
  constructor(params) {
@@ -2804,13 +2825,23 @@ var SingleComponentPackSolver = class extends BaseSolver {
2804
2825
  let optimalPosition;
2805
2826
  if (this.activeSubSolver.solved && this.activeSubSolver.optimalPosition) {
2806
2827
  optimalPosition = this.activeSubSolver.optimalPosition;
2807
- const hasOverlap = checkOverlapWithPackedComponents({
2828
+ const { hasOverlap, gapDistance } = checkOverlapWithPackedComponents({
2808
2829
  component: this.createPackedComponent(optimalPosition, rotation),
2809
2830
  packedComponents: this.packedComponents,
2810
2831
  minGap: this.minGap
2811
2832
  });
2812
- if (!hasOverlap) {
2813
- distance = this.calculateDistance(optimalPosition, rotation);
2833
+ distance = this.calculateDistance(optimalPosition, rotation);
2834
+ if (hasOverlap) {
2835
+ this.rejectedCandidates.push({
2836
+ segment: queuedSegment.segment,
2837
+ rotation,
2838
+ optimalPosition,
2839
+ distance,
2840
+ segmentIndex: queuedSegment.segmentIndex,
2841
+ rotationIndex: this.currentRotationIndex,
2842
+ gapDistance
2843
+ });
2844
+ } else {
2814
2845
  this.candidateResults.push({
2815
2846
  segment: queuedSegment.segment,
2816
2847
  rotation,
@@ -2982,16 +3013,26 @@ var SingleComponentPackSolver = class extends BaseSolver {
2982
3013
  this.visualizeOutlinePhase(graphics);
2983
3014
  for (let i = 0; i < this.candidateResults.length; i++) {
2984
3015
  const candidate = this.candidateResults[i];
2985
- if (candidate.optimalPosition) {
2986
- const step = i;
2987
- const isBest = step === 0;
2988
- graphics.points.push({
2989
- x: candidate.optimalPosition.x,
2990
- y: candidate.optimalPosition.y,
2991
- label: `step=${step}, d=${candidate.distance.toFixed(3)}`,
2992
- color: isBest ? "rgba(0,255,0,0.8)" : "rgba(255,165,0,0.6)"
2993
- });
2994
- }
3016
+ if (!candidate.optimalPosition) continue;
3017
+ const step = i;
3018
+ const isBest = step === 0;
3019
+ graphics.points.push({
3020
+ x: candidate.optimalPosition.x,
3021
+ y: candidate.optimalPosition.y,
3022
+ label: `step=${step}, d=${candidate.distance.toFixed(3)}`,
3023
+ color: isBest ? "rgba(0,255,0,0.8)" : "rgba(255,165,0,0.6)"
3024
+ });
3025
+ }
3026
+ for (let i = 0; i < this.rejectedCandidates.length; i++) {
3027
+ const candidate = this.rejectedCandidates[i];
3028
+ if (!candidate.optimalPosition) continue;
3029
+ graphics.points.push({
3030
+ x: candidate.optimalPosition.x,
3031
+ y: candidate.optimalPosition.y,
3032
+ label: `rejected, d=${candidate.distance.toFixed(3)}
3033
+ gap_distance=${candidate.gapDistance}`,
3034
+ color: "rgba(255,0,0,0.8)"
3035
+ });
2995
3036
  }
2996
3037
  if (this.outputPackedComponent) {
2997
3038
  for (const pad of this.outputPackedComponent.pads) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "calculate-packing",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.27",
5
+ "version": "0.0.29",
6
6
  "description": "Calculate a packing layout with support for different strategy configurations",
7
7
  "scripts": {
8
8
  "start": "cosmos",
@@ -19,7 +19,7 @@
19
19
  "@biomejs/biome": "^2.1.1",
20
20
  "@flatten-js/core": "^1.6.2",
21
21
  "@react-hook/resize-observer": "^2.0.2",
22
- "@tscircuit/circuit-json-util": "^0.0.57",
22
+ "@tscircuit/circuit-json-util": "^0.0.66",
23
23
  "@tscircuit/footprinter": "^0.0.203",
24
24
  "@tscircuit/math-utils": "^0.0.19",
25
25
  "@types/bun": "latest",