@tscircuit/3d-viewer 0.0.528 → 0.0.530

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 +296 -429
  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.529",
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.90",
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) => {
@@ -32005,6 +31915,7 @@ function createPanelOutlineTextureForLayer({
32005
31915
 
32006
31916
  // src/utils/trace-texture.ts
32007
31917
  import * as THREE21 from "three";
31918
+ import { CircuitToCanvasDrawer } from "circuit-to-canvas";
32008
31919
  import { su as su7 } from "@tscircuit/circuit-json-util";
32009
31920
  function isWireRoutePoint(point) {
32010
31921
  return point && point.route_type === "wire" && typeof point.layer === "string" && typeof point.width === "number";
@@ -32017,14 +31928,17 @@ function createTraceTextureForLayer({
32017
31928
  traceTextureResolution
32018
31929
  }) {
32019
31930
  const pcbTraces = su7(circuitJson).pcb_trace.list();
32020
- const allPcbVias = su7(circuitJson).pcb_via.list();
32021
- const allPcbPlatedHoles = su7(
32022
- circuitJson
32023
- ).pcb_plated_hole.list();
31931
+ const pcbVias = su7(circuitJson).pcb_via.list();
31932
+ const pcbPlatedHoles = su7(circuitJson).pcb_plated_hole.list();
31933
+ const pcbRenderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32024
31934
  const tracesOnLayer = pcbTraces.filter(
32025
31935
  (t) => t.route.some((p) => isWireRoutePoint(p) && p.layer === layer)
32026
31936
  );
32027
31937
  if (tracesOnLayer.length === 0) return null;
31938
+ const platedHolesOnLayer = pcbPlatedHoles.filter(
31939
+ (hole) => hole.layers.includes(layer)
31940
+ );
31941
+ const elementsToDraw = [...tracesOnLayer, ...pcbVias, ...platedHolesOnLayer];
32028
31942
  const boardOutlineBounds = calculateOutlineBounds(boardData);
32029
31943
  const canvas = document.createElement("canvas");
32030
31944
  const canvasWidth = Math.floor(
@@ -32041,82 +31955,51 @@ function createTraceTextureForLayer({
32041
31955
  ctx.translate(0, canvasHeight);
32042
31956
  ctx.scale(1, -1);
32043
31957
  }
32044
- tracesOnLayer.forEach((trace) => {
32045
- let firstPoint = true;
32046
- ctx.beginPath();
32047
- ctx.strokeStyle = traceColor;
32048
- ctx.lineCap = "round";
32049
- ctx.lineJoin = "round";
32050
- let currentLineWidth = 0;
32051
- for (const point of trace.route) {
32052
- if (!isWireRoutePoint(point) || point.layer !== layer) {
32053
- if (!firstPoint) ctx.stroke();
32054
- firstPoint = true;
32055
- continue;
32056
- }
32057
- const pcbX = point.x;
32058
- const pcbY = point.y;
32059
- currentLineWidth = point.width * traceTextureResolution;
32060
- ctx.lineWidth = currentLineWidth;
32061
- const canvasX = (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
32062
- const canvasY = (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
32063
- if (firstPoint) {
32064
- ctx.moveTo(canvasX, canvasY);
32065
- firstPoint = false;
32066
- } else {
32067
- ctx.lineTo(canvasX, canvasY);
31958
+ const transparent = "rgba(0,0,0,0)";
31959
+ const drawer = new CircuitToCanvasDrawer(ctx);
31960
+ drawer.configure({
31961
+ colorOverrides: {
31962
+ copper: {
31963
+ top: traceColor,
31964
+ bottom: traceColor,
31965
+ inner1: traceColor,
31966
+ inner2: traceColor,
31967
+ inner3: traceColor,
31968
+ inner4: traceColor,
31969
+ inner5: traceColor,
31970
+ inner6: traceColor
31971
+ },
31972
+ copperPour: { top: transparent, bottom: transparent },
31973
+ drill: transparent,
31974
+ boardOutline: transparent,
31975
+ substrate: transparent,
31976
+ keepout: transparent,
31977
+ fabricationNote: transparent,
31978
+ courtyard: { top: transparent, bottom: transparent },
31979
+ silkscreen: { top: transparent, bottom: transparent },
31980
+ soldermask: { top: transparent, bottom: transparent },
31981
+ soldermaskWithCopperUnderneath: {
31982
+ top: transparent,
31983
+ bottom: transparent
31984
+ },
31985
+ soldermaskOverCopper: {
31986
+ top: transparent,
31987
+ bottom: transparent
32068
31988
  }
32069
31989
  }
32070
- if (!firstPoint) {
32071
- ctx.stroke();
32072
- }
32073
31990
  });
32074
- ctx.globalCompositeOperation = "destination-out";
32075
- ctx.fillStyle = "black";
32076
- allPcbVias.forEach((via) => {
32077
- const canvasX = (via.x - boardOutlineBounds.minX) * traceTextureResolution;
32078
- const canvasY = (boardOutlineBounds.maxY - via.y) * traceTextureResolution;
32079
- const canvasRadius = via.outer_diameter / 2 * traceTextureResolution;
32080
- ctx.beginPath();
32081
- ctx.arc(canvasX, canvasY, canvasRadius, 0, 2 * Math.PI, false);
32082
- ctx.fill();
31991
+ drawer.setCameraBounds({
31992
+ minX: boardOutlineBounds.minX,
31993
+ maxX: boardOutlineBounds.maxX,
31994
+ minY: boardOutlineBounds.minY,
31995
+ maxY: boardOutlineBounds.maxY
32083
31996
  });
32084
- allPcbPlatedHoles.forEach((ph) => {
32085
- if (ph.layers.includes(layer) && ph.shape === "circle") {
32086
- const canvasX = (ph.x - boardOutlineBounds.minX) * traceTextureResolution;
32087
- const canvasY = (boardOutlineBounds.maxY - ph.y) * traceTextureResolution;
32088
- const canvasRadius = ph.outer_diameter / 2 * traceTextureResolution;
32089
- ctx.beginPath();
32090
- ctx.arc(canvasX, canvasY, canvasRadius, 0, 2 * Math.PI, false);
32091
- ctx.fill();
32092
- } else if (ph.layers.includes(layer) && ph.shape === "rotated_pill_hole_with_rect_pad") {
32093
- const canvasX = (ph.x - boardOutlineBounds.minX) * traceTextureResolution;
32094
- const canvasY = (boardOutlineBounds.maxY - ph.y) * traceTextureResolution;
32095
- const padWidth = (ph.rect_pad_width ?? ph.hole_width ?? 0) * traceTextureResolution;
32096
- const padHeight = (ph.rect_pad_height ?? ph.hole_height ?? 0) * traceTextureResolution;
32097
- const rectCcwRotationDeg = ph.rect_ccw_rotation || 0;
32098
- const rectRotation = -rectCcwRotationDeg;
32099
- if (rectRotation) {
32100
- ctx.save();
32101
- ctx.translate(canvasX, canvasY);
32102
- ctx.rotate(rectRotation * Math.PI / 180);
32103
- ctx.beginPath();
32104
- ctx.rect(-padWidth / 2, -padHeight / 2, padWidth, padHeight);
32105
- ctx.fill();
32106
- ctx.restore();
32107
- } else {
32108
- ctx.beginPath();
32109
- ctx.rect(
32110
- canvasX - padWidth / 2,
32111
- canvasY - padHeight / 2,
32112
- padWidth,
32113
- padHeight
32114
- );
32115
- ctx.fill();
32116
- }
32117
- }
31997
+ drawer.drawElements(elementsToDraw, {
31998
+ layers: [pcbRenderLayer],
31999
+ drawSoldermask: false,
32000
+ drawSoldermaskTop: false,
32001
+ drawSoldermaskBottom: false
32118
32002
  });
32119
- ctx.globalCompositeOperation = "source-over";
32120
32003
  const texture = new THREE21.CanvasTexture(canvas);
32121
32004
  texture.generateMipmaps = true;
32122
32005
  texture.minFilter = THREE21.LinearMipmapLinearFilter;
@@ -32130,7 +32013,7 @@ function createTraceTextureForLayer({
32130
32013
  import * as THREE22 from "three";
32131
32014
 
32132
32015
  // src/textures/copper-text/copper-text-drawing.ts
32133
- import { CircuitToCanvasDrawer } from "circuit-to-canvas";
32016
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
32134
32017
  var setDrawerBounds = (drawer, bounds) => {
32135
32018
  drawer.setCameraBounds({
32136
32019
  minX: bounds.minX,
@@ -32147,7 +32030,7 @@ var drawCopperTextLayer = ({
32147
32030
  copperColor
32148
32031
  }) => {
32149
32032
  const renderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32150
- const drawer = new CircuitToCanvasDrawer(ctx);
32033
+ const drawer = new CircuitToCanvasDrawer2(ctx);
32151
32034
  drawer.configure({
32152
32035
  colorOverrides: {
32153
32036
  copper: {
@@ -32175,7 +32058,7 @@ var drawCopperTextLayer = ({
32175
32058
  maskCanvas.height = ctx.canvas.height;
32176
32059
  const maskCtx = maskCanvas.getContext("2d");
32177
32060
  if (!maskCtx) return;
32178
- const knockoutCutoutDrawer = new CircuitToCanvasDrawer(maskCtx);
32061
+ const knockoutCutoutDrawer = new CircuitToCanvasDrawer2(maskCtx);
32179
32062
  knockoutCutoutDrawer.configure({
32180
32063
  colorOverrides: {
32181
32064
  copper: {
@@ -32251,7 +32134,7 @@ function createCopperTextTextureForLayer({
32251
32134
  import * as THREE23 from "three";
32252
32135
 
32253
32136
  // src/textures/fabrication-note/fabrication-note-drawing.ts
32254
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
32137
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
32255
32138
 
32256
32139
  // src/utils/units.ts
32257
32140
  var MM_PER_INCH = 25.4;
@@ -32349,7 +32232,7 @@ var drawFabricationNoteLayer = ({
32349
32232
  }) => {
32350
32233
  const renderLayer = `${layer}_fabrication_note`;
32351
32234
  const normalizedElements = elements.map(normalizeFabricationElement);
32352
- const drawer = new CircuitToCanvasDrawer2(ctx);
32235
+ const drawer = new CircuitToCanvasDrawer3(ctx);
32353
32236
  drawer.configure({
32354
32237
  colorOverrides: {
32355
32238
  copper: {
@@ -32488,7 +32371,7 @@ function createFabricationNoteTextureForLayer({
32488
32371
  import * as THREE24 from "three";
32489
32372
 
32490
32373
  // src/textures/pcb-note/pcb-note-drawing.ts
32491
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
32374
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
32492
32375
  var TRANSPARENT2 = "rgba(0,0,0,0)";
32493
32376
  var setDrawerBounds3 = (drawer, bounds) => {
32494
32377
  drawer.setCameraBounds({
@@ -32567,7 +32450,7 @@ var drawPcbNoteLayer = ({
32567
32450
  elements
32568
32451
  }) => {
32569
32452
  const normalizedElements = elements.map(normalizePcbNoteElement);
32570
- const drawer = new CircuitToCanvasDrawer3(ctx);
32453
+ const drawer = new CircuitToCanvasDrawer4(ctx);
32571
32454
  drawer.configure({
32572
32455
  colorOverrides: {
32573
32456
  copper: {
@@ -32649,7 +32532,7 @@ function createPcbNoteTextureForLayer({
32649
32532
  import * as THREE25 from "three";
32650
32533
 
32651
32534
  // src/textures/silkscreen/silkscreen-drawing.ts
32652
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
32535
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
32653
32536
  var FABRICATION_NOTE_COLOR2 = "rgb(255,243,204)";
32654
32537
  var TRANSPARENT3 = "rgba(0,0,0,0)";
32655
32538
  var setDrawerBounds4 = (drawer, bounds) => {
@@ -32668,7 +32551,7 @@ var drawSilkscreenLayer = ({
32668
32551
  silkscreenColor
32669
32552
  }) => {
32670
32553
  const renderLayer = layer === "top" ? "top_silkscreen" : "bottom_silkscreen";
32671
- const drawer = new CircuitToCanvasDrawer4(ctx);
32554
+ const drawer = new CircuitToCanvasDrawer5(ctx);
32672
32555
  drawer.configure({
32673
32556
  colorOverrides: {
32674
32557
  copper: {
@@ -32768,7 +32651,7 @@ function createSilkscreenTextureForLayer({
32768
32651
  import * as THREE26 from "three";
32769
32652
 
32770
32653
  // src/textures/soldermask/soldermask-drawing.ts
32771
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
32654
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
32772
32655
  var toRgb = (colorArr) => {
32773
32656
  const [r = 0, g = 0, b = 0] = colorArr;
32774
32657
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -32804,7 +32687,7 @@ var drawSoldermaskLayer = ({
32804
32687
  }) => {
32805
32688
  const palette = getSoldermaskPalette(boardMaterial);
32806
32689
  const copperRenderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32807
- const drawer = new CircuitToCanvasDrawer5(ctx);
32690
+ const drawer = new CircuitToCanvasDrawer6(ctx);
32808
32691
  drawer.configure({
32809
32692
  colorOverrides: {
32810
32693
  copper: {
@@ -32848,7 +32731,7 @@ var drawSoldermaskLayer = ({
32848
32731
  if (uncoveredPours.length > 0) {
32849
32732
  ctx.save();
32850
32733
  ctx.globalCompositeOperation = "destination-out";
32851
- const cutoutDrawer = new CircuitToCanvasDrawer5(ctx);
32734
+ const cutoutDrawer = new CircuitToCanvasDrawer6(ctx);
32852
32735
  cutoutDrawer.configure({
32853
32736
  colorOverrides: {
32854
32737
  copper: {
@@ -32906,6 +32789,109 @@ function createSoldermaskTextureForLayer({
32906
32789
  return texture;
32907
32790
  }
32908
32791
 
32792
+ // src/textures/create-through-hole-texture-for-layer.ts
32793
+ import * as THREE27 from "three";
32794
+
32795
+ // src/textures/through-hole/through-hole-drawing.ts
32796
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
32797
+ var setDrawerBounds6 = (drawer, bounds) => {
32798
+ drawer.setCameraBounds({
32799
+ minX: bounds.minX,
32800
+ maxX: bounds.maxX,
32801
+ minY: bounds.minY,
32802
+ maxY: bounds.maxY
32803
+ });
32804
+ };
32805
+ var drawThroughHoleLayer = ({
32806
+ ctx,
32807
+ layer,
32808
+ bounds,
32809
+ elements,
32810
+ copperColor
32811
+ }) => {
32812
+ const renderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32813
+ const transparent = "rgba(0,0,0,0)";
32814
+ const drawer = new CircuitToCanvasDrawer7(ctx);
32815
+ drawer.configure({
32816
+ colorOverrides: {
32817
+ copper: {
32818
+ top: copperColor,
32819
+ bottom: copperColor,
32820
+ inner1: copperColor,
32821
+ inner2: copperColor,
32822
+ inner3: copperColor,
32823
+ inner4: copperColor,
32824
+ inner5: copperColor,
32825
+ inner6: copperColor
32826
+ },
32827
+ drill: transparent,
32828
+ boardOutline: transparent,
32829
+ substrate: transparent,
32830
+ keepout: transparent,
32831
+ fabricationNote: transparent,
32832
+ silkscreen: { top: transparent, bottom: transparent },
32833
+ courtyard: { top: transparent, bottom: transparent },
32834
+ soldermask: { top: transparent, bottom: transparent },
32835
+ soldermaskWithCopperUnderneath: {
32836
+ top: transparent,
32837
+ bottom: transparent
32838
+ },
32839
+ soldermaskOverCopper: {
32840
+ top: transparent,
32841
+ bottom: transparent
32842
+ }
32843
+ }
32844
+ });
32845
+ setDrawerBounds6(drawer, bounds);
32846
+ drawer.drawElements(elements, {
32847
+ layers: [renderLayer]
32848
+ });
32849
+ };
32850
+
32851
+ // src/textures/create-through-hole-texture-for-layer.ts
32852
+ function createThroughHoleTextureForLayer({
32853
+ layer,
32854
+ circuitJson,
32855
+ boardData,
32856
+ copperColor = "rgb(230, 153, 51)",
32857
+ traceTextureResolution = TRACE_TEXTURE_RESOLUTION
32858
+ }) {
32859
+ const elements = circuitJson.filter((element) => {
32860
+ if (element.type === "pcb_via") return true;
32861
+ if (element.type !== "pcb_plated_hole") return false;
32862
+ const platedHole2 = element;
32863
+ return !Array.isArray(platedHole2.layers) || platedHole2.layers.includes(layer);
32864
+ });
32865
+ if (elements.length === 0) return null;
32866
+ const bounds = calculateOutlineBounds(boardData);
32867
+ const canvasWidth = Math.floor(bounds.width * traceTextureResolution);
32868
+ const canvasHeight = Math.floor(bounds.height * traceTextureResolution);
32869
+ if (canvasWidth <= 0 || canvasHeight <= 0) return null;
32870
+ const canvas = document.createElement("canvas");
32871
+ canvas.width = canvasWidth;
32872
+ canvas.height = canvasHeight;
32873
+ const ctx = canvas.getContext("2d");
32874
+ if (!ctx) return null;
32875
+ if (layer === "bottom") {
32876
+ ctx.translate(0, canvasHeight);
32877
+ ctx.scale(1, -1);
32878
+ }
32879
+ drawThroughHoleLayer({
32880
+ ctx,
32881
+ layer,
32882
+ bounds,
32883
+ elements,
32884
+ copperColor
32885
+ });
32886
+ const texture = new THREE27.CanvasTexture(canvas);
32887
+ texture.generateMipmaps = true;
32888
+ texture.minFilter = THREE27.LinearMipmapLinearFilter;
32889
+ texture.magFilter = THREE27.LinearFilter;
32890
+ texture.anisotropy = 16;
32891
+ texture.needsUpdate = true;
32892
+ return texture;
32893
+ }
32894
+
32909
32895
  // src/textures/create-combined-board-textures.ts
32910
32896
  var toRgb2 = (colorArr) => {
32911
32897
  const [r = 0, g = 0, b = 0] = colorArr;
@@ -32938,10 +32924,10 @@ var createCombinedTexture = ({
32938
32924
  const image = texture.image;
32939
32925
  ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
32940
32926
  });
32941
- const combinedTexture = new THREE27.CanvasTexture(canvas);
32927
+ const combinedTexture = new THREE28.CanvasTexture(canvas);
32942
32928
  combinedTexture.generateMipmaps = false;
32943
- combinedTexture.minFilter = THREE27.LinearFilter;
32944
- combinedTexture.magFilter = THREE27.LinearFilter;
32929
+ combinedTexture.minFilter = THREE28.LinearFilter;
32930
+ combinedTexture.magFilter = THREE28.LinearFilter;
32945
32931
  combinedTexture.premultiplyAlpha = true;
32946
32932
  combinedTexture.anisotropy = 16;
32947
32933
  combinedTexture.needsUpdate = true;
@@ -32953,8 +32939,7 @@ function createCombinedBoardTextures({
32953
32939
  traceTextureResolution,
32954
32940
  visibility
32955
32941
  }) {
32956
- const traceColorWithMask = toRgb2(colors.fr4TracesWithMaskGreen);
32957
- const traceColorWithoutMask = toRgb2(colors.fr4TracesWithoutMaskTan);
32942
+ const traceColor = toRgb2(colors.copper);
32958
32943
  const silkscreenColor = "rgb(255,255,255)";
32959
32944
  const copperColor = toRgb2(colors.copper);
32960
32945
  const showBoardBody = visibility?.boardBody ?? true;
@@ -32972,7 +32957,7 @@ function createCombinedBoardTextures({
32972
32957
  layer,
32973
32958
  circuitJson,
32974
32959
  boardData,
32975
- traceColor: showMask ? traceColorWithMask : traceColorWithoutMask,
32960
+ traceColor,
32976
32961
  traceTextureResolution
32977
32962
  }) : null;
32978
32963
  const copperTextTexture = showCopper ? createCopperTextTextureForLayer({
@@ -32989,6 +32974,13 @@ function createCombinedBoardTextures({
32989
32974
  copperColor,
32990
32975
  traceTextureResolution
32991
32976
  }) : null;
32977
+ const throughHoleTexture = showCopper ? createThroughHoleTextureForLayer({
32978
+ layer,
32979
+ circuitJson,
32980
+ boardData,
32981
+ copperColor,
32982
+ traceTextureResolution
32983
+ }) : null;
32992
32984
  const silkscreenTexture = showSilkscreen ? createSilkscreenTextureForLayer({
32993
32985
  layer,
32994
32986
  circuitJson,
@@ -33019,6 +33011,7 @@ function createCombinedBoardTextures({
33019
33011
  textures: [
33020
33012
  traceTexture,
33021
33013
  padTexture,
33014
+ throughHoleTexture,
33022
33015
  soldermaskTexture,
33023
33016
  copperTextTexture,
33024
33017
  silkscreenTexture,
@@ -33038,15 +33031,15 @@ function createCombinedBoardTextures({
33038
33031
  }
33039
33032
 
33040
33033
  // src/textures/create-copper-pour-texture-for-layer.ts
33041
- import * as THREE28 from "three";
33042
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
33034
+ import * as THREE29 from "three";
33035
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer8 } from "circuit-to-canvas";
33043
33036
 
33044
33037
  // src/geoms/brep-converter.ts
33045
33038
  var import_primitives7 = __toESM(require_primitives(), 1);
33046
33039
  var import_booleans5 = __toESM(require_booleans(), 1);
33047
33040
 
33048
33041
  // src/textures/create-three-texture-meshes.ts
33049
- import * as THREE29 from "three";
33042
+ import * as THREE30 from "three";
33050
33043
  function createTexturePlane(config, boardData) {
33051
33044
  const {
33052
33045
  texture,
@@ -33058,15 +33051,15 @@ function createTexturePlane(config, boardData) {
33058
33051
  } = config;
33059
33052
  if (!texture) return null;
33060
33053
  const boardOutlineBounds = calculateOutlineBounds(boardData);
33061
- const planeGeom = new THREE29.PlaneGeometry(
33054
+ const planeGeom = new THREE30.PlaneGeometry(
33062
33055
  boardOutlineBounds.width,
33063
33056
  boardOutlineBounds.height
33064
33057
  );
33065
- const material = new THREE29.MeshBasicMaterial({
33058
+ const material = new THREE30.MeshBasicMaterial({
33066
33059
  map: texture,
33067
33060
  transparent: true,
33068
33061
  alphaTest: 0.08,
33069
- side: THREE29.DoubleSide,
33062
+ side: THREE30.DoubleSide,
33070
33063
  depthWrite: true,
33071
33064
  polygonOffset: usePolygonOffset,
33072
33065
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -33074,7 +33067,7 @@ function createTexturePlane(config, boardData) {
33074
33067
  polygonOffsetUnits: usePolygonOffset ? -4 : 0,
33075
33068
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
33076
33069
  });
33077
- const mesh = new THREE29.Mesh(planeGeom, material);
33070
+ const mesh = new THREE30.Mesh(planeGeom, material);
33078
33071
  mesh.position.set(
33079
33072
  boardOutlineBounds.centerX,
33080
33073
  boardOutlineBounds.centerY,
@@ -33119,7 +33112,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
33119
33112
  }
33120
33113
 
33121
33114
  // src/three-components/JscadBoardTextures.tsx
33122
- import * as THREE30 from "three";
33115
+ import * as THREE31 from "three";
33123
33116
 
33124
33117
  // src/utils/layer-texture-resolution.ts
33125
33118
  var DEFAULT_MAX_TEXTURE_PIXELS = 4e6;
@@ -33215,7 +33208,7 @@ function JscadBoardTextures({
33215
33208
  const typedMaterial = material;
33216
33209
  for (const prop of textureProps) {
33217
33210
  const texture = typedMaterial[prop];
33218
- if (texture && texture instanceof THREE30.Texture) {
33211
+ if (texture && texture instanceof THREE31.Texture) {
33219
33212
  texture.dispose();
33220
33213
  typedMaterial[prop] = null;
33221
33214
  }
@@ -33225,22 +33218,22 @@ function JscadBoardTextures({
33225
33218
  const createTexturePlane2 = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false, depthWrite = true, renderOrder = 1) => {
33226
33219
  if (!texture) return null;
33227
33220
  const boardOutlineBounds = calculateOutlineBounds(boardData);
33228
- const planeGeom = new THREE30.PlaneGeometry(
33221
+ const planeGeom = new THREE31.PlaneGeometry(
33229
33222
  boardOutlineBounds.width,
33230
33223
  boardOutlineBounds.height
33231
33224
  );
33232
- const material = new THREE30.MeshBasicMaterial({
33225
+ const material = new THREE31.MeshBasicMaterial({
33233
33226
  map: texture,
33234
33227
  transparent: true,
33235
33228
  alphaTest: 0.08,
33236
- side: THREE30.DoubleSide,
33229
+ side: THREE31.DoubleSide,
33237
33230
  depthWrite,
33238
33231
  polygonOffset: usePolygonOffset,
33239
33232
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
33240
33233
  polygonOffsetUnits: usePolygonOffset ? -4 : 0,
33241
33234
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
33242
33235
  });
33243
- const mesh = new THREE30.Mesh(planeGeom, material);
33236
+ const mesh = new THREE31.Mesh(planeGeom, material);
33244
33237
  mesh.position.set(
33245
33238
  boardOutlineBounds.centerX,
33246
33239
  boardOutlineBounds.centerY,
@@ -33285,7 +33278,7 @@ function JscadBoardTextures({
33285
33278
  mesh.geometry.dispose();
33286
33279
  if (Array.isArray(mesh.material)) {
33287
33280
  mesh.material.forEach((material) => disposeTextureMaterial(material));
33288
- } else if (mesh.material instanceof THREE30.Material) {
33281
+ } else if (mesh.material instanceof THREE31.Material) {
33289
33282
  disposeTextureMaterial(mesh.material);
33290
33283
  }
33291
33284
  });
@@ -33518,12 +33511,12 @@ var CadViewerJscad = forwardRef3(
33518
33511
  // src/CadViewerManifold.tsx
33519
33512
  import { su as su17 } from "@tscircuit/circuit-json-util";
33520
33513
  import { useEffect as useEffect25, useMemo as useMemo22, useState as useState16 } from "react";
33521
- import * as THREE37 from "three";
33514
+ import * as THREE38 from "three";
33522
33515
 
33523
33516
  // src/hooks/useManifoldBoardBuilder.ts
33524
33517
  import { su as su16 } from "@tscircuit/circuit-json-util";
33525
33518
  import { useEffect as useEffect24, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33526
- import * as THREE34 from "three";
33519
+ import * as THREE35 from "three";
33527
33520
 
33528
33521
  // src/utils/manifold/create-manifold-board.ts
33529
33522
  var arePointsClockwise2 = (points) => {
@@ -33865,17 +33858,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
33865
33858
 
33866
33859
  // src/utils/manifold/process-plated-holes.ts
33867
33860
  import { su as su14 } from "@tscircuit/circuit-json-util";
33868
- import * as THREE32 from "three";
33861
+ import * as THREE33 from "three";
33869
33862
 
33870
33863
  // src/utils/manifold-mesh-to-three-geometry.ts
33871
- import * as THREE31 from "three";
33864
+ import * as THREE32 from "three";
33872
33865
  function manifoldMeshToThreeGeometry(manifoldMesh) {
33873
- const geometry = new THREE31.BufferGeometry();
33866
+ const geometry = new THREE32.BufferGeometry();
33874
33867
  geometry.setAttribute(
33875
33868
  "position",
33876
- new THREE31.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
33869
+ new THREE32.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
33877
33870
  );
33878
- geometry.setIndex(new THREE31.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
33871
+ geometry.setIndex(new THREE32.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
33879
33872
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
33880
33873
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
33881
33874
  const start = manifoldMesh.runIndex[i];
@@ -33909,7 +33902,7 @@ var createEllipsePoints = (width10, height10, segments) => {
33909
33902
  }
33910
33903
  return points;
33911
33904
  };
33912
- var COPPER_COLOR = new THREE32.Color(...colors.copper);
33905
+ var COPPER_COLOR = new THREE33.Color(...colors.copper);
33913
33906
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
33914
33907
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
33915
33908
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -34011,6 +34004,10 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34011
34004
  return holeOp;
34012
34005
  };
34013
34006
  pcbPlatedHoles.forEach((ph, index2) => {
34007
+ const internalCopperThickness = Math.max(
34008
+ pcbThickness - 2 * (PLATED_HOLE_PAD_THICKNESS + PLATED_HOLE_SURFACE_CLEARANCE + PLATED_HOLE_FILL_CLEARANCE),
34009
+ M
34010
+ );
34014
34011
  if (ph.shape === "circle") {
34015
34012
  const translatedDrill = createPlatedHoleDrill({
34016
34013
  Manifold,
@@ -34023,7 +34020,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34023
34020
  });
34024
34021
  manifoldInstancesForCleanup.push(translatedDrill);
34025
34022
  platedHoleBoardDrills.push(translatedDrill);
34026
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34023
+ const copperPartThickness = internalCopperThickness;
34027
34024
  const platedPart = Manifold.cylinder(
34028
34025
  copperPartThickness,
34029
34026
  ph.outer_diameter / 2,
@@ -34083,7 +34080,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34083
34080
  ]);
34084
34081
  manifoldInstancesForCleanup.push(translatedBoardPillDrill);
34085
34082
  platedHoleBoardDrills.push(translatedBoardPillDrill);
34086
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34083
+ const copperPartThickness = internalCopperThickness;
34087
34084
  const outerCopperOpUnrotated = createPillOp(
34088
34085
  outerW,
34089
34086
  outerH,
@@ -34161,29 +34158,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34161
34158
  borderRadius: rectBorderRadius
34162
34159
  });
34163
34160
  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
34161
  const barrelPill = createPillOp(
34188
34162
  holeW,
34189
34163
  holeH,
@@ -34191,12 +34165,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34191
34165
  // Slightly shorter than board
34192
34166
  ).translate([holeOffsetX, holeOffsetY, 0]);
34193
34167
  manifoldInstancesForCleanup.push(barrelPill);
34194
- const copperUnion = Manifold.union([
34195
- mainFill,
34196
- topPad,
34197
- bottomPad,
34198
- barrelPill
34199
- ]);
34168
+ const copperUnion = Manifold.union([mainFill, barrelPill]);
34200
34169
  manifoldInstancesForCleanup.push(copperUnion);
34201
34170
  const holeCutOp = createPillOp(
34202
34171
  Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
@@ -34276,39 +34245,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34276
34245
  manifoldInstancesForCleanup.push(rotatedMainFill);
34277
34246
  mainFill = rotatedMainFill;
34278
34247
  }
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
34248
  let barrelPill = createPillOp(
34313
34249
  holeW,
34314
34250
  holeH,
@@ -34321,12 +34257,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34321
34257
  barrelPill = rotatedBarrel;
34322
34258
  }
34323
34259
  manifoldInstancesForCleanup.push(barrelPill);
34324
- const copperUnion = Manifold.union([
34325
- mainFill,
34326
- topPad,
34327
- bottomPad,
34328
- barrelPill
34329
- ]);
34260
+ const copperUnion = Manifold.union([mainFill, barrelPill]);
34330
34261
  manifoldInstancesForCleanup.push(copperUnion);
34331
34262
  let holeCutOp = createPillOp(
34332
34263
  Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
@@ -34383,23 +34314,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34383
34314
  padOutline,
34384
34315
  thickness: fillThickness
34385
34316
  });
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);
34317
+ if (!mainFill) return;
34403
34318
  const barrelOp = createHoleOpForPolygonPad({
34404
34319
  ph,
34405
34320
  depth: pcbThickness * 1.02
@@ -34410,12 +34325,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34410
34325
  depth: pcbThickness * 0.8,
34411
34326
  sizeDelta: -2 * M
34412
34327
  }) || barrelOp;
34413
- const copperUnion = Manifold.union([
34414
- mainFill,
34415
- topTranslated,
34416
- bottomTranslated,
34417
- barrelOp
34418
- ]);
34328
+ const copperUnion = Manifold.union([mainFill, barrelOp]);
34419
34329
  manifoldInstancesForCleanup.push(copperUnion);
34420
34330
  const finalCopper = copperUnion.subtract(holeCutOp);
34421
34331
  manifoldInstancesForCleanup.push(finalCopper);
@@ -34472,7 +34382,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34472
34382
  const translatedDrill = boardDrillOp.translate([ph.x, ph.y, 0]);
34473
34383
  manifoldInstancesForCleanup.push(translatedDrill);
34474
34384
  platedHoleBoardDrills.push(translatedDrill);
34475
- const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
34385
+ const copperPartThickness = internalCopperThickness;
34476
34386
  let outerPoints = createEllipsePoints(
34477
34387
  outerW,
34478
34388
  outerH,
@@ -34571,29 +34481,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34571
34481
  borderRadius: rectBorderRadius
34572
34482
  });
34573
34483
  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
34484
  const barrelCylinder = Manifold.cylinder(
34598
34485
  pcbThickness * 0.8,
34599
34486
  // Slightly taller than board
@@ -34603,12 +34490,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34603
34490
  true
34604
34491
  ).translate([holeOffsetX, holeOffsetY, 0]);
34605
34492
  manifoldInstancesForCleanup.push(barrelCylinder);
34606
- const copperUnion = Manifold.union([
34607
- mainFill,
34608
- topPad,
34609
- bottomPad,
34610
- barrelCylinder
34611
- ]);
34493
+ const copperUnion = Manifold.union([mainFill, barrelCylinder]);
34612
34494
  manifoldInstancesForCleanup.push(copperUnion);
34613
34495
  const holeDrill = Manifold.cylinder(
34614
34496
  pcbThickness * 1.2,
@@ -34651,7 +34533,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
34651
34533
 
34652
34534
  // src/utils/manifold/process-vias.ts
34653
34535
  import { su as su15 } from "@tscircuit/circuit-json-util";
34654
- import * as THREE33 from "three";
34536
+ import * as THREE34 from "three";
34655
34537
 
34656
34538
  // src/utils/via-geoms.ts
34657
34539
  function createViaCopper2({
@@ -34664,7 +34546,6 @@ function createViaCopper2({
34664
34546
  zOffset = 1e-3,
34665
34547
  segments = 32
34666
34548
  }) {
34667
- const padThickness = zOffset;
34668
34549
  const platingThickness = zOffset;
34669
34550
  if (outerDiameter < holeDiameter) {
34670
34551
  throw new Error(
@@ -34676,22 +34557,8 @@ function createViaCopper2({
34676
34557
  holeDiameter / 2 + platingThickness
34677
34558
  );
34678
34559
  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;
34560
+ const viaSolid = barrel;
34561
+ const drillHeight = thickness + 2 * zOffset;
34695
34562
  const drill = Manifold.cylinder(
34696
34563
  drillHeight,
34697
34564
  holeDiameter / 2,
@@ -34704,7 +34571,7 @@ function createViaCopper2({
34704
34571
  }
34705
34572
 
34706
34573
  // src/utils/manifold/process-vias.ts
34707
- var COPPER_COLOR2 = new THREE33.Color(...colors.copper);
34574
+ var COPPER_COLOR2 = new THREE34.Color(...colors.copper);
34708
34575
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
34709
34576
  const viaBoardDrills = [];
34710
34577
  const pcbVias = su15(circuitJson).pcb_via.list();
@@ -34924,7 +34791,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34924
34791
  {
34925
34792
  key: "plated-holes-union",
34926
34793
  geometry: cutPlatedGeom,
34927
- color: new THREE34.Color(
34794
+ color: new THREE35.Color(
34928
34795
  colors.copper[0],
34929
34796
  colors.copper[1],
34930
34797
  colors.copper[2]
@@ -34954,7 +34821,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34954
34821
  const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Tan;
34955
34822
  currentGeoms.board = {
34956
34823
  geometry: finalBoardGeom,
34957
- color: new THREE34.Color(
34824
+ color: new THREE35.Color(
34958
34825
  matColorArray[0],
34959
34826
  matColorArray[1],
34960
34827
  matColorArray[2]
@@ -34999,11 +34866,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34999
34866
  };
35000
34867
 
35001
34868
  // src/utils/manifold/create-three-geometry-meshes.ts
35002
- import * as THREE36 from "three";
34869
+ import * as THREE37 from "three";
35003
34870
 
35004
34871
  // src/utils/create-board-material.ts
35005
- import * as THREE35 from "three";
35006
- var DEFAULT_SIDE = THREE35.DoubleSide;
34872
+ import * as THREE36 from "three";
34873
+ var DEFAULT_SIDE = THREE36.DoubleSide;
35007
34874
  var createBoardMaterial = ({
35008
34875
  material,
35009
34876
  color,
@@ -35011,7 +34878,7 @@ var createBoardMaterial = ({
35011
34878
  isFaux = false
35012
34879
  }) => {
35013
34880
  if (material === "fr4") {
35014
- return new THREE35.MeshPhysicalMaterial({
34881
+ return new THREE36.MeshPhysicalMaterial({
35015
34882
  color,
35016
34883
  side,
35017
34884
  metalness: 0,
@@ -35028,7 +34895,7 @@ var createBoardMaterial = ({
35028
34895
  polygonOffsetUnits: 1
35029
34896
  });
35030
34897
  }
35031
- return new THREE35.MeshStandardMaterial({
34898
+ return new THREE36.MeshStandardMaterial({
35032
34899
  color,
35033
34900
  side,
35034
34901
  flatShading: true,
@@ -35047,12 +34914,12 @@ function createGeometryMeshes(geoms) {
35047
34914
  const meshes = [];
35048
34915
  if (!geoms) return meshes;
35049
34916
  if (geoms.board && geoms.board.geometry) {
35050
- const mesh = new THREE36.Mesh(
34917
+ const mesh = new THREE37.Mesh(
35051
34918
  geoms.board.geometry,
35052
34919
  createBoardMaterial({
35053
34920
  material: geoms.board.material,
35054
34921
  color: geoms.board.color,
35055
- side: THREE36.DoubleSide,
34922
+ side: THREE37.DoubleSide,
35056
34923
  isFaux: geoms.board.isFaux
35057
34924
  })
35058
34925
  );
@@ -35062,11 +34929,11 @@ function createGeometryMeshes(geoms) {
35062
34929
  const createMeshesFromArray = (geomArray) => {
35063
34930
  if (geomArray) {
35064
34931
  geomArray.forEach((comp) => {
35065
- const mesh = new THREE36.Mesh(
34932
+ const mesh = new THREE37.Mesh(
35066
34933
  comp.geometry,
35067
- new THREE36.MeshStandardMaterial({
34934
+ new THREE37.MeshStandardMaterial({
35068
34935
  color: comp.color,
35069
- side: THREE36.DoubleSide,
34936
+ side: THREE37.DoubleSide,
35070
34937
  flatShading: true
35071
34938
  // Consistent with board
35072
34939
  })
@@ -35110,7 +34977,7 @@ var BoardMeshes = ({
35110
34977
  const typedMaterial = material;
35111
34978
  for (const prop of textureProps) {
35112
34979
  const texture = typedMaterial[prop];
35113
- if (texture && texture instanceof THREE37.Texture) {
34980
+ if (texture && texture instanceof THREE38.Texture) {
35114
34981
  texture.dispose();
35115
34982
  typedMaterial[prop] = null;
35116
34983
  }
@@ -42052,7 +41919,7 @@ var KeyboardShortcutsDialog = ({
42052
41919
 
42053
41920
  // src/CadViewer.tsx
42054
41921
  import { jsx as jsx38, jsxs as jsxs11 } from "react/jsx-runtime";
42055
- var DEFAULT_TARGET = new THREE38.Vector3(0, 0, 0);
41922
+ var DEFAULT_TARGET = new THREE39.Vector3(0, 0, 0);
42056
41923
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
42057
41924
  var CadViewerInner = (props) => {
42058
41925
  const [engine, setEngine] = useState36("manifold");
@@ -42319,11 +42186,11 @@ var CadViewer = (props) => {
42319
42186
  // src/convert-circuit-json-to-3d-svg.ts
42320
42187
  var import_debug = __toESM(require_browser(), 1);
42321
42188
  import { su as su18 } from "@tscircuit/circuit-json-util";
42322
- import * as THREE42 from "three";
42189
+ import * as THREE43 from "three";
42323
42190
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
42324
42191
 
42325
42192
  // src/utils/create-geometry-from-polygons.ts
42326
- import * as THREE39 from "three";
42193
+ import * as THREE40 from "three";
42327
42194
  import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute3 } from "three";
42328
42195
  function createGeometryFromPolygons(polygons) {
42329
42196
  const geometry = new BufferGeometry4();
@@ -42337,12 +42204,12 @@ function createGeometryFromPolygons(polygons) {
42337
42204
  ...polygon3.vertices[i + 1]
42338
42205
  // Third vertex
42339
42206
  );
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)
42207
+ const v1 = new THREE40.Vector3(...polygon3.vertices[0]);
42208
+ const v2 = new THREE40.Vector3(...polygon3.vertices[i]);
42209
+ const v3 = new THREE40.Vector3(...polygon3.vertices[i + 1]);
42210
+ const normal = new THREE40.Vector3().crossVectors(
42211
+ new THREE40.Vector3().subVectors(v2, v1),
42212
+ new THREE40.Vector3().subVectors(v3, v1)
42346
42213
  ).normalize();
42347
42214
  normals.push(
42348
42215
  normal.x,
@@ -42366,10 +42233,10 @@ function createGeometryFromPolygons(polygons) {
42366
42233
  var import_modeling2 = __toESM(require_src(), 1);
42367
42234
  var import_jscad_planner2 = __toESM(require_dist(), 1);
42368
42235
  var jscadModeling2 = __toESM(require_src(), 1);
42369
- import * as THREE41 from "three";
42236
+ import * as THREE42 from "three";
42370
42237
 
42371
42238
  // src/utils/load-model.ts
42372
- import * as THREE40 from "three";
42239
+ import * as THREE41 from "three";
42373
42240
  import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
42374
42241
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
42375
42242
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -42377,12 +42244,12 @@ async function load3DModel(url) {
42377
42244
  if (url.endsWith(".stl")) {
42378
42245
  const loader = new STLLoader2();
42379
42246
  const geometry = await loader.loadAsync(url);
42380
- const material = new THREE40.MeshStandardMaterial({
42247
+ const material = new THREE41.MeshStandardMaterial({
42381
42248
  color: 8947848,
42382
42249
  metalness: 0.5,
42383
42250
  roughness: 0.5
42384
42251
  });
42385
- return new THREE40.Mesh(geometry, material);
42252
+ return new THREE41.Mesh(geometry, material);
42386
42253
  }
42387
42254
  if (url.endsWith(".obj")) {
42388
42255
  const loader = new OBJLoader2();
@@ -42415,9 +42282,9 @@ async function renderComponent(component, scene) {
42415
42282
  }
42416
42283
  if (component.rotation) {
42417
42284
  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)
42285
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42286
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42287
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42421
42288
  );
42422
42289
  }
42423
42290
  scene.add(model);
@@ -42431,13 +42298,13 @@ async function renderComponent(component, scene) {
42431
42298
  );
42432
42299
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
42433
42300
  const threeGeom = convertCSGToThreeGeom(jscadObject);
42434
- const material2 = new THREE41.MeshStandardMaterial({
42301
+ const material2 = new THREE42.MeshStandardMaterial({
42435
42302
  color: 8947848,
42436
42303
  metalness: 0.5,
42437
42304
  roughness: 0.5,
42438
- side: THREE41.DoubleSide
42305
+ side: THREE42.DoubleSide
42439
42306
  });
42440
- const mesh2 = new THREE41.Mesh(threeGeom, material2);
42307
+ const mesh2 = new THREE42.Mesh(threeGeom, material2);
42441
42308
  if (component.position) {
42442
42309
  mesh2.position.set(
42443
42310
  component.position.x ?? 0,
@@ -42447,9 +42314,9 @@ async function renderComponent(component, scene) {
42447
42314
  }
42448
42315
  if (component.rotation) {
42449
42316
  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)
42317
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42318
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42319
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42453
42320
  );
42454
42321
  }
42455
42322
  scene.add(mesh2);
@@ -42466,17 +42333,17 @@ async function renderComponent(component, scene) {
42466
42333
  if (!geom || !geom.polygons && !geom.sides) {
42467
42334
  continue;
42468
42335
  }
42469
- const color = new THREE41.Color(geomInfo.color);
42336
+ const color = new THREE42.Color(geomInfo.color);
42470
42337
  color.convertLinearToSRGB();
42471
42338
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
42472
42339
  const threeGeom = convertCSGToThreeGeom(geomWithColor);
42473
- const material2 = new THREE41.MeshStandardMaterial({
42340
+ const material2 = new THREE42.MeshStandardMaterial({
42474
42341
  vertexColors: true,
42475
42342
  metalness: 0.2,
42476
42343
  roughness: 0.8,
42477
- side: THREE41.DoubleSide
42344
+ side: THREE42.DoubleSide
42478
42345
  });
42479
- const mesh2 = new THREE41.Mesh(threeGeom, material2);
42346
+ const mesh2 = new THREE42.Mesh(threeGeom, material2);
42480
42347
  if (component.position) {
42481
42348
  mesh2.position.set(
42482
42349
  component.position.x ?? 0,
@@ -42486,22 +42353,22 @@ async function renderComponent(component, scene) {
42486
42353
  }
42487
42354
  if (component.rotation) {
42488
42355
  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)
42356
+ THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
42357
+ THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
42358
+ THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
42492
42359
  );
42493
42360
  }
42494
42361
  scene.add(mesh2);
42495
42362
  }
42496
42363
  return;
42497
42364
  }
42498
- const geometry = new THREE41.BoxGeometry(0.5, 0.5, 0.5);
42499
- const material = new THREE41.MeshStandardMaterial({
42365
+ const geometry = new THREE42.BoxGeometry(0.5, 0.5, 0.5);
42366
+ const material = new THREE42.MeshStandardMaterial({
42500
42367
  color: 16711680,
42501
42368
  transparent: true,
42502
42369
  opacity: 0.25
42503
42370
  });
42504
- const mesh = new THREE41.Mesh(geometry, material);
42371
+ const mesh = new THREE42.Mesh(geometry, material);
42505
42372
  if (component.position) {
42506
42373
  mesh.position.set(
42507
42374
  component.position.x ?? 0,
@@ -42522,11 +42389,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42522
42389
  padding = 20,
42523
42390
  zoom = 1.5
42524
42391
  } = options;
42525
- const scene = new THREE42.Scene();
42392
+ const scene = new THREE43.Scene();
42526
42393
  const renderer = new SVGRenderer();
42527
42394
  renderer.setSize(width10, height10);
42528
- renderer.setClearColor(new THREE42.Color(backgroundColor), 1);
42529
- const camera = new THREE42.OrthographicCamera();
42395
+ renderer.setClearColor(new THREE43.Color(backgroundColor), 1);
42396
+ const camera = new THREE43.OrthographicCamera();
42530
42397
  const aspect = width10 / height10;
42531
42398
  const frustumSize = 100;
42532
42399
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -42540,11 +42407,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42540
42407
  camera.position.set(position.x, position.y, position.z);
42541
42408
  camera.up.set(0, 1, 0);
42542
42409
  const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
42543
- camera.lookAt(new THREE42.Vector3(lookAt.x, lookAt.y, lookAt.z));
42410
+ camera.lookAt(new THREE43.Vector3(lookAt.x, lookAt.y, lookAt.z));
42544
42411
  camera.updateProjectionMatrix();
42545
- const ambientLight = new THREE42.AmbientLight(16777215, Math.PI / 2);
42412
+ const ambientLight = new THREE43.AmbientLight(16777215, Math.PI / 2);
42546
42413
  scene.add(ambientLight);
42547
- const pointLight = new THREE42.PointLight(16777215, Math.PI / 4);
42414
+ const pointLight = new THREE43.PointLight(16777215, Math.PI / 4);
42548
42415
  pointLight.position.set(-10, -10, 10);
42549
42416
  scene.add(pointLight);
42550
42417
  const components = su18(circuitJson).cad_component.list();
@@ -42555,7 +42422,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42555
42422
  const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
42556
42423
  if (boardGeom) {
42557
42424
  const solderMaskColor = colors.fr4SolderMaskGreen;
42558
- const baseColor = new THREE42.Color(
42425
+ const baseColor = new THREE43.Color(
42559
42426
  solderMaskColor[0],
42560
42427
  solderMaskColor[1],
42561
42428
  solderMaskColor[2]
@@ -42567,28 +42434,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42567
42434
  const material = createBoardMaterial({
42568
42435
  material: boardData?.material,
42569
42436
  color: baseColor,
42570
- side: THREE42.DoubleSide
42437
+ side: THREE43.DoubleSide
42571
42438
  });
42572
- const mesh = new THREE42.Mesh(geometry, material);
42439
+ const mesh = new THREE43.Mesh(geometry, material);
42573
42440
  scene.add(mesh);
42574
42441
  }
42575
42442
  }
42576
- const gridColor = new THREE42.Color(8947848);
42577
- const gridHelper = new THREE42.GridHelper(100, 100, gridColor, gridColor);
42443
+ const gridColor = new THREE43.Color(8947848);
42444
+ const gridHelper = new THREE43.GridHelper(100, 100, gridColor, gridColor);
42578
42445
  gridHelper.rotation.x = Math.PI / 2;
42579
42446
  const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
42580
42447
  for (const mat of materials) {
42581
42448
  mat.transparent = true;
42582
42449
  mat.opacity = 0.3;
42583
- if (mat instanceof THREE42.LineBasicMaterial) {
42450
+ if (mat instanceof THREE43.LineBasicMaterial) {
42584
42451
  mat.color = gridColor;
42585
42452
  mat.vertexColors = false;
42586
42453
  }
42587
42454
  }
42588
42455
  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());
42456
+ const box = new THREE43.Box3().setFromObject(scene);
42457
+ const center = box.getCenter(new THREE43.Vector3());
42458
+ const size4 = box.getSize(new THREE43.Vector3());
42592
42459
  scene.position.sub(center);
42593
42460
  const maxDim = Math.max(size4.x, size4.y, size4.z);
42594
42461
  if (maxDim > 0) {