@tscircuit/3d-viewer 0.0.429 → 0.0.430

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.
Files changed (2) hide show
  1. package/dist/index.js +239 -138
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1129,13 +1129,13 @@ var require_squaredLength = __commonJS({
1129
1129
  var require_subtract = __commonJS({
1130
1130
  "node_modules/@jscad/modeling/src/maths/vec3/subtract.js"(exports, module) {
1131
1131
  "use strict";
1132
- var subtract5 = (out, a, b) => {
1132
+ var subtract6 = (out, a, b) => {
1133
1133
  out[0] = a[0] - b[0];
1134
1134
  out[1] = a[1] - b[1];
1135
1135
  out[2] = a[2] - b[2];
1136
1136
  return out;
1137
1137
  };
1138
- module.exports = subtract5;
1138
+ module.exports = subtract6;
1139
1139
  }
1140
1140
  });
1141
1141
 
@@ -1676,7 +1676,7 @@ var require_scale2 = __commonJS({
1676
1676
  var require_subtract2 = __commonJS({
1677
1677
  "node_modules/@jscad/modeling/src/maths/mat4/subtract.js"(exports, module) {
1678
1678
  "use strict";
1679
- var subtract5 = (out, a, b) => {
1679
+ var subtract6 = (out, a, b) => {
1680
1680
  out[0] = a[0] - b[0];
1681
1681
  out[1] = a[1] - b[1];
1682
1682
  out[2] = a[2] - b[2];
@@ -1695,7 +1695,7 @@ var require_subtract2 = __commonJS({
1695
1695
  out[15] = a[15] - b[15];
1696
1696
  return out;
1697
1697
  };
1698
- module.exports = subtract5;
1698
+ module.exports = subtract6;
1699
1699
  }
1700
1700
  });
1701
1701
 
@@ -1712,7 +1712,7 @@ var require_toString2 = __commonJS({
1712
1712
  var require_translate = __commonJS({
1713
1713
  "node_modules/@jscad/modeling/src/maths/mat4/translate.js"(exports, module) {
1714
1714
  "use strict";
1715
- var translate8 = (out, matrix, offsets) => {
1715
+ var translate9 = (out, matrix, offsets) => {
1716
1716
  const x = offsets[0];
1717
1717
  const y = offsets[1];
1718
1718
  const z133 = offsets[2];
@@ -1765,7 +1765,7 @@ var require_translate = __commonJS({
1765
1765
  }
1766
1766
  return out;
1767
1767
  };
1768
- module.exports = translate8;
1768
+ module.exports = translate9;
1769
1769
  }
1770
1770
  });
1771
1771
 
@@ -2205,12 +2205,12 @@ var require_squaredLength2 = __commonJS({
2205
2205
  var require_subtract3 = __commonJS({
2206
2206
  "node_modules/@jscad/modeling/src/maths/vec2/subtract.js"(exports, module) {
2207
2207
  "use strict";
2208
- var subtract5 = (out, a, b) => {
2208
+ var subtract6 = (out, a, b) => {
2209
2209
  out[0] = a[0] - b[0];
2210
2210
  out[1] = a[1] - b[1];
2211
2211
  return out;
2212
2212
  };
2213
- module.exports = subtract5;
2213
+ module.exports = subtract6;
2214
2214
  }
2215
2215
  });
2216
2216
 
@@ -2671,14 +2671,14 @@ var require_point_line_distance = __commonJS({
2671
2671
  "node_modules/@jscad/modeling/src/operations/hulls/quickhull/point-line-distance.js"(exports, module) {
2672
2672
  "use strict";
2673
2673
  var cross = require_cross();
2674
- var subtract5 = require_subtract();
2674
+ var subtract6 = require_subtract();
2675
2675
  var squaredLength = require_squaredLength();
2676
2676
  var distanceSquared = (p, a, b) => {
2677
2677
  const ab = [];
2678
2678
  const ap = [];
2679
2679
  const cr = [];
2680
- subtract5(ab, b, a);
2681
- subtract5(ap, p, a);
2680
+ subtract6(ab, b, a);
2681
+ subtract6(ap, p, a);
2682
2682
  const area = squaredLength(cross(cr, ap, ab));
2683
2683
  const s = squaredLength(ab);
2684
2684
  if (s === 0) {
@@ -2697,11 +2697,11 @@ var require_get_plane_normal = __commonJS({
2697
2697
  "use strict";
2698
2698
  var cross = require_cross();
2699
2699
  var normalize = require_normalize();
2700
- var subtract5 = require_subtract();
2700
+ var subtract6 = require_subtract();
2701
2701
  var planeNormal = (out, point1, point2, point32) => {
2702
2702
  const tmp = [0, 0, 0];
2703
- subtract5(out, point1, point2);
2704
- subtract5(tmp, point2, point32);
2703
+ subtract6(out, point1, point2);
2704
+ subtract6(tmp, point2, point32);
2705
2705
  cross(out, out, tmp);
2706
2706
  return normalize(out, out);
2707
2707
  };
@@ -2915,7 +2915,7 @@ var require_Face = __commonJS({
2915
2915
  var length2 = require_length();
2916
2916
  var normalize = require_normalize();
2917
2917
  var scale2 = require_scale();
2918
- var subtract5 = require_subtract();
2918
+ var subtract6 = require_subtract();
2919
2919
  var HalfEdge = require_HalfEdge();
2920
2920
  var VISIBLE = 0;
2921
2921
  var NON_CONVEX = 1;
@@ -2949,14 +2949,14 @@ var require_Face = __commonJS({
2949
2949
  const e0 = this.edge;
2950
2950
  const e1 = e0.next;
2951
2951
  let e2 = e1.next;
2952
- const v2 = subtract5([], e1.head().point, e0.head().point);
2952
+ const v2 = subtract6([], e1.head().point, e0.head().point);
2953
2953
  const t = [];
2954
2954
  const v1 = [];
2955
2955
  this.nVertices = 2;
2956
2956
  this.normal = [0, 0, 0];
2957
2957
  while (e2 !== e0) {
2958
2958
  copy(v1, v2);
2959
- subtract5(v2, e2.head().point, e0.head().point);
2959
+ subtract6(v2, e2.head().point, e0.head().point);
2960
2960
  add(this.normal, this.normal, cross(t, v1, v2));
2961
2961
  e2 = e2.next;
2962
2962
  this.nVertices += 1;
@@ -2980,7 +2980,7 @@ var require_Face = __commonJS({
2980
2980
  } while (edge !== this.edge);
2981
2981
  const p1 = maxEdge.tail().point;
2982
2982
  const p2 = maxEdge.head().point;
2983
- const maxVector = subtract5([], p2, p1);
2983
+ const maxVector = subtract6([], p2, p1);
2984
2984
  const maxLength = Math.sqrt(maxSquaredLength);
2985
2985
  scale2(maxVector, maxVector, 1 / maxLength);
2986
2986
  const maxProjection = dot(this.normal, maxVector);
@@ -5426,7 +5426,7 @@ var require_colorize = __commonJS({
5426
5426
  newpoly.color = color;
5427
5427
  return newpoly;
5428
5428
  };
5429
- var colorize7 = (color, ...objects) => {
5429
+ var colorize8 = (color, ...objects) => {
5430
5430
  if (!Array.isArray(color)) throw new Error("color must be an array");
5431
5431
  if (color.length < 3) throw new Error("color must contain R, G and B values");
5432
5432
  if (color.length === 3) color = [color[0], color[1], color[2], 1];
@@ -5442,7 +5442,7 @@ var require_colorize = __commonJS({
5442
5442
  });
5443
5443
  return results.length === 1 ? results[0] : results;
5444
5444
  };
5445
- module.exports = colorize7;
5445
+ module.exports = colorize8;
5446
5446
  }
5447
5447
  });
5448
5448
 
@@ -7555,7 +7555,7 @@ var require_circle = __commonJS({
7555
7555
  var { TAU } = require_constants();
7556
7556
  var ellipse = require_ellipse();
7557
7557
  var { isGTE } = require_commonChecks();
7558
- var circle = (options) => {
7558
+ var circle2 = (options) => {
7559
7559
  const defaults = {
7560
7560
  center: [0, 0],
7561
7561
  radius: 1,
@@ -7568,7 +7568,7 @@ var require_circle = __commonJS({
7568
7568
  radius = [radius, radius];
7569
7569
  return ellipse({ center, radius, startAngle, endAngle, segments });
7570
7570
  };
7571
- module.exports = circle;
7571
+ module.exports = circle2;
7572
7572
  }
7573
7573
  });
7574
7574
 
@@ -9746,7 +9746,7 @@ var require_translate2 = __commonJS({
9746
9746
  var geom2 = require_geom2();
9747
9747
  var geom3 = require_geom3();
9748
9748
  var path2 = require_path2();
9749
- var translate8 = (offset4, ...objects) => {
9749
+ var translate9 = (offset4, ...objects) => {
9750
9750
  if (!Array.isArray(offset4)) throw new Error("offset must be an array");
9751
9751
  objects = flatten(objects);
9752
9752
  if (objects.length === 0) throw new Error("wrong number of arguments");
@@ -9761,11 +9761,11 @@ var require_translate2 = __commonJS({
9761
9761
  });
9762
9762
  return results.length === 1 ? results[0] : results;
9763
9763
  };
9764
- var translateX = (offset4, ...objects) => translate8([offset4, 0, 0], objects);
9765
- var translateY = (offset4, ...objects) => translate8([0, offset4, 0], objects);
9766
- var translateZ = (offset4, ...objects) => translate8([0, 0, offset4], objects);
9764
+ var translateX = (offset4, ...objects) => translate9([offset4, 0, 0], objects);
9765
+ var translateY = (offset4, ...objects) => translate9([0, offset4, 0], objects);
9766
+ var translateZ = (offset4, ...objects) => translate9([0, 0, offset4], objects);
9767
9767
  module.exports = {
9768
- translate: translate8,
9768
+ translate: translate9,
9769
9769
  translateX,
9770
9770
  translateY,
9771
9771
  translateZ
@@ -9780,8 +9780,8 @@ var require_torus = __commonJS({
9780
9780
  var { TAU } = require_constants();
9781
9781
  var extrudeRotate = require_extrudeRotate();
9782
9782
  var { rotate: rotate2 } = require_rotate3();
9783
- var { translate: translate8 } = require_translate2();
9784
- var circle = require_circle();
9783
+ var { translate: translate9 } = require_translate2();
9784
+ var circle2 = require_circle();
9785
9785
  var { isGT, isGTE } = require_commonChecks();
9786
9786
  var torus = (options) => {
9787
9787
  const defaults = {
@@ -9801,11 +9801,11 @@ var require_torus = __commonJS({
9801
9801
  if (!isGTE(startAngle, 0)) throw new Error("startAngle must be positive");
9802
9802
  if (!isGT(outerRotation, 0)) throw new Error("outerRotation must be greater than zero");
9803
9803
  if (innerRadius >= outerRadius) throw new Error("inner circle is too large to rotate about the outer circle");
9804
- let innerCircle = circle({ radius: innerRadius, segments: innerSegments });
9804
+ let innerCircle = circle2({ radius: innerRadius, segments: innerSegments });
9805
9805
  if (innerRotation !== 0) {
9806
9806
  innerCircle = rotate2([0, 0, innerRotation], innerCircle);
9807
9807
  }
9808
- innerCircle = translate8([outerRadius, 0], innerCircle);
9808
+ innerCircle = translate9([outerRadius, 0], innerCircle);
9809
9809
  const extrudeOptions = {
9810
9810
  startAngle,
9811
9811
  angle: outerRotation,
@@ -11612,7 +11612,7 @@ var require_subtractGeom3 = __commonJS({
11612
11612
  var flatten = require_flatten();
11613
11613
  var retessellate = require_retessellate();
11614
11614
  var subtractSub = require_subtractGeom3Sub();
11615
- var subtract5 = (...geometries) => {
11615
+ var subtract6 = (...geometries) => {
11616
11616
  geometries = flatten(geometries);
11617
11617
  let newgeometry = geometries.shift();
11618
11618
  geometries.forEach((geometry) => {
@@ -11621,7 +11621,7 @@ var require_subtractGeom3 = __commonJS({
11621
11621
  newgeometry = retessellate(newgeometry);
11622
11622
  return newgeometry;
11623
11623
  };
11624
- module.exports = subtract5;
11624
+ module.exports = subtract6;
11625
11625
  }
11626
11626
  });
11627
11627
 
@@ -11635,14 +11635,14 @@ var require_subtractGeom2 = __commonJS({
11635
11635
  var fromFakePolygons = require_fromFakePolygons();
11636
11636
  var to3DWalls = require_to3DWalls();
11637
11637
  var subtractGeom3 = require_subtractGeom3();
11638
- var subtract5 = (...geometries) => {
11638
+ var subtract6 = (...geometries) => {
11639
11639
  geometries = flatten(geometries);
11640
11640
  const newgeometries = geometries.map((geometry) => to3DWalls({ z0: -1, z1: 1 }, geometry));
11641
11641
  const newgeom3 = subtractGeom3(newgeometries);
11642
11642
  const epsilon = measureEpsilon(newgeom3);
11643
11643
  return fromFakePolygons(epsilon, geom3.toPolygons(newgeom3));
11644
11644
  };
11645
- module.exports = subtract5;
11645
+ module.exports = subtract6;
11646
11646
  }
11647
11647
  });
11648
11648
 
@@ -11656,7 +11656,7 @@ var require_subtract4 = __commonJS({
11656
11656
  var geom3 = require_geom3();
11657
11657
  var subtractGeom2 = require_subtractGeom2();
11658
11658
  var subtractGeom3 = require_subtractGeom3();
11659
- var subtract5 = (...geometries) => {
11659
+ var subtract6 = (...geometries) => {
11660
11660
  geometries = flatten(geometries);
11661
11661
  if (geometries.length === 0) throw new Error("wrong number of arguments");
11662
11662
  if (!areAllShapesTheSameType(geometries)) {
@@ -11667,7 +11667,7 @@ var require_subtract4 = __commonJS({
11667
11667
  if (geom3.isA(geometry)) return subtractGeom3(geometries);
11668
11668
  return geometry;
11669
11669
  };
11670
- module.exports = subtract5;
11670
+ module.exports = subtract6;
11671
11671
  }
11672
11672
  });
11673
11673
 
@@ -12451,7 +12451,7 @@ var require_extrudeLinear = __commonJS({
12451
12451
  var path2 = require_path2();
12452
12452
  var extrudeLinearGeom2 = require_extrudeLinearGeom2();
12453
12453
  var extrudeLinearPath2 = require_extrudeLinearPath2();
12454
- var extrudeLinear7 = (options, ...objects) => {
12454
+ var extrudeLinear8 = (options, ...objects) => {
12455
12455
  const defaults = {
12456
12456
  height: 1,
12457
12457
  twistAngle: 0,
@@ -12469,7 +12469,7 @@ var require_extrudeLinear = __commonJS({
12469
12469
  });
12470
12470
  return results.length === 1 ? results[0] : results;
12471
12471
  };
12472
- module.exports = extrudeLinear7;
12472
+ module.exports = extrudeLinear8;
12473
12473
  }
12474
12474
  });
12475
12475
 
@@ -13528,7 +13528,7 @@ var require_align = __commonJS({
13528
13528
  var flatten = require_flatten();
13529
13529
  var padArrayToLength = require_padArrayToLength();
13530
13530
  var measureAggregateBoundingBox = require_measureAggregateBoundingBox();
13531
- var { translate: translate8 } = require_translate2();
13531
+ var { translate: translate9 } = require_translate2();
13532
13532
  var validateOptions = (options) => {
13533
13533
  if (!Array.isArray(options.modes) || options.modes.length > 3) throw new Error("align(): modes must be an array of length <= 3");
13534
13534
  options.modes = padArrayToLength(options.modes, "none", 3);
@@ -13565,7 +13565,7 @@ var require_align = __commonJS({
13565
13565
  translation[i] = relativeTo[i] - bounds[0][i];
13566
13566
  }
13567
13567
  }
13568
- return translate8(translation, geometry);
13568
+ return translate9(translation, geometry);
13569
13569
  };
13570
13570
  var align = (options, ...geometries) => {
13571
13571
  const defaults = {
@@ -13602,7 +13602,7 @@ var require_center = __commonJS({
13602
13602
  var geom3 = require_geom3();
13603
13603
  var path2 = require_path2();
13604
13604
  var measureBoundingBox = require_measureBoundingBox2();
13605
- var { translate: translate8 } = require_translate2();
13605
+ var { translate: translate9 } = require_translate2();
13606
13606
  var centerGeometry = (options, object) => {
13607
13607
  const defaults = {
13608
13608
  axes: [true, true, true],
@@ -13614,7 +13614,7 @@ var require_center = __commonJS({
13614
13614
  if (axes[0]) offset4[0] = relativeTo[0] - (bounds[0][0] + (bounds[1][0] - bounds[0][0]) / 2);
13615
13615
  if (axes[1]) offset4[1] = relativeTo[1] - (bounds[0][1] + (bounds[1][1] - bounds[0][1]) / 2);
13616
13616
  if (axes[2]) offset4[2] = relativeTo[2] - (bounds[0][2] + (bounds[1][2] - bounds[0][2]) / 2);
13617
- return translate8(offset4, object);
13617
+ return translate9(offset4, object);
13618
13618
  };
13619
13619
  var center = (options, ...objects) => {
13620
13620
  const defaults = {
@@ -24319,7 +24319,7 @@ var m2host = (raw_params) => {
24319
24319
  }
24320
24320
  const centerX = (minX + maxX) / 2;
24321
24321
  const centerY = (minY + maxY) / 2;
24322
- const translate8 = (el) => {
24322
+ const translate9 = (el) => {
24323
24323
  if (typeof el.x === "number") el.x -= centerX;
24324
24324
  if (typeof el.y === "number") el.y -= centerY;
24325
24325
  if (el.center) {
@@ -24333,9 +24333,9 @@ var m2host = (raw_params) => {
24333
24333
  }));
24334
24334
  }
24335
24335
  };
24336
- for (const pad2 of pads) translate8(pad2);
24337
- translate8(cutout);
24338
- translate8(pin1Marker);
24336
+ for (const pad2 of pads) translate9(pad2);
24337
+ translate9(cutout);
24338
+ translate9(pin1Marker);
24339
24339
  return {
24340
24340
  circuitJson: [
24341
24341
  ...pads,
@@ -26789,7 +26789,7 @@ import * as THREE14 from "three";
26789
26789
  // package.json
26790
26790
  var package_default = {
26791
26791
  name: "@tscircuit/3d-viewer",
26792
- version: "0.0.428",
26792
+ version: "0.0.429",
26793
26793
  main: "./dist/index.js",
26794
26794
  module: "./dist/index.js",
26795
26795
  type: "module",
@@ -27952,10 +27952,10 @@ var createBoardGeomFromCircuitJson = (circuitJson, opts = {}) => {
27952
27952
  };
27953
27953
 
27954
27954
  // src/BoardGeomBuilder.ts
27955
- var import_transforms6 = __toESM(require_transforms(), 1);
27956
- var import_primitives8 = __toESM(require_primitives(), 1);
27957
- var import_colors6 = __toESM(require_colors(), 1);
27958
- var import_booleans4 = __toESM(require_booleans(), 1);
27955
+ var import_transforms7 = __toESM(require_transforms(), 1);
27956
+ var import_primitives9 = __toESM(require_primitives(), 1);
27957
+ var import_colors7 = __toESM(require_colors(), 1);
27958
+ var import_booleans5 = __toESM(require_booleans(), 1);
27959
27959
  import { su as su3 } from "@tscircuit/circuit-json-util";
27960
27960
 
27961
27961
  // src/geoms/plated-hole.ts
@@ -28338,7 +28338,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28338
28338
  };
28339
28339
 
28340
28340
  // src/BoardGeomBuilder.ts
28341
- var import_extrusions6 = __toESM(require_extrusions(), 1);
28341
+ var import_extrusions7 = __toESM(require_extrusions(), 1);
28342
28342
  var import_expansions4 = __toESM(require_expansions(), 1);
28343
28343
 
28344
28344
  // src/geoms/create-geoms-for-silkscreen-text.ts
@@ -28812,9 +28812,52 @@ function createSilkscreenRectGeom(rect, ctx) {
28812
28812
  return (0, import_colors5.colorize)([1, 1, 1], rectGeom);
28813
28813
  }
28814
28814
 
28815
- // src/geoms/brep-converter.ts
28815
+ // src/geoms/create-geoms-for-silkscreen-circle.ts
28816
28816
  var import_primitives7 = __toESM(require_primitives(), 1);
28817
+ var import_extrusions6 = __toESM(require_extrusions(), 1);
28818
+ var import_transforms6 = __toESM(require_transforms(), 1);
28819
+ var import_colors6 = __toESM(require_colors(), 1);
28817
28820
  var import_booleans3 = __toESM(require_booleans(), 1);
28821
+ var CIRCLE_SEGMENTS = 64;
28822
+ function createSilkscreenCircleGeom(circleEl, ctx) {
28823
+ const radius = coerceDimensionToMm(circleEl.radius, 0);
28824
+ if (radius <= 0) return void 0;
28825
+ const strokeWidth = coerceDimensionToMm(circleEl.stroke_width, 0.12);
28826
+ const hasStroke = strokeWidth > 0;
28827
+ const centerX = parseDimensionToMm(circleEl.center?.x) ?? 0;
28828
+ const centerY = parseDimensionToMm(circleEl.center?.y) ?? 0;
28829
+ const layerSign = circleEl.layer === "bottom" ? -1 : 1;
28830
+ const zPos = layerSign * ctx.pcbThickness / 2 + layerSign * M * 1.5;
28831
+ const baseHeight = 0.012;
28832
+ let circleGeom;
28833
+ if (hasStroke) {
28834
+ const outerRadius = radius + strokeWidth / 2;
28835
+ const innerRadius = radius - strokeWidth / 2;
28836
+ const outerCircle2d = (0, import_primitives7.circle)({
28837
+ radius: outerRadius,
28838
+ segments: CIRCLE_SEGMENTS
28839
+ });
28840
+ let ring3d = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, outerCircle2d);
28841
+ if (innerRadius > 0) {
28842
+ const innerCircle2d = (0, import_primitives7.circle)({
28843
+ radius: innerRadius,
28844
+ segments: CIRCLE_SEGMENTS
28845
+ });
28846
+ const inner3d = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, innerCircle2d);
28847
+ ring3d = (0, import_booleans3.subtract)(ring3d, inner3d);
28848
+ }
28849
+ circleGeom = ring3d;
28850
+ } else {
28851
+ const filledCircle2d = (0, import_primitives7.circle)({ radius, segments: CIRCLE_SEGMENTS });
28852
+ circleGeom = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, filledCircle2d);
28853
+ }
28854
+ const translatedGeom = (0, import_transforms6.translate)([centerX, centerY, zPos], circleGeom);
28855
+ return (0, import_colors6.colorize)([1, 1, 1], translatedGeom);
28856
+ }
28857
+
28858
+ // src/geoms/brep-converter.ts
28859
+ var import_primitives8 = __toESM(require_primitives(), 1);
28860
+ var import_booleans4 = __toESM(require_booleans(), 1);
28818
28861
  function segmentToPoints(p1, p2, bulge, arcSegments) {
28819
28862
  if (!bulge || Math.abs(bulge) < 1e-9) {
28820
28863
  return [];
@@ -28882,7 +28925,7 @@ function createGeom2FromBRep(brep, arcSegments = 16) {
28882
28925
  if (arePointsClockwise2(outerPoints)) {
28883
28926
  outerPoints.reverse();
28884
28927
  }
28885
- const outerGeom = (0, import_primitives7.polygon)({ points: outerPoints });
28928
+ const outerGeom = (0, import_primitives8.polygon)({ points: outerPoints });
28886
28929
  if (!brep.inner_rings || brep.inner_rings.length === 0) {
28887
28930
  return outerGeom;
28888
28931
  }
@@ -28891,10 +28934,10 @@ function createGeom2FromBRep(brep, arcSegments = 16) {
28891
28934
  if (arePointsClockwise2(innerPoints)) {
28892
28935
  innerPoints.reverse();
28893
28936
  }
28894
- return (0, import_primitives7.polygon)({ points: innerPoints });
28937
+ return (0, import_primitives8.polygon)({ points: innerPoints });
28895
28938
  });
28896
28939
  if (innerGeoms.length === 0) return outerGeom;
28897
- return (0, import_booleans3.subtract)(outerGeom, innerGeoms);
28940
+ return (0, import_booleans4.subtract)(outerGeom, innerGeoms);
28898
28941
  }
28899
28942
 
28900
28943
  // src/BoardGeomBuilder.ts
@@ -28904,15 +28947,15 @@ var BOARD_CLIP_XY_OUTSET = 0.05;
28904
28947
  var createCenteredRectPadGeom = (width10, height10, thickness, rectBorderRadius) => {
28905
28948
  const clampedRadius = clampRectBorderRadius(width10, height10, rectBorderRadius);
28906
28949
  if (clampedRadius <= 0) {
28907
- return (0, import_primitives8.cuboid)({ center: [0, 0, 0], size: [width10, height10, thickness] });
28950
+ return (0, import_primitives9.cuboid)({ center: [0, 0, 0], size: [width10, height10, thickness] });
28908
28951
  }
28909
- const rect2d = (0, import_primitives8.roundedRectangle)({
28952
+ const rect2d = (0, import_primitives9.roundedRectangle)({
28910
28953
  size: [width10, height10],
28911
28954
  roundRadius: clampedRadius,
28912
28955
  segments: PAD_ROUNDED_SEGMENTS
28913
28956
  });
28914
- const extruded = (0, import_extrusions6.extrudeLinear)({ height: thickness }, rect2d);
28915
- return (0, import_transforms6.translate)([0, 0, -thickness / 2], extruded);
28957
+ const extruded = (0, import_extrusions7.extrudeLinear)({ height: thickness }, rect2d);
28958
+ return (0, import_transforms7.translate)([0, 0, -thickness / 2], extruded);
28916
28959
  };
28917
28960
  var buildStateOrder = [
28918
28961
  "initializing",
@@ -28925,6 +28968,7 @@ var buildStateOrder = [
28925
28968
  "processing_vias",
28926
28969
  "processing_silkscreen_text",
28927
28970
  "processing_silkscreen_lines",
28971
+ "processing_silkscreen_circles",
28928
28972
  "processing_silkscreen_rects",
28929
28973
  "processing_silkscreen_paths",
28930
28974
  "finalizing",
@@ -28941,6 +28985,7 @@ var BoardGeomBuilder = class {
28941
28985
  silkscreenTexts;
28942
28986
  silkscreenPaths;
28943
28987
  silkscreenLines;
28988
+ silkscreenCircles;
28944
28989
  silkscreenRects;
28945
28990
  pcb_cutouts;
28946
28991
  pcb_copper_pours;
@@ -28955,6 +29000,7 @@ var BoardGeomBuilder = class {
28955
29000
  silkscreenTextGeoms = [];
28956
29001
  silkscreenPathGeoms = [];
28957
29002
  silkscreenLineGeoms = [];
29003
+ silkscreenCircleGeoms = [];
28958
29004
  silkscreenRectGeoms = [];
28959
29005
  copperPourGeoms = [];
28960
29006
  boardClipGeom = null;
@@ -28990,6 +29036,7 @@ var BoardGeomBuilder = class {
28990
29036
  this.silkscreenTexts = su3(circuitJson).pcb_silkscreen_text.list();
28991
29037
  this.silkscreenPaths = su3(circuitJson).pcb_silkscreen_path.list();
28992
29038
  this.silkscreenLines = su3(circuitJson).pcb_silkscreen_line.list();
29039
+ this.silkscreenCircles = su3(circuitJson).pcb_silkscreen_circle.list();
28993
29040
  this.silkscreenRects = su3(circuitJson).pcb_silkscreen_rect.list();
28994
29041
  this.pcb_cutouts = su3(circuitJson).pcb_cutout.list();
28995
29042
  this.pcb_copper_pours = circuitJson.filter(
@@ -29015,11 +29062,11 @@ var BoardGeomBuilder = class {
29015
29062
  { xyOutset: BOARD_CLIP_XY_OUTSET }
29016
29063
  );
29017
29064
  } else {
29018
- this.boardGeom = (0, import_primitives8.cuboid)({
29065
+ this.boardGeom = (0, import_primitives9.cuboid)({
29019
29066
  size: [this.board.width, this.board.height, this.ctx.pcbThickness],
29020
29067
  center: [this.board.center.x, this.board.center.y, 0]
29021
29068
  });
29022
- this.boardClipGeom = (0, import_primitives8.cuboid)({
29069
+ this.boardClipGeom = (0, import_primitives9.cuboid)({
29023
29070
  size: [
29024
29071
  this.board.width + 2 * BOARD_CLIP_XY_OUTSET,
29025
29072
  this.board.height + 2 * BOARD_CLIP_XY_OUTSET,
@@ -29099,6 +29146,16 @@ var BoardGeomBuilder = class {
29099
29146
  this.goToNextState();
29100
29147
  }
29101
29148
  break;
29149
+ case "processing_silkscreen_circles":
29150
+ if (this.currentIndex < this.silkscreenCircles.length) {
29151
+ this.processSilkscreenCircle(
29152
+ this.silkscreenCircles[this.currentIndex]
29153
+ );
29154
+ this.currentIndex++;
29155
+ } else {
29156
+ this.goToNextState();
29157
+ }
29158
+ break;
29102
29159
  case "processing_silkscreen_rects":
29103
29160
  if (this.currentIndex < this.silkscreenRects.length) {
29104
29161
  this.processSilkscreenRect(this.silkscreenRects[this.currentIndex]);
@@ -29145,17 +29202,17 @@ var BoardGeomBuilder = class {
29145
29202
  const cutoutHeight = this.ctx.pcbThickness * 1.5;
29146
29203
  switch (cutout.shape) {
29147
29204
  case "rect":
29148
- cutoutGeom = (0, import_primitives8.cuboid)({
29205
+ cutoutGeom = (0, import_primitives9.cuboid)({
29149
29206
  center: [cutout.center.x, cutout.center.y, 0],
29150
29207
  size: [cutout.width, cutout.height, cutoutHeight]
29151
29208
  });
29152
29209
  if (cutout.rotation) {
29153
29210
  const rotationRadians = cutout.rotation * Math.PI / 180;
29154
- cutoutGeom = (0, import_transforms6.rotateZ)(rotationRadians, cutoutGeom);
29211
+ cutoutGeom = (0, import_transforms7.rotateZ)(rotationRadians, cutoutGeom);
29155
29212
  }
29156
29213
  break;
29157
29214
  case "circle":
29158
- cutoutGeom = (0, import_primitives8.cylinder)({
29215
+ cutoutGeom = (0, import_primitives9.cylinder)({
29159
29216
  center: [cutout.center.x, cutout.center.y, 0],
29160
29217
  radius: cutout.radius,
29161
29218
  height: cutoutHeight
@@ -29172,13 +29229,13 @@ var BoardGeomBuilder = class {
29172
29229
  if (arePointsClockwise(pointsVec2)) {
29173
29230
  pointsVec2 = pointsVec2.reverse();
29174
29231
  }
29175
- const polygon2d = (0, import_primitives8.polygon)({ points: pointsVec2 });
29176
- cutoutGeom = (0, import_extrusions6.extrudeLinear)({ height: cutoutHeight }, polygon2d);
29177
- cutoutGeom = (0, import_transforms6.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
29232
+ const polygon2d = (0, import_primitives9.polygon)({ points: pointsVec2 });
29233
+ cutoutGeom = (0, import_extrusions7.extrudeLinear)({ height: cutoutHeight }, polygon2d);
29234
+ cutoutGeom = (0, import_transforms7.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
29178
29235
  break;
29179
29236
  }
29180
29237
  if (cutoutGeom) {
29181
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cutoutGeom);
29238
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cutoutGeom);
29182
29239
  }
29183
29240
  }
29184
29241
  processCopperPour(pour) {
@@ -29186,22 +29243,22 @@ var BoardGeomBuilder = class {
29186
29243
  const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.copper;
29187
29244
  let pourGeom = null;
29188
29245
  if (pour.shape === "rect") {
29189
- let baseGeom = (0, import_primitives8.cuboid)({
29246
+ let baseGeom = (0, import_primitives9.cuboid)({
29190
29247
  center: [0, 0, 0],
29191
29248
  // Create at origin for rotation
29192
29249
  size: [pour.width, pour.height, M]
29193
29250
  });
29194
29251
  if ("rotation" in pour && pour.rotation) {
29195
29252
  const rotationRadians = pour.rotation * Math.PI / 180;
29196
- baseGeom = (0, import_transforms6.rotateZ)(rotationRadians, baseGeom);
29253
+ baseGeom = (0, import_transforms7.rotateZ)(rotationRadians, baseGeom);
29197
29254
  }
29198
- pourGeom = (0, import_transforms6.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
29255
+ pourGeom = (0, import_transforms7.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
29199
29256
  } else if (pour.shape === "brep") {
29200
29257
  const brepShape = pour.brep_shape;
29201
29258
  if (brepShape && brepShape.outer_ring) {
29202
29259
  const pourGeom2 = createGeom2FromBRep(brepShape);
29203
- pourGeom = (0, import_extrusions6.extrudeLinear)({ height: M }, pourGeom2);
29204
- pourGeom = (0, import_transforms6.translate)([0, 0, zPos], pourGeom);
29260
+ pourGeom = (0, import_extrusions7.extrudeLinear)({ height: M }, pourGeom2);
29261
+ pourGeom = (0, import_transforms7.translate)([0, 0, zPos], pourGeom);
29205
29262
  }
29206
29263
  } else if (pour.shape === "polygon") {
29207
29264
  let pointsVec2 = pour.points.map((p) => [p.x, p.y]);
@@ -29214,17 +29271,17 @@ var BoardGeomBuilder = class {
29214
29271
  if (arePointsClockwise(pointsVec2)) {
29215
29272
  pointsVec2 = pointsVec2.reverse();
29216
29273
  }
29217
- const polygon2d = (0, import_primitives8.polygon)({ points: pointsVec2 });
29218
- pourGeom = (0, import_extrusions6.extrudeLinear)({ height: M }, polygon2d);
29219
- pourGeom = (0, import_transforms6.translate)([0, 0, zPos], pourGeom);
29274
+ const polygon2d = (0, import_primitives9.polygon)({ points: pointsVec2 });
29275
+ pourGeom = (0, import_extrusions7.extrudeLinear)({ height: M }, polygon2d);
29276
+ pourGeom = (0, import_transforms7.translate)([0, 0, zPos], pourGeom);
29220
29277
  }
29221
29278
  if (pourGeom) {
29222
29279
  if (this.boardClipGeom) {
29223
- pourGeom = (0, import_booleans4.intersect)(this.boardClipGeom, pourGeom);
29280
+ pourGeom = (0, import_booleans5.intersect)(this.boardClipGeom, pourGeom);
29224
29281
  }
29225
29282
  const covered = pour.covered_with_solder_mask !== false;
29226
29283
  const pourMaterialColor = covered ? tracesMaterialColors[this.board.material] ?? colors.fr4GreenSolderWithMask : colors.copper;
29227
- const coloredPourGeom = (0, import_colors6.colorize)(pourMaterialColor, pourGeom);
29284
+ const coloredPourGeom = (0, import_colors7.colorize)(pourMaterialColor, pourGeom);
29228
29285
  this.copperPourGeoms.push(coloredPourGeom);
29229
29286
  }
29230
29287
  }
@@ -29233,7 +29290,7 @@ var BoardGeomBuilder = class {
29233
29290
  if (ph.shape === "circle" || ph.shape === "circular_hole_with_rect_pad") {
29234
29291
  let cyGeom = null;
29235
29292
  if (ph.shape === "circular_hole_with_rect_pad") {
29236
- cyGeom = (0, import_primitives8.cylinder)({
29293
+ cyGeom = (0, import_primitives9.cylinder)({
29237
29294
  center: [
29238
29295
  ph.x + (ph.hole_offset_x || 0),
29239
29296
  ph.y + (ph.hole_offset_y || 0),
@@ -29245,7 +29302,7 @@ var BoardGeomBuilder = class {
29245
29302
  // Ensure it cuts through
29246
29303
  });
29247
29304
  } else {
29248
- cyGeom = (0, import_primitives8.cylinder)({
29305
+ cyGeom = (0, import_primitives9.cylinder)({
29249
29306
  center: [ph.x, ph.y, 0],
29250
29307
  radius: ph.hole_diameter / 2 + M,
29251
29308
  // Add margin for subtraction
@@ -29254,10 +29311,10 @@ var BoardGeomBuilder = class {
29254
29311
  });
29255
29312
  }
29256
29313
  if (!opts.dontCutBoard) {
29257
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cyGeom);
29314
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cyGeom);
29258
29315
  }
29259
29316
  this.padGeoms = this.padGeoms.map(
29260
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, cyGeom))
29317
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, cyGeom))
29261
29318
  );
29262
29319
  const platedHoleGeom = platedHole(ph, this.ctx, {
29263
29320
  clipGeom: this.boardClipGeom
@@ -29271,8 +29328,8 @@ var BoardGeomBuilder = class {
29271
29328
  const rectLength = Math.abs(holeWidth - holeHeight);
29272
29329
  let pillHole;
29273
29330
  if (ph.shape === "pill_hole_with_rect_pad") {
29274
- pillHole = (0, import_booleans4.union)(
29275
- (0, import_primitives8.cuboid)({
29331
+ pillHole = (0, import_booleans5.union)(
29332
+ (0, import_primitives9.cuboid)({
29276
29333
  center: [
29277
29334
  ph.x + (ph.hole_offset_x || 0),
29278
29335
  ph.y + (ph.hole_offset_y || 0),
@@ -29280,7 +29337,7 @@ var BoardGeomBuilder = class {
29280
29337
  ],
29281
29338
  size: shouldRotate ? [holeHeight, rectLength, this.ctx.pcbThickness * 1.5] : [rectLength, holeHeight, this.ctx.pcbThickness * 1.5]
29282
29339
  }),
29283
- (0, import_primitives8.cylinder)({
29340
+ (0, import_primitives9.cylinder)({
29284
29341
  center: shouldRotate ? [
29285
29342
  ph.x + (ph.hole_offset_x || 0),
29286
29343
  ph.y + (ph.hole_offset_y || 0) - rectLength / 2,
@@ -29293,7 +29350,7 @@ var BoardGeomBuilder = class {
29293
29350
  radius: holeRadius,
29294
29351
  height: this.ctx.pcbThickness * 1.5
29295
29352
  }),
29296
- (0, import_primitives8.cylinder)({
29353
+ (0, import_primitives9.cylinder)({
29297
29354
  center: shouldRotate ? [
29298
29355
  ph.x + (ph.hole_offset_x || 0),
29299
29356
  ph.y + (ph.hole_offset_y || 0) + rectLength / 2,
@@ -29308,17 +29365,17 @@ var BoardGeomBuilder = class {
29308
29365
  })
29309
29366
  );
29310
29367
  } else {
29311
- pillHole = (0, import_booleans4.union)(
29312
- (0, import_primitives8.cuboid)({
29368
+ pillHole = (0, import_booleans5.union)(
29369
+ (0, import_primitives9.cuboid)({
29313
29370
  center: [ph.x, ph.y, 0],
29314
29371
  size: shouldRotate ? [holeHeight, rectLength, this.ctx.pcbThickness * 1.5] : [rectLength, holeHeight, this.ctx.pcbThickness * 1.5]
29315
29372
  }),
29316
- (0, import_primitives8.cylinder)({
29373
+ (0, import_primitives9.cylinder)({
29317
29374
  center: shouldRotate ? [ph.x, ph.y - rectLength / 2, 0] : [ph.x - rectLength / 2, ph.y, 0],
29318
29375
  radius: holeRadius,
29319
29376
  height: this.ctx.pcbThickness * 1.5
29320
29377
  }),
29321
- (0, import_primitives8.cylinder)({
29378
+ (0, import_primitives9.cylinder)({
29322
29379
  center: shouldRotate ? [ph.x, ph.y + rectLength / 2, 0] : [ph.x + rectLength / 2, ph.y, 0],
29323
29380
  radius: holeRadius,
29324
29381
  height: this.ctx.pcbThickness * 1.5
@@ -29326,10 +29383,10 @@ var BoardGeomBuilder = class {
29326
29383
  );
29327
29384
  }
29328
29385
  if (!opts.dontCutBoard) {
29329
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, pillHole);
29386
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, pillHole);
29330
29387
  }
29331
29388
  this.padGeoms = this.padGeoms.map(
29332
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, pillHole))
29389
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, pillHole))
29333
29390
  );
29334
29391
  const platedHoleGeom = platedHole(ph, this.ctx, {
29335
29392
  clipGeom: this.boardClipGeom
@@ -29342,22 +29399,22 @@ var BoardGeomBuilder = class {
29342
29399
  const holeDepth = this.ctx.pcbThickness * 1.5;
29343
29400
  const copperInset = 0.02;
29344
29401
  if (hole.hole_shape === "round" || hole.hole_shape === "circle") {
29345
- const cyGeom = (0, import_primitives8.cylinder)({
29402
+ const cyGeom = (0, import_primitives9.cylinder)({
29346
29403
  center: [hole.x, hole.y, 0],
29347
29404
  radius: hole.hole_diameter / 2 + M,
29348
29405
  height: holeDepth
29349
29406
  });
29350
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cyGeom);
29407
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cyGeom);
29351
29408
  this.padGeoms = this.padGeoms.map(
29352
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, cyGeom))
29409
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, cyGeom))
29353
29410
  );
29354
- const copperCut = (0, import_primitives8.cylinder)({
29411
+ const copperCut = (0, import_primitives9.cylinder)({
29355
29412
  center: [hole.x, hole.y, 0],
29356
29413
  radius: hole.hole_diameter / 2 + M / 2,
29357
29414
  height: holeDepth
29358
29415
  });
29359
29416
  this.platedHoleGeoms = this.platedHoleGeoms.map(
29360
- (phg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(phg, copperCut))
29417
+ (phg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperCut))
29361
29418
  );
29362
29419
  } else if (hole.hole_shape === "pill" || hole.hole_shape === "rotated_pill") {
29363
29420
  const holeWidth = hole.hole_width;
@@ -29367,34 +29424,34 @@ var BoardGeomBuilder = class {
29367
29424
  const isRotated = hole.hole_shape === "rotated_pill";
29368
29425
  let pillHole;
29369
29426
  if (holeWidth > holeHeight) {
29370
- pillHole = (0, import_booleans4.union)(
29371
- (0, import_primitives8.cuboid)({
29427
+ pillHole = (0, import_booleans5.union)(
29428
+ (0, import_primitives9.cuboid)({
29372
29429
  center: [hole.x, hole.y, 0],
29373
29430
  size: [rectLength, holeHeight, holeDepth]
29374
29431
  }),
29375
- (0, import_primitives8.cylinder)({
29432
+ (0, import_primitives9.cylinder)({
29376
29433
  center: [hole.x - rectLength / 2, hole.y, 0],
29377
29434
  radius: holeRadius,
29378
29435
  height: holeDepth
29379
29436
  }),
29380
- (0, import_primitives8.cylinder)({
29437
+ (0, import_primitives9.cylinder)({
29381
29438
  center: [hole.x + rectLength / 2, hole.y, 0],
29382
29439
  radius: holeRadius,
29383
29440
  height: holeDepth
29384
29441
  })
29385
29442
  );
29386
29443
  } else {
29387
- pillHole = (0, import_booleans4.union)(
29388
- (0, import_primitives8.cuboid)({
29444
+ pillHole = (0, import_booleans5.union)(
29445
+ (0, import_primitives9.cuboid)({
29389
29446
  center: [hole.x, hole.y, 0],
29390
29447
  size: [holeWidth, rectLength, holeDepth]
29391
29448
  }),
29392
- (0, import_primitives8.cylinder)({
29449
+ (0, import_primitives9.cylinder)({
29393
29450
  center: [hole.x, hole.y - rectLength / 2, 0],
29394
29451
  radius: holeRadius,
29395
29452
  height: holeDepth
29396
29453
  }),
29397
- (0, import_primitives8.cylinder)({
29454
+ (0, import_primitives9.cylinder)({
29398
29455
  center: [hole.x, hole.y + rectLength / 2, 0],
29399
29456
  radius: holeRadius,
29400
29457
  height: holeDepth
@@ -29403,15 +29460,15 @@ var BoardGeomBuilder = class {
29403
29460
  }
29404
29461
  if (isRotated) {
29405
29462
  const rotationRadians = hole.ccw_rotation * Math.PI / 180;
29406
- pillHole = (0, import_transforms6.rotateZ)(rotationRadians, pillHole);
29463
+ pillHole = (0, import_transforms7.rotateZ)(rotationRadians, pillHole);
29407
29464
  }
29408
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, pillHole);
29465
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, pillHole);
29409
29466
  this.padGeoms = this.padGeoms.map(
29410
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, pillHole))
29467
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, pillHole))
29411
29468
  );
29412
29469
  const copperPill = (0, import_expansions4.expand)({ delta: -copperInset }, pillHole);
29413
29470
  this.platedHoleGeoms = this.platedHoleGeoms.map(
29414
- (phg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(phg, copperPill))
29471
+ (phg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperPill))
29415
29472
  );
29416
29473
  }
29417
29474
  }
@@ -29426,12 +29483,12 @@ var BoardGeomBuilder = class {
29426
29483
  M,
29427
29484
  rectBorderRadius
29428
29485
  );
29429
- const positionedPadGeom = (0, import_transforms6.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29486
+ const positionedPadGeom = (0, import_transforms7.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29430
29487
  let finalPadGeom = positionedPadGeom;
29431
29488
  if (this.boardClipGeom) {
29432
- finalPadGeom = (0, import_booleans4.intersect)(this.boardClipGeom, finalPadGeom);
29489
+ finalPadGeom = (0, import_booleans5.intersect)(this.boardClipGeom, finalPadGeom);
29433
29490
  }
29434
- finalPadGeom = (0, import_colors6.colorize)(colors.copper, finalPadGeom);
29491
+ finalPadGeom = (0, import_colors7.colorize)(colors.copper, finalPadGeom);
29435
29492
  this.padGeoms.push(finalPadGeom);
29436
29493
  } else if (pad2.shape === "rotated_rect") {
29437
29494
  let basePadGeom = createCenteredRectPadGeom(
@@ -29441,24 +29498,24 @@ var BoardGeomBuilder = class {
29441
29498
  rectBorderRadius
29442
29499
  );
29443
29500
  const rotationRadians = pad2.ccw_rotation * Math.PI / 180;
29444
- basePadGeom = (0, import_transforms6.rotateZ)(rotationRadians, basePadGeom);
29445
- const positionedPadGeom = (0, import_transforms6.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29501
+ basePadGeom = (0, import_transforms7.rotateZ)(rotationRadians, basePadGeom);
29502
+ const positionedPadGeom = (0, import_transforms7.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29446
29503
  let finalPadGeom = positionedPadGeom;
29447
29504
  if (this.boardClipGeom) {
29448
- finalPadGeom = (0, import_booleans4.intersect)(this.boardClipGeom, finalPadGeom);
29505
+ finalPadGeom = (0, import_booleans5.intersect)(this.boardClipGeom, finalPadGeom);
29449
29506
  }
29450
- finalPadGeom = (0, import_colors6.colorize)(colors.copper, finalPadGeom);
29507
+ finalPadGeom = (0, import_colors7.colorize)(colors.copper, finalPadGeom);
29451
29508
  this.padGeoms.push(finalPadGeom);
29452
29509
  } else if (pad2.shape === "circle") {
29453
- let padGeom = (0, import_primitives8.cylinder)({
29510
+ let padGeom = (0, import_primitives9.cylinder)({
29454
29511
  center: [pad2.x, pad2.y, zPos],
29455
29512
  radius: pad2.radius,
29456
29513
  height: M
29457
29514
  });
29458
29515
  if (this.boardClipGeom) {
29459
- padGeom = (0, import_booleans4.intersect)(this.boardClipGeom, padGeom);
29516
+ padGeom = (0, import_booleans5.intersect)(this.boardClipGeom, padGeom);
29460
29517
  }
29461
- padGeom = (0, import_colors6.colorize)(colors.copper, padGeom);
29518
+ padGeom = (0, import_colors7.colorize)(colors.copper, padGeom);
29462
29519
  this.padGeoms.push(padGeom);
29463
29520
  }
29464
29521
  }
@@ -29472,14 +29529,14 @@ var BoardGeomBuilder = class {
29472
29529
  if (currentSegmentPoints.length >= 2 && currentLayer) {
29473
29530
  const layerSign = currentLayer === "bottom" ? -1 : 1;
29474
29531
  const zCenter = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.traces;
29475
- const linePath = (0, import_primitives8.line)(currentSegmentPoints);
29532
+ const linePath = (0, import_primitives9.line)(currentSegmentPoints);
29476
29533
  const expandedPath = (0, import_expansions4.expand)(
29477
29534
  { delta: currentWidth / 2, corners: "round" },
29478
29535
  linePath
29479
29536
  );
29480
- let traceGeom = (0, import_transforms6.translate)(
29537
+ let traceGeom = (0, import_transforms7.translate)(
29481
29538
  [0, 0, zCenter - M / 2],
29482
- (0, import_extrusions6.extrudeLinear)({ height: M }, expandedPath)
29539
+ (0, import_extrusions7.extrudeLinear)({ height: M }, expandedPath)
29483
29540
  );
29484
29541
  const startPointCoords = currentSegmentPoints[0];
29485
29542
  const endPointCoords = currentSegmentPoints[currentSegmentPoints.length - 1];
@@ -29488,27 +29545,27 @@ var BoardGeomBuilder = class {
29488
29545
  startPointCoords[1]
29489
29546
  );
29490
29547
  if (startHole) {
29491
- const cuttingCylinder = (0, import_primitives8.cylinder)({
29548
+ const cuttingCylinder = (0, import_primitives9.cylinder)({
29492
29549
  center: [startPointCoords[0], startPointCoords[1], zCenter],
29493
29550
  radius: startHole.diameter / 2 + M,
29494
29551
  height: M
29495
29552
  });
29496
- traceGeom = (0, import_booleans4.subtract)(traceGeom, cuttingCylinder);
29553
+ traceGeom = (0, import_booleans5.subtract)(traceGeom, cuttingCylinder);
29497
29554
  }
29498
29555
  const endHole = this.getHoleToCut(endPointCoords[0], endPointCoords[1]);
29499
29556
  if (endHole) {
29500
- const cuttingCylinder = (0, import_primitives8.cylinder)({
29557
+ const cuttingCylinder = (0, import_primitives9.cylinder)({
29501
29558
  center: [endPointCoords[0], endPointCoords[1], zCenter],
29502
29559
  radius: endHole.diameter / 2 + M,
29503
29560
  height: M
29504
29561
  });
29505
- traceGeom = (0, import_booleans4.subtract)(traceGeom, cuttingCylinder);
29562
+ traceGeom = (0, import_booleans5.subtract)(traceGeom, cuttingCylinder);
29506
29563
  }
29507
29564
  const tracesMaterialColor = tracesMaterialColors[this.board.material] ?? colors.fr4GreenSolderWithMask;
29508
29565
  if (this.boardClipGeom) {
29509
- traceGeom = (0, import_booleans4.intersect)(this.boardClipGeom, traceGeom);
29566
+ traceGeom = (0, import_booleans5.intersect)(this.boardClipGeom, traceGeom);
29510
29567
  }
29511
- traceGeom = (0, import_colors6.colorize)(tracesMaterialColor, traceGeom);
29568
+ traceGeom = (0, import_colors7.colorize)(tracesMaterialColor, traceGeom);
29512
29569
  this.traceGeoms.push(traceGeom);
29513
29570
  }
29514
29571
  currentSegmentPoints = [];
@@ -29575,7 +29632,7 @@ var BoardGeomBuilder = class {
29575
29632
  point2[0] + xOffset + st.anchor_position.x,
29576
29633
  point2[1] + yOffset + st.anchor_position.y
29577
29634
  ]);
29578
- const textPath = (0, import_primitives8.line)(alignedOutline);
29635
+ const textPath = (0, import_primitives9.line)(alignedOutline);
29579
29636
  const fontSize = st.font_size || 0.25;
29580
29637
  const expansionDelta = Math.min(
29581
29638
  Math.max(0.01, fontSize * 0.1),
@@ -29587,19 +29644,19 @@ var BoardGeomBuilder = class {
29587
29644
  );
29588
29645
  let textGeom;
29589
29646
  if (st.layer === "bottom") {
29590
- textGeom = (0, import_transforms6.translate)(
29647
+ textGeom = (0, import_transforms7.translate)(
29591
29648
  [0, 0, -this.ctx.pcbThickness / 2 - M],
29592
29649
  // Position above board
29593
- (0, import_extrusions6.extrudeLinear)({ height: 0.012 }, expandedPath)
29650
+ (0, import_extrusions7.extrudeLinear)({ height: 0.012 }, expandedPath)
29594
29651
  );
29595
29652
  } else {
29596
- textGeom = (0, import_transforms6.translate)(
29653
+ textGeom = (0, import_transforms7.translate)(
29597
29654
  [0, 0, this.ctx.pcbThickness / 2 + M],
29598
29655
  // Position above board
29599
- (0, import_extrusions6.extrudeLinear)({ height: 0.012 }, expandedPath)
29656
+ (0, import_extrusions7.extrudeLinear)({ height: 0.012 }, expandedPath)
29600
29657
  );
29601
29658
  }
29602
- textGeom = (0, import_colors6.colorize)([1, 1, 1], textGeom);
29659
+ textGeom = (0, import_colors7.colorize)([1, 1, 1], textGeom);
29603
29660
  this.silkscreenTextGeoms.push(textGeom);
29604
29661
  }
29605
29662
  }
@@ -29615,6 +29672,12 @@ var BoardGeomBuilder = class {
29615
29672
  this.silkscreenLineGeoms.push(lineGeom);
29616
29673
  }
29617
29674
  }
29675
+ processSilkscreenCircle(sc) {
29676
+ const circleGeom = createSilkscreenCircleGeom(sc, this.ctx);
29677
+ if (circleGeom) {
29678
+ this.silkscreenCircleGeoms.push(circleGeom);
29679
+ }
29680
+ }
29618
29681
  processSilkscreenRect(sr) {
29619
29682
  const rectGeom = createSilkscreenRectGeom(sr, this.ctx);
29620
29683
  if (rectGeom) {
@@ -29624,7 +29687,7 @@ var BoardGeomBuilder = class {
29624
29687
  finalize() {
29625
29688
  if (!this.boardGeom) return;
29626
29689
  const boardMaterialColor = boardMaterialColors[this.board.material] ?? colors.fr4Green;
29627
- this.boardGeom = (0, import_colors6.colorize)(boardMaterialColor, this.boardGeom);
29690
+ this.boardGeom = (0, import_colors7.colorize)(boardMaterialColor, this.boardGeom);
29628
29691
  this.finalGeoms = [
29629
29692
  this.boardGeom,
29630
29693
  ...this.platedHoleGeoms,
@@ -29634,6 +29697,7 @@ var BoardGeomBuilder = class {
29634
29697
  ...this.copperPourGeoms,
29635
29698
  ...this.silkscreenTextGeoms,
29636
29699
  ...this.silkscreenLineGeoms,
29700
+ ...this.silkscreenCircleGeoms,
29637
29701
  ...this.silkscreenRectGeoms,
29638
29702
  ...this.silkscreenPathGeoms
29639
29703
  ];
@@ -30160,11 +30224,13 @@ function createSilkscreenTextureForLayer({
30160
30224
  const pcbSilkscreenPaths = su6(circuitJson).pcb_silkscreen_path.list();
30161
30225
  const pcbSilkscreenLines = su6(circuitJson).pcb_silkscreen_line.list();
30162
30226
  const pcbSilkscreenRects = su6(circuitJson).pcb_silkscreen_rect.list();
30227
+ const pcbSilkscreenCircles = su6(circuitJson).pcb_silkscreen_circle.list();
30163
30228
  const textsOnLayer = pcbSilkscreenTexts.filter((t) => t.layer === layer);
30164
30229
  const pathsOnLayer = pcbSilkscreenPaths.filter((p) => p.layer === layer);
30165
30230
  const linesOnLayer = pcbSilkscreenLines.filter((l) => l.layer === layer);
30166
30231
  const rectsOnLayer = pcbSilkscreenRects.filter((r) => r.layer === layer);
30167
- if (textsOnLayer.length === 0 && pathsOnLayer.length === 0 && linesOnLayer.length === 0 && rectsOnLayer.length === 0) {
30232
+ const circlesOnLayer = pcbSilkscreenCircles.filter((c) => c.layer === layer);
30233
+ if (textsOnLayer.length === 0 && pathsOnLayer.length === 0 && linesOnLayer.length === 0 && rectsOnLayer.length === 0 && circlesOnLayer.length === 0) {
30168
30234
  return null;
30169
30235
  }
30170
30236
  const canvas = document.createElement("canvas");
@@ -30209,6 +30275,41 @@ function createSilkscreenTextureForLayer({
30209
30275
  });
30210
30276
  ctx.stroke();
30211
30277
  });
30278
+ circlesOnLayer.forEach((circleEl) => {
30279
+ const radius = coerceDimensionToMm(circleEl.radius, 0);
30280
+ if (radius <= 0) return;
30281
+ const strokeWidth = coerceDimensionToMm(circleEl.stroke_width, 0.12);
30282
+ const hasStroke = strokeWidth > 0;
30283
+ const centerXmm = parseDimensionToMm(circleEl.center?.x) ?? 0;
30284
+ const centerYmm = parseDimensionToMm(circleEl.center?.y) ?? 0;
30285
+ const canvasCenterX = canvasXFromPcb(centerXmm);
30286
+ const canvasCenterY = canvasYFromPcb(centerYmm);
30287
+ const radiusPx = radius * traceTextureResolution;
30288
+ ctx.save();
30289
+ ctx.translate(canvasCenterX, canvasCenterY);
30290
+ if (hasStroke) {
30291
+ const outerRadiusPx = radiusPx + strokeWidth / 2 * traceTextureResolution;
30292
+ const innerRadiusPx = Math.max(
30293
+ 0,
30294
+ radiusPx - strokeWidth / 2 * traceTextureResolution
30295
+ );
30296
+ if (innerRadiusPx > 0) {
30297
+ ctx.beginPath();
30298
+ ctx.arc(0, 0, outerRadiusPx, 0, 2 * Math.PI);
30299
+ ctx.arc(0, 0, innerRadiusPx, 0, 2 * Math.PI, true);
30300
+ ctx.fill("evenodd");
30301
+ } else {
30302
+ ctx.beginPath();
30303
+ ctx.arc(0, 0, outerRadiusPx, 0, 2 * Math.PI);
30304
+ ctx.fill();
30305
+ }
30306
+ } else {
30307
+ ctx.beginPath();
30308
+ ctx.arc(0, 0, radiusPx, 0, 2 * Math.PI);
30309
+ ctx.fill();
30310
+ }
30311
+ ctx.restore();
30312
+ });
30212
30313
  rectsOnLayer.forEach((rect) => {
30213
30314
  const width10 = coerceDimensionToMm(rect.width, 0);
30214
30315
  const height10 = coerceDimensionToMm(rect.height, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.429",
3
+ "version": "0.0.430",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -61,7 +61,7 @@
61
61
  "@vitejs/plugin-react": "^4.3.4",
62
62
  "bun-match-svg": "^0.0.9",
63
63
  "bun-types": "1.2.1",
64
- "circuit-json": "0.0.300",
64
+ "circuit-json": "0.0.303",
65
65
  "circuit-to-svg": "^0.0.179",
66
66
  "debug": "^4.4.0",
67
67
  "jscad-electronics": "^0.0.48",