@tscircuit/3d-viewer 0.0.443 → 0.0.444

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 +225 -92
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1073,13 +1073,13 @@ var require_rotateZ = __commonJS({
1073
1073
  var require_scale = __commonJS({
1074
1074
  "node_modules/@jscad/modeling/src/maths/vec3/scale.js"(exports, module) {
1075
1075
  "use strict";
1076
- var scale2 = (out, vector, amount) => {
1076
+ var scale3 = (out, vector, amount) => {
1077
1077
  out[0] = vector[0] * amount;
1078
1078
  out[1] = vector[1] * amount;
1079
1079
  out[2] = vector[2] * amount;
1080
1080
  return out;
1081
1081
  };
1082
- module.exports = scale2;
1082
+ module.exports = scale3;
1083
1083
  }
1084
1084
  });
1085
1085
 
@@ -1646,7 +1646,7 @@ var require_rotateZ2 = __commonJS({
1646
1646
  var require_scale2 = __commonJS({
1647
1647
  "node_modules/@jscad/modeling/src/maths/mat4/scale.js"(exports, module) {
1648
1648
  "use strict";
1649
- var scale2 = (out, matrix, dimensions) => {
1649
+ var scale3 = (out, matrix, dimensions) => {
1650
1650
  const x = dimensions[0];
1651
1651
  const y = dimensions[1];
1652
1652
  const z135 = dimensions[2];
@@ -1668,7 +1668,7 @@ var require_scale2 = __commonJS({
1668
1668
  out[15] = matrix[15];
1669
1669
  return out;
1670
1670
  };
1671
- module.exports = scale2;
1671
+ module.exports = scale3;
1672
1672
  }
1673
1673
  });
1674
1674
 
@@ -2153,12 +2153,12 @@ var require_normalize2 = __commonJS({
2153
2153
  var require_scale3 = __commonJS({
2154
2154
  "node_modules/@jscad/modeling/src/maths/vec2/scale.js"(exports, module) {
2155
2155
  "use strict";
2156
- var scale2 = (out, vector, amount) => {
2156
+ var scale3 = (out, vector, amount) => {
2157
2157
  out[0] = vector[0] * amount;
2158
2158
  out[1] = vector[1] * amount;
2159
2159
  return out;
2160
2160
  };
2161
- module.exports = scale2;
2161
+ module.exports = scale3;
2162
2162
  }
2163
2163
  });
2164
2164
 
@@ -2914,7 +2914,7 @@ var require_Face = __commonJS({
2914
2914
  var dot = require_dot();
2915
2915
  var length2 = require_length();
2916
2916
  var normalize = require_normalize();
2917
- var scale2 = require_scale();
2917
+ var scale3 = require_scale();
2918
2918
  var subtract6 = require_subtract();
2919
2919
  var HalfEdge = require_HalfEdge();
2920
2920
  var VISIBLE = 0;
@@ -2962,7 +2962,7 @@ var require_Face = __commonJS({
2962
2962
  this.nVertices += 1;
2963
2963
  }
2964
2964
  this.area = length2(this.normal);
2965
- this.normal = scale2(this.normal, this.normal, 1 / this.area);
2965
+ this.normal = scale3(this.normal, this.normal, 1 / this.area);
2966
2966
  }
2967
2967
  computeNormalMinArea(minArea) {
2968
2968
  this.computeNormal();
@@ -2982,9 +2982,9 @@ var require_Face = __commonJS({
2982
2982
  const p2 = maxEdge.head().point;
2983
2983
  const maxVector = subtract6([], p2, p1);
2984
2984
  const maxLength = Math.sqrt(maxSquaredLength);
2985
- scale2(maxVector, maxVector, 1 / maxLength);
2985
+ scale3(maxVector, maxVector, 1 / maxLength);
2986
2986
  const maxProjection = dot(this.normal, maxVector);
2987
- scale2(maxVector, maxVector, -maxProjection);
2987
+ scale3(maxVector, maxVector, -maxProjection);
2988
2988
  add(this.normal, this.normal, maxVector);
2989
2989
  normalize(this.normal, this.normal);
2990
2990
  }
@@ -2996,7 +2996,7 @@ var require_Face = __commonJS({
2996
2996
  add(this.centroid, this.centroid, edge.head().point);
2997
2997
  edge = edge.next;
2998
2998
  } while (edge !== this.edge);
2999
- scale2(this.centroid, this.centroid, 1 / this.nVertices);
2999
+ scale3(this.centroid, this.centroid, 1 / this.nVertices);
3000
3000
  }
3001
3001
  computeNormalAndCentroid(minArea) {
3002
3002
  if (typeof minArea !== "undefined") {
@@ -13656,7 +13656,7 @@ var require_scale4 = __commonJS({
13656
13656
  var geom2 = require_geom2();
13657
13657
  var geom3 = require_geom3();
13658
13658
  var path2 = require_path2();
13659
- var scale2 = (factors, ...objects) => {
13659
+ var scale3 = (factors, ...objects) => {
13660
13660
  if (!Array.isArray(factors)) throw new Error("factors must be an array");
13661
13661
  objects = flatten(objects);
13662
13662
  if (objects.length === 0) throw new Error("wrong number of arguments");
@@ -13672,11 +13672,11 @@ var require_scale4 = __commonJS({
13672
13672
  });
13673
13673
  return results.length === 1 ? results[0] : results;
13674
13674
  };
13675
- var scaleX = (factor, ...objects) => scale2([factor, 1, 1], objects);
13676
- var scaleY = (factor, ...objects) => scale2([1, factor, 1], objects);
13677
- var scaleZ = (factor, ...objects) => scale2([1, 1, factor], objects);
13675
+ var scaleX = (factor, ...objects) => scale3([factor, 1, 1], objects);
13676
+ var scaleY = (factor, ...objects) => scale3([1, factor, 1], objects);
13677
+ var scaleZ = (factor, ...objects) => scale3([1, 1, factor], objects);
13678
13678
  module.exports = {
13679
- scale: scale2,
13679
+ scale: scale3,
13680
13680
  scaleX,
13681
13681
  scaleY,
13682
13682
  scaleZ
@@ -14530,7 +14530,7 @@ function MixedStlModel({
14530
14530
  onHover,
14531
14531
  onUnhover,
14532
14532
  isHovered,
14533
- scale: scale2
14533
+ scale: scale3
14534
14534
  }) {
14535
14535
  const obj = useGlobalObjLoader(url);
14536
14536
  const { rootObject } = useThree();
@@ -14570,8 +14570,8 @@ function MixedStlModel({
14570
14570
  model.rotation.copy(rotation2);
14571
14571
  }
14572
14572
  }
14573
- if (scale2 !== void 0) {
14574
- model.scale.setScalar(scale2);
14573
+ if (scale3 !== void 0) {
14574
+ model.scale.setScalar(scale3);
14575
14575
  }
14576
14576
  }, [
14577
14577
  model,
@@ -14581,7 +14581,7 @@ function MixedStlModel({
14581
14581
  Array.isArray(rotation2) ? rotation2[0] : rotation2?.x,
14582
14582
  Array.isArray(rotation2) ? rotation2[1] : rotation2?.y,
14583
14583
  Array.isArray(rotation2) ? rotation2[2] : rotation2?.z,
14584
- scale2
14584
+ scale3
14585
14585
  ]);
14586
14586
  if (obj instanceof Error) {
14587
14587
  throw obj;
@@ -14639,7 +14639,7 @@ function GltfModel({
14639
14639
  onHover,
14640
14640
  onUnhover,
14641
14641
  isHovered,
14642
- scale: scale2
14642
+ scale: scale3
14643
14643
  }) {
14644
14644
  const { renderer, rootObject } = useThree();
14645
14645
  const [model, setModel] = useState3(null);
@@ -14666,7 +14666,7 @@ function GltfModel({
14666
14666
  if (!model) return;
14667
14667
  if (position) model.position.fromArray(position);
14668
14668
  if (rotation2) model.rotation.fromArray(rotation2);
14669
- if (scale2 !== void 0) model.scale.setScalar(scale2);
14669
+ if (scale3 !== void 0) model.scale.setScalar(scale3);
14670
14670
  }, [
14671
14671
  model,
14672
14672
  position?.[0],
@@ -14675,7 +14675,7 @@ function GltfModel({
14675
14675
  rotation2?.[0],
14676
14676
  rotation2?.[1],
14677
14677
  rotation2?.[2],
14678
- scale2
14678
+ scale3
14679
14679
  ]);
14680
14680
  useEffect5(() => {
14681
14681
  if (!rootObject || !model) return;
@@ -24828,9 +24828,9 @@ function getExpandedStroke(strokeInput, width10) {
24828
24828
  addPoint(current2, normalPrev, -1);
24829
24829
  addPoint(current2, normalNext, -1);
24830
24830
  } else {
24831
- const scale2 = 1 / miterLength;
24832
- addPoint(current2, { x: miterX * scale2, y: miterY * scale2 }, 1);
24833
- addPoint(current2, { x: miterX * scale2, y: miterY * scale2 }, -1);
24831
+ const scale3 = 1 / miterLength;
24832
+ addPoint(current2, { x: miterX * scale3, y: miterY * scale3 }, 1);
24833
+ addPoint(current2, { x: miterX * scale3, y: miterY * scale3 }, -1);
24834
24834
  }
24835
24835
  }
24836
24836
  const lastNormal = getNormal(
@@ -27905,7 +27905,7 @@ var JscadModel = ({
27905
27905
  onHover,
27906
27906
  onUnhover,
27907
27907
  isHovered,
27908
- scale: scale2
27908
+ scale: scale3
27909
27909
  }) => {
27910
27910
  const { rootObject } = useThree();
27911
27911
  const { threeGeom, material } = useMemo4(() => {
@@ -27936,7 +27936,7 @@ var JscadModel = ({
27936
27936
  if (!mesh) return;
27937
27937
  if (positionOffset) mesh.position.fromArray(positionOffset);
27938
27938
  if (rotationOffset) mesh.rotation.fromArray(rotationOffset);
27939
- if (scale2 !== void 0) mesh.scale.setScalar(scale2);
27939
+ if (scale3 !== void 0) mesh.scale.setScalar(scale3);
27940
27940
  }, [
27941
27941
  mesh,
27942
27942
  positionOffset?.[0],
@@ -27945,7 +27945,7 @@ var JscadModel = ({
27945
27945
  rotationOffset?.[0],
27946
27946
  rotationOffset?.[1],
27947
27947
  rotationOffset?.[2],
27948
- scale2
27948
+ scale3
27949
27949
  ]);
27950
27950
  useMemo4(() => {
27951
27951
  if (!material) return;
@@ -27982,7 +27982,7 @@ var FootprinterModel = ({
27982
27982
  onHover,
27983
27983
  onUnhover,
27984
27984
  isHovered,
27985
- scale: scale2
27985
+ scale: scale3
27986
27986
  }) => {
27987
27987
  const { rootObject } = useThree();
27988
27988
  const group = useMemo5(() => {
@@ -28018,7 +28018,7 @@ var FootprinterModel = ({
28018
28018
  if (!group) return;
28019
28019
  if (positionOffset) group.position.fromArray(positionOffset);
28020
28020
  if (rotationOffset) group.rotation.fromArray(rotationOffset);
28021
- if (scale2 !== void 0) group.scale.setScalar(scale2);
28021
+ if (scale3 !== void 0) group.scale.setScalar(scale3);
28022
28022
  }, [
28023
28023
  group,
28024
28024
  positionOffset?.[0],
@@ -28027,7 +28027,7 @@ var FootprinterModel = ({
28027
28027
  rotationOffset?.[0],
28028
28028
  rotationOffset?.[1],
28029
28029
  rotationOffset?.[2],
28030
- scale2
28030
+ scale3
28031
28031
  ]);
28032
28032
  useEffect7(() => {
28033
28033
  if (!group) return;
@@ -28318,7 +28318,7 @@ import * as THREE15 from "three";
28318
28318
  // package.json
28319
28319
  var package_default = {
28320
28320
  name: "@tscircuit/3d-viewer",
28321
- version: "0.0.442",
28321
+ version: "0.0.443",
28322
28322
  main: "./dist/index.js",
28323
28323
  module: "./dist/index.js",
28324
28324
  type: "module",
@@ -29617,7 +29617,7 @@ var createBoardGeomFromCircuitJson = (circuitJson, opts = {}) => {
29617
29617
  };
29618
29618
 
29619
29619
  // src/BoardGeomBuilder.ts
29620
- var import_transforms8 = __toESM(require_transforms(), 1);
29620
+ var import_transforms9 = __toESM(require_transforms(), 1);
29621
29621
  var import_primitives10 = __toESM(require_primitives(), 1);
29622
29622
  var import_colors7 = __toESM(require_colors(), 1);
29623
29623
  var import_booleans6 = __toESM(require_booleans(), 1);
@@ -29627,8 +29627,9 @@ import { su as su3 } from "@tscircuit/circuit-json-util";
29627
29627
  var import_primitives4 = __toESM(require_primitives(), 1);
29628
29628
  var import_colors2 = __toESM(require_colors(), 1);
29629
29629
  var import_booleans2 = __toESM(require_booleans(), 1);
29630
- var import_extrusions3 = __toESM(require_extrusions(), 1);
29631
29630
  var import_transforms3 = __toESM(require_transforms(), 1);
29631
+ var import_extrusions3 = __toESM(require_extrusions(), 1);
29632
+ var import_transforms4 = __toESM(require_transforms(), 1);
29632
29633
 
29633
29634
  // src/utils/rect-border-radius.ts
29634
29635
  function clampRectBorderRadius(width10, height10, rawRadius) {
@@ -29760,7 +29761,7 @@ var createRectPadGeom = ({
29760
29761
  });
29761
29762
  const extruded = (0, import_extrusions3.extrudeLinear)({ height: thickness }, rect2d);
29762
29763
  const offsetZ = center[2] - thickness / 2;
29763
- return (0, import_transforms3.translate)([center[0], center[1], offsetZ], extruded);
29764
+ return (0, import_transforms4.translate)([center[0], center[1], offsetZ], extruded);
29764
29765
  };
29765
29766
  var platedHole = (plated_hole, ctx, options = {}) => {
29766
29767
  const { clipGeom } = options;
@@ -29785,6 +29786,39 @@ var platedHole = (plated_hole, ctx, options = {}) => {
29785
29786
  });
29786
29787
  return (0, import_colors2.colorize)(colors.copper, (0, import_booleans2.subtract)(copperSolid, drill));
29787
29788
  }
29789
+ if (plated_hole.shape === "oval") {
29790
+ const outerWidth = plated_hole.outer_width || plated_hole.hole_width || 0;
29791
+ const outerHeight = plated_hole.outer_height || plated_hole.hole_height || 0;
29792
+ const holeWidth = plated_hole.hole_width || 0;
29793
+ const holeHeight = plated_hole.hole_height || 0;
29794
+ const copperBody = (() => {
29795
+ const circle2 = (0, import_primitives4.cylinder)({
29796
+ center: [0, 0, 0],
29797
+ radius: 1,
29798
+ height: copperSpan + 0.01,
29799
+ segments: 64
29800
+ // High segment count for smooth ellipse
29801
+ });
29802
+ const scaled = (0, import_transforms3.scale)([outerWidth / 2, outerHeight / 2, 1], circle2);
29803
+ return (0, import_transforms4.translate)([plated_hole.x, plated_hole.y, 0], scaled);
29804
+ })();
29805
+ const copperSolid = maybeClip(copperBody, clipGeom);
29806
+ const drill = (() => {
29807
+ const circle2 = (0, import_primitives4.cylinder)({
29808
+ center: [0, 0, 0],
29809
+ radius: 1,
29810
+ height: throughDrillHeight,
29811
+ segments: 64
29812
+ // High segment count for smooth ellipse
29813
+ });
29814
+ const scaled = (0, import_transforms3.scale)(
29815
+ [Math.max(holeWidth / 2, 0.01), Math.max(holeHeight / 2, 0.01), 1],
29816
+ circle2
29817
+ );
29818
+ return (0, import_transforms4.translate)([plated_hole.x, plated_hole.y, 0], scaled);
29819
+ })();
29820
+ return (0, import_colors2.colorize)(colors.copper, (0, import_booleans2.subtract)(copperSolid, drill));
29821
+ }
29788
29822
  if (plated_hole.shape === "circular_hole_with_rect_pad") {
29789
29823
  const holeOffsetX = plated_hole.hole_offset_x || 0;
29790
29824
  const holeOffsetY = plated_hole.hole_offset_y || 0;
@@ -29823,7 +29857,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
29823
29857
  segments: RECT_PAD_SEGMENTS
29824
29858
  });
29825
29859
  const extruded = (0, import_extrusions3.extrudeLinear)({ height: height10 }, rect2d);
29826
- return (0, import_transforms3.translate)(
29860
+ return (0, import_transforms4.translate)(
29827
29861
  [plated_hole.x, plated_hole.y, centerZ - height10 / 2],
29828
29862
  extruded
29829
29863
  );
@@ -29876,9 +29910,9 @@ var platedHole = (plated_hole, ctx, options = {}) => {
29876
29910
  const rotationRadians = (plated_hole.ccw_rotation || 0) * Math.PI / 180;
29877
29911
  const rotateAroundCenter = (geom) => {
29878
29912
  if (!rotationRadians) return geom;
29879
- const toOrigin = (0, import_transforms3.translate)([-plated_hole.x, -plated_hole.y, 0], geom);
29880
- const rotated = (0, import_transforms3.rotate)([0, 0, rotationRadians], toOrigin);
29881
- return (0, import_transforms3.translate)([plated_hole.x, plated_hole.y, 0], rotated);
29913
+ const toOrigin = (0, import_transforms4.translate)([-plated_hole.x, -plated_hole.y, 0], geom);
29914
+ const rotated = (0, import_transforms4.rotate)([0, 0, rotationRadians], toOrigin);
29915
+ return (0, import_transforms4.translate)([plated_hole.x, plated_hole.y, 0], rotated);
29882
29916
  };
29883
29917
  const shouldRotate = plated_hole.hole_height > plated_hole.hole_width;
29884
29918
  const holeWidth = shouldRotate ? plated_hole.hole_height : plated_hole.hole_width;
@@ -30049,7 +30083,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30049
30083
  segments: RECT_PAD_SEGMENTS
30050
30084
  });
30051
30085
  const extruded = (0, import_extrusions3.extrudeLinear)({ height: height10 }, rect2d);
30052
- return (0, import_transforms3.translate)(
30086
+ return (0, import_transforms4.translate)(
30053
30087
  [plated_hole.x, plated_hole.y, centerZ - height10 / 2],
30054
30088
  extruded
30055
30089
  );
@@ -30111,7 +30145,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30111
30145
  const createPolygonPad = (thickness, zCenter) => {
30112
30146
  const safeThickness = Math.max(thickness, M);
30113
30147
  const extruded = (0, import_extrusions3.extrudeLinear)({ height: safeThickness }, polygon2d);
30114
- return (0, import_transforms3.translate)(
30148
+ return (0, import_transforms4.translate)(
30115
30149
  [plated_hole.x, plated_hole.y, zCenter - safeThickness / 2],
30116
30150
  extruded
30117
30151
  );
@@ -30449,7 +30483,7 @@ function createSilkscreenTextGeoms(silkscreenText) {
30449
30483
  var import_primitives5 = __toESM(require_primitives(), 1);
30450
30484
  var import_expansions2 = __toESM(require_expansions(), 1);
30451
30485
  var import_extrusions4 = __toESM(require_extrusions(), 1);
30452
- var import_transforms4 = __toESM(require_transforms(), 1);
30486
+ var import_transforms5 = __toESM(require_transforms(), 1);
30453
30487
  var import_colors3 = __toESM(require_colors(), 1);
30454
30488
 
30455
30489
  // src/utils/units.ts
@@ -30512,7 +30546,7 @@ function createSilkscreenPathGeom(sp, ctx) {
30512
30546
  );
30513
30547
  const layerSign = sp.layer === "bottom" ? -1 : 1;
30514
30548
  const zPos = layerSign * ctx.pcbThickness / 2 + layerSign * M * 1.5;
30515
- let pathGeom = (0, import_transforms4.translate)(
30549
+ let pathGeom = (0, import_transforms5.translate)(
30516
30550
  [0, 0, zPos],
30517
30551
  (0, import_extrusions4.extrudeLinear)({ height: 0.012 }, expandedPath)
30518
30552
  // Standard silkscreen thickness
@@ -30525,7 +30559,7 @@ function createSilkscreenPathGeom(sp, ctx) {
30525
30559
  var import_primitives6 = __toESM(require_primitives(), 1);
30526
30560
  var import_expansions3 = __toESM(require_expansions(), 1);
30527
30561
  var import_extrusions5 = __toESM(require_extrusions(), 1);
30528
- var import_transforms5 = __toESM(require_transforms(), 1);
30562
+ var import_transforms6 = __toESM(require_transforms(), 1);
30529
30563
  var import_colors4 = __toESM(require_colors(), 1);
30530
30564
  function createSilkscreenLineGeom(sl, ctx) {
30531
30565
  const x1 = parseDimensionToMm(sl.x1) ?? 0;
@@ -30545,7 +30579,7 @@ function createSilkscreenLineGeom(sl, ctx) {
30545
30579
  );
30546
30580
  const layerSign = sl.layer === "bottom" ? -1 : 1;
30547
30581
  const zPos = layerSign * ctx.pcbThickness / 2 + layerSign * M * 1.5;
30548
- let lineGeom = (0, import_transforms5.translate)(
30582
+ let lineGeom = (0, import_transforms6.translate)(
30549
30583
  [0, 0, zPos],
30550
30584
  (0, import_extrusions5.extrudeLinear)({ height: 0.012 }, expandedLine)
30551
30585
  );
@@ -30556,7 +30590,7 @@ function createSilkscreenLineGeom(sl, ctx) {
30556
30590
  // src/geoms/create-geoms-for-silkscreen-rect.ts
30557
30591
  var import_primitives7 = __toESM(require_primitives(), 1);
30558
30592
  var import_extrusions6 = __toESM(require_extrusions(), 1);
30559
- var import_transforms6 = __toESM(require_transforms(), 1);
30593
+ var import_transforms7 = __toESM(require_transforms(), 1);
30560
30594
  var import_colors5 = __toESM(require_colors(), 1);
30561
30595
  var import_booleans3 = __toESM(require_booleans(), 1);
30562
30596
  var RECT_SEGMENTS = 64;
@@ -30611,14 +30645,14 @@ function createSilkscreenRectGeom(rect, ctx) {
30611
30645
  if (!rectGeom) return void 0;
30612
30646
  const layerSign = rect.layer === "bottom" ? -1 : 1;
30613
30647
  const zPos = layerSign * ctx.pcbThickness / 2 + layerSign * M * 1.5;
30614
- rectGeom = (0, import_transforms6.translate)([centerX, centerY, zPos], rectGeom);
30648
+ rectGeom = (0, import_transforms7.translate)([centerX, centerY, zPos], rectGeom);
30615
30649
  return (0, import_colors5.colorize)([1, 1, 1], rectGeom);
30616
30650
  }
30617
30651
 
30618
30652
  // src/geoms/create-geoms-for-silkscreen-circle.ts
30619
30653
  var import_primitives8 = __toESM(require_primitives(), 1);
30620
30654
  var import_extrusions7 = __toESM(require_extrusions(), 1);
30621
- var import_transforms7 = __toESM(require_transforms(), 1);
30655
+ var import_transforms8 = __toESM(require_transforms(), 1);
30622
30656
  var import_colors6 = __toESM(require_colors(), 1);
30623
30657
  var import_booleans4 = __toESM(require_booleans(), 1);
30624
30658
  var CIRCLE_SEGMENTS = 64;
@@ -30654,7 +30688,7 @@ function createSilkscreenCircleGeom(circleEl, ctx) {
30654
30688
  const filledCircle2d = (0, import_primitives8.circle)({ radius, segments: CIRCLE_SEGMENTS });
30655
30689
  circleGeom = (0, import_extrusions7.extrudeLinear)({ height: baseHeight }, filledCircle2d);
30656
30690
  }
30657
- const translatedGeom = (0, import_transforms7.translate)([centerX, centerY, zPos], circleGeom);
30691
+ const translatedGeom = (0, import_transforms8.translate)([centerX, centerY, zPos], circleGeom);
30658
30692
  return (0, import_colors6.colorize)([1, 1, 1], translatedGeom);
30659
30693
  }
30660
30694
 
@@ -30758,7 +30792,7 @@ var createCenteredRectPadGeom = (width10, height10, thickness, rectBorderRadius)
30758
30792
  segments: PAD_ROUNDED_SEGMENTS
30759
30793
  });
30760
30794
  const extruded = (0, import_extrusions8.extrudeLinear)({ height: thickness }, rect2d);
30761
- return (0, import_transforms8.translate)([0, 0, -thickness / 2], extruded);
30795
+ return (0, import_transforms9.translate)([0, 0, -thickness / 2], extruded);
30762
30796
  };
30763
30797
  var buildStateOrder = [
30764
30798
  "initializing",
@@ -31037,8 +31071,8 @@ var BoardGeomBuilder = class {
31037
31071
  segments: PAD_ROUNDED_SEGMENTS
31038
31072
  });
31039
31073
  cutoutGeom = (0, import_extrusions8.extrudeLinear)({ height: cutoutHeight }, rect2d);
31040
- cutoutGeom = (0, import_transforms8.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
31041
- cutoutGeom = (0, import_transforms8.translate)(
31074
+ cutoutGeom = (0, import_transforms9.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
31075
+ cutoutGeom = (0, import_transforms9.translate)(
31042
31076
  [cutout.center.x, cutout.center.y, 0],
31043
31077
  cutoutGeom
31044
31078
  );
@@ -31047,14 +31081,14 @@ var BoardGeomBuilder = class {
31047
31081
  center: [0, 0, 0],
31048
31082
  size: [cutout.width, cutout.height, cutoutHeight]
31049
31083
  });
31050
- cutoutGeom = (0, import_transforms8.translate)(
31084
+ cutoutGeom = (0, import_transforms9.translate)(
31051
31085
  [cutout.center.x, cutout.center.y, 0],
31052
31086
  baseCutoutGeom
31053
31087
  );
31054
31088
  }
31055
31089
  if (cutout.rotation) {
31056
31090
  const rotationRadians = cutout.rotation * Math.PI / 180;
31057
- cutoutGeom = (0, import_transforms8.rotateZ)(rotationRadians, cutoutGeom);
31091
+ cutoutGeom = (0, import_transforms9.rotateZ)(rotationRadians, cutoutGeom);
31058
31092
  }
31059
31093
  break;
31060
31094
  case "circle":
@@ -31077,7 +31111,7 @@ var BoardGeomBuilder = class {
31077
31111
  }
31078
31112
  const polygon2d = (0, import_primitives10.polygon)({ points: pointsVec2 });
31079
31113
  cutoutGeom = (0, import_extrusions8.extrudeLinear)({ height: cutoutHeight }, polygon2d);
31080
- cutoutGeom = (0, import_transforms8.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
31114
+ cutoutGeom = (0, import_transforms9.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
31081
31115
  break;
31082
31116
  }
31083
31117
  if (cutoutGeom) {
@@ -31096,15 +31130,15 @@ var BoardGeomBuilder = class {
31096
31130
  });
31097
31131
  if ("rotation" in pour && pour.rotation) {
31098
31132
  const rotationRadians = pour.rotation * Math.PI / 180;
31099
- baseGeom = (0, import_transforms8.rotateZ)(rotationRadians, baseGeom);
31133
+ baseGeom = (0, import_transforms9.rotateZ)(rotationRadians, baseGeom);
31100
31134
  }
31101
- pourGeom = (0, import_transforms8.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
31135
+ pourGeom = (0, import_transforms9.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
31102
31136
  } else if (pour.shape === "brep") {
31103
31137
  const brepShape = pour.brep_shape;
31104
31138
  if (brepShape && brepShape.outer_ring) {
31105
31139
  const pourGeom2 = createGeom2FromBRep(brepShape);
31106
31140
  pourGeom = (0, import_extrusions8.extrudeLinear)({ height: M }, pourGeom2);
31107
- pourGeom = (0, import_transforms8.translate)([0, 0, zPos], pourGeom);
31141
+ pourGeom = (0, import_transforms9.translate)([0, 0, zPos], pourGeom);
31108
31142
  }
31109
31143
  } else if (pour.shape === "polygon") {
31110
31144
  let pointsVec2 = pour.points.map((p) => [p.x, p.y]);
@@ -31119,7 +31153,7 @@ var BoardGeomBuilder = class {
31119
31153
  }
31120
31154
  const polygon2d = (0, import_primitives10.polygon)({ points: pointsVec2 });
31121
31155
  pourGeom = (0, import_extrusions8.extrudeLinear)({ height: M }, polygon2d);
31122
- pourGeom = (0, import_transforms8.translate)([0, 0, zPos], pourGeom);
31156
+ pourGeom = (0, import_transforms9.translate)([0, 0, zPos], pourGeom);
31123
31157
  }
31124
31158
  if (pourGeom) {
31125
31159
  if (this.boardClipGeom) {
@@ -31191,9 +31225,9 @@ var BoardGeomBuilder = class {
31191
31225
  );
31192
31226
  if (ph.ccw_rotation) {
31193
31227
  const rotationRadians = ph.ccw_rotation * Math.PI / 180;
31194
- pillHole = (0, import_transforms8.translate)(
31228
+ pillHole = (0, import_transforms9.translate)(
31195
31229
  [ph.x, ph.y, 0],
31196
- (0, import_transforms8.rotateZ)(rotationRadians, (0, import_transforms8.translate)([-ph.x, -ph.y, 0], pillHole))
31230
+ (0, import_transforms9.rotateZ)(rotationRadians, (0, import_transforms9.translate)([-ph.x, -ph.y, 0], pillHole))
31197
31231
  );
31198
31232
  }
31199
31233
  if (!opts.dontCutBoard) {
@@ -31343,7 +31377,7 @@ var BoardGeomBuilder = class {
31343
31377
  }
31344
31378
  if (isRotated) {
31345
31379
  const rotationRadians = hole.ccw_rotation * Math.PI / 180;
31346
- pillHole = (0, import_transforms8.rotateZ)(rotationRadians, pillHole);
31380
+ pillHole = (0, import_transforms9.rotateZ)(rotationRadians, pillHole);
31347
31381
  }
31348
31382
  this.boardGeom = (0, import_booleans6.subtract)(this.boardGeom, pillHole);
31349
31383
  this.padGeoms = this.padGeoms.map(
@@ -31366,7 +31400,7 @@ var BoardGeomBuilder = class {
31366
31400
  M,
31367
31401
  rectBorderRadius
31368
31402
  );
31369
- const positionedPadGeom = (0, import_transforms8.translate)([pad2.x, pad2.y, zPos], basePadGeom);
31403
+ const positionedPadGeom = (0, import_transforms9.translate)([pad2.x, pad2.y, zPos], basePadGeom);
31370
31404
  let finalPadGeom = positionedPadGeom;
31371
31405
  if (this.boardClipGeom) {
31372
31406
  finalPadGeom = (0, import_booleans6.intersect)(this.boardClipGeom, finalPadGeom);
@@ -31381,8 +31415,8 @@ var BoardGeomBuilder = class {
31381
31415
  rectBorderRadius
31382
31416
  );
31383
31417
  const rotationRadians = pad2.ccw_rotation * Math.PI / 180;
31384
- basePadGeom = (0, import_transforms8.rotateZ)(rotationRadians, basePadGeom);
31385
- const positionedPadGeom = (0, import_transforms8.translate)([pad2.x, pad2.y, zPos], basePadGeom);
31418
+ basePadGeom = (0, import_transforms9.rotateZ)(rotationRadians, basePadGeom);
31419
+ const positionedPadGeom = (0, import_transforms9.translate)([pad2.x, pad2.y, zPos], basePadGeom);
31386
31420
  let finalPadGeom = positionedPadGeom;
31387
31421
  if (this.boardClipGeom) {
31388
31422
  finalPadGeom = (0, import_booleans6.intersect)(this.boardClipGeom, finalPadGeom);
@@ -31417,7 +31451,7 @@ var BoardGeomBuilder = class {
31417
31451
  { delta: currentWidth / 2, corners: "round" },
31418
31452
  linePath
31419
31453
  );
31420
- let traceGeom = (0, import_transforms8.translate)(
31454
+ let traceGeom = (0, import_transforms9.translate)(
31421
31455
  [0, 0, zCenter - M / 2],
31422
31456
  (0, import_extrusions8.extrudeLinear)({ height: M }, expandedPath)
31423
31457
  );
@@ -31527,13 +31561,13 @@ var BoardGeomBuilder = class {
31527
31561
  );
31528
31562
  let textGeom;
31529
31563
  if (st.layer === "bottom") {
31530
- textGeom = (0, import_transforms8.translate)(
31564
+ textGeom = (0, import_transforms9.translate)(
31531
31565
  [0, 0, -this.ctx.pcbThickness / 2 - M],
31532
31566
  // Position above board
31533
31567
  (0, import_extrusions8.extrudeLinear)({ height: 0.012 }, expandedPath)
31534
31568
  );
31535
31569
  } else {
31536
- textGeom = (0, import_transforms8.translate)(
31570
+ textGeom = (0, import_transforms9.translate)(
31537
31571
  [0, 0, this.ctx.pcbThickness / 2 + M],
31538
31572
  // Position above board
31539
31573
  (0, import_extrusions8.extrudeLinear)({ height: 0.012 }, expandedPath)
@@ -31653,7 +31687,7 @@ var Text = ({
31653
31687
  parent,
31654
31688
  position,
31655
31689
  rotation: rotation2,
31656
- scale: scale2,
31690
+ scale: scale3,
31657
31691
  color,
31658
31692
  fontSize,
31659
31693
  anchorX,
@@ -31666,7 +31700,7 @@ var Text = ({
31666
31700
  textMesh.text = children;
31667
31701
  if (position) textMesh.position.fromArray(position);
31668
31702
  if (rotation2) textMesh.rotation.fromArray(rotation2);
31669
- if (scale2) textMesh.scale.fromArray(scale2);
31703
+ if (scale3) textMesh.scale.fromArray(scale3);
31670
31704
  textMesh.color = color || "white";
31671
31705
  textMesh.fontSize = fontSize || 1;
31672
31706
  textMesh.anchorX = anchorX || "center";
@@ -31679,7 +31713,7 @@ var Text = ({
31679
31713
  children,
31680
31714
  position,
31681
31715
  rotation2,
31682
- scale2,
31716
+ scale3,
31683
31717
  color,
31684
31718
  fontSize,
31685
31719
  anchorX,
@@ -33088,6 +33122,105 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
33088
33122
  geometry: threeGeom,
33089
33123
  color: COPPER_COLOR
33090
33124
  });
33125
+ } else if (ph.shape === "oval") {
33126
+ const holeW = ph.hole_width;
33127
+ const holeH = ph.hole_height;
33128
+ const outerW = ph.outer_width ?? holeW + 0.4;
33129
+ const outerH = ph.outer_height ?? holeH + 0.4;
33130
+ const drillW = holeW + 2 * MANIFOLD_Z_OFFSET;
33131
+ const drillH = holeH + 2 * MANIFOLD_Z_OFFSET;
33132
+ const drillDepth = pcbThickness * 1.2;
33133
+ let boardDrillPoints = createEllipsePoints(
33134
+ drillW,
33135
+ drillH,
33136
+ SMOOTH_CIRCLE_SEGMENTS
33137
+ );
33138
+ if (arePointsClockwise3(boardDrillPoints)) {
33139
+ boardDrillPoints = boardDrillPoints.reverse();
33140
+ }
33141
+ const boardDrillCrossSection = CrossSection.ofPolygons([boardDrillPoints]);
33142
+ manifoldInstancesForCleanup.push(boardDrillCrossSection);
33143
+ let boardDrillOp = Manifold.extrude(
33144
+ boardDrillCrossSection,
33145
+ drillDepth,
33146
+ 0,
33147
+ 0,
33148
+ [1, 1],
33149
+ true
33150
+ );
33151
+ manifoldInstancesForCleanup.push(boardDrillOp);
33152
+ if (ph.ccw_rotation) {
33153
+ const rotatedDrill = boardDrillOp.rotate([0, 0, ph.ccw_rotation]);
33154
+ manifoldInstancesForCleanup.push(rotatedDrill);
33155
+ boardDrillOp = rotatedDrill;
33156
+ }
33157
+ const translatedDrill = boardDrillOp.translate([ph.x, ph.y, 0]);
33158
+ manifoldInstancesForCleanup.push(translatedDrill);
33159
+ platedHoleBoardDrills.push(translatedDrill);
33160
+ const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
33161
+ let outerPoints = createEllipsePoints(
33162
+ outerW,
33163
+ outerH,
33164
+ SMOOTH_CIRCLE_SEGMENTS
33165
+ );
33166
+ if (arePointsClockwise3(outerPoints)) {
33167
+ outerPoints = outerPoints.reverse();
33168
+ }
33169
+ const outerCrossSection = CrossSection.ofPolygons([outerPoints]);
33170
+ manifoldInstancesForCleanup.push(outerCrossSection);
33171
+ let outerCopperOp = Manifold.extrude(
33172
+ outerCrossSection,
33173
+ copperPartThickness,
33174
+ 0,
33175
+ 0,
33176
+ [1, 1],
33177
+ true
33178
+ );
33179
+ manifoldInstancesForCleanup.push(outerCopperOp);
33180
+ let innerPoints = createEllipsePoints(
33181
+ holeW,
33182
+ holeH,
33183
+ SMOOTH_CIRCLE_SEGMENTS
33184
+ );
33185
+ if (arePointsClockwise3(innerPoints)) {
33186
+ innerPoints = innerPoints.reverse();
33187
+ }
33188
+ const innerCrossSection = CrossSection.ofPolygons([innerPoints]);
33189
+ manifoldInstancesForCleanup.push(innerCrossSection);
33190
+ let innerDrillOp = Manifold.extrude(
33191
+ innerCrossSection,
33192
+ copperPartThickness * 1.05,
33193
+ 0,
33194
+ 0,
33195
+ [1, 1],
33196
+ true
33197
+ );
33198
+ manifoldInstancesForCleanup.push(innerDrillOp);
33199
+ let finalPlatedPartOp = outerCopperOp.subtract(innerDrillOp);
33200
+ manifoldInstancesForCleanup.push(finalPlatedPartOp);
33201
+ if (ph.ccw_rotation) {
33202
+ const rotatedOp = finalPlatedPartOp.rotate([0, 0, ph.ccw_rotation]);
33203
+ manifoldInstancesForCleanup.push(rotatedOp);
33204
+ finalPlatedPartOp = rotatedOp;
33205
+ }
33206
+ const translatedPlatedPart = finalPlatedPartOp.translate([ph.x, ph.y, 0]);
33207
+ manifoldInstancesForCleanup.push(translatedPlatedPart);
33208
+ let finalCopperOp = translatedPlatedPart;
33209
+ if (boardClipVolume) {
33210
+ const clipped = Manifold.intersection([
33211
+ translatedPlatedPart,
33212
+ boardClipVolume
33213
+ ]);
33214
+ manifoldInstancesForCleanup.push(clipped);
33215
+ finalCopperOp = clipped;
33216
+ }
33217
+ platedHoleCopperOpsForSubtract.push(finalCopperOp);
33218
+ const threeGeom = manifoldMeshToThreeGeometry(finalCopperOp.getMesh());
33219
+ platedHoleCopperGeoms.push({
33220
+ key: `ph-${ph.pcb_plated_hole_id || index2}`,
33221
+ geometry: threeGeom,
33222
+ color: COPPER_COLOR
33223
+ });
33091
33224
  } else if (ph.shape === "circular_hole_with_rect_pad") {
33092
33225
  const holeOffsetX = ph.hole_offset_x || 0;
33093
33226
  const holeOffsetY = ph.hole_offset_y || 0;
@@ -36676,21 +36809,21 @@ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetPar
36676
36809
  }
36677
36810
  const clientRect = element.getBoundingClientRect();
36678
36811
  const domElement = unwrapElement(element);
36679
- let scale2 = createCoords(1);
36812
+ let scale3 = createCoords(1);
36680
36813
  if (includeScale) {
36681
36814
  if (offsetParent) {
36682
36815
  if (isElement(offsetParent)) {
36683
- scale2 = getScale(offsetParent);
36816
+ scale3 = getScale(offsetParent);
36684
36817
  }
36685
36818
  } else {
36686
- scale2 = getScale(element);
36819
+ scale3 = getScale(element);
36687
36820
  }
36688
36821
  }
36689
36822
  const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
36690
- let x = (clientRect.left + visualOffsets.x) / scale2.x;
36691
- let y = (clientRect.top + visualOffsets.y) / scale2.y;
36692
- let width10 = clientRect.width / scale2.x;
36693
- let height10 = clientRect.height / scale2.y;
36823
+ let x = (clientRect.left + visualOffsets.x) / scale3.x;
36824
+ let y = (clientRect.top + visualOffsets.y) / scale3.y;
36825
+ let width10 = clientRect.width / scale3.x;
36826
+ let height10 = clientRect.height / scale3.y;
36694
36827
  if (domElement) {
36695
36828
  const win = getWindow(domElement);
36696
36829
  const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
@@ -36752,7 +36885,7 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
36752
36885
  scrollLeft: 0,
36753
36886
  scrollTop: 0
36754
36887
  };
36755
- let scale2 = createCoords(1);
36888
+ let scale3 = createCoords(1);
36756
36889
  const offsets = createCoords(0);
36757
36890
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
36758
36891
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
@@ -36761,17 +36894,17 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
36761
36894
  }
36762
36895
  if (isHTMLElement(offsetParent)) {
36763
36896
  const offsetRect = getBoundingClientRect(offsetParent);
36764
- scale2 = getScale(offsetParent);
36897
+ scale3 = getScale(offsetParent);
36765
36898
  offsets.x = offsetRect.x + offsetParent.clientLeft;
36766
36899
  offsets.y = offsetRect.y + offsetParent.clientTop;
36767
36900
  }
36768
36901
  }
36769
36902
  const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
36770
36903
  return {
36771
- width: rect.width * scale2.x,
36772
- height: rect.height * scale2.y,
36773
- x: rect.x * scale2.x - scroll.scrollLeft * scale2.x + offsets.x + htmlOffset.x,
36774
- y: rect.y * scale2.y - scroll.scrollTop * scale2.y + offsets.y + htmlOffset.y
36904
+ width: rect.width * scale3.x,
36905
+ height: rect.height * scale3.y,
36906
+ x: rect.x * scale3.x - scroll.scrollLeft * scale3.x + offsets.x + htmlOffset.x,
36907
+ y: rect.y * scale3.y - scroll.scrollTop * scale3.y + offsets.y + htmlOffset.y
36775
36908
  };
36776
36909
  }
36777
36910
  function getClientRects(element) {
@@ -36838,11 +36971,11 @@ function getInnerBoundingClientRect(element, strategy) {
36838
36971
  const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
36839
36972
  const top = clientRect.top + element.clientTop;
36840
36973
  const left = clientRect.left + element.clientLeft;
36841
- const scale2 = isHTMLElement(element) ? getScale(element) : createCoords(1);
36842
- const width10 = element.clientWidth * scale2.x;
36843
- const height10 = element.clientHeight * scale2.y;
36844
- const x = left * scale2.x;
36845
- const y = top * scale2.y;
36974
+ const scale3 = isHTMLElement(element) ? getScale(element) : createCoords(1);
36975
+ const width10 = element.clientWidth * scale3.x;
36976
+ const height10 = element.clientHeight * scale3.y;
36977
+ const x = left * scale3.x;
36978
+ const y = top * scale3.y;
36846
36979
  return {
36847
36980
  width: width10,
36848
36981
  height: height10,
@@ -41440,8 +41573,8 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
41440
41573
  scene.position.sub(center);
41441
41574
  const maxDim = Math.max(size5.x, size5.y, size5.z);
41442
41575
  if (maxDim > 0) {
41443
- const scale2 = (1 - padding / 100) / maxDim;
41444
- scene.scale.multiplyScalar(scale2 * 100);
41576
+ const scale3 = (1 - padding / 100) / maxDim;
41577
+ scene.scale.multiplyScalar(scale3 * 100);
41445
41578
  }
41446
41579
  camera.updateProjectionMatrix();
41447
41580
  renderer.render(scene, camera);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.443",
3
+ "version": "0.0.444",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",