@tscircuit/3d-viewer 0.0.528 → 0.0.529

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 +234 -339
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -11357,7 +11357,7 @@ var require_unionGeom3 = __commonJS({
11357
11357
  var flatten = require_flatten();
11358
11358
  var retessellate = require_retessellate();
11359
11359
  var unionSub = require_unionGeom3Sub();
11360
- var union5 = (...geometries) => {
11360
+ var union4 = (...geometries) => {
11361
11361
  geometries = flatten(geometries);
11362
11362
  let i;
11363
11363
  for (i = 1; i < geometries.length; i += 2) {
@@ -11367,7 +11367,7 @@ var require_unionGeom3 = __commonJS({
11367
11367
  newgeometry = retessellate(newgeometry);
11368
11368
  return newgeometry;
11369
11369
  };
11370
- module.exports = union5;
11370
+ module.exports = union4;
11371
11371
  }
11372
11372
  });
11373
11373
 
@@ -11698,14 +11698,14 @@ var require_unionGeom2 = __commonJS({
11698
11698
  var fromFakePolygons = require_fromFakePolygons();
11699
11699
  var to3DWalls = require_to3DWalls();
11700
11700
  var unionGeom3 = require_unionGeom3();
11701
- var union5 = (...geometries) => {
11701
+ var union4 = (...geometries) => {
11702
11702
  geometries = flatten(geometries);
11703
11703
  const newgeometries = geometries.map((geometry) => to3DWalls({ z0: -1, z1: 1 }, geometry));
11704
11704
  const newgeom3 = unionGeom3(newgeometries);
11705
11705
  const epsilon = measureEpsilon(newgeom3);
11706
11706
  return fromFakePolygons(epsilon, geom3.toPolygons(newgeom3));
11707
11707
  };
11708
- module.exports = union5;
11708
+ module.exports = union4;
11709
11709
  }
11710
11710
  });
11711
11711
 
@@ -11719,7 +11719,7 @@ var require_union = __commonJS({
11719
11719
  var geom3 = require_geom3();
11720
11720
  var unionGeom2 = require_unionGeom2();
11721
11721
  var unionGeom3 = require_unionGeom3();
11722
- var union5 = (...geometries) => {
11722
+ var union4 = (...geometries) => {
11723
11723
  geometries = flatten(geometries);
11724
11724
  if (geometries.length === 0) throw new Error("wrong number of arguments");
11725
11725
  if (!areAllShapesTheSameType(geometries)) {
@@ -11730,7 +11730,7 @@ var require_union = __commonJS({
11730
11730
  if (geom3.isA(geometry)) return unionGeom3(geometries);
11731
11731
  return geometry;
11732
11732
  };
11733
- module.exports = union5;
11733
+ module.exports = union4;
11734
11734
  }
11735
11735
  });
11736
11736
 
@@ -12121,7 +12121,7 @@ var require_expandGeom3 = __commonJS({
12121
12121
  "node_modules/@jscad/modeling/src/operations/expansions/expandGeom3.js"(exports, module) {
12122
12122
  "use strict";
12123
12123
  var geom3 = require_geom3();
12124
- var union5 = require_union();
12124
+ var union4 = require_union();
12125
12125
  var expandShell = require_expandShell();
12126
12126
  var expandGeom3 = (options, geometry) => {
12127
12127
  const defaults = {
@@ -12137,7 +12137,7 @@ var require_expandGeom3 = __commonJS({
12137
12137
  if (polygons.length === 0) throw new Error("the given geometry cannot be empty");
12138
12138
  options = { delta, corners, segments };
12139
12139
  const expanded = expandShell(options, geometry);
12140
- return union5(geometry, expanded);
12140
+ return union4(geometry, expanded);
12141
12141
  };
12142
12142
  module.exports = expandGeom3;
12143
12143
  }
@@ -12831,7 +12831,7 @@ var require_hullChain = __commonJS({
12831
12831
  "node_modules/@jscad/modeling/src/operations/hulls/hullChain.js"(exports, module) {
12832
12832
  "use strict";
12833
12833
  var flatten = require_flatten();
12834
- var union5 = require_union();
12834
+ var union4 = require_union();
12835
12835
  var hull = require_hull();
12836
12836
  var hullChain = (...geometries) => {
12837
12837
  geometries = flatten(geometries);
@@ -12840,7 +12840,7 @@ var require_hullChain = __commonJS({
12840
12840
  for (let i = 1; i < geometries.length; i++) {
12841
12841
  hulls.push(hull(geometries[i - 1], geometries[i]));
12842
12842
  }
12843
- return union5(hulls);
12843
+ return union4(hulls);
12844
12844
  };
12845
12845
  module.exports = hullChain;
12846
12846
  }
@@ -14433,7 +14433,7 @@ var require_browser = __commonJS({
14433
14433
 
14434
14434
  // src/CadViewer.tsx
14435
14435
  import { useState as useState36, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect44 } from "react";
14436
- import * as THREE38 from "three";
14436
+ import * as THREE39 from "three";
14437
14437
 
14438
14438
  // src/CadViewerJscad.tsx
14439
14439
  import { su as su11 } from "@tscircuit/circuit-json-util";
@@ -28769,7 +28769,7 @@ import * as THREE16 from "three";
28769
28769
  // package.json
28770
28770
  var package_default = {
28771
28771
  name: "@tscircuit/3d-viewer",
28772
- version: "0.0.527",
28772
+ version: "0.0.528",
28773
28773
  main: "./dist/index.js",
28774
28774
  module: "./dist/index.js",
28775
28775
  type: "module",
@@ -28799,7 +28799,7 @@ var package_default = {
28799
28799
  "@jscad/regl-renderer": "^2.6.12",
28800
28800
  "@jscad/stl-serializer": "^2.1.20",
28801
28801
  "circuit-json": "^0.0.391",
28802
- "circuit-to-canvas": "^0.0.87",
28802
+ "circuit-to-canvas": "^0.0.89",
28803
28803
  "react-hot-toast": "^2.6.0",
28804
28804
  three: "^0.165.0",
28805
28805
  "three-stdlib": "^2.36.0",
@@ -30216,26 +30216,6 @@ function extractRectBorderRadius(source) {
30216
30216
  var PLATED_HOLE_DRILL_OVERREACH = 0.05;
30217
30217
  var RECT_PAD_SEGMENTS = 64;
30218
30218
  var maybeClip = (geom, clipGeom) => clipGeom ? (0, import_booleans2.intersect)(clipGeom, geom) : geom;
30219
- var createRectPadGeom = ({
30220
- width: width10,
30221
- height: height10,
30222
- thickness,
30223
- center,
30224
- borderRadius
30225
- }) => {
30226
- const clampedRadius = clampRectBorderRadius(width10, height10, borderRadius);
30227
- if (clampedRadius <= 0) {
30228
- return (0, import_primitives4.cuboid)({ center, size: [width10, height10, thickness] });
30229
- }
30230
- const rect2d = (0, import_primitives4.roundedRectangle)({
30231
- size: [width10, height10],
30232
- roundRadius: clampedRadius,
30233
- segments: RECT_PAD_SEGMENTS
30234
- });
30235
- const extruded = (0, import_extrusions3.extrudeLinear)({ height: thickness }, rect2d);
30236
- const offsetZ = center[2] - thickness / 2;
30237
- return (0, import_transforms4.translate)([center[0], center[1], offsetZ], extruded);
30238
- };
30239
30219
  var platedHole = (plated_hole, ctx, options = {}) => {
30240
30220
  const { clipGeom } = options;
30241
30221
  if (!plated_hole.shape) plated_hole.shape = "circle";
@@ -30243,9 +30223,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30243
30223
  const surfaceClearance = Math.max(ctx.pcbThickness * 3e-4, M / 20);
30244
30224
  const fillClearance = Math.max(ctx.pcbThickness * 25e-4, M / 4);
30245
30225
  const throughDrillHeight = ctx.pcbThickness + 2 * PLATED_HOLE_DRILL_OVERREACH + 4 * M;
30246
- const topSurfaceZ = ctx.pcbThickness / 2 + surfaceClearance + padThickness / 2;
30247
- const bottomSurfaceZ = -ctx.pcbThickness / 2 - surfaceClearance - padThickness / 2;
30248
- const copperSurfaceSpan = ctx.pcbThickness + 2 * surfaceClearance;
30249
30226
  const copperFillHeight = Math.max(
30250
30227
  ctx.pcbThickness - 2 * (padThickness + surfaceClearance + fillClearance),
30251
30228
  M
@@ -30253,7 +30230,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30253
30230
  const barrelHeight = Math.max(copperFillHeight, M);
30254
30231
  if (plated_hole.shape === "circle") {
30255
30232
  const outerDiameter = plated_hole.outer_diameter ?? Math.max(plated_hole.hole_diameter, 0);
30256
- const copperHeight = copperSurfaceSpan;
30233
+ const copperHeight = copperFillHeight;
30257
30234
  const copperBody = (0, import_primitives4.cylinder)({
30258
30235
  center: [plated_hole.x, plated_hole.y, 0],
30259
30236
  radius: outerDiameter / 2,
@@ -30276,7 +30253,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30276
30253
  const circle = (0, import_primitives4.cylinder)({
30277
30254
  center: [0, 0, 0],
30278
30255
  radius: 1,
30279
- height: copperSurfaceSpan,
30256
+ height: copperFillHeight,
30280
30257
  segments: 64
30281
30258
  // High segment count for smooth ellipse
30282
30259
  });
@@ -30308,22 +30285,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30308
30285
  const rectBorderRadius = extractRectBorderRadius(plated_hole);
30309
30286
  const copperSolid = maybeClip(
30310
30287
  (0, import_booleans2.union)(
30311
- // Top rectangular pad (thicker to ensure connection)
30312
- createRectPadGeom({
30313
- width: padWidth,
30314
- height: padHeight,
30315
- thickness: padThickness,
30316
- center: [plated_hole.x, plated_hole.y, topSurfaceZ],
30317
- borderRadius: rectBorderRadius
30318
- }),
30319
- // Bottom rectangular pad (thicker to ensure connection)
30320
- createRectPadGeom({
30321
- width: padWidth,
30322
- height: padHeight,
30323
- thickness: padThickness,
30324
- center: [plated_hole.x, plated_hole.y, bottomSurfaceZ],
30325
- borderRadius: rectBorderRadius
30326
- }),
30327
30288
  // Main copper fill between pads with rounded corners
30328
30289
  (() => {
30329
30290
  const rect2d = (0, import_primitives4.roundedRectangle)({
@@ -30385,7 +30346,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30385
30346
  const outerRadius = outerPillHeight / 2;
30386
30347
  const rectLength = Math.abs(holeWidth - holeHeight);
30387
30348
  const outerRectLength = Math.abs(outerPillWidth - outerPillHeight);
30388
- const copperHeight = copperSurfaceSpan;
30349
+ const copperHeight = copperFillHeight;
30389
30350
  const createPillSection = (width10, height10, thickness) => {
30390
30351
  const radius = height10 / 2;
30391
30352
  const length51 = Math.abs(width10 - height10);
@@ -30525,20 +30486,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30525
30486
  height: throughDrillHeight
30526
30487
  })
30527
30488
  );
30528
- const copperTopPad = createRectPadGeom({
30529
- width: padWidth,
30530
- height: padHeight,
30531
- thickness: padThickness,
30532
- center: [plated_hole.x, plated_hole.y, topSurfaceZ],
30533
- borderRadius: rectBorderRadius
30534
- });
30535
- const copperBottomPad = createRectPadGeom({
30536
- width: padWidth,
30537
- height: padHeight,
30538
- thickness: padThickness,
30539
- center: [plated_hole.x, plated_hole.y, bottomSurfaceZ],
30540
- borderRadius: rectBorderRadius
30541
- });
30542
30489
  const copperFill = (() => {
30543
30490
  const rect2d = (0, import_primitives4.roundedRectangle)({
30544
30491
  size: [padWidth, padHeight],
@@ -30551,8 +30498,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30551
30498
  extruded
30552
30499
  );
30553
30500
  })();
30554
- const copperTopPadCut = (0, import_booleans2.subtract)(copperTopPad, holeCut);
30555
- const copperBottomPadCut = (0, import_booleans2.subtract)(copperBottomPad, holeCut);
30556
30501
  const copperFillCut = (0, import_booleans2.subtract)(copperFill, holeCut);
30557
30502
  const barrelHoleCut = (0, import_booleans2.union)(
30558
30503
  (0, import_primitives4.cuboid)({
@@ -30588,7 +30533,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30588
30533
  );
30589
30534
  const barrelWithHole = (0, import_booleans2.subtract)(barrel, barrelHoleCut);
30590
30535
  const finalCopper = maybeClip(
30591
- (0, import_booleans2.union)(copperTopPadCut, copperBottomPadCut, copperFillCut, barrelWithHole),
30536
+ (0, import_booleans2.union)(copperFillCut, barrelWithHole),
30592
30537
  clipGeom
30593
30538
  );
30594
30539
  return (0, import_colors2.colorize)(colors.copper, finalCopper);
@@ -30672,24 +30617,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30672
30617
  })
30673
30618
  )
30674
30619
  );
30675
- const copperTopPad = rotateRectPad(
30676
- createRectPadGeom({
30677
- width: padWidth,
30678
- height: padHeight,
30679
- thickness: padThickness,
30680
- center: [plated_hole.x, plated_hole.y, topSurfaceZ],
30681
- borderRadius: rectBorderRadius
30682
- })
30683
- );
30684
- const copperBottomPad = rotateRectPad(
30685
- createRectPadGeom({
30686
- width: padWidth,
30687
- height: padHeight,
30688
- thickness: padThickness,
30689
- center: [plated_hole.x, plated_hole.y, bottomSurfaceZ],
30690
- borderRadius: rectBorderRadius
30691
- })
30692
- );
30693
30620
  const copperFill = rotateRectPad(
30694
30621
  (() => {
30695
30622
  const rect2d = (0, import_primitives4.roundedRectangle)({
@@ -30704,8 +30631,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30704
30631
  );
30705
30632
  })()
30706
30633
  );
30707
- const copperTopPadCut = (0, import_booleans2.subtract)(copperTopPad, holeCut);
30708
- const copperBottomPadCut = (0, import_booleans2.subtract)(copperBottomPad, holeCut);
30709
30634
  const copperFillCut = (0, import_booleans2.subtract)(copperFill, holeCut);
30710
30635
  const barrelHoleCut = rotateHole(
30711
30636
  (0, import_booleans2.union)(
@@ -30727,7 +30652,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30727
30652
  );
30728
30653
  const barrelWithHole = (0, import_booleans2.subtract)(barrel, barrelHoleCut);
30729
30654
  const finalCopper = maybeClip(
30730
- (0, import_booleans2.union)(copperTopPadCut, copperBottomPadCut, copperFillCut, barrelWithHole),
30655
+ (0, import_booleans2.union)(copperFillCut, barrelWithHole),
30731
30656
  clipGeom
30732
30657
  );
30733
30658
  return (0, import_colors2.colorize)(colors.copper, finalCopper);
@@ -30753,9 +30678,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
30753
30678
  );
30754
30679
  };
30755
30680
  const mainFill = createPolygonPad(copperFillHeight, centerZ);
30756
- const topPad = createPolygonPad(padThickness, topSurfaceZ);
30757
- const bottomPad = createPolygonPad(padThickness, bottomSurfaceZ);
30758
- const copperSolid = maybeClip((0, import_booleans2.union)(mainFill, topPad, bottomPad), clipGeom);
30681
+ const copperSolid = maybeClip(mainFill, clipGeom);
30759
30682
  const barrel = createHoleWithPolygonPadHoleGeom(plated_hole, barrelHeight);
30760
30683
  if (!barrel) return (0, import_colors2.colorize)(colors.copper, copperSolid);
30761
30684
  const drill = createHoleWithPolygonPadHoleGeom(plated_hole, throughDrillHeight, {
@@ -30789,7 +30712,6 @@ function createViaCopper({
30789
30712
  `Invalid via geometry: outerDiameter (${outerDiameter}) must be > holeDiameter (${holeDiameter})`
30790
30713
  );
30791
30714
  }
30792
- const padThickness = M;
30793
30715
  const platingThickness = M;
30794
30716
  const barrelRadius = Math.min(
30795
30717
  outerDiameter / 2,
@@ -30801,20 +30723,8 @@ function createViaCopper({
30801
30723
  height: thickness,
30802
30724
  segments: SMOOTH_CIRCLE_SEGMENTS
30803
30725
  });
30804
- const topPad = (0, import_primitives5.cylinder)({
30805
- center: [0, 0, thickness / 2],
30806
- radius: outerDiameter / 2,
30807
- height: padThickness,
30808
- segments: SMOOTH_CIRCLE_SEGMENTS
30809
- });
30810
- const bottomPad = (0, import_primitives5.cylinder)({
30811
- center: [0, 0, -thickness / 2],
30812
- radius: outerDiameter / 2,
30813
- height: padThickness,
30814
- segments: SMOOTH_CIRCLE_SEGMENTS
30815
- });
30816
- const viaSolid = (0, import_booleans3.union)([barrel, topPad, bottomPad]);
30817
- const drillHeight = thickness + padThickness * 2;
30726
+ const viaSolid = barrel;
30727
+ const drillHeight = thickness + 2 * M;
30818
30728
  const drill = (0, import_primitives5.cylinder)({
30819
30729
  center: [0, 0, 0],
30820
30730
  radius: holeDiameter / 2,
@@ -31738,7 +31648,7 @@ import { su as su8 } from "@tscircuit/circuit-json-util";
31738
31648
  import { useEffect as useEffect23, useMemo as useMemo19 } from "react";
31739
31649
 
31740
31650
  // src/textures/create-combined-board-textures.ts
31741
- import * as THREE27 from "three";
31651
+ import * as THREE28 from "three";
31742
31652
 
31743
31653
  // node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
31744
31654
  var getBoundsFromPoints = (points) => {
@@ -32906,6 +32816,109 @@ function createSoldermaskTextureForLayer({
32906
32816
  return texture;
32907
32817
  }
32908
32818
 
32819
+ // src/textures/create-through-hole-texture-for-layer.ts
32820
+ import * as THREE27 from "three";
32821
+
32822
+ // src/textures/through-hole/through-hole-drawing.ts
32823
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
32824
+ var setDrawerBounds6 = (drawer, bounds) => {
32825
+ drawer.setCameraBounds({
32826
+ minX: bounds.minX,
32827
+ maxX: bounds.maxX,
32828
+ minY: bounds.minY,
32829
+ maxY: bounds.maxY
32830
+ });
32831
+ };
32832
+ var drawThroughHoleLayer = ({
32833
+ ctx,
32834
+ layer,
32835
+ bounds,
32836
+ elements,
32837
+ copperColor
32838
+ }) => {
32839
+ const renderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32840
+ const transparent = "rgba(0,0,0,0)";
32841
+ const drawer = new CircuitToCanvasDrawer6(ctx);
32842
+ drawer.configure({
32843
+ colorOverrides: {
32844
+ copper: {
32845
+ top: copperColor,
32846
+ bottom: copperColor,
32847
+ inner1: copperColor,
32848
+ inner2: copperColor,
32849
+ inner3: copperColor,
32850
+ inner4: copperColor,
32851
+ inner5: copperColor,
32852
+ inner6: copperColor
32853
+ },
32854
+ drill: transparent,
32855
+ boardOutline: transparent,
32856
+ substrate: transparent,
32857
+ keepout: transparent,
32858
+ fabricationNote: transparent,
32859
+ silkscreen: { top: transparent, bottom: transparent },
32860
+ courtyard: { top: transparent, bottom: transparent },
32861
+ soldermask: { top: transparent, bottom: transparent },
32862
+ soldermaskWithCopperUnderneath: {
32863
+ top: transparent,
32864
+ bottom: transparent
32865
+ },
32866
+ soldermaskOverCopper: {
32867
+ top: transparent,
32868
+ bottom: transparent
32869
+ }
32870
+ }
32871
+ });
32872
+ setDrawerBounds6(drawer, bounds);
32873
+ drawer.drawElements(elements, {
32874
+ layers: [renderLayer]
32875
+ });
32876
+ };
32877
+
32878
+ // src/textures/create-through-hole-texture-for-layer.ts
32879
+ function createThroughHoleTextureForLayer({
32880
+ layer,
32881
+ circuitJson,
32882
+ boardData,
32883
+ copperColor = "rgb(230, 153, 51)",
32884
+ traceTextureResolution = TRACE_TEXTURE_RESOLUTION
32885
+ }) {
32886
+ const elements = circuitJson.filter((element) => {
32887
+ if (element.type === "pcb_via") return true;
32888
+ if (element.type !== "pcb_plated_hole") return false;
32889
+ const platedHole2 = element;
32890
+ return !Array.isArray(platedHole2.layers) || platedHole2.layers.includes(layer);
32891
+ });
32892
+ if (elements.length === 0) return null;
32893
+ const bounds = calculateOutlineBounds(boardData);
32894
+ const canvasWidth = Math.floor(bounds.width * traceTextureResolution);
32895
+ const canvasHeight = Math.floor(bounds.height * traceTextureResolution);
32896
+ if (canvasWidth <= 0 || canvasHeight <= 0) return null;
32897
+ const canvas = document.createElement("canvas");
32898
+ canvas.width = canvasWidth;
32899
+ canvas.height = canvasHeight;
32900
+ const ctx = canvas.getContext("2d");
32901
+ if (!ctx) return null;
32902
+ if (layer === "bottom") {
32903
+ ctx.translate(0, canvasHeight);
32904
+ ctx.scale(1, -1);
32905
+ }
32906
+ drawThroughHoleLayer({
32907
+ ctx,
32908
+ layer,
32909
+ bounds,
32910
+ elements,
32911
+ copperColor
32912
+ });
32913
+ const texture = new THREE27.CanvasTexture(canvas);
32914
+ texture.generateMipmaps = true;
32915
+ texture.minFilter = THREE27.LinearMipmapLinearFilter;
32916
+ texture.magFilter = THREE27.LinearFilter;
32917
+ texture.anisotropy = 16;
32918
+ texture.needsUpdate = true;
32919
+ return texture;
32920
+ }
32921
+
32909
32922
  // src/textures/create-combined-board-textures.ts
32910
32923
  var toRgb2 = (colorArr) => {
32911
32924
  const [r = 0, g = 0, b = 0] = colorArr;
@@ -32938,10 +32951,10 @@ var createCombinedTexture = ({
32938
32951
  const image = texture.image;
32939
32952
  ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
32940
32953
  });
32941
- const combinedTexture = new THREE27.CanvasTexture(canvas);
32954
+ const combinedTexture = new THREE28.CanvasTexture(canvas);
32942
32955
  combinedTexture.generateMipmaps = false;
32943
- combinedTexture.minFilter = THREE27.LinearFilter;
32944
- combinedTexture.magFilter = THREE27.LinearFilter;
32956
+ combinedTexture.minFilter = THREE28.LinearFilter;
32957
+ combinedTexture.magFilter = THREE28.LinearFilter;
32945
32958
  combinedTexture.premultiplyAlpha = true;
32946
32959
  combinedTexture.anisotropy = 16;
32947
32960
  combinedTexture.needsUpdate = true;
@@ -32989,6 +33002,13 @@ function createCombinedBoardTextures({
32989
33002
  copperColor,
32990
33003
  traceTextureResolution
32991
33004
  }) : null;
33005
+ const throughHoleTexture = showCopper ? createThroughHoleTextureForLayer({
33006
+ layer,
33007
+ circuitJson,
33008
+ boardData,
33009
+ copperColor,
33010
+ traceTextureResolution
33011
+ }) : null;
32992
33012
  const silkscreenTexture = showSilkscreen ? createSilkscreenTextureForLayer({
32993
33013
  layer,
32994
33014
  circuitJson,
@@ -33019,6 +33039,7 @@ function createCombinedBoardTextures({
33019
33039
  textures: [
33020
33040
  traceTexture,
33021
33041
  padTexture,
33042
+ throughHoleTexture,
33022
33043
  soldermaskTexture,
33023
33044
  copperTextTexture,
33024
33045
  silkscreenTexture,
@@ -33038,15 +33059,15 @@ function createCombinedBoardTextures({
33038
33059
  }
33039
33060
 
33040
33061
  // src/textures/create-copper-pour-texture-for-layer.ts
33041
- import * as THREE28 from "three";
33042
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
33062
+ import * as THREE29 from "three";
33063
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
33043
33064
 
33044
33065
  // src/geoms/brep-converter.ts
33045
33066
  var import_primitives7 = __toESM(require_primitives(), 1);
33046
33067
  var import_booleans5 = __toESM(require_booleans(), 1);
33047
33068
 
33048
33069
  // src/textures/create-three-texture-meshes.ts
33049
- import * as THREE29 from "three";
33070
+ import * as THREE30 from "three";
33050
33071
  function createTexturePlane(config, boardData) {
33051
33072
  const {
33052
33073
  texture,
@@ -33058,15 +33079,15 @@ function createTexturePlane(config, boardData) {
33058
33079
  } = config;
33059
33080
  if (!texture) return null;
33060
33081
  const boardOutlineBounds = calculateOutlineBounds(boardData);
33061
- const planeGeom = new THREE29.PlaneGeometry(
33082
+ const planeGeom = new THREE30.PlaneGeometry(
33062
33083
  boardOutlineBounds.width,
33063
33084
  boardOutlineBounds.height
33064
33085
  );
33065
- const material = new THREE29.MeshBasicMaterial({
33086
+ const material = new THREE30.MeshBasicMaterial({
33066
33087
  map: texture,
33067
33088
  transparent: true,
33068
33089
  alphaTest: 0.08,
33069
- side: THREE29.DoubleSide,
33090
+ side: THREE30.DoubleSide,
33070
33091
  depthWrite: true,
33071
33092
  polygonOffset: usePolygonOffset,
33072
33093
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -33074,7 +33095,7 @@ function createTexturePlane(config, boardData) {
33074
33095
  polygonOffsetUnits: usePolygonOffset ? -4 : 0,
33075
33096
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
33076
33097
  });
33077
- const mesh = new THREE29.Mesh(planeGeom, material);
33098
+ const mesh = new THREE30.Mesh(planeGeom, material);
33078
33099
  mesh.position.set(
33079
33100
  boardOutlineBounds.centerX,
33080
33101
  boardOutlineBounds.centerY,
@@ -33119,7 +33140,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
33119
33140
  }
33120
33141
 
33121
33142
  // src/three-components/JscadBoardTextures.tsx
33122
- import * as THREE30 from "three";
33143
+ import * as THREE31 from "three";
33123
33144
 
33124
33145
  // src/utils/layer-texture-resolution.ts
33125
33146
  var DEFAULT_MAX_TEXTURE_PIXELS = 4e6;
@@ -33215,7 +33236,7 @@ function JscadBoardTextures({
33215
33236
  const typedMaterial = material;
33216
33237
  for (const prop of textureProps) {
33217
33238
  const texture = typedMaterial[prop];
33218
- if (texture && texture instanceof THREE30.Texture) {
33239
+ if (texture && texture instanceof THREE31.Texture) {
33219
33240
  texture.dispose();
33220
33241
  typedMaterial[prop] = null;
33221
33242
  }
@@ -33225,22 +33246,22 @@ function JscadBoardTextures({
33225
33246
  const createTexturePlane2 = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false, depthWrite = true, renderOrder = 1) => {
33226
33247
  if (!texture) return null;
33227
33248
  const boardOutlineBounds = calculateOutlineBounds(boardData);
33228
- const planeGeom = new THREE30.PlaneGeometry(
33249
+ const planeGeom = new THREE31.PlaneGeometry(
33229
33250
  boardOutlineBounds.width,
33230
33251
  boardOutlineBounds.height
33231
33252
  );
33232
- const material = new THREE30.MeshBasicMaterial({
33253
+ const material = new THREE31.MeshBasicMaterial({
33233
33254
  map: texture,
33234
33255
  transparent: true,
33235
33256
  alphaTest: 0.08,
33236
- side: THREE30.DoubleSide,
33257
+ side: THREE31.DoubleSide,
33237
33258
  depthWrite,
33238
33259
  polygonOffset: usePolygonOffset,
33239
33260
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
33240
33261
  polygonOffsetUnits: usePolygonOffset ? -4 : 0,
33241
33262
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
33242
33263
  });
33243
- const mesh = new THREE30.Mesh(planeGeom, material);
33264
+ const mesh = new THREE31.Mesh(planeGeom, material);
33244
33265
  mesh.position.set(
33245
33266
  boardOutlineBounds.centerX,
33246
33267
  boardOutlineBounds.centerY,
@@ -33285,7 +33306,7 @@ function JscadBoardTextures({
33285
33306
  mesh.geometry.dispose();
33286
33307
  if (Array.isArray(mesh.material)) {
33287
33308
  mesh.material.forEach((material) => disposeTextureMaterial(material));
33288
- } else if (mesh.material instanceof THREE30.Material) {
33309
+ } else if (mesh.material instanceof THREE31.Material) {
33289
33310
  disposeTextureMaterial(mesh.material);
33290
33311
  }
33291
33312
  });
@@ -33518,12 +33539,12 @@ var CadViewerJscad = forwardRef3(
33518
33539
  // src/CadViewerManifold.tsx
33519
33540
  import { su as su17 } from "@tscircuit/circuit-json-util";
33520
33541
  import { useEffect as useEffect25, useMemo as useMemo22, useState as useState16 } from "react";
33521
- import * as THREE37 from "three";
33542
+ import * as THREE38 from "three";
33522
33543
 
33523
33544
  // src/hooks/useManifoldBoardBuilder.ts
33524
33545
  import { su as su16 } from "@tscircuit/circuit-json-util";
33525
33546
  import { useEffect as useEffect24, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33526
- import * as THREE34 from "three";
33547
+ import * as THREE35 from "three";
33527
33548
 
33528
33549
  // src/utils/manifold/create-manifold-board.ts
33529
33550
  var arePointsClockwise2 = (points) => {
@@ -33865,17 +33886,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
33865
33886
 
33866
33887
  // src/utils/manifold/process-plated-holes.ts
33867
33888
  import { su as su14 } from "@tscircuit/circuit-json-util";
33868
- import * as THREE32 from "three";
33889
+ import * as THREE33 from "three";
33869
33890
 
33870
33891
  // src/utils/manifold-mesh-to-three-geometry.ts
33871
- import * as THREE31 from "three";
33892
+ import * as THREE32 from "three";
33872
33893
  function manifoldMeshToThreeGeometry(manifoldMesh) {
33873
- const geometry = new THREE31.BufferGeometry();
33894
+ const geometry = new THREE32.BufferGeometry();
33874
33895
  geometry.setAttribute(
33875
33896
  "position",
33876
- new THREE31.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
33897
+ new THREE32.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
33877
33898
  );
33878
- geometry.setIndex(new THREE31.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
33899
+ geometry.setIndex(new THREE32.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
33879
33900
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
33880
33901
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
33881
33902
  const start = manifoldMesh.runIndex[i];
@@ -33909,7 +33930,7 @@ var createEllipsePoints = (width10, height10, segments) => {
33909
33930
  }
33910
33931
  return points;
33911
33932
  };
33912
- var COPPER_COLOR = new THREE32.Color(...colors.copper);
33933
+ var COPPER_COLOR = new THREE33.Color(...colors.copper);
33913
33934
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
33914
33935
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
33915
33936
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -34011,6 +34032,10 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34011
34032
  return holeOp;
34012
34033
  };
34013
34034
  pcbPlatedHoles.forEach((ph, index2) => {
34035
+ const internalCopperThickness = Math.max(
34036
+ pcbThickness - 2 * (PLATED_HOLE_PAD_THICKNESS + PLATED_HOLE_SURFACE_CLEARANCE + PLATED_HOLE_FILL_CLEARANCE),
34037
+ M
34038
+ );
34014
34039
  if (ph.shape === "circle") {
34015
34040
  const translatedDrill = createPlatedHoleDrill({
34016
34041
  Manifold,
@@ -34023,7 +34048,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34023
34048
  });
34024
34049
  manifoldInstancesForCleanup.push(translatedDrill);
34025
34050
  platedHoleBoardDrills.push(translatedDrill);
34026
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34051
+ const copperPartThickness = internalCopperThickness;
34027
34052
  const platedPart = Manifold.cylinder(
34028
34053
  copperPartThickness,
34029
34054
  ph.outer_diameter / 2,
@@ -34083,7 +34108,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34083
34108
  ]);
34084
34109
  manifoldInstancesForCleanup.push(translatedBoardPillDrill);
34085
34110
  platedHoleBoardDrills.push(translatedBoardPillDrill);
34086
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34111
+ const copperPartThickness = internalCopperThickness;
34087
34112
  const outerCopperOpUnrotated = createPillOp(
34088
34113
  outerW,
34089
34114
  outerH,
@@ -34161,29 +34186,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34161
34186
  borderRadius: rectBorderRadius
34162
34187
  });
34163
34188
  manifoldInstancesForCleanup.push(mainFill);
34164
- const topPad = createRoundedRectPrism({
34165
- Manifold,
34166
- width: padWidth,
34167
- height: padHeight,
34168
- thickness: padThickness,
34169
- borderRadius: rectBorderRadius
34170
- }).translate([
34171
- 0,
34172
- 0,
34173
- pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
34174
- ]);
34175
- const bottomPad = createRoundedRectPrism({
34176
- Manifold,
34177
- width: padWidth,
34178
- height: padHeight,
34179
- thickness: padThickness,
34180
- borderRadius: rectBorderRadius
34181
- }).translate([
34182
- 0,
34183
- 0,
34184
- -pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
34185
- ]);
34186
- manifoldInstancesForCleanup.push(topPad, bottomPad);
34187
34189
  const barrelPill = createPillOp(
34188
34190
  holeW,
34189
34191
  holeH,
@@ -34191,12 +34193,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34191
34193
  // Slightly shorter than board
34192
34194
  ).translate([holeOffsetX, holeOffsetY, 0]);
34193
34195
  manifoldInstancesForCleanup.push(barrelPill);
34194
- const copperUnion = Manifold.union([
34195
- mainFill,
34196
- topPad,
34197
- bottomPad,
34198
- barrelPill
34199
- ]);
34196
+ const copperUnion = Manifold.union([mainFill, barrelPill]);
34200
34197
  manifoldInstancesForCleanup.push(copperUnion);
34201
34198
  const holeCutOp = createPillOp(
34202
34199
  Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
@@ -34276,39 +34273,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34276
34273
  manifoldInstancesForCleanup.push(rotatedMainFill);
34277
34274
  mainFill = rotatedMainFill;
34278
34275
  }
34279
- let topPad = createRoundedRectPrism({
34280
- Manifold,
34281
- width: padWidth,
34282
- height: padHeight,
34283
- thickness: padThickness,
34284
- borderRadius: rectBorderRadius
34285
- }).translate([
34286
- 0,
34287
- 0,
34288
- pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
34289
- ]);
34290
- if (ph.rect_ccw_rotation) {
34291
- const rotatedTopPad = topPad.rotate([0, 0, ph.rect_ccw_rotation]);
34292
- manifoldInstancesForCleanup.push(rotatedTopPad);
34293
- topPad = rotatedTopPad;
34294
- }
34295
- let bottomPad = createRoundedRectPrism({
34296
- Manifold,
34297
- width: padWidth,
34298
- height: padHeight,
34299
- thickness: padThickness,
34300
- borderRadius: rectBorderRadius
34301
- }).translate([
34302
- 0,
34303
- 0,
34304
- -pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
34305
- ]);
34306
- if (ph.rect_ccw_rotation) {
34307
- const rotatedBottomPad = bottomPad.rotate([0, 0, ph.rect_ccw_rotation]);
34308
- manifoldInstancesForCleanup.push(rotatedBottomPad);
34309
- bottomPad = rotatedBottomPad;
34310
- }
34311
- manifoldInstancesForCleanup.push(topPad, bottomPad);
34312
34276
  let barrelPill = createPillOp(
34313
34277
  holeW,
34314
34278
  holeH,
@@ -34321,12 +34285,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34321
34285
  barrelPill = rotatedBarrel;
34322
34286
  }
34323
34287
  manifoldInstancesForCleanup.push(barrelPill);
34324
- const copperUnion = Manifold.union([
34325
- mainFill,
34326
- topPad,
34327
- bottomPad,
34328
- barrelPill
34329
- ]);
34288
+ const copperUnion = Manifold.union([mainFill, barrelPill]);
34330
34289
  manifoldInstancesForCleanup.push(copperUnion);
34331
34290
  let holeCutOp = createPillOp(
34332
34291
  Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
@@ -34383,23 +34342,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34383
34342
  padOutline,
34384
34343
  thickness: fillThickness
34385
34344
  });
34386
- const topPad = createPolygonPadOp({ padOutline, thickness: padThickness });
34387
- const bottomPad = createPolygonPadOp({
34388
- padOutline,
34389
- thickness: padThickness
34390
- });
34391
- if (!mainFill || !topPad || !bottomPad) return;
34392
- const topTranslated = topPad.translate([
34393
- 0,
34394
- 0,
34395
- pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
34396
- ]);
34397
- const bottomTranslated = bottomPad.translate([
34398
- 0,
34399
- 0,
34400
- -pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
34401
- ]);
34402
- manifoldInstancesForCleanup.push(topTranslated, bottomTranslated);
34345
+ if (!mainFill) return;
34403
34346
  const barrelOp = createHoleOpForPolygonPad({
34404
34347
  ph,
34405
34348
  depth: pcbThickness * 1.02
@@ -34410,12 +34353,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34410
34353
  depth: pcbThickness * 0.8,
34411
34354
  sizeDelta: -2 * M
34412
34355
  }) || barrelOp;
34413
- const copperUnion = Manifold.union([
34414
- mainFill,
34415
- topTranslated,
34416
- bottomTranslated,
34417
- barrelOp
34418
- ]);
34356
+ const copperUnion = Manifold.union([mainFill, barrelOp]);
34419
34357
  manifoldInstancesForCleanup.push(copperUnion);
34420
34358
  const finalCopper = copperUnion.subtract(holeCutOp);
34421
34359
  manifoldInstancesForCleanup.push(finalCopper);
@@ -34472,7 +34410,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34472
34410
  const translatedDrill = boardDrillOp.translate([ph.x, ph.y, 0]);
34473
34411
  manifoldInstancesForCleanup.push(translatedDrill);
34474
34412
  platedHoleBoardDrills.push(translatedDrill);
34475
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34413
+ const copperPartThickness = internalCopperThickness;
34476
34414
  let outerPoints = createEllipsePoints(
34477
34415
  outerW,
34478
34416
  outerH,
@@ -34571,29 +34509,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34571
34509
  borderRadius: rectBorderRadius
34572
34510
  });
34573
34511
  manifoldInstancesForCleanup.push(mainFill);
34574
- const topPad = createRoundedRectPrism({
34575
- Manifold,
34576
- width: padWidth,
34577
- height: padHeight,
34578
- thickness: padThickness,
34579
- borderRadius: rectBorderRadius
34580
- }).translate([
34581
- 0,
34582
- 0,
34583
- pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
34584
- ]);
34585
- const bottomPad = createRoundedRectPrism({
34586
- Manifold,
34587
- width: padWidth,
34588
- height: padHeight,
34589
- thickness: padThickness,
34590
- borderRadius: rectBorderRadius
34591
- }).translate([
34592
- 0,
34593
- 0,
34594
- -pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
34595
- ]);
34596
- manifoldInstancesForCleanup.push(topPad, bottomPad);
34597
34512
  const barrelCylinder = Manifold.cylinder(
34598
34513
  pcbThickness * 0.8,
34599
34514
  // Slightly taller than board
@@ -34603,12 +34518,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34603
34518
  true
34604
34519
  ).translate([holeOffsetX, holeOffsetY, 0]);
34605
34520
  manifoldInstancesForCleanup.push(barrelCylinder);
34606
- const copperUnion = Manifold.union([
34607
- mainFill,
34608
- topPad,
34609
- bottomPad,
34610
- barrelCylinder
34611
- ]);
34521
+ const copperUnion = Manifold.union([mainFill, barrelCylinder]);
34612
34522
  manifoldInstancesForCleanup.push(copperUnion);
34613
34523
  const holeDrill = Manifold.cylinder(
34614
34524
  pcbThickness * 1.2,
@@ -34651,7 +34561,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34651
34561
 
34652
34562
  // src/utils/manifold/process-vias.ts
34653
34563
  import { su as su15 } from "@tscircuit/circuit-json-util";
34654
- import * as THREE33 from "three";
34564
+ import * as THREE34 from "three";
34655
34565
 
34656
34566
  // src/utils/via-geoms.ts
34657
34567
  function createViaCopper2({
@@ -34664,7 +34574,6 @@ function createViaCopper2({
34664
34574
  zOffset = 1e-3,
34665
34575
  segments = 32
34666
34576
  }) {
34667
- const padThickness = zOffset;
34668
34577
  const platingThickness = zOffset;
34669
34578
  if (outerDiameter < holeDiameter) {
34670
34579
  throw new Error(
@@ -34676,22 +34585,8 @@ function createViaCopper2({
34676
34585
  holeDiameter / 2 + platingThickness
34677
34586
  );
34678
34587
  const barrel = Manifold.cylinder(thickness, barrelRadius, -1, segments, true);
34679
- const topPad = Manifold.cylinder(
34680
- padThickness,
34681
- outerDiameter / 2,
34682
- -1,
34683
- segments,
34684
- true
34685
- ).translate([0, 0, thickness / 2]);
34686
- const bottomPad = Manifold.cylinder(
34687
- padThickness,
34688
- outerDiameter / 2,
34689
- -1,
34690
- segments,
34691
- true
34692
- ).translate([0, 0, -thickness / 2]);
34693
- const viaSolid = Manifold.union([barrel, topPad, bottomPad]);
34694
- const drillHeight = thickness + padThickness * 2;
34588
+ const viaSolid = barrel;
34589
+ const drillHeight = thickness + 2 * zOffset;
34695
34590
  const drill = Manifold.cylinder(
34696
34591
  drillHeight,
34697
34592
  holeDiameter / 2,
@@ -34704,7 +34599,7 @@ function createViaCopper2({
34704
34599
  }
34705
34600
 
34706
34601
  // src/utils/manifold/process-vias.ts
34707
- var COPPER_COLOR2 = new THREE33.Color(...colors.copper);
34602
+ var COPPER_COLOR2 = new THREE34.Color(...colors.copper);
34708
34603
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
34709
34604
  const viaBoardDrills = [];
34710
34605
  const pcbVias = su15(circuitJson).pcb_via.list();
@@ -34924,7 +34819,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34924
34819
  {
34925
34820
  key: "plated-holes-union",
34926
34821
  geometry: cutPlatedGeom,
34927
- color: new THREE34.Color(
34822
+ color: new THREE35.Color(
34928
34823
  colors.copper[0],
34929
34824
  colors.copper[1],
34930
34825
  colors.copper[2]
@@ -34954,7 +34849,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34954
34849
  const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Tan;
34955
34850
  currentGeoms.board = {
34956
34851
  geometry: finalBoardGeom,
34957
- color: new THREE34.Color(
34852
+ color: new THREE35.Color(
34958
34853
  matColorArray[0],
34959
34854
  matColorArray[1],
34960
34855
  matColorArray[2]
@@ -34999,11 +34894,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34999
34894
  };
35000
34895
 
35001
34896
  // src/utils/manifold/create-three-geometry-meshes.ts
35002
- import * as THREE36 from "three";
34897
+ import * as THREE37 from "three";
35003
34898
 
35004
34899
  // src/utils/create-board-material.ts
35005
- import * as THREE35 from "three";
35006
- var DEFAULT_SIDE = THREE35.DoubleSide;
34900
+ import * as THREE36 from "three";
34901
+ var DEFAULT_SIDE = THREE36.DoubleSide;
35007
34902
  var createBoardMaterial = ({
35008
34903
  material,
35009
34904
  color,
@@ -35011,7 +34906,7 @@ var createBoardMaterial = ({
35011
34906
  isFaux = false
35012
34907
  }) => {
35013
34908
  if (material === "fr4") {
35014
- return new THREE35.MeshPhysicalMaterial({
34909
+ return new THREE36.MeshPhysicalMaterial({
35015
34910
  color,
35016
34911
  side,
35017
34912
  metalness: 0,
@@ -35028,7 +34923,7 @@ var createBoardMaterial = ({
35028
34923
  polygonOffsetUnits: 1
35029
34924
  });
35030
34925
  }
35031
- return new THREE35.MeshStandardMaterial({
34926
+ return new THREE36.MeshStandardMaterial({
35032
34927
  color,
35033
34928
  side,
35034
34929
  flatShading: true,
@@ -35047,12 +34942,12 @@ function createGeometryMeshes(geoms) {
35047
34942
  const meshes = [];
35048
34943
  if (!geoms) return meshes;
35049
34944
  if (geoms.board && geoms.board.geometry) {
35050
- const mesh = new THREE36.Mesh(
34945
+ const mesh = new THREE37.Mesh(
35051
34946
  geoms.board.geometry,
35052
34947
  createBoardMaterial({
35053
34948
  material: geoms.board.material,
35054
34949
  color: geoms.board.color,
35055
- side: THREE36.DoubleSide,
34950
+ side: THREE37.DoubleSide,
35056
34951
  isFaux: geoms.board.isFaux
35057
34952
  })
35058
34953
  );
@@ -35062,11 +34957,11 @@ function createGeometryMeshes(geoms) {
35062
34957
  const createMeshesFromArray = (geomArray) => {
35063
34958
  if (geomArray) {
35064
34959
  geomArray.forEach((comp) => {
35065
- const mesh = new THREE36.Mesh(
34960
+ const mesh = new THREE37.Mesh(
35066
34961
  comp.geometry,
35067
- new THREE36.MeshStandardMaterial({
34962
+ new THREE37.MeshStandardMaterial({
35068
34963
  color: comp.color,
35069
- side: THREE36.DoubleSide,
34964
+ side: THREE37.DoubleSide,
35070
34965
  flatShading: true
35071
34966
  // Consistent with board
35072
34967
  })
@@ -35110,7 +35005,7 @@ var BoardMeshes = ({
35110
35005
  const typedMaterial = material;
35111
35006
  for (const prop of textureProps) {
35112
35007
  const texture = typedMaterial[prop];
35113
- if (texture && texture instanceof THREE37.Texture) {
35008
+ if (texture && texture instanceof THREE38.Texture) {
35114
35009
  texture.dispose();
35115
35010
  typedMaterial[prop] = null;
35116
35011
  }
@@ -42052,7 +41947,7 @@ var KeyboardShortcutsDialog = ({
42052
41947
 
42053
41948
  // src/CadViewer.tsx
42054
41949
  import { jsx as jsx38, jsxs as jsxs11 } from "react/jsx-runtime";
42055
- var DEFAULT_TARGET = new THREE38.Vector3(0, 0, 0);
41950
+ var DEFAULT_TARGET = new THREE39.Vector3(0, 0, 0);
42056
41951
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
42057
41952
  var CadViewerInner = (props) => {
42058
41953
  const [engine, setEngine] = useState36("manifold");
@@ -42319,11 +42214,11 @@ var CadViewer = (props) => {
42319
42214
  // src/convert-circuit-json-to-3d-svg.ts
42320
42215
  var import_debug = __toESM(require_browser(), 1);
42321
42216
  import { su as su18 } from "@tscircuit/circuit-json-util";
42322
- import * as THREE42 from "three";
42217
+ import * as THREE43 from "three";
42323
42218
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
42324
42219
 
42325
42220
  // src/utils/create-geometry-from-polygons.ts
42326
- import * as THREE39 from "three";
42221
+ import * as THREE40 from "three";
42327
42222
  import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute3 } from "three";
42328
42223
  function createGeometryFromPolygons(polygons) {
42329
42224
  const geometry = new BufferGeometry4();
@@ -42337,12 +42232,12 @@ function createGeometryFromPolygons(polygons) {
42337
42232
  ...polygon3.vertices[i + 1]
42338
42233
  // Third vertex
42339
42234
  );
42340
- const v1 = new THREE39.Vector3(...polygon3.vertices[0]);
42341
- const v2 = new THREE39.Vector3(...polygon3.vertices[i]);
42342
- const v3 = new THREE39.Vector3(...polygon3.vertices[i + 1]);
42343
- const normal = new THREE39.Vector3().crossVectors(
42344
- new THREE39.Vector3().subVectors(v2, v1),
42345
- new THREE39.Vector3().subVectors(v3, v1)
42235
+ const v1 = new THREE40.Vector3(...polygon3.vertices[0]);
42236
+ const v2 = new THREE40.Vector3(...polygon3.vertices[i]);
42237
+ const v3 = new THREE40.Vector3(...polygon3.vertices[i + 1]);
42238
+ const normal = new THREE40.Vector3().crossVectors(
42239
+ new THREE40.Vector3().subVectors(v2, v1),
42240
+ new THREE40.Vector3().subVectors(v3, v1)
42346
42241
  ).normalize();
42347
42242
  normals.push(
42348
42243
  normal.x,
@@ -42366,10 +42261,10 @@ function createGeometryFromPolygons(polygons) {
42366
42261
  var import_modeling2 = __toESM(require_src(), 1);
42367
42262
  var import_jscad_planner2 = __toESM(require_dist(), 1);
42368
42263
  var jscadModeling2 = __toESM(require_src(), 1);
42369
- import * as THREE41 from "three";
42264
+ import * as THREE42 from "three";
42370
42265
 
42371
42266
  // src/utils/load-model.ts
42372
- import * as THREE40 from "three";
42267
+ import * as THREE41 from "three";
42373
42268
  import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
42374
42269
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
42375
42270
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -42377,12 +42272,12 @@ async function load3DModel(url) {
42377
42272
  if (url.endsWith(".stl")) {
42378
42273
  const loader = new STLLoader2();
42379
42274
  const geometry = await loader.loadAsync(url);
42380
- const material = new THREE40.MeshStandardMaterial({
42275
+ const material = new THREE41.MeshStandardMaterial({
42381
42276
  color: 8947848,
42382
42277
  metalness: 0.5,
42383
42278
  roughness: 0.5
42384
42279
  });
42385
- return new THREE40.Mesh(geometry, material);
42280
+ return new THREE41.Mesh(geometry, material);
42386
42281
  }
42387
42282
  if (url.endsWith(".obj")) {
42388
42283
  const loader = new OBJLoader2();
@@ -42415,9 +42310,9 @@ async function renderComponent(component, scene) {
42415
42310
  }
42416
42311
  if (component.rotation) {
42417
42312
  model.rotation.set(
42418
- THREE41.MathUtils.degToRad(component.rotation.x ?? 0),
42419
- THREE41.MathUtils.degToRad(component.rotation.y ?? 0),
42420
- THREE41.MathUtils.degToRad(component.rotation.z ?? 0)
42313
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42314
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42315
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42421
42316
  );
42422
42317
  }
42423
42318
  scene.add(model);
@@ -42431,13 +42326,13 @@ async function renderComponent(component, scene) {
42431
42326
  );
42432
42327
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
42433
42328
  const threeGeom = convertCSGToThreeGeom(jscadObject);
42434
- const material2 = new THREE41.MeshStandardMaterial({
42329
+ const material2 = new THREE42.MeshStandardMaterial({
42435
42330
  color: 8947848,
42436
42331
  metalness: 0.5,
42437
42332
  roughness: 0.5,
42438
- side: THREE41.DoubleSide
42333
+ side: THREE42.DoubleSide
42439
42334
  });
42440
- const mesh2 = new THREE41.Mesh(threeGeom, material2);
42335
+ const mesh2 = new THREE42.Mesh(threeGeom, material2);
42441
42336
  if (component.position) {
42442
42337
  mesh2.position.set(
42443
42338
  component.position.x ?? 0,
@@ -42447,9 +42342,9 @@ async function renderComponent(component, scene) {
42447
42342
  }
42448
42343
  if (component.rotation) {
42449
42344
  mesh2.rotation.set(
42450
- THREE41.MathUtils.degToRad(component.rotation.x ?? 0),
42451
- THREE41.MathUtils.degToRad(component.rotation.y ?? 0),
42452
- THREE41.MathUtils.degToRad(component.rotation.z ?? 0)
42345
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42346
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42347
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42453
42348
  );
42454
42349
  }
42455
42350
  scene.add(mesh2);
@@ -42466,17 +42361,17 @@ async function renderComponent(component, scene) {
42466
42361
  if (!geom || !geom.polygons && !geom.sides) {
42467
42362
  continue;
42468
42363
  }
42469
- const color = new THREE41.Color(geomInfo.color);
42364
+ const color = new THREE42.Color(geomInfo.color);
42470
42365
  color.convertLinearToSRGB();
42471
42366
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
42472
42367
  const threeGeom = convertCSGToThreeGeom(geomWithColor);
42473
- const material2 = new THREE41.MeshStandardMaterial({
42368
+ const material2 = new THREE42.MeshStandardMaterial({
42474
42369
  vertexColors: true,
42475
42370
  metalness: 0.2,
42476
42371
  roughness: 0.8,
42477
- side: THREE41.DoubleSide
42372
+ side: THREE42.DoubleSide
42478
42373
  });
42479
- const mesh2 = new THREE41.Mesh(threeGeom, material2);
42374
+ const mesh2 = new THREE42.Mesh(threeGeom, material2);
42480
42375
  if (component.position) {
42481
42376
  mesh2.position.set(
42482
42377
  component.position.x ?? 0,
@@ -42486,22 +42381,22 @@ async function renderComponent(component, scene) {
42486
42381
  }
42487
42382
  if (component.rotation) {
42488
42383
  mesh2.rotation.set(
42489
- THREE41.MathUtils.degToRad(component.rotation.x ?? 0),
42490
- THREE41.MathUtils.degToRad(component.rotation.y ?? 0),
42491
- THREE41.MathUtils.degToRad(component.rotation.z ?? 0)
42384
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42385
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42386
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42492
42387
  );
42493
42388
  }
42494
42389
  scene.add(mesh2);
42495
42390
  }
42496
42391
  return;
42497
42392
  }
42498
- const geometry = new THREE41.BoxGeometry(0.5, 0.5, 0.5);
42499
- const material = new THREE41.MeshStandardMaterial({
42393
+ const geometry = new THREE42.BoxGeometry(0.5, 0.5, 0.5);
42394
+ const material = new THREE42.MeshStandardMaterial({
42500
42395
  color: 16711680,
42501
42396
  transparent: true,
42502
42397
  opacity: 0.25
42503
42398
  });
42504
- const mesh = new THREE41.Mesh(geometry, material);
42399
+ const mesh = new THREE42.Mesh(geometry, material);
42505
42400
  if (component.position) {
42506
42401
  mesh.position.set(
42507
42402
  component.position.x ?? 0,
@@ -42522,11 +42417,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42522
42417
  padding = 20,
42523
42418
  zoom = 1.5
42524
42419
  } = options;
42525
- const scene = new THREE42.Scene();
42420
+ const scene = new THREE43.Scene();
42526
42421
  const renderer = new SVGRenderer();
42527
42422
  renderer.setSize(width10, height10);
42528
- renderer.setClearColor(new THREE42.Color(backgroundColor), 1);
42529
- const camera = new THREE42.OrthographicCamera();
42423
+ renderer.setClearColor(new THREE43.Color(backgroundColor), 1);
42424
+ const camera = new THREE43.OrthographicCamera();
42530
42425
  const aspect = width10 / height10;
42531
42426
  const frustumSize = 100;
42532
42427
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -42540,11 +42435,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42540
42435
  camera.position.set(position.x, position.y, position.z);
42541
42436
  camera.up.set(0, 1, 0);
42542
42437
  const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
42543
- camera.lookAt(new THREE42.Vector3(lookAt.x, lookAt.y, lookAt.z));
42438
+ camera.lookAt(new THREE43.Vector3(lookAt.x, lookAt.y, lookAt.z));
42544
42439
  camera.updateProjectionMatrix();
42545
- const ambientLight = new THREE42.AmbientLight(16777215, Math.PI / 2);
42440
+ const ambientLight = new THREE43.AmbientLight(16777215, Math.PI / 2);
42546
42441
  scene.add(ambientLight);
42547
- const pointLight = new THREE42.PointLight(16777215, Math.PI / 4);
42442
+ const pointLight = new THREE43.PointLight(16777215, Math.PI / 4);
42548
42443
  pointLight.position.set(-10, -10, 10);
42549
42444
  scene.add(pointLight);
42550
42445
  const components = su18(circuitJson).cad_component.list();
@@ -42555,7 +42450,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42555
42450
  const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
42556
42451
  if (boardGeom) {
42557
42452
  const solderMaskColor = colors.fr4SolderMaskGreen;
42558
- const baseColor = new THREE42.Color(
42453
+ const baseColor = new THREE43.Color(
42559
42454
  solderMaskColor[0],
42560
42455
  solderMaskColor[1],
42561
42456
  solderMaskColor[2]
@@ -42567,28 +42462,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42567
42462
  const material = createBoardMaterial({
42568
42463
  material: boardData?.material,
42569
42464
  color: baseColor,
42570
- side: THREE42.DoubleSide
42465
+ side: THREE43.DoubleSide
42571
42466
  });
42572
- const mesh = new THREE42.Mesh(geometry, material);
42467
+ const mesh = new THREE43.Mesh(geometry, material);
42573
42468
  scene.add(mesh);
42574
42469
  }
42575
42470
  }
42576
- const gridColor = new THREE42.Color(8947848);
42577
- const gridHelper = new THREE42.GridHelper(100, 100, gridColor, gridColor);
42471
+ const gridColor = new THREE43.Color(8947848);
42472
+ const gridHelper = new THREE43.GridHelper(100, 100, gridColor, gridColor);
42578
42473
  gridHelper.rotation.x = Math.PI / 2;
42579
42474
  const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
42580
42475
  for (const mat of materials) {
42581
42476
  mat.transparent = true;
42582
42477
  mat.opacity = 0.3;
42583
- if (mat instanceof THREE42.LineBasicMaterial) {
42478
+ if (mat instanceof THREE43.LineBasicMaterial) {
42584
42479
  mat.color = gridColor;
42585
42480
  mat.vertexColors = false;
42586
42481
  }
42587
42482
  }
42588
42483
  scene.add(gridHelper);
42589
- const box = new THREE42.Box3().setFromObject(scene);
42590
- const center = box.getCenter(new THREE42.Vector3());
42591
- const size4 = box.getSize(new THREE42.Vector3());
42484
+ const box = new THREE43.Box3().setFromObject(scene);
42485
+ const center = box.getCenter(new THREE43.Vector3());
42486
+ const size4 = box.getSize(new THREE43.Vector3());
42592
42487
  scene.position.sub(center);
42593
42488
  const maxDim = Math.max(size4.x, size4.y, size4.z);
42594
42489
  if (maxDim > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.528",
3
+ "version": "0.0.529",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "@jscad/regl-renderer": "^2.6.12",
31
31
  "@jscad/stl-serializer": "^2.1.20",
32
32
  "circuit-json": "^0.0.391",
33
- "circuit-to-canvas": "^0.0.87",
33
+ "circuit-to-canvas": "^0.0.89",
34
34
  "react-hot-toast": "^2.6.0",
35
35
  "three": "^0.165.0",
36
36
  "three-stdlib": "^2.36.0",