@tscircuit/footprinter 0.0.155 → 0.0.157

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.js CHANGED
@@ -1580,43 +1580,103 @@ var pinrow_def = z11.object({
1580
1580
  });
1581
1581
  var pinrow = (raw_params) => {
1582
1582
  const parameters = pinrow_def.parse(raw_params);
1583
- const { p, id, od, rows } = parameters;
1584
- const numPins = parameters.num_pins;
1583
+ const { p, id, od, rows, num_pins } = parameters;
1585
1584
  const holes = [];
1585
+ const numPinsPerRow = Math.ceil(num_pins / rows);
1586
+ const ySpacing = -p;
1586
1587
  const addPin = (pinNumber, xoff, yoff) => {
1587
1588
  holes.push(platedhole(pinNumber, xoff, yoff, id, od));
1588
1589
  holes.push(
1589
1590
  silkscreenPin({ x: xoff, y: yoff + p / 2, fs: od / 5, pn: pinNumber })
1590
1591
  );
1591
1592
  };
1592
- if (rows > 1) {
1593
- const numPinsPerRow = Math.ceil(numPins / rows);
1594
- const ySpacing = p;
1595
- for (let row = 0; row < rows; row++) {
1596
- const yoff = row * ySpacing;
1597
- const startPin = row * numPinsPerRow;
1598
- const xStart = -((numPinsPerRow - 1) / 2) * p;
1599
- for (let i = 0; i < numPinsPerRow; i++) {
1600
- const pinNumber = startPin + i + 1;
1601
- if (pinNumber > numPins)
1602
- break;
1603
- const xoff = xStart + i * p;
1604
- addPin(pinNumber, xoff, yoff);
1605
- }
1606
- }
1607
- } else {
1608
- const xStart = -((numPins - 1) / 2) * p;
1609
- for (let i = 0; i < numPins; i++) {
1593
+ const usedPositions = /* @__PURE__ */ new Set();
1594
+ const useBGAStyle = rows > 2 && numPinsPerRow > 2;
1595
+ if (rows === 1) {
1596
+ const xStart = -((num_pins - 1) / 2) * p;
1597
+ for (let i = 0; i < num_pins; i++) {
1610
1598
  const pinNumber = i + 1;
1611
1599
  const xoff = xStart + i * p;
1600
+ const posKey = `${xoff},${0}`;
1601
+ if (usedPositions.has(posKey))
1602
+ throw new Error(`Overlap at ${posKey}`);
1603
+ usedPositions.add(posKey);
1612
1604
  addPin(pinNumber, xoff, 0);
1613
1605
  }
1606
+ } else if (useBGAStyle) {
1607
+ const xStart = -((numPinsPerRow - 1) / 2) * p;
1608
+ let currentPin = 1;
1609
+ for (let row = 0; row < rows && currentPin <= num_pins; row++) {
1610
+ for (let col = 0; col < numPinsPerRow && currentPin <= num_pins; col++) {
1611
+ const xoff = xStart + col * p;
1612
+ const yoff = row * ySpacing;
1613
+ const posKey = `${xoff},${yoff}`;
1614
+ if (usedPositions.has(posKey))
1615
+ throw new Error(`Overlap at ${posKey}`);
1616
+ usedPositions.add(posKey);
1617
+ addPin(currentPin++, xoff, yoff);
1618
+ }
1619
+ }
1620
+ } else {
1621
+ const xStart = -((numPinsPerRow - 1) / 2) * p;
1622
+ let currentPin = 1;
1623
+ let top = 0;
1624
+ let bottom = rows - 1;
1625
+ let left = 0;
1626
+ let right = numPinsPerRow - 1;
1627
+ while (currentPin <= num_pins && top <= bottom && left <= right) {
1628
+ for (let row = top; row <= bottom && currentPin <= num_pins; row++) {
1629
+ const xoff = xStart + left * p;
1630
+ const yoff = row * ySpacing;
1631
+ const posKey = `${xoff},${yoff}`;
1632
+ if (usedPositions.has(posKey))
1633
+ throw new Error(`Overlap at ${posKey}`);
1634
+ usedPositions.add(posKey);
1635
+ addPin(currentPin++, xoff, yoff);
1636
+ }
1637
+ left++;
1638
+ for (let col = left; col <= right && currentPin <= num_pins; col++) {
1639
+ const xoff = xStart + col * p;
1640
+ const yoff = bottom * ySpacing;
1641
+ const posKey = `${xoff},${yoff}`;
1642
+ if (usedPositions.has(posKey))
1643
+ throw new Error(`Overlap at ${posKey}`);
1644
+ usedPositions.add(posKey);
1645
+ addPin(currentPin++, xoff, yoff);
1646
+ }
1647
+ bottom--;
1648
+ if (left <= right) {
1649
+ for (let row = bottom; row >= top && currentPin <= num_pins; row--) {
1650
+ const xoff = xStart + right * p;
1651
+ const yoff = row * ySpacing;
1652
+ const posKey = `${xoff},${yoff}`;
1653
+ if (usedPositions.has(posKey))
1654
+ throw new Error(`Overlap at ${posKey}`);
1655
+ usedPositions.add(posKey);
1656
+ addPin(currentPin++, xoff, yoff);
1657
+ }
1658
+ right--;
1659
+ }
1660
+ if (top <= bottom) {
1661
+ for (let col = right; col >= left && currentPin <= num_pins; col--) {
1662
+ const xoff = xStart + col * p;
1663
+ const yoff = top * ySpacing;
1664
+ const posKey = `${xoff},${yoff}`;
1665
+ if (usedPositions.has(posKey))
1666
+ throw new Error(`Overlap at ${posKey}`);
1667
+ usedPositions.add(posKey);
1668
+ addPin(currentPin++, xoff, yoff);
1669
+ }
1670
+ top++;
1671
+ }
1672
+ }
1673
+ if (currentPin - 1 < num_pins) {
1674
+ throw new Error(
1675
+ `Missing pins: assigned ${currentPin - 1}, expected ${num_pins}`
1676
+ );
1677
+ }
1614
1678
  }
1615
- const perRow = rows > 1 ? Math.ceil(numPins / rows) : numPins;
1616
- const xStartGroup = -((perRow - 1) / 2) * p;
1617
- const groupTextX = xStartGroup + (perRow - 1) / 2 * p;
1618
- const groupTextY = rows * p;
1619
- const refText = silkscreenRef(groupTextX, groupTextY, 0.5);
1679
+ const refText = silkscreenRef(0, p, 0.5);
1620
1680
  return {
1621
1681
  circuitJson: [...holes, refText],
1622
1682
  parameters
@@ -5671,6 +5731,7 @@ var solderjumper = (params) => {
5671
5731
  pcb_trace_id: "",
5672
5732
  route: [
5673
5733
  {
5734
+ start_pcb_port_id: `{PIN${from}}`,
5674
5735
  x: x1,
5675
5736
  y: 0,
5676
5737
  width: traceWidth,
@@ -5678,6 +5739,7 @@ var solderjumper = (params) => {
5678
5739
  route_type: "wire"
5679
5740
  },
5680
5741
  {
5742
+ end_pcb_port_id: `{PIN${to}}`,
5681
5743
  x: x2,
5682
5744
  y: 0,
5683
5745
  width: traceWidth,