@tscircuit/3d-viewer 0.0.420 → 0.0.421

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 +50 -56
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26647,7 +26647,7 @@ import * as THREE14 from "three";
26647
26647
  // package.json
26648
26648
  var package_default = {
26649
26649
  name: "@tscircuit/3d-viewer",
26650
- version: "0.0.419",
26650
+ version: "0.0.420",
26651
26651
  main: "./dist/index.js",
26652
26652
  module: "./dist/index.js",
26653
26653
  type: "module",
@@ -27719,6 +27719,10 @@ import { su as su2 } from "@tscircuit/circuit-json-util";
27719
27719
 
27720
27720
  // src/geoms/constants.ts
27721
27721
  var M = 0.01;
27722
+ var BOARD_SURFACE_OFFSET = {
27723
+ traces: 1e-3,
27724
+ copper: 2e-3
27725
+ };
27722
27726
  var colors = {
27723
27727
  copper: [0.9, 0.6, 0.2],
27724
27728
  fr4Green: [0.04, 0.16, 0.08],
@@ -27864,9 +27868,12 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27864
27868
  const { clipGeom } = options;
27865
27869
  if (!plated_hole.shape) plated_hole.shape = "circle";
27866
27870
  const throughDrillHeight = ctx.pcbThickness + 2 * platedHoleLipHeight + 4 * M;
27871
+ const topSurfaceZ = ctx.pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper;
27872
+ const bottomSurfaceZ = -ctx.pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper;
27873
+ const copperSpan = topSurfaceZ - bottomSurfaceZ;
27867
27874
  if (plated_hole.shape === "circle") {
27868
27875
  const outerDiameter = plated_hole.outer_diameter ?? Math.max(plated_hole.hole_diameter, 0);
27869
- const copperHeight = ctx.pcbThickness + 2 * platedHoleLipHeight;
27876
+ const copperHeight = copperSpan + 0.01;
27870
27877
  const copperBody = (0, import_primitives3.cylinder)({
27871
27878
  center: [plated_hole.x, plated_hole.y, 0],
27872
27879
  radius: outerDiameter / 2,
@@ -27894,12 +27901,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27894
27901
  height: padHeight,
27895
27902
  thickness: platedHoleLipHeight,
27896
27903
  // Slightly thicker to ensure connection
27897
- center: [
27898
- plated_hole.x,
27899
- plated_hole.y,
27900
- ctx.pcbThickness / 2 + platedHoleLipHeight / 2 + M - 0.05
27901
- // Adjusted for thickness
27902
- ],
27904
+ center: [plated_hole.x, plated_hole.y, topSurfaceZ],
27903
27905
  borderRadius: rectBorderRadius
27904
27906
  }),
27905
27907
  // Bottom rectangular pad (thicker to ensure connection)
@@ -27908,17 +27910,15 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27908
27910
  height: padHeight,
27909
27911
  thickness: platedHoleLipHeight,
27910
27912
  // Slightly thicker to ensure connection
27911
- center: [
27912
- plated_hole.x,
27913
- plated_hole.y,
27914
- -ctx.pcbThickness / 2 - platedHoleLipHeight / 2 - M + 0.05
27915
- // Adjusted for thickness
27916
- ],
27913
+ center: [plated_hole.x, plated_hole.y, bottomSurfaceZ],
27917
27914
  borderRadius: rectBorderRadius
27918
27915
  }),
27919
27916
  // Main copper fill between pads with rounded corners
27920
27917
  (() => {
27921
- const height10 = ctx.pcbThickness - platedHoleLipHeight * 2 - M * 2 + 0.1;
27918
+ const height10 = Math.max(copperSpan - platedHoleLipHeight * 2, M);
27919
+ const topPadBottom = topSurfaceZ;
27920
+ const bottomPadTop = bottomSurfaceZ;
27921
+ const centerZ = (topPadBottom + bottomPadTop) / 2;
27922
27922
  const rect2d = (0, import_primitives3.roundedRectangle)({
27923
27923
  size: [padWidth, padHeight],
27924
27924
  roundRadius: rectBorderRadius || 0,
@@ -27926,12 +27926,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27926
27926
  });
27927
27927
  const extruded = (0, import_extrusions2.extrudeLinear)({ height: height10 }, rect2d);
27928
27928
  return (0, import_transforms2.translate)(
27929
- [
27930
- plated_hole.x,
27931
- plated_hole.y,
27932
- -height10 / 2
27933
- // Center vertically
27934
- ],
27929
+ [plated_hole.x, plated_hole.y, centerZ - height10 / 2],
27935
27930
  extruded
27936
27931
  );
27937
27932
  })(),
@@ -27943,7 +27938,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27943
27938
  0
27944
27939
  ],
27945
27940
  radius: plated_hole.hole_diameter / 2,
27946
- height: ctx.pcbThickness
27941
+ height: copperSpan
27947
27942
  })
27948
27943
  ),
27949
27944
  clipGeom
@@ -27964,7 +27959,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27964
27959
  0
27965
27960
  ],
27966
27961
  radius: plated_hole.hole_diameter / 2,
27967
- height: ctx.pcbThickness
27962
+ height: copperSpan
27968
27963
  });
27969
27964
  let finalCopper = (0, import_booleans.union)(
27970
27965
  (0, import_booleans.subtract)(copperSolid, barrel),
@@ -27989,7 +27984,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
27989
27984
  const outerRadius = outerPillHeight / 2;
27990
27985
  const rectLength = Math.abs(holeWidth - holeHeight);
27991
27986
  const outerRectLength = Math.abs(outerPillWidth - outerPillHeight);
27992
- const copperHeight = ctx.pcbThickness + 2 * (platedHoleLipHeight + M);
27987
+ const copperHeight = copperSpan + 0.01;
27993
27988
  const createPillSection = (width10, height10, thickness) => {
27994
27989
  const radius = height10 / 2;
27995
27990
  const length2 = Math.abs(width10 - height10);
@@ -28058,11 +28053,11 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28058
28053
  size: shouldRotate ? [
28059
28054
  holeHeight + 2 * barrelMargin,
28060
28055
  rectLength + 2 * barrelMargin,
28061
- ctx.pcbThickness + 0.02
28056
+ copperSpan
28062
28057
  ] : [
28063
28058
  rectLength + 2 * barrelMargin,
28064
28059
  holeHeight + 2 * barrelMargin,
28065
- ctx.pcbThickness
28060
+ copperSpan
28066
28061
  ]
28067
28062
  }),
28068
28063
  (0, import_primitives3.cylinder)({
@@ -28076,7 +28071,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28076
28071
  0
28077
28072
  ],
28078
28073
  radius: holeRadius + barrelMargin,
28079
- height: ctx.pcbThickness + 0.02
28074
+ height: copperSpan
28080
28075
  }),
28081
28076
  (0, import_primitives3.cylinder)({
28082
28077
  center: shouldRotate ? [
@@ -28089,7 +28084,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28089
28084
  0
28090
28085
  ],
28091
28086
  radius: holeRadius + barrelMargin,
28092
- height: ctx.pcbThickness + 0.02
28087
+ height: copperSpan
28093
28088
  })
28094
28089
  );
28095
28090
  const holeCut = (0, import_booleans.union)(
@@ -28128,33 +28123,31 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28128
28123
  width: padWidth,
28129
28124
  height: padHeight,
28130
28125
  thickness: platedHoleLipHeight,
28131
- center: [
28132
- plated_hole.x,
28133
- plated_hole.y,
28134
- ctx.pcbThickness / 2 + platedHoleLipHeight / 2 + M - 0.05
28135
- ],
28126
+ center: [plated_hole.x, plated_hole.y, topSurfaceZ],
28136
28127
  borderRadius: rectBorderRadius
28137
28128
  });
28138
28129
  const copperBottomPad = createRectPadGeom({
28139
28130
  width: padWidth,
28140
28131
  height: padHeight,
28141
28132
  thickness: platedHoleLipHeight,
28142
- center: [
28143
- plated_hole.x,
28144
- plated_hole.y,
28145
- -ctx.pcbThickness / 2 - platedHoleLipHeight / 2 - M + 0.05
28146
- ],
28133
+ center: [plated_hole.x, plated_hole.y, bottomSurfaceZ],
28147
28134
  borderRadius: rectBorderRadius
28148
28135
  });
28149
28136
  const copperFill = (() => {
28150
- const height10 = ctx.pcbThickness - platedHoleLipHeight * 2 - M * 2 + 0.1;
28137
+ const height10 = Math.max(copperSpan - platedHoleLipHeight * 2, M);
28138
+ const topPadBottom = topSurfaceZ;
28139
+ const bottomPadTop = bottomSurfaceZ;
28140
+ const centerZ = (topPadBottom + bottomPadTop) / 2;
28151
28141
  const rect2d = (0, import_primitives3.roundedRectangle)({
28152
28142
  size: [padWidth, padHeight],
28153
28143
  roundRadius: rectBorderRadius || 0,
28154
28144
  segments: RECT_PAD_SEGMENTS
28155
28145
  });
28156
28146
  const extruded = (0, import_extrusions2.extrudeLinear)({ height: height10 }, rect2d);
28157
- return (0, import_transforms2.translate)([plated_hole.x, plated_hole.y, -height10 / 2], extruded);
28147
+ return (0, import_transforms2.translate)(
28148
+ [plated_hole.x, plated_hole.y, centerZ - height10 / 2],
28149
+ extruded
28150
+ );
28158
28151
  })();
28159
28152
  const copperTopPadCut = (0, import_booleans.subtract)(copperTopPad, holeCut);
28160
28153
  const copperBottomPadCut = (0, import_booleans.subtract)(copperBottomPad, holeCut);
@@ -28880,7 +28873,7 @@ var BoardGeomBuilder = class {
28880
28873
  }
28881
28874
  processCopperPour(pour) {
28882
28875
  const layerSign = pour.layer === "bottom" ? -1 : 1;
28883
- const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * M;
28876
+ const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.copper;
28884
28877
  let pourGeom = null;
28885
28878
  if (pour.shape === "rect") {
28886
28879
  let baseGeom = (0, import_primitives6.cuboid)({
@@ -29112,7 +29105,7 @@ var BoardGeomBuilder = class {
29112
29105
  }
29113
29106
  processPad(pad2) {
29114
29107
  const layerSign = pad2.layer === "bottom" ? -1 : 1;
29115
- const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * M * 2;
29108
+ const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.copper;
29116
29109
  const rectBorderRadius = extractRectBorderRadius(pad2);
29117
29110
  if (pad2.shape === "rect") {
29118
29111
  const basePadGeom = createCenteredRectPadGeom(
@@ -29166,14 +29159,14 @@ var BoardGeomBuilder = class {
29166
29159
  const finishSegment = () => {
29167
29160
  if (currentSegmentPoints.length >= 2 && currentLayer) {
29168
29161
  const layerSign = currentLayer === "bottom" ? -1 : 1;
29169
- const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * M;
29162
+ const zCenter = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.traces;
29170
29163
  const linePath = (0, import_primitives6.line)(currentSegmentPoints);
29171
29164
  const expandedPath = (0, import_expansions3.expand)(
29172
29165
  { delta: currentWidth / 2, corners: "round" },
29173
29166
  linePath
29174
29167
  );
29175
29168
  let traceGeom = (0, import_transforms4.translate)(
29176
- [0, 0, zPos],
29169
+ [0, 0, zCenter - M / 2],
29177
29170
  (0, import_extrusions4.extrudeLinear)({ height: M }, expandedPath)
29178
29171
  );
29179
29172
  const startPointCoords = currentSegmentPoints[0];
@@ -29184,7 +29177,7 @@ var BoardGeomBuilder = class {
29184
29177
  );
29185
29178
  if (startHole) {
29186
29179
  const cuttingCylinder = (0, import_primitives6.cylinder)({
29187
- center: [startPointCoords[0], startPointCoords[1], zPos + M / 2],
29180
+ center: [startPointCoords[0], startPointCoords[1], zCenter],
29188
29181
  radius: startHole.diameter / 2 + M,
29189
29182
  height: M
29190
29183
  });
@@ -29193,7 +29186,7 @@ var BoardGeomBuilder = class {
29193
29186
  const endHole = this.getHoleToCut(endPointCoords[0], endPointCoords[1]);
29194
29187
  if (endHole) {
29195
29188
  const cuttingCylinder = (0, import_primitives6.cylinder)({
29196
- center: [endPointCoords[0], endPointCoords[1], zPos + M / 2],
29189
+ center: [endPointCoords[0], endPointCoords[1], zCenter],
29197
29190
  radius: endHole.diameter / 2 + M,
29198
29191
  height: M
29199
29192
  });
@@ -30294,7 +30287,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
30294
30287
  Manifold,
30295
30288
  width: padWidth,
30296
30289
  height: padHeight,
30297
- thickness: pcbThickness - 2 * padThickness + 0.1,
30290
+ thickness: pcbThickness - 2 * padThickness - 2 * BOARD_SURFACE_OFFSET.copper + 0.1,
30298
30291
  // Fill between pads
30299
30292
  borderRadius: rectBorderRadius
30300
30293
  });
@@ -30305,14 +30298,14 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
30305
30298
  height: padHeight,
30306
30299
  thickness: padThickness,
30307
30300
  borderRadius: rectBorderRadius
30308
- }).translate([0, 0, pcbThickness / 2 - padThickness / 2 + 0.05]);
30301
+ }).translate([0, 0, pcbThickness / 2 / 2 + BOARD_SURFACE_OFFSET.copper]);
30309
30302
  const bottomPad = createRoundedRectPrism({
30310
30303
  Manifold,
30311
30304
  width: padWidth,
30312
30305
  height: padHeight,
30313
30306
  thickness: padThickness,
30314
30307
  borderRadius: rectBorderRadius
30315
- }).translate([0, 0, -pcbThickness / 2 + padThickness / 2 - 0.05]);
30308
+ }).translate([0, 0, -pcbThickness / 2 / 2 - BOARD_SURFACE_OFFSET.copper]);
30316
30309
  manifoldInstancesForCleanup.push(topPad, bottomPad);
30317
30310
  const barrelPill = createPillOp(
30318
30311
  holeW,
@@ -30379,7 +30372,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
30379
30372
  Manifold,
30380
30373
  width: padWidth,
30381
30374
  height: padHeight,
30382
- thickness: pcbThickness - 2 * padThickness + 0.1,
30375
+ thickness: pcbThickness - 2 * padThickness - 2 * BOARD_SURFACE_OFFSET.copper + 0.1,
30383
30376
  // Fill between pads
30384
30377
  borderRadius: rectBorderRadius
30385
30378
  });
@@ -30390,14 +30383,14 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
30390
30383
  height: padHeight,
30391
30384
  thickness: padThickness,
30392
30385
  borderRadius: rectBorderRadius
30393
- }).translate([0, 0, pcbThickness / 2 - padThickness / 2 + 0.05]);
30386
+ }).translate([0, 0, pcbThickness / 2 / 2 + BOARD_SURFACE_OFFSET.copper]);
30394
30387
  const bottomPad = createRoundedRectPrism({
30395
30388
  Manifold,
30396
30389
  width: padWidth,
30397
30390
  height: padHeight,
30398
30391
  thickness: padThickness,
30399
30392
  borderRadius: rectBorderRadius
30400
- }).translate([0, 0, -pcbThickness / 2 + padThickness / 2 - 0.05]);
30393
+ }).translate([0, 0, -pcbThickness / 2 / 2 - BOARD_SURFACE_OFFSET.copper]);
30401
30394
  manifoldInstancesForCleanup.push(topPad, bottomPad);
30402
30395
  const barrelCylinder = Manifold.cylinder(
30403
30396
  pcbThickness * 1.02,
@@ -30549,7 +30542,7 @@ function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifold
30549
30542
  const smtPads = su10(circuitJson).pcb_smtpad.list();
30550
30543
  smtPads.forEach((pad2, index2) => {
30551
30544
  const padBaseThickness = DEFAULT_SMT_PAD_THICKNESS;
30552
- const zPos = pad2.layer === "bottom" ? -pcbThickness / 2 - padBaseThickness / 2 - MANIFOLD_Z_OFFSET : pcbThickness / 2 + padBaseThickness / 2 + MANIFOLD_Z_OFFSET;
30545
+ const zPos = pad2.layer === "bottom" ? -pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper : pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper;
30553
30546
  let padManifoldOp = createPadManifoldOp({
30554
30547
  Manifold,
30555
30548
  pad: pad2,
@@ -31261,8 +31254,8 @@ function createTextureMeshes(textures, boardData, pcbThickness) {
31261
31254
  };
31262
31255
  const topTraceMesh = createTexturePlane(
31263
31256
  textures.topTrace,
31264
- pcbThickness / 2 + 0.015,
31265
- // Offset similar to CadViewerManifold
31257
+ pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces,
31258
+ // Use consistent copper offset
31266
31259
  false,
31267
31260
  "trace"
31268
31261
  );
@@ -31277,7 +31270,8 @@ function createTextureMeshes(textures, boardData, pcbThickness) {
31277
31270
  if (topSilkscreenMesh) meshes.push(topSilkscreenMesh);
31278
31271
  const bottomTraceMesh = createTexturePlane(
31279
31272
  textures.bottomTrace,
31280
- -pcbThickness / 2 - 0.015,
31273
+ -pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces,
31274
+ // Use consistent copper offset
31281
31275
  true,
31282
31276
  "trace"
31283
31277
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.420",
3
+ "version": "0.0.421",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",