@tscircuit/cli 0.1.2448 → 0.1.2449

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/cli/main.js CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/cli/main.js
3
- size: 47851148 bytes
4
- sha256: b95bc5fe0094448e24fbf9fca20564b150e46b32beb45403576a1866a55f7e23
3
+ size: 47854982 bytes
4
+ sha256: ccd1dcb8f8fc2c5af463b1d040420c4e51b8451283b318de656885f02bdf9d13
package/dist/lib/index.js CHANGED
@@ -74583,7 +74583,7 @@ import { applyToPoint as applyToPoint28 } from "transformation-matrix";
74583
74583
  import { ViaTenting } from "kicadts";
74584
74584
  import { Footprint as Footprint5 } from "kicadts";
74585
74585
  import { applyToPoint as applyToPoint29 } from "transformation-matrix";
74586
- import { GrLine } from "kicadts";
74586
+ import { GrCircle, GrLine } from "kicadts";
74587
74587
  import {
74588
74588
  At as At3,
74589
74589
  GrText,
@@ -80735,7 +80735,34 @@ function createGrTextFromCircuitJson({
80735
80735
  grText.position = position;
80736
80736
  return grText;
80737
80737
  }
80738
+ var signedDistanceToPolygon = (x, y, geometry) => {
80739
+ let inside = false;
80740
+ let minDistanceSquared = Infinity;
80741
+ for (const polygon of geometry) {
80742
+ for (const ring of polygon) {
80743
+ for (let i = 0;i < ring.length; i++) {
80744
+ const [ax, ay] = ring[i];
80745
+ const [bx, by] = ring[(i + 1) % ring.length];
80746
+ const dx = bx - ax;
80747
+ const dy = by - ay;
80748
+ const lengthSquared = dx * dx + dy * dy;
80749
+ if (lengthSquared === 0)
80750
+ continue;
80751
+ const px = x - ax;
80752
+ const py = y - ay;
80753
+ const t = Math.max(0, Math.min(1, (px * dx + py * dy) / lengthSquared));
80754
+ const distanceSquared = (px - t * dx) ** 2 + (py - t * dy) ** 2;
80755
+ minDistanceSquared = Math.min(minDistanceSquared, distanceSquared);
80756
+ if (ay > y !== by > y && px < py * dx / dy)
80757
+ inside = !inside;
80758
+ }
80759
+ }
80760
+ }
80761
+ const distance = Math.sqrt(minDistanceSquared);
80762
+ return inside ? distance : -distance;
80763
+ };
80738
80764
  var KICAD_PCB_UNITS_PER_MM = 1e6;
80765
+ var KICAD_PCB_GRID_MM = 1 / KICAD_PCB_UNITS_PER_MM;
80739
80766
  var roundBoardCoordinate = (coordinateMm) => Math.round(coordinateMm * KICAD_PCB_UNITS_PER_MM) / KICAD_PCB_UNITS_PER_MM;
80740
80767
  var roundPolygonToKicadPrecision = (geometry) => geometry.map((polygon) => polygon.map((ring) => ring.map(([x, y]) => [roundBoardCoordinate(x), roundBoardCoordinate(y)])));
80741
80768
  var pointsAreEqual = (a, b) => !!a && !!b && a.x === b.x && a.y === b.y;
@@ -80765,6 +80792,11 @@ var appendGraphicLine = (kicadPcb, grLine) => {
80765
80792
  graphicLines.push(grLine);
80766
80793
  kicadPcb.graphicLines = graphicLines;
80767
80794
  };
80795
+ var appendGraphicCircle = (kicadPcb, grCircle) => {
80796
+ const graphicCircles = kicadPcb.graphicCircles;
80797
+ graphicCircles.push(grCircle);
80798
+ kicadPcb.graphicCircles = graphicCircles;
80799
+ };
80768
80800
  var rotatePointAroundOrigin = (point, rotationDegrees = 0) => {
80769
80801
  if (!rotationDegrees)
80770
80802
  return point;
@@ -80875,6 +80907,7 @@ var AddGraphicsStage = class extends ConverterStage {
80875
80907
  if (firstOutline) {
80876
80908
  const pcbCutouts2 = this.ctx.db.pcb_cutout?.list() || [];
80877
80909
  const cutoutPolys = [];
80910
+ const circularCutouts = /* @__PURE__ */ new Map;
80878
80911
  for (const cutout of pcbCutouts2) {
80879
80912
  if (cutout.shape === "rect") {
80880
80913
  const cutoutCorners = getRectCutoutCorners(cutout);
@@ -80882,11 +80915,29 @@ var AddGraphicsStage = class extends ConverterStage {
80882
80915
  [cutoutCorners.map((point) => toKicadPoint(point, c2kMatPcb))]
80883
80916
  ]);
80884
80917
  } else if (cutout.shape === "circle") {
80885
- cutoutPolys.push([
80918
+ const geometry = [
80886
80919
  [
80887
80920
  circleToPolygon(cutout.center, cutout.radius).map(([x, y]) => toKicadPoint({ x, y }, c2kMatPcb))
80888
80921
  ]
80889
- ]);
80922
+ ];
80923
+ cutoutPolys.push(geometry);
80924
+ const [cx, cy] = toKicadPoint(cutout.center, c2kMatPcb);
80925
+ const [ex, ey] = toKicadPoint({ x: cutout.center.x + cutout.radius, y: cutout.center.y }, c2kMatPcb);
80926
+ const radius = Math.hypot(ex - cx, ey - cy);
80927
+ if (radius === 0)
80928
+ continue;
80929
+ circularCutouts.set(geometry, {
80930
+ cx,
80931
+ cy,
80932
+ radius,
80933
+ graphic: new GrCircle({
80934
+ center: { x: cx, y: cy },
80935
+ end: { x: ex, y: ey },
80936
+ layer: "Edge.Cuts",
80937
+ width: edgeCutsWidth,
80938
+ fill: "none"
80939
+ })
80940
+ });
80890
80941
  } else if (cutout.shape === "polygon") {
80891
80942
  cutoutPolys.push([
80892
80943
  [cutout.points.map((point) => toKicadPoint(point, c2kMatPcb))]
@@ -80894,8 +80945,54 @@ var AddGraphicsStage = class extends ConverterStage {
80894
80945
  }
80895
80946
  }
80896
80947
  let boardGeom = otherOutlines.length > 0 ? import_polygon_clipping.default.union(firstOutline, ...otherOutlines) : firstOutline;
80897
- if (cutoutPolys.length > 0) {
80898
- boardGeom = import_polygon_clipping.default.difference(roundPolygonToKicadPrecision(boardGeom), ...cutoutPolys);
80948
+ const bounds = cutoutPolys.map((geometry) => {
80949
+ const circle = circularCutouts.get(geometry);
80950
+ if (circle) {
80951
+ const r = circle.radius + KICAD_PCB_GRID_MM;
80952
+ return {
80953
+ minX: circle.cx - r,
80954
+ maxX: circle.cx + r,
80955
+ minY: circle.cy - r,
80956
+ maxY: circle.cy + r
80957
+ };
80958
+ }
80959
+ const ring = geometry[0][0];
80960
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
80961
+ for (const [x, y] of ring) {
80962
+ minX = Math.min(minX, x);
80963
+ maxX = Math.max(maxX, x);
80964
+ minY = Math.min(minY, y);
80965
+ maxY = Math.max(maxY, y);
80966
+ }
80967
+ return { minX, maxX, minY, maxY };
80968
+ });
80969
+ const clippedCutouts = cutoutPolys.filter((geometry, index) => {
80970
+ const circle = circularCutouts.get(geometry);
80971
+ if (!circle)
80972
+ return true;
80973
+ const requiredClearance = circle.radius + KICAD_PCB_GRID_MM;
80974
+ if (signedDistanceToPolygon(circle.cx, circle.cy, boardGeom) <= requiredClearance)
80975
+ return true;
80976
+ const box = bounds[index];
80977
+ const intersectsAnotherCutout = cutoutPolys.some((other, otherIndex) => {
80978
+ if (index === otherIndex)
80979
+ return false;
80980
+ const otherBox = bounds[otherIndex];
80981
+ if (box.minX > otherBox.maxX || box.maxX < otherBox.minX || box.minY > otherBox.maxY || box.maxY < otherBox.minY)
80982
+ return false;
80983
+ const otherCircle = circularCutouts.get(other);
80984
+ if (otherCircle) {
80985
+ return Math.hypot(circle.cx - otherCircle.cx, circle.cy - otherCircle.cy) <= requiredClearance + otherCircle.radius;
80986
+ }
80987
+ return signedDistanceToPolygon(circle.cx, circle.cy, other) >= -requiredClearance;
80988
+ });
80989
+ if (intersectsAnotherCutout)
80990
+ return true;
80991
+ appendGraphicCircle(kicadPcb, circle.graphic);
80992
+ return false;
80993
+ });
80994
+ if (clippedCutouts.length > 0) {
80995
+ boardGeom = import_polygon_clipping.default.difference(roundPolygonToKicadPrecision(boardGeom), ...clippedCutouts);
80899
80996
  }
80900
80997
  boardGeom = roundPolygonToKicadPrecision(boardGeom);
80901
80998
  for (const poly of boardGeom) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.2448",
3
+ "version": "0.1.2449",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/cli"
@@ -44,7 +44,7 @@
44
44
  "circuit-json-to-fdm-component-box": "^0.0.2",
45
45
  "circuit-json-to-footprinter": "^0.0.59",
46
46
  "circuit-json-to-gerber": "^0.0.122",
47
- "circuit-json-to-kicad": "0.0.271",
47
+ "circuit-json-to-kicad": "0.0.272",
48
48
  "circuit-json-to-readable-netlist": "^0.0.15",
49
49
  "circuit-json-to-step": "^0.0.63",
50
50
  "circuit-json-to-tscircuit": "^0.0.50",