@tscircuit/3d-viewer 0.0.527 → 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.
- package/dist/index.js +250 -342
- package/package.json +3 -3
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
28772
|
+
version: "0.0.528",
|
|
28773
28773
|
main: "./dist/index.js",
|
|
28774
28774
|
module: "./dist/index.js",
|
|
28775
28775
|
type: "module",
|
|
@@ -28798,8 +28798,8 @@ var package_default = {
|
|
|
28798
28798
|
dependencies: {
|
|
28799
28799
|
"@jscad/regl-renderer": "^2.6.12",
|
|
28800
28800
|
"@jscad/stl-serializer": "^2.1.20",
|
|
28801
|
-
"circuit-json": "^0.0.
|
|
28802
|
-
"circuit-to-canvas": "^0.0.
|
|
28801
|
+
"circuit-json": "^0.0.391",
|
|
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 =
|
|
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:
|
|
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 =
|
|
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)(
|
|
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)(
|
|
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
|
|
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
|
|
30805
|
-
|
|
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
|
|
31651
|
+
import * as THREE28 from "three";
|
|
31742
31652
|
|
|
31743
31653
|
// node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
|
|
31744
31654
|
var getBoundsFromPoints = (points) => {
|
|
@@ -31925,8 +31835,16 @@ function createPadTextureForLayer({
|
|
|
31925
31835
|
}
|
|
31926
31836
|
|
|
31927
31837
|
// src/utils/panel-outline-texture.ts
|
|
31928
|
-
import * as THREE20 from "three";
|
|
31929
31838
|
import { su as su6 } from "@tscircuit/circuit-json-util";
|
|
31839
|
+
import * as THREE20 from "three";
|
|
31840
|
+
var resolvePanelIdForTexture = (circuitJson) => {
|
|
31841
|
+
const panels = circuitJson.filter(
|
|
31842
|
+
(e) => e.type === "pcb_panel"
|
|
31843
|
+
);
|
|
31844
|
+
if (panels.length === 0) return null;
|
|
31845
|
+
if (panels.length === 1) return panels[0].pcb_panel_id;
|
|
31846
|
+
return null;
|
|
31847
|
+
};
|
|
31930
31848
|
function createPanelOutlineTextureForLayer({
|
|
31931
31849
|
layer,
|
|
31932
31850
|
circuitJson,
|
|
@@ -31934,7 +31852,12 @@ function createPanelOutlineTextureForLayer({
|
|
|
31934
31852
|
outlineColor = "black",
|
|
31935
31853
|
traceTextureResolution
|
|
31936
31854
|
}) {
|
|
31937
|
-
const
|
|
31855
|
+
const panelId = resolvePanelIdForTexture(circuitJson);
|
|
31856
|
+
if (!panelId) return null;
|
|
31857
|
+
const allBoards = su6(circuitJson).pcb_board.list();
|
|
31858
|
+
const boardsInPanel = allBoards.filter(
|
|
31859
|
+
(b) => b.pcb_panel_id === panelId || b.position_mode === "relative_to_panel_anchor" && !b.pcb_panel_id
|
|
31860
|
+
);
|
|
31938
31861
|
if (boardsInPanel.length === 0) {
|
|
31939
31862
|
return null;
|
|
31940
31863
|
}
|
|
@@ -32893,6 +32816,109 @@ function createSoldermaskTextureForLayer({
|
|
|
32893
32816
|
return texture;
|
|
32894
32817
|
}
|
|
32895
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
|
+
|
|
32896
32922
|
// src/textures/create-combined-board-textures.ts
|
|
32897
32923
|
var toRgb2 = (colorArr) => {
|
|
32898
32924
|
const [r = 0, g = 0, b = 0] = colorArr;
|
|
@@ -32925,10 +32951,10 @@ var createCombinedTexture = ({
|
|
|
32925
32951
|
const image = texture.image;
|
|
32926
32952
|
ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
|
|
32927
32953
|
});
|
|
32928
|
-
const combinedTexture = new
|
|
32954
|
+
const combinedTexture = new THREE28.CanvasTexture(canvas);
|
|
32929
32955
|
combinedTexture.generateMipmaps = false;
|
|
32930
|
-
combinedTexture.minFilter =
|
|
32931
|
-
combinedTexture.magFilter =
|
|
32956
|
+
combinedTexture.minFilter = THREE28.LinearFilter;
|
|
32957
|
+
combinedTexture.magFilter = THREE28.LinearFilter;
|
|
32932
32958
|
combinedTexture.premultiplyAlpha = true;
|
|
32933
32959
|
combinedTexture.anisotropy = 16;
|
|
32934
32960
|
combinedTexture.needsUpdate = true;
|
|
@@ -32976,6 +33002,13 @@ function createCombinedBoardTextures({
|
|
|
32976
33002
|
copperColor,
|
|
32977
33003
|
traceTextureResolution
|
|
32978
33004
|
}) : null;
|
|
33005
|
+
const throughHoleTexture = showCopper ? createThroughHoleTextureForLayer({
|
|
33006
|
+
layer,
|
|
33007
|
+
circuitJson,
|
|
33008
|
+
boardData,
|
|
33009
|
+
copperColor,
|
|
33010
|
+
traceTextureResolution
|
|
33011
|
+
}) : null;
|
|
32979
33012
|
const silkscreenTexture = showSilkscreen ? createSilkscreenTextureForLayer({
|
|
32980
33013
|
layer,
|
|
32981
33014
|
circuitJson,
|
|
@@ -33006,6 +33039,7 @@ function createCombinedBoardTextures({
|
|
|
33006
33039
|
textures: [
|
|
33007
33040
|
traceTexture,
|
|
33008
33041
|
padTexture,
|
|
33042
|
+
throughHoleTexture,
|
|
33009
33043
|
soldermaskTexture,
|
|
33010
33044
|
copperTextTexture,
|
|
33011
33045
|
silkscreenTexture,
|
|
@@ -33025,15 +33059,15 @@ function createCombinedBoardTextures({
|
|
|
33025
33059
|
}
|
|
33026
33060
|
|
|
33027
33061
|
// src/textures/create-copper-pour-texture-for-layer.ts
|
|
33028
|
-
import * as
|
|
33029
|
-
import { CircuitToCanvasDrawer as
|
|
33062
|
+
import * as THREE29 from "three";
|
|
33063
|
+
import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
|
|
33030
33064
|
|
|
33031
33065
|
// src/geoms/brep-converter.ts
|
|
33032
33066
|
var import_primitives7 = __toESM(require_primitives(), 1);
|
|
33033
33067
|
var import_booleans5 = __toESM(require_booleans(), 1);
|
|
33034
33068
|
|
|
33035
33069
|
// src/textures/create-three-texture-meshes.ts
|
|
33036
|
-
import * as
|
|
33070
|
+
import * as THREE30 from "three";
|
|
33037
33071
|
function createTexturePlane(config, boardData) {
|
|
33038
33072
|
const {
|
|
33039
33073
|
texture,
|
|
@@ -33045,15 +33079,15 @@ function createTexturePlane(config, boardData) {
|
|
|
33045
33079
|
} = config;
|
|
33046
33080
|
if (!texture) return null;
|
|
33047
33081
|
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
33048
|
-
const planeGeom = new
|
|
33082
|
+
const planeGeom = new THREE30.PlaneGeometry(
|
|
33049
33083
|
boardOutlineBounds.width,
|
|
33050
33084
|
boardOutlineBounds.height
|
|
33051
33085
|
);
|
|
33052
|
-
const material = new
|
|
33086
|
+
const material = new THREE30.MeshBasicMaterial({
|
|
33053
33087
|
map: texture,
|
|
33054
33088
|
transparent: true,
|
|
33055
33089
|
alphaTest: 0.08,
|
|
33056
|
-
side:
|
|
33090
|
+
side: THREE30.DoubleSide,
|
|
33057
33091
|
depthWrite: true,
|
|
33058
33092
|
polygonOffset: usePolygonOffset,
|
|
33059
33093
|
polygonOffsetFactor: usePolygonOffset ? -4 : 0,
|
|
@@ -33061,7 +33095,7 @@ function createTexturePlane(config, boardData) {
|
|
|
33061
33095
|
polygonOffsetUnits: usePolygonOffset ? -4 : 0,
|
|
33062
33096
|
opacity: isFaux ? FAUX_BOARD_OPACITY : 1
|
|
33063
33097
|
});
|
|
33064
|
-
const mesh = new
|
|
33098
|
+
const mesh = new THREE30.Mesh(planeGeom, material);
|
|
33065
33099
|
mesh.position.set(
|
|
33066
33100
|
boardOutlineBounds.centerX,
|
|
33067
33101
|
boardOutlineBounds.centerY,
|
|
@@ -33106,7 +33140,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
|
|
|
33106
33140
|
}
|
|
33107
33141
|
|
|
33108
33142
|
// src/three-components/JscadBoardTextures.tsx
|
|
33109
|
-
import * as
|
|
33143
|
+
import * as THREE31 from "three";
|
|
33110
33144
|
|
|
33111
33145
|
// src/utils/layer-texture-resolution.ts
|
|
33112
33146
|
var DEFAULT_MAX_TEXTURE_PIXELS = 4e6;
|
|
@@ -33202,7 +33236,7 @@ function JscadBoardTextures({
|
|
|
33202
33236
|
const typedMaterial = material;
|
|
33203
33237
|
for (const prop of textureProps) {
|
|
33204
33238
|
const texture = typedMaterial[prop];
|
|
33205
|
-
if (texture && texture instanceof
|
|
33239
|
+
if (texture && texture instanceof THREE31.Texture) {
|
|
33206
33240
|
texture.dispose();
|
|
33207
33241
|
typedMaterial[prop] = null;
|
|
33208
33242
|
}
|
|
@@ -33212,22 +33246,22 @@ function JscadBoardTextures({
|
|
|
33212
33246
|
const createTexturePlane2 = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false, depthWrite = true, renderOrder = 1) => {
|
|
33213
33247
|
if (!texture) return null;
|
|
33214
33248
|
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
33215
|
-
const planeGeom = new
|
|
33249
|
+
const planeGeom = new THREE31.PlaneGeometry(
|
|
33216
33250
|
boardOutlineBounds.width,
|
|
33217
33251
|
boardOutlineBounds.height
|
|
33218
33252
|
);
|
|
33219
|
-
const material = new
|
|
33253
|
+
const material = new THREE31.MeshBasicMaterial({
|
|
33220
33254
|
map: texture,
|
|
33221
33255
|
transparent: true,
|
|
33222
33256
|
alphaTest: 0.08,
|
|
33223
|
-
side:
|
|
33257
|
+
side: THREE31.DoubleSide,
|
|
33224
33258
|
depthWrite,
|
|
33225
33259
|
polygonOffset: usePolygonOffset,
|
|
33226
33260
|
polygonOffsetFactor: usePolygonOffset ? -4 : 0,
|
|
33227
33261
|
polygonOffsetUnits: usePolygonOffset ? -4 : 0,
|
|
33228
33262
|
opacity: isFaux ? FAUX_BOARD_OPACITY : 1
|
|
33229
33263
|
});
|
|
33230
|
-
const mesh = new
|
|
33264
|
+
const mesh = new THREE31.Mesh(planeGeom, material);
|
|
33231
33265
|
mesh.position.set(
|
|
33232
33266
|
boardOutlineBounds.centerX,
|
|
33233
33267
|
boardOutlineBounds.centerY,
|
|
@@ -33272,7 +33306,7 @@ function JscadBoardTextures({
|
|
|
33272
33306
|
mesh.geometry.dispose();
|
|
33273
33307
|
if (Array.isArray(mesh.material)) {
|
|
33274
33308
|
mesh.material.forEach((material) => disposeTextureMaterial(material));
|
|
33275
|
-
} else if (mesh.material instanceof
|
|
33309
|
+
} else if (mesh.material instanceof THREE31.Material) {
|
|
33276
33310
|
disposeTextureMaterial(mesh.material);
|
|
33277
33311
|
}
|
|
33278
33312
|
});
|
|
@@ -33505,12 +33539,12 @@ var CadViewerJscad = forwardRef3(
|
|
|
33505
33539
|
// src/CadViewerManifold.tsx
|
|
33506
33540
|
import { su as su17 } from "@tscircuit/circuit-json-util";
|
|
33507
33541
|
import { useEffect as useEffect25, useMemo as useMemo22, useState as useState16 } from "react";
|
|
33508
|
-
import * as
|
|
33542
|
+
import * as THREE38 from "three";
|
|
33509
33543
|
|
|
33510
33544
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
33511
33545
|
import { su as su16 } from "@tscircuit/circuit-json-util";
|
|
33512
33546
|
import { useEffect as useEffect24, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
|
|
33513
|
-
import * as
|
|
33547
|
+
import * as THREE35 from "three";
|
|
33514
33548
|
|
|
33515
33549
|
// src/utils/manifold/create-manifold-board.ts
|
|
33516
33550
|
var arePointsClockwise2 = (points) => {
|
|
@@ -33852,17 +33886,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
|
|
|
33852
33886
|
|
|
33853
33887
|
// src/utils/manifold/process-plated-holes.ts
|
|
33854
33888
|
import { su as su14 } from "@tscircuit/circuit-json-util";
|
|
33855
|
-
import * as
|
|
33889
|
+
import * as THREE33 from "three";
|
|
33856
33890
|
|
|
33857
33891
|
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
33858
|
-
import * as
|
|
33892
|
+
import * as THREE32 from "three";
|
|
33859
33893
|
function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
33860
|
-
const geometry = new
|
|
33894
|
+
const geometry = new THREE32.BufferGeometry();
|
|
33861
33895
|
geometry.setAttribute(
|
|
33862
33896
|
"position",
|
|
33863
|
-
new
|
|
33897
|
+
new THREE32.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
|
|
33864
33898
|
);
|
|
33865
|
-
geometry.setIndex(new
|
|
33899
|
+
geometry.setIndex(new THREE32.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
|
|
33866
33900
|
if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
|
|
33867
33901
|
for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
|
|
33868
33902
|
const start = manifoldMesh.runIndex[i];
|
|
@@ -33896,7 +33930,7 @@ var createEllipsePoints = (width10, height10, segments) => {
|
|
|
33896
33930
|
}
|
|
33897
33931
|
return points;
|
|
33898
33932
|
};
|
|
33899
|
-
var COPPER_COLOR = new
|
|
33933
|
+
var COPPER_COLOR = new THREE33.Color(...colors.copper);
|
|
33900
33934
|
var PLATED_HOLE_LIP_HEIGHT = 0.05;
|
|
33901
33935
|
var PLATED_HOLE_PAD_THICKNESS = 3e-3;
|
|
33902
33936
|
var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
|
|
@@ -33998,6 +34032,10 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
33998
34032
|
return holeOp;
|
|
33999
34033
|
};
|
|
34000
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
|
+
);
|
|
34001
34039
|
if (ph.shape === "circle") {
|
|
34002
34040
|
const translatedDrill = createPlatedHoleDrill({
|
|
34003
34041
|
Manifold,
|
|
@@ -34010,7 +34048,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34010
34048
|
});
|
|
34011
34049
|
manifoldInstancesForCleanup.push(translatedDrill);
|
|
34012
34050
|
platedHoleBoardDrills.push(translatedDrill);
|
|
34013
|
-
const copperPartThickness =
|
|
34051
|
+
const copperPartThickness = internalCopperThickness;
|
|
34014
34052
|
const platedPart = Manifold.cylinder(
|
|
34015
34053
|
copperPartThickness,
|
|
34016
34054
|
ph.outer_diameter / 2,
|
|
@@ -34070,7 +34108,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34070
34108
|
]);
|
|
34071
34109
|
manifoldInstancesForCleanup.push(translatedBoardPillDrill);
|
|
34072
34110
|
platedHoleBoardDrills.push(translatedBoardPillDrill);
|
|
34073
|
-
const copperPartThickness =
|
|
34111
|
+
const copperPartThickness = internalCopperThickness;
|
|
34074
34112
|
const outerCopperOpUnrotated = createPillOp(
|
|
34075
34113
|
outerW,
|
|
34076
34114
|
outerH,
|
|
@@ -34148,29 +34186,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34148
34186
|
borderRadius: rectBorderRadius
|
|
34149
34187
|
});
|
|
34150
34188
|
manifoldInstancesForCleanup.push(mainFill);
|
|
34151
|
-
const topPad = createRoundedRectPrism({
|
|
34152
|
-
Manifold,
|
|
34153
|
-
width: padWidth,
|
|
34154
|
-
height: padHeight,
|
|
34155
|
-
thickness: padThickness,
|
|
34156
|
-
borderRadius: rectBorderRadius
|
|
34157
|
-
}).translate([
|
|
34158
|
-
0,
|
|
34159
|
-
0,
|
|
34160
|
-
pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
|
|
34161
|
-
]);
|
|
34162
|
-
const bottomPad = createRoundedRectPrism({
|
|
34163
|
-
Manifold,
|
|
34164
|
-
width: padWidth,
|
|
34165
|
-
height: padHeight,
|
|
34166
|
-
thickness: padThickness,
|
|
34167
|
-
borderRadius: rectBorderRadius
|
|
34168
|
-
}).translate([
|
|
34169
|
-
0,
|
|
34170
|
-
0,
|
|
34171
|
-
-pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
|
|
34172
|
-
]);
|
|
34173
|
-
manifoldInstancesForCleanup.push(topPad, bottomPad);
|
|
34174
34189
|
const barrelPill = createPillOp(
|
|
34175
34190
|
holeW,
|
|
34176
34191
|
holeH,
|
|
@@ -34178,12 +34193,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34178
34193
|
// Slightly shorter than board
|
|
34179
34194
|
).translate([holeOffsetX, holeOffsetY, 0]);
|
|
34180
34195
|
manifoldInstancesForCleanup.push(barrelPill);
|
|
34181
|
-
const copperUnion = Manifold.union([
|
|
34182
|
-
mainFill,
|
|
34183
|
-
topPad,
|
|
34184
|
-
bottomPad,
|
|
34185
|
-
barrelPill
|
|
34186
|
-
]);
|
|
34196
|
+
const copperUnion = Manifold.union([mainFill, barrelPill]);
|
|
34187
34197
|
manifoldInstancesForCleanup.push(copperUnion);
|
|
34188
34198
|
const holeCutOp = createPillOp(
|
|
34189
34199
|
Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
|
|
@@ -34263,39 +34273,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34263
34273
|
manifoldInstancesForCleanup.push(rotatedMainFill);
|
|
34264
34274
|
mainFill = rotatedMainFill;
|
|
34265
34275
|
}
|
|
34266
|
-
let topPad = createRoundedRectPrism({
|
|
34267
|
-
Manifold,
|
|
34268
|
-
width: padWidth,
|
|
34269
|
-
height: padHeight,
|
|
34270
|
-
thickness: padThickness,
|
|
34271
|
-
borderRadius: rectBorderRadius
|
|
34272
|
-
}).translate([
|
|
34273
|
-
0,
|
|
34274
|
-
0,
|
|
34275
|
-
pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
|
|
34276
|
-
]);
|
|
34277
|
-
if (ph.rect_ccw_rotation) {
|
|
34278
|
-
const rotatedTopPad = topPad.rotate([0, 0, ph.rect_ccw_rotation]);
|
|
34279
|
-
manifoldInstancesForCleanup.push(rotatedTopPad);
|
|
34280
|
-
topPad = rotatedTopPad;
|
|
34281
|
-
}
|
|
34282
|
-
let bottomPad = createRoundedRectPrism({
|
|
34283
|
-
Manifold,
|
|
34284
|
-
width: padWidth,
|
|
34285
|
-
height: padHeight,
|
|
34286
|
-
thickness: padThickness,
|
|
34287
|
-
borderRadius: rectBorderRadius
|
|
34288
|
-
}).translate([
|
|
34289
|
-
0,
|
|
34290
|
-
0,
|
|
34291
|
-
-pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
|
|
34292
|
-
]);
|
|
34293
|
-
if (ph.rect_ccw_rotation) {
|
|
34294
|
-
const rotatedBottomPad = bottomPad.rotate([0, 0, ph.rect_ccw_rotation]);
|
|
34295
|
-
manifoldInstancesForCleanup.push(rotatedBottomPad);
|
|
34296
|
-
bottomPad = rotatedBottomPad;
|
|
34297
|
-
}
|
|
34298
|
-
manifoldInstancesForCleanup.push(topPad, bottomPad);
|
|
34299
34276
|
let barrelPill = createPillOp(
|
|
34300
34277
|
holeW,
|
|
34301
34278
|
holeH,
|
|
@@ -34308,12 +34285,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34308
34285
|
barrelPill = rotatedBarrel;
|
|
34309
34286
|
}
|
|
34310
34287
|
manifoldInstancesForCleanup.push(barrelPill);
|
|
34311
|
-
const copperUnion = Manifold.union([
|
|
34312
|
-
mainFill,
|
|
34313
|
-
topPad,
|
|
34314
|
-
bottomPad,
|
|
34315
|
-
barrelPill
|
|
34316
|
-
]);
|
|
34288
|
+
const copperUnion = Manifold.union([mainFill, barrelPill]);
|
|
34317
34289
|
manifoldInstancesForCleanup.push(copperUnion);
|
|
34318
34290
|
let holeCutOp = createPillOp(
|
|
34319
34291
|
Math.max(holeW - 2 * PLATED_HOLE_LIP_HEIGHT, 0.01),
|
|
@@ -34370,23 +34342,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34370
34342
|
padOutline,
|
|
34371
34343
|
thickness: fillThickness
|
|
34372
34344
|
});
|
|
34373
|
-
|
|
34374
|
-
const bottomPad = createPolygonPadOp({
|
|
34375
|
-
padOutline,
|
|
34376
|
-
thickness: padThickness
|
|
34377
|
-
});
|
|
34378
|
-
if (!mainFill || !topPad || !bottomPad) return;
|
|
34379
|
-
const topTranslated = topPad.translate([
|
|
34380
|
-
0,
|
|
34381
|
-
0,
|
|
34382
|
-
pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
|
|
34383
|
-
]);
|
|
34384
|
-
const bottomTranslated = bottomPad.translate([
|
|
34385
|
-
0,
|
|
34386
|
-
0,
|
|
34387
|
-
-pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
|
|
34388
|
-
]);
|
|
34389
|
-
manifoldInstancesForCleanup.push(topTranslated, bottomTranslated);
|
|
34345
|
+
if (!mainFill) return;
|
|
34390
34346
|
const barrelOp = createHoleOpForPolygonPad({
|
|
34391
34347
|
ph,
|
|
34392
34348
|
depth: pcbThickness * 1.02
|
|
@@ -34397,12 +34353,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34397
34353
|
depth: pcbThickness * 0.8,
|
|
34398
34354
|
sizeDelta: -2 * M
|
|
34399
34355
|
}) || barrelOp;
|
|
34400
|
-
const copperUnion = Manifold.union([
|
|
34401
|
-
mainFill,
|
|
34402
|
-
topTranslated,
|
|
34403
|
-
bottomTranslated,
|
|
34404
|
-
barrelOp
|
|
34405
|
-
]);
|
|
34356
|
+
const copperUnion = Manifold.union([mainFill, barrelOp]);
|
|
34406
34357
|
manifoldInstancesForCleanup.push(copperUnion);
|
|
34407
34358
|
const finalCopper = copperUnion.subtract(holeCutOp);
|
|
34408
34359
|
manifoldInstancesForCleanup.push(finalCopper);
|
|
@@ -34459,7 +34410,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34459
34410
|
const translatedDrill = boardDrillOp.translate([ph.x, ph.y, 0]);
|
|
34460
34411
|
manifoldInstancesForCleanup.push(translatedDrill);
|
|
34461
34412
|
platedHoleBoardDrills.push(translatedDrill);
|
|
34462
|
-
const copperPartThickness =
|
|
34413
|
+
const copperPartThickness = internalCopperThickness;
|
|
34463
34414
|
let outerPoints = createEllipsePoints(
|
|
34464
34415
|
outerW,
|
|
34465
34416
|
outerH,
|
|
@@ -34558,29 +34509,6 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34558
34509
|
borderRadius: rectBorderRadius
|
|
34559
34510
|
});
|
|
34560
34511
|
manifoldInstancesForCleanup.push(mainFill);
|
|
34561
|
-
const topPad = createRoundedRectPrism({
|
|
34562
|
-
Manifold,
|
|
34563
|
-
width: padWidth,
|
|
34564
|
-
height: padHeight,
|
|
34565
|
-
thickness: padThickness,
|
|
34566
|
-
borderRadius: rectBorderRadius
|
|
34567
|
-
}).translate([
|
|
34568
|
-
0,
|
|
34569
|
-
0,
|
|
34570
|
-
pcbThickness / 2 + PLATED_HOLE_SURFACE_CLEARANCE + padThickness / 2
|
|
34571
|
-
]);
|
|
34572
|
-
const bottomPad = createRoundedRectPrism({
|
|
34573
|
-
Manifold,
|
|
34574
|
-
width: padWidth,
|
|
34575
|
-
height: padHeight,
|
|
34576
|
-
thickness: padThickness,
|
|
34577
|
-
borderRadius: rectBorderRadius
|
|
34578
|
-
}).translate([
|
|
34579
|
-
0,
|
|
34580
|
-
0,
|
|
34581
|
-
-pcbThickness / 2 - PLATED_HOLE_SURFACE_CLEARANCE - padThickness / 2
|
|
34582
|
-
]);
|
|
34583
|
-
manifoldInstancesForCleanup.push(topPad, bottomPad);
|
|
34584
34512
|
const barrelCylinder = Manifold.cylinder(
|
|
34585
34513
|
pcbThickness * 0.8,
|
|
34586
34514
|
// Slightly taller than board
|
|
@@ -34590,12 +34518,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34590
34518
|
true
|
|
34591
34519
|
).translate([holeOffsetX, holeOffsetY, 0]);
|
|
34592
34520
|
manifoldInstancesForCleanup.push(barrelCylinder);
|
|
34593
|
-
const copperUnion = Manifold.union([
|
|
34594
|
-
mainFill,
|
|
34595
|
-
topPad,
|
|
34596
|
-
bottomPad,
|
|
34597
|
-
barrelCylinder
|
|
34598
|
-
]);
|
|
34521
|
+
const copperUnion = Manifold.union([mainFill, barrelCylinder]);
|
|
34599
34522
|
manifoldInstancesForCleanup.push(copperUnion);
|
|
34600
34523
|
const holeDrill = Manifold.cylinder(
|
|
34601
34524
|
pcbThickness * 1.2,
|
|
@@ -34638,7 +34561,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34638
34561
|
|
|
34639
34562
|
// src/utils/manifold/process-vias.ts
|
|
34640
34563
|
import { su as su15 } from "@tscircuit/circuit-json-util";
|
|
34641
|
-
import * as
|
|
34564
|
+
import * as THREE34 from "three";
|
|
34642
34565
|
|
|
34643
34566
|
// src/utils/via-geoms.ts
|
|
34644
34567
|
function createViaCopper2({
|
|
@@ -34651,7 +34574,6 @@ function createViaCopper2({
|
|
|
34651
34574
|
zOffset = 1e-3,
|
|
34652
34575
|
segments = 32
|
|
34653
34576
|
}) {
|
|
34654
|
-
const padThickness = zOffset;
|
|
34655
34577
|
const platingThickness = zOffset;
|
|
34656
34578
|
if (outerDiameter < holeDiameter) {
|
|
34657
34579
|
throw new Error(
|
|
@@ -34663,22 +34585,8 @@ function createViaCopper2({
|
|
|
34663
34585
|
holeDiameter / 2 + platingThickness
|
|
34664
34586
|
);
|
|
34665
34587
|
const barrel = Manifold.cylinder(thickness, barrelRadius, -1, segments, true);
|
|
34666
|
-
const
|
|
34667
|
-
|
|
34668
|
-
outerDiameter / 2,
|
|
34669
|
-
-1,
|
|
34670
|
-
segments,
|
|
34671
|
-
true
|
|
34672
|
-
).translate([0, 0, thickness / 2]);
|
|
34673
|
-
const bottomPad = Manifold.cylinder(
|
|
34674
|
-
padThickness,
|
|
34675
|
-
outerDiameter / 2,
|
|
34676
|
-
-1,
|
|
34677
|
-
segments,
|
|
34678
|
-
true
|
|
34679
|
-
).translate([0, 0, -thickness / 2]);
|
|
34680
|
-
const viaSolid = Manifold.union([barrel, topPad, bottomPad]);
|
|
34681
|
-
const drillHeight = thickness + padThickness * 2;
|
|
34588
|
+
const viaSolid = barrel;
|
|
34589
|
+
const drillHeight = thickness + 2 * zOffset;
|
|
34682
34590
|
const drill = Manifold.cylinder(
|
|
34683
34591
|
drillHeight,
|
|
34684
34592
|
holeDiameter / 2,
|
|
@@ -34691,7 +34599,7 @@ function createViaCopper2({
|
|
|
34691
34599
|
}
|
|
34692
34600
|
|
|
34693
34601
|
// src/utils/manifold/process-vias.ts
|
|
34694
|
-
var COPPER_COLOR2 = new
|
|
34602
|
+
var COPPER_COLOR2 = new THREE34.Color(...colors.copper);
|
|
34695
34603
|
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
34696
34604
|
const viaBoardDrills = [];
|
|
34697
34605
|
const pcbVias = su15(circuitJson).pcb_via.list();
|
|
@@ -34911,7 +34819,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
|
|
|
34911
34819
|
{
|
|
34912
34820
|
key: "plated-holes-union",
|
|
34913
34821
|
geometry: cutPlatedGeom,
|
|
34914
|
-
color: new
|
|
34822
|
+
color: new THREE35.Color(
|
|
34915
34823
|
colors.copper[0],
|
|
34916
34824
|
colors.copper[1],
|
|
34917
34825
|
colors.copper[2]
|
|
@@ -34941,7 +34849,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
|
|
|
34941
34849
|
const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Tan;
|
|
34942
34850
|
currentGeoms.board = {
|
|
34943
34851
|
geometry: finalBoardGeom,
|
|
34944
|
-
color: new
|
|
34852
|
+
color: new THREE35.Color(
|
|
34945
34853
|
matColorArray[0],
|
|
34946
34854
|
matColorArray[1],
|
|
34947
34855
|
matColorArray[2]
|
|
@@ -34986,11 +34894,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
|
|
|
34986
34894
|
};
|
|
34987
34895
|
|
|
34988
34896
|
// src/utils/manifold/create-three-geometry-meshes.ts
|
|
34989
|
-
import * as
|
|
34897
|
+
import * as THREE37 from "three";
|
|
34990
34898
|
|
|
34991
34899
|
// src/utils/create-board-material.ts
|
|
34992
|
-
import * as
|
|
34993
|
-
var DEFAULT_SIDE =
|
|
34900
|
+
import * as THREE36 from "three";
|
|
34901
|
+
var DEFAULT_SIDE = THREE36.DoubleSide;
|
|
34994
34902
|
var createBoardMaterial = ({
|
|
34995
34903
|
material,
|
|
34996
34904
|
color,
|
|
@@ -34998,7 +34906,7 @@ var createBoardMaterial = ({
|
|
|
34998
34906
|
isFaux = false
|
|
34999
34907
|
}) => {
|
|
35000
34908
|
if (material === "fr4") {
|
|
35001
|
-
return new
|
|
34909
|
+
return new THREE36.MeshPhysicalMaterial({
|
|
35002
34910
|
color,
|
|
35003
34911
|
side,
|
|
35004
34912
|
metalness: 0,
|
|
@@ -35015,7 +34923,7 @@ var createBoardMaterial = ({
|
|
|
35015
34923
|
polygonOffsetUnits: 1
|
|
35016
34924
|
});
|
|
35017
34925
|
}
|
|
35018
|
-
return new
|
|
34926
|
+
return new THREE36.MeshStandardMaterial({
|
|
35019
34927
|
color,
|
|
35020
34928
|
side,
|
|
35021
34929
|
flatShading: true,
|
|
@@ -35034,12 +34942,12 @@ function createGeometryMeshes(geoms) {
|
|
|
35034
34942
|
const meshes = [];
|
|
35035
34943
|
if (!geoms) return meshes;
|
|
35036
34944
|
if (geoms.board && geoms.board.geometry) {
|
|
35037
|
-
const mesh = new
|
|
34945
|
+
const mesh = new THREE37.Mesh(
|
|
35038
34946
|
geoms.board.geometry,
|
|
35039
34947
|
createBoardMaterial({
|
|
35040
34948
|
material: geoms.board.material,
|
|
35041
34949
|
color: geoms.board.color,
|
|
35042
|
-
side:
|
|
34950
|
+
side: THREE37.DoubleSide,
|
|
35043
34951
|
isFaux: geoms.board.isFaux
|
|
35044
34952
|
})
|
|
35045
34953
|
);
|
|
@@ -35049,11 +34957,11 @@ function createGeometryMeshes(geoms) {
|
|
|
35049
34957
|
const createMeshesFromArray = (geomArray) => {
|
|
35050
34958
|
if (geomArray) {
|
|
35051
34959
|
geomArray.forEach((comp) => {
|
|
35052
|
-
const mesh = new
|
|
34960
|
+
const mesh = new THREE37.Mesh(
|
|
35053
34961
|
comp.geometry,
|
|
35054
|
-
new
|
|
34962
|
+
new THREE37.MeshStandardMaterial({
|
|
35055
34963
|
color: comp.color,
|
|
35056
|
-
side:
|
|
34964
|
+
side: THREE37.DoubleSide,
|
|
35057
34965
|
flatShading: true
|
|
35058
34966
|
// Consistent with board
|
|
35059
34967
|
})
|
|
@@ -35097,7 +35005,7 @@ var BoardMeshes = ({
|
|
|
35097
35005
|
const typedMaterial = material;
|
|
35098
35006
|
for (const prop of textureProps) {
|
|
35099
35007
|
const texture = typedMaterial[prop];
|
|
35100
|
-
if (texture && texture instanceof
|
|
35008
|
+
if (texture && texture instanceof THREE38.Texture) {
|
|
35101
35009
|
texture.dispose();
|
|
35102
35010
|
typedMaterial[prop] = null;
|
|
35103
35011
|
}
|
|
@@ -42039,7 +41947,7 @@ var KeyboardShortcutsDialog = ({
|
|
|
42039
41947
|
|
|
42040
41948
|
// src/CadViewer.tsx
|
|
42041
41949
|
import { jsx as jsx38, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
42042
|
-
var DEFAULT_TARGET = new
|
|
41950
|
+
var DEFAULT_TARGET = new THREE39.Vector3(0, 0, 0);
|
|
42043
41951
|
var INITIAL_CAMERA_POSITION = [5, -5, 5];
|
|
42044
41952
|
var CadViewerInner = (props) => {
|
|
42045
41953
|
const [engine, setEngine] = useState36("manifold");
|
|
@@ -42306,11 +42214,11 @@ var CadViewer = (props) => {
|
|
|
42306
42214
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
42307
42215
|
var import_debug = __toESM(require_browser(), 1);
|
|
42308
42216
|
import { su as su18 } from "@tscircuit/circuit-json-util";
|
|
42309
|
-
import * as
|
|
42217
|
+
import * as THREE43 from "three";
|
|
42310
42218
|
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
|
|
42311
42219
|
|
|
42312
42220
|
// src/utils/create-geometry-from-polygons.ts
|
|
42313
|
-
import * as
|
|
42221
|
+
import * as THREE40 from "three";
|
|
42314
42222
|
import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute3 } from "three";
|
|
42315
42223
|
function createGeometryFromPolygons(polygons) {
|
|
42316
42224
|
const geometry = new BufferGeometry4();
|
|
@@ -42324,12 +42232,12 @@ function createGeometryFromPolygons(polygons) {
|
|
|
42324
42232
|
...polygon3.vertices[i + 1]
|
|
42325
42233
|
// Third vertex
|
|
42326
42234
|
);
|
|
42327
|
-
const v1 = new
|
|
42328
|
-
const v2 = new
|
|
42329
|
-
const v3 = new
|
|
42330
|
-
const normal = new
|
|
42331
|
-
new
|
|
42332
|
-
new
|
|
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)
|
|
42333
42241
|
).normalize();
|
|
42334
42242
|
normals.push(
|
|
42335
42243
|
normal.x,
|
|
@@ -42353,10 +42261,10 @@ function createGeometryFromPolygons(polygons) {
|
|
|
42353
42261
|
var import_modeling2 = __toESM(require_src(), 1);
|
|
42354
42262
|
var import_jscad_planner2 = __toESM(require_dist(), 1);
|
|
42355
42263
|
var jscadModeling2 = __toESM(require_src(), 1);
|
|
42356
|
-
import * as
|
|
42264
|
+
import * as THREE42 from "three";
|
|
42357
42265
|
|
|
42358
42266
|
// src/utils/load-model.ts
|
|
42359
|
-
import * as
|
|
42267
|
+
import * as THREE41 from "three";
|
|
42360
42268
|
import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
42361
42269
|
import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
42362
42270
|
import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
|
|
@@ -42364,12 +42272,12 @@ async function load3DModel(url) {
|
|
|
42364
42272
|
if (url.endsWith(".stl")) {
|
|
42365
42273
|
const loader = new STLLoader2();
|
|
42366
42274
|
const geometry = await loader.loadAsync(url);
|
|
42367
|
-
const material = new
|
|
42275
|
+
const material = new THREE41.MeshStandardMaterial({
|
|
42368
42276
|
color: 8947848,
|
|
42369
42277
|
metalness: 0.5,
|
|
42370
42278
|
roughness: 0.5
|
|
42371
42279
|
});
|
|
42372
|
-
return new
|
|
42280
|
+
return new THREE41.Mesh(geometry, material);
|
|
42373
42281
|
}
|
|
42374
42282
|
if (url.endsWith(".obj")) {
|
|
42375
42283
|
const loader = new OBJLoader2();
|
|
@@ -42402,9 +42310,9 @@ async function renderComponent(component, scene) {
|
|
|
42402
42310
|
}
|
|
42403
42311
|
if (component.rotation) {
|
|
42404
42312
|
model.rotation.set(
|
|
42405
|
-
|
|
42406
|
-
|
|
42407
|
-
|
|
42313
|
+
THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42314
|
+
THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42315
|
+
THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42408
42316
|
);
|
|
42409
42317
|
}
|
|
42410
42318
|
scene.add(model);
|
|
@@ -42418,13 +42326,13 @@ async function renderComponent(component, scene) {
|
|
|
42418
42326
|
);
|
|
42419
42327
|
if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
|
|
42420
42328
|
const threeGeom = convertCSGToThreeGeom(jscadObject);
|
|
42421
|
-
const material2 = new
|
|
42329
|
+
const material2 = new THREE42.MeshStandardMaterial({
|
|
42422
42330
|
color: 8947848,
|
|
42423
42331
|
metalness: 0.5,
|
|
42424
42332
|
roughness: 0.5,
|
|
42425
|
-
side:
|
|
42333
|
+
side: THREE42.DoubleSide
|
|
42426
42334
|
});
|
|
42427
|
-
const mesh2 = new
|
|
42335
|
+
const mesh2 = new THREE42.Mesh(threeGeom, material2);
|
|
42428
42336
|
if (component.position) {
|
|
42429
42337
|
mesh2.position.set(
|
|
42430
42338
|
component.position.x ?? 0,
|
|
@@ -42434,9 +42342,9 @@ async function renderComponent(component, scene) {
|
|
|
42434
42342
|
}
|
|
42435
42343
|
if (component.rotation) {
|
|
42436
42344
|
mesh2.rotation.set(
|
|
42437
|
-
|
|
42438
|
-
|
|
42439
|
-
|
|
42345
|
+
THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42346
|
+
THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42347
|
+
THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42440
42348
|
);
|
|
42441
42349
|
}
|
|
42442
42350
|
scene.add(mesh2);
|
|
@@ -42453,17 +42361,17 @@ async function renderComponent(component, scene) {
|
|
|
42453
42361
|
if (!geom || !geom.polygons && !geom.sides) {
|
|
42454
42362
|
continue;
|
|
42455
42363
|
}
|
|
42456
|
-
const color = new
|
|
42364
|
+
const color = new THREE42.Color(geomInfo.color);
|
|
42457
42365
|
color.convertLinearToSRGB();
|
|
42458
42366
|
const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
|
|
42459
42367
|
const threeGeom = convertCSGToThreeGeom(geomWithColor);
|
|
42460
|
-
const material2 = new
|
|
42368
|
+
const material2 = new THREE42.MeshStandardMaterial({
|
|
42461
42369
|
vertexColors: true,
|
|
42462
42370
|
metalness: 0.2,
|
|
42463
42371
|
roughness: 0.8,
|
|
42464
|
-
side:
|
|
42372
|
+
side: THREE42.DoubleSide
|
|
42465
42373
|
});
|
|
42466
|
-
const mesh2 = new
|
|
42374
|
+
const mesh2 = new THREE42.Mesh(threeGeom, material2);
|
|
42467
42375
|
if (component.position) {
|
|
42468
42376
|
mesh2.position.set(
|
|
42469
42377
|
component.position.x ?? 0,
|
|
@@ -42473,22 +42381,22 @@ async function renderComponent(component, scene) {
|
|
|
42473
42381
|
}
|
|
42474
42382
|
if (component.rotation) {
|
|
42475
42383
|
mesh2.rotation.set(
|
|
42476
|
-
|
|
42477
|
-
|
|
42478
|
-
|
|
42384
|
+
THREE42.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42385
|
+
THREE42.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42386
|
+
THREE42.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42479
42387
|
);
|
|
42480
42388
|
}
|
|
42481
42389
|
scene.add(mesh2);
|
|
42482
42390
|
}
|
|
42483
42391
|
return;
|
|
42484
42392
|
}
|
|
42485
|
-
const geometry = new
|
|
42486
|
-
const material = new
|
|
42393
|
+
const geometry = new THREE42.BoxGeometry(0.5, 0.5, 0.5);
|
|
42394
|
+
const material = new THREE42.MeshStandardMaterial({
|
|
42487
42395
|
color: 16711680,
|
|
42488
42396
|
transparent: true,
|
|
42489
42397
|
opacity: 0.25
|
|
42490
42398
|
});
|
|
42491
|
-
const mesh = new
|
|
42399
|
+
const mesh = new THREE42.Mesh(geometry, material);
|
|
42492
42400
|
if (component.position) {
|
|
42493
42401
|
mesh.position.set(
|
|
42494
42402
|
component.position.x ?? 0,
|
|
@@ -42509,11 +42417,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42509
42417
|
padding = 20,
|
|
42510
42418
|
zoom = 1.5
|
|
42511
42419
|
} = options;
|
|
42512
|
-
const scene = new
|
|
42420
|
+
const scene = new THREE43.Scene();
|
|
42513
42421
|
const renderer = new SVGRenderer();
|
|
42514
42422
|
renderer.setSize(width10, height10);
|
|
42515
|
-
renderer.setClearColor(new
|
|
42516
|
-
const camera = new
|
|
42423
|
+
renderer.setClearColor(new THREE43.Color(backgroundColor), 1);
|
|
42424
|
+
const camera = new THREE43.OrthographicCamera();
|
|
42517
42425
|
const aspect = width10 / height10;
|
|
42518
42426
|
const frustumSize = 100;
|
|
42519
42427
|
const halfFrustumSize = frustumSize / 2 / zoom;
|
|
@@ -42527,11 +42435,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42527
42435
|
camera.position.set(position.x, position.y, position.z);
|
|
42528
42436
|
camera.up.set(0, 1, 0);
|
|
42529
42437
|
const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
|
|
42530
|
-
camera.lookAt(new
|
|
42438
|
+
camera.lookAt(new THREE43.Vector3(lookAt.x, lookAt.y, lookAt.z));
|
|
42531
42439
|
camera.updateProjectionMatrix();
|
|
42532
|
-
const ambientLight = new
|
|
42440
|
+
const ambientLight = new THREE43.AmbientLight(16777215, Math.PI / 2);
|
|
42533
42441
|
scene.add(ambientLight);
|
|
42534
|
-
const pointLight = new
|
|
42442
|
+
const pointLight = new THREE43.PointLight(16777215, Math.PI / 4);
|
|
42535
42443
|
pointLight.position.set(-10, -10, 10);
|
|
42536
42444
|
scene.add(pointLight);
|
|
42537
42445
|
const components = su18(circuitJson).cad_component.list();
|
|
@@ -42542,7 +42450,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42542
42450
|
const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
|
|
42543
42451
|
if (boardGeom) {
|
|
42544
42452
|
const solderMaskColor = colors.fr4SolderMaskGreen;
|
|
42545
|
-
const baseColor = new
|
|
42453
|
+
const baseColor = new THREE43.Color(
|
|
42546
42454
|
solderMaskColor[0],
|
|
42547
42455
|
solderMaskColor[1],
|
|
42548
42456
|
solderMaskColor[2]
|
|
@@ -42554,28 +42462,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42554
42462
|
const material = createBoardMaterial({
|
|
42555
42463
|
material: boardData?.material,
|
|
42556
42464
|
color: baseColor,
|
|
42557
|
-
side:
|
|
42465
|
+
side: THREE43.DoubleSide
|
|
42558
42466
|
});
|
|
42559
|
-
const mesh = new
|
|
42467
|
+
const mesh = new THREE43.Mesh(geometry, material);
|
|
42560
42468
|
scene.add(mesh);
|
|
42561
42469
|
}
|
|
42562
42470
|
}
|
|
42563
|
-
const gridColor = new
|
|
42564
|
-
const gridHelper = new
|
|
42471
|
+
const gridColor = new THREE43.Color(8947848);
|
|
42472
|
+
const gridHelper = new THREE43.GridHelper(100, 100, gridColor, gridColor);
|
|
42565
42473
|
gridHelper.rotation.x = Math.PI / 2;
|
|
42566
42474
|
const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
|
|
42567
42475
|
for (const mat of materials) {
|
|
42568
42476
|
mat.transparent = true;
|
|
42569
42477
|
mat.opacity = 0.3;
|
|
42570
|
-
if (mat instanceof
|
|
42478
|
+
if (mat instanceof THREE43.LineBasicMaterial) {
|
|
42571
42479
|
mat.color = gridColor;
|
|
42572
42480
|
mat.vertexColors = false;
|
|
42573
42481
|
}
|
|
42574
42482
|
}
|
|
42575
42483
|
scene.add(gridHelper);
|
|
42576
|
-
const box = new
|
|
42577
|
-
const center = box.getCenter(new
|
|
42578
|
-
const size4 = box.getSize(new
|
|
42484
|
+
const box = new THREE43.Box3().setFromObject(scene);
|
|
42485
|
+
const center = box.getCenter(new THREE43.Vector3());
|
|
42486
|
+
const size4 = box.getSize(new THREE43.Vector3());
|
|
42579
42487
|
scene.position.sub(center);
|
|
42580
42488
|
const maxDim = Math.max(size4.x, size4.y, size4.z);
|
|
42581
42489
|
if (maxDim > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/3d-viewer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.529",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@jscad/regl-renderer": "^2.6.12",
|
|
31
31
|
"@jscad/stl-serializer": "^2.1.20",
|
|
32
|
-
"circuit-json": "^0.0.
|
|
33
|
-
"circuit-to-canvas": "^0.0.
|
|
32
|
+
"circuit-json": "^0.0.391",
|
|
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",
|