@tscircuit/3d-viewer 0.0.232 → 0.0.233
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.d.ts +27 -9
- package/dist/index.js +485 -469
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -43,18 +43,36 @@ declare function useExportGltfUrl(options?: Options): [
|
|
|
43
43
|
error: ErrorEvent | undefined
|
|
44
44
|
];
|
|
45
45
|
|
|
46
|
-
interface
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
interface ManifoldGeoms {
|
|
47
|
+
board?: {
|
|
48
|
+
geometry: THREE.BufferGeometry;
|
|
49
|
+
color: THREE.Color;
|
|
50
|
+
};
|
|
51
|
+
platedHoles?: Array<{
|
|
52
|
+
key: string;
|
|
53
|
+
geometry: THREE.BufferGeometry;
|
|
54
|
+
color: THREE.Color;
|
|
55
|
+
}>;
|
|
56
|
+
smtPads?: Array<{
|
|
50
57
|
key: string;
|
|
51
58
|
geometry: THREE.BufferGeometry;
|
|
52
59
|
color: THREE.Color;
|
|
53
60
|
}>;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
vias?: Array<{
|
|
62
|
+
key: string;
|
|
63
|
+
geometry: THREE.BufferGeometry;
|
|
64
|
+
color: THREE.Color;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
interface ManifoldTextures {
|
|
68
|
+
topTrace?: THREE.CanvasTexture | null;
|
|
69
|
+
bottomTrace?: THREE.CanvasTexture | null;
|
|
70
|
+
topSilkscreen?: THREE.CanvasTexture | null;
|
|
71
|
+
bottomSilkscreen?: THREE.CanvasTexture | null;
|
|
72
|
+
}
|
|
73
|
+
interface UseManifoldBoardBuilderResult {
|
|
74
|
+
geoms: ManifoldGeoms | null;
|
|
75
|
+
textures: ManifoldTextures | null;
|
|
58
76
|
pcbThickness: number | null;
|
|
59
77
|
error: string | null;
|
|
60
78
|
isLoading: boolean;
|
|
@@ -64,4 +82,4 @@ declare const useManifoldBoardBuilder: (manifoldJSModule: ManifoldToplevel | nul
|
|
|
64
82
|
|
|
65
83
|
declare function applyJsdomShim(jsdom: JSDOM): void;
|
|
66
84
|
|
|
67
|
-
export { CadViewer, applyJsdomShim, convertCircuitJsonTo3dSvg, useExportGltfUrl, useManifoldBoardBuilder, useSaveGltfAs };
|
|
85
|
+
export { CadViewer, type ManifoldGeoms, type ManifoldTextures, applyJsdomShim, convertCircuitJsonTo3dSvg, useExportGltfUrl, useManifoldBoardBuilder, useSaveGltfAs };
|
package/dist/index.js
CHANGED
|
@@ -16985,7 +16985,7 @@ import { Canvas, useFrame as useFrame2 } from "@react-three/fiber";
|
|
|
16985
16985
|
// package.json
|
|
16986
16986
|
var package_default = {
|
|
16987
16987
|
name: "@tscircuit/3d-viewer",
|
|
16988
|
-
version: "0.0.
|
|
16988
|
+
version: "0.0.232",
|
|
16989
16989
|
main: "./dist/index.js",
|
|
16990
16990
|
module: "./dist/index.js",
|
|
16991
16991
|
type: "module",
|
|
@@ -17310,6 +17310,10 @@ var colors = {
|
|
|
17310
17310
|
fr1Copper: [0.8, 0.4, 0.2],
|
|
17311
17311
|
fr1CopperSolderWithMask: [0.9, 0.6, 0.2]
|
|
17312
17312
|
};
|
|
17313
|
+
var MANIFOLD_Z_OFFSET = 1e-3;
|
|
17314
|
+
var SMOOTH_CIRCLE_SEGMENTS = 32;
|
|
17315
|
+
var DEFAULT_SMT_PAD_THICKNESS = 0.035;
|
|
17316
|
+
var TRACE_TEXTURE_RESOLUTION = 200;
|
|
17313
17317
|
var boardMaterialColors = {
|
|
17314
17318
|
fr1: colors.fr1Copper,
|
|
17315
17319
|
fr4: colors.fr4Green
|
|
@@ -18976,14 +18980,13 @@ var CadViewerJscad = forwardRef2(
|
|
|
18976
18980
|
|
|
18977
18981
|
// src/CadViewerManifold.tsx
|
|
18978
18982
|
import { useEffect as useEffect6, useState as useState8, useMemo as useMemo7 } from "react";
|
|
18979
|
-
import { su as
|
|
18980
|
-
import * as THREE8 from "three";
|
|
18983
|
+
import { su as su12 } from "@tscircuit/soup-util";
|
|
18981
18984
|
import ManifoldModule from "manifold-3d";
|
|
18982
18985
|
|
|
18983
18986
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
18984
18987
|
import { useState as useState7, useEffect as useEffect5, useMemo as useMemo6, useRef as useRef6 } from "react";
|
|
18985
|
-
import { su as
|
|
18986
|
-
import * as
|
|
18988
|
+
import { su as su11 } from "@tscircuit/soup-util";
|
|
18989
|
+
import * as THREE10 from "three";
|
|
18987
18990
|
|
|
18988
18991
|
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
18989
18992
|
import * as THREE4 from "three";
|
|
@@ -19008,18 +19011,22 @@ function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
|
19008
19011
|
|
|
19009
19012
|
// src/utils/trace-texture.ts
|
|
19010
19013
|
import * as THREE5 from "three";
|
|
19014
|
+
import { su as su5 } from "@tscircuit/soup-util";
|
|
19011
19015
|
function isWireRoutePoint(point) {
|
|
19012
19016
|
return point && point.route_type === "wire" && typeof point.layer === "string" && typeof point.width === "number";
|
|
19013
19017
|
}
|
|
19014
19018
|
function createTraceTextureForLayer({
|
|
19015
19019
|
layer,
|
|
19016
|
-
|
|
19020
|
+
circuitJson,
|
|
19017
19021
|
boardData,
|
|
19018
19022
|
traceColor,
|
|
19019
|
-
traceTextureResolution
|
|
19020
|
-
allPcbVias,
|
|
19021
|
-
allPcbPlatedHoles
|
|
19023
|
+
traceTextureResolution
|
|
19022
19024
|
}) {
|
|
19025
|
+
const pcbTraces = su5(circuitJson).pcb_trace.list();
|
|
19026
|
+
const allPcbVias = su5(circuitJson).pcb_via.list();
|
|
19027
|
+
const allPcbPlatedHoles = su5(
|
|
19028
|
+
circuitJson
|
|
19029
|
+
).pcb_plated_hole.list();
|
|
19023
19030
|
const tracesOnLayer = pcbTraces.filter(
|
|
19024
19031
|
(t) => t.route.some((p) => isWireRoutePoint(p) && p.layer === layer)
|
|
19025
19032
|
);
|
|
@@ -19098,14 +19105,16 @@ function createTraceTextureForLayer({
|
|
|
19098
19105
|
// src/utils/silkscreen-texture.ts
|
|
19099
19106
|
var import_text2 = __toESM(require_text(), 1);
|
|
19100
19107
|
import * as THREE6 from "three";
|
|
19108
|
+
import { su as su6 } from "@tscircuit/soup-util";
|
|
19101
19109
|
function createSilkscreenTextureForLayer({
|
|
19102
19110
|
layer,
|
|
19103
|
-
|
|
19104
|
-
pcbSilkscreenPaths,
|
|
19111
|
+
circuitJson,
|
|
19105
19112
|
boardData,
|
|
19106
19113
|
silkscreenColor = "rgb(255,255,255)",
|
|
19107
19114
|
traceTextureResolution
|
|
19108
19115
|
}) {
|
|
19116
|
+
const pcbSilkscreenTexts = su6(circuitJson).pcb_silkscreen_text.list();
|
|
19117
|
+
const pcbSilkscreenPaths = su6(circuitJson).pcb_silkscreen_path.list();
|
|
19109
19118
|
const textsOnLayer = pcbSilkscreenTexts.filter((t) => t.layer === layer);
|
|
19110
19119
|
const pathsOnLayer = pcbSilkscreenPaths.filter((p) => p.layer === layer);
|
|
19111
19120
|
if (textsOnLayer.length === 0 && pathsOnLayer.length === 0) return null;
|
|
@@ -19226,19 +19235,8 @@ function createSilkscreenTextureForLayer({
|
|
|
19226
19235
|
return texture;
|
|
19227
19236
|
}
|
|
19228
19237
|
|
|
19229
|
-
// src/utils/
|
|
19230
|
-
|
|
19231
|
-
Manifold,
|
|
19232
|
-
pad,
|
|
19233
|
-
padBaseThickness
|
|
19234
|
-
}) {
|
|
19235
|
-
if (pad.shape === "rect") {
|
|
19236
|
-
return Manifold.cube([pad.width, pad.height, padBaseThickness], true);
|
|
19237
|
-
} else if (pad.shape === "circle" && pad.radius) {
|
|
19238
|
-
return Manifold.cylinder(padBaseThickness, pad.radius, -1, 32, true);
|
|
19239
|
-
}
|
|
19240
|
-
return null;
|
|
19241
|
-
}
|
|
19238
|
+
// src/utils/manifold/process-non-plated-holes.ts
|
|
19239
|
+
import { su as su7 } from "@tscircuit/soup-util";
|
|
19242
19240
|
|
|
19243
19241
|
// src/utils/hole-geoms.ts
|
|
19244
19242
|
function createCircleHoleDrill({
|
|
@@ -19278,6 +19276,91 @@ function createPlatedHoleDrill({
|
|
|
19278
19276
|
return drill.translate([x, y, 0]);
|
|
19279
19277
|
}
|
|
19280
19278
|
|
|
19279
|
+
// src/utils/manifold/process-non-plated-holes.ts
|
|
19280
|
+
function isCircleHole(hole) {
|
|
19281
|
+
return (hole.shape === "circle" || hole.hole_shape === "circle") && typeof hole.hole_diameter === "number";
|
|
19282
|
+
}
|
|
19283
|
+
function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
19284
|
+
const nonPlatedHoleBoardDrills = [];
|
|
19285
|
+
const pcbHoles = su7(circuitJson).pcb_hole.list();
|
|
19286
|
+
pcbHoles.forEach((hole) => {
|
|
19287
|
+
if (isCircleHole(hole)) {
|
|
19288
|
+
const translatedDrill = createCircleHoleDrill({
|
|
19289
|
+
Manifold,
|
|
19290
|
+
x: hole.x,
|
|
19291
|
+
y: hole.y,
|
|
19292
|
+
diameter: hole.hole_diameter,
|
|
19293
|
+
thickness: pcbThickness,
|
|
19294
|
+
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19295
|
+
});
|
|
19296
|
+
manifoldInstancesForCleanup.push(translatedDrill);
|
|
19297
|
+
nonPlatedHoleBoardDrills.push(translatedDrill);
|
|
19298
|
+
}
|
|
19299
|
+
});
|
|
19300
|
+
return { nonPlatedHoleBoardDrills };
|
|
19301
|
+
}
|
|
19302
|
+
|
|
19303
|
+
// src/utils/manifold/process-plated-holes.ts
|
|
19304
|
+
import { su as su8 } from "@tscircuit/soup-util";
|
|
19305
|
+
import * as THREE7 from "three";
|
|
19306
|
+
var COPPER_COLOR = new THREE7.Color(...colors.copper);
|
|
19307
|
+
function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
19308
|
+
const platedHoleBoardDrills = [];
|
|
19309
|
+
const pcbPlatedHoles = su8(circuitJson).pcb_plated_hole.list();
|
|
19310
|
+
const platedHoleCopperGeoms = [];
|
|
19311
|
+
pcbPlatedHoles.forEach((ph, index) => {
|
|
19312
|
+
if (ph.shape === "circle") {
|
|
19313
|
+
const translatedDrill = createPlatedHoleDrill({
|
|
19314
|
+
Manifold,
|
|
19315
|
+
x: ph.x,
|
|
19316
|
+
y: ph.y,
|
|
19317
|
+
outerDiameter: ph.outer_diameter,
|
|
19318
|
+
// Drill for the board
|
|
19319
|
+
thickness: pcbThickness,
|
|
19320
|
+
zOffset: MANIFOLD_Z_OFFSET,
|
|
19321
|
+
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19322
|
+
});
|
|
19323
|
+
manifoldInstancesForCleanup.push(translatedDrill);
|
|
19324
|
+
platedHoleBoardDrills.push(translatedDrill);
|
|
19325
|
+
const copperPartThickness = pcbThickness + 2 * MANIFOLD_Z_OFFSET;
|
|
19326
|
+
let platedPart = Manifold.cylinder(
|
|
19327
|
+
copperPartThickness,
|
|
19328
|
+
ph.outer_diameter / 2,
|
|
19329
|
+
-1,
|
|
19330
|
+
SMOOTH_CIRCLE_SEGMENTS,
|
|
19331
|
+
true
|
|
19332
|
+
);
|
|
19333
|
+
manifoldInstancesForCleanup.push(platedPart);
|
|
19334
|
+
const drillForCopper = Manifold.cylinder(
|
|
19335
|
+
copperPartThickness * 1.05,
|
|
19336
|
+
// ensure it cuts through
|
|
19337
|
+
ph.hole_diameter / 2,
|
|
19338
|
+
-1,
|
|
19339
|
+
SMOOTH_CIRCLE_SEGMENTS,
|
|
19340
|
+
true
|
|
19341
|
+
);
|
|
19342
|
+
manifoldInstancesForCleanup.push(drillForCopper);
|
|
19343
|
+
const finalPlatedPartOp = platedPart.subtract(drillForCopper);
|
|
19344
|
+
manifoldInstancesForCleanup.push(finalPlatedPartOp);
|
|
19345
|
+
const translatedPlatedPart = finalPlatedPartOp.translate([ph.x, ph.y, 0]);
|
|
19346
|
+
manifoldInstancesForCleanup.push(translatedPlatedPart);
|
|
19347
|
+
const threeGeom = manifoldMeshToThreeGeometry(
|
|
19348
|
+
translatedPlatedPart.getMesh()
|
|
19349
|
+
);
|
|
19350
|
+
platedHoleCopperGeoms.push({
|
|
19351
|
+
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
19352
|
+
geometry: threeGeom,
|
|
19353
|
+
color: COPPER_COLOR
|
|
19354
|
+
});
|
|
19355
|
+
}
|
|
19356
|
+
});
|
|
19357
|
+
return { platedHoleBoardDrills, platedHoleCopperGeoms };
|
|
19358
|
+
}
|
|
19359
|
+
|
|
19360
|
+
// src/utils/manifold/process-vias.ts
|
|
19361
|
+
import { su as su9 } from "@tscircuit/soup-util";
|
|
19362
|
+
import * as THREE8 from "three";
|
|
19363
|
+
|
|
19281
19364
|
// src/utils/via-geoms.ts
|
|
19282
19365
|
function createViaCopper({
|
|
19283
19366
|
Manifold,
|
|
@@ -19308,7 +19391,98 @@ function createViaCopper({
|
|
|
19308
19391
|
return finalViaCopperOp.translate([x, y, 0]);
|
|
19309
19392
|
}
|
|
19310
19393
|
|
|
19311
|
-
// src/
|
|
19394
|
+
// src/utils/manifold/process-vias.ts
|
|
19395
|
+
var COPPER_COLOR2 = new THREE8.Color(...colors.copper);
|
|
19396
|
+
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
19397
|
+
const viaBoardDrills = [];
|
|
19398
|
+
const pcbVias = su9(circuitJson).pcb_via.list();
|
|
19399
|
+
const viaCopperGeoms = [];
|
|
19400
|
+
pcbVias.forEach((via, index) => {
|
|
19401
|
+
if (typeof via.outer_diameter === "number") {
|
|
19402
|
+
const translatedDrill = createPlatedHoleDrill({
|
|
19403
|
+
Manifold,
|
|
19404
|
+
x: via.x,
|
|
19405
|
+
y: via.y,
|
|
19406
|
+
outerDiameter: via.outer_diameter,
|
|
19407
|
+
thickness: pcbThickness,
|
|
19408
|
+
zOffset: MANIFOLD_Z_OFFSET,
|
|
19409
|
+
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19410
|
+
});
|
|
19411
|
+
manifoldInstancesForCleanup.push(translatedDrill);
|
|
19412
|
+
viaBoardDrills.push(translatedDrill);
|
|
19413
|
+
}
|
|
19414
|
+
if (typeof via.outer_diameter === "number" && typeof via.hole_diameter === "number") {
|
|
19415
|
+
const translatedViaCopper = createViaCopper({
|
|
19416
|
+
Manifold,
|
|
19417
|
+
x: via.x,
|
|
19418
|
+
y: via.y,
|
|
19419
|
+
outerDiameter: via.outer_diameter,
|
|
19420
|
+
holeDiameter: via.hole_diameter,
|
|
19421
|
+
thickness: pcbThickness,
|
|
19422
|
+
zOffset: MANIFOLD_Z_OFFSET,
|
|
19423
|
+
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19424
|
+
});
|
|
19425
|
+
manifoldInstancesForCleanup.push(translatedViaCopper);
|
|
19426
|
+
const threeGeom = manifoldMeshToThreeGeometry(
|
|
19427
|
+
translatedViaCopper.getMesh()
|
|
19428
|
+
);
|
|
19429
|
+
viaCopperGeoms.push({
|
|
19430
|
+
key: `via-${via.pcb_via_id || index}`,
|
|
19431
|
+
geometry: threeGeom,
|
|
19432
|
+
color: COPPER_COLOR2
|
|
19433
|
+
});
|
|
19434
|
+
}
|
|
19435
|
+
});
|
|
19436
|
+
return { viaBoardDrills, viaCopperGeoms };
|
|
19437
|
+
}
|
|
19438
|
+
|
|
19439
|
+
// src/utils/manifold/process-smt-pads.ts
|
|
19440
|
+
import { su as su10 } from "@tscircuit/soup-util";
|
|
19441
|
+
import * as THREE9 from "three";
|
|
19442
|
+
|
|
19443
|
+
// src/utils/pad-geoms.ts
|
|
19444
|
+
function createPadManifoldOp({
|
|
19445
|
+
Manifold,
|
|
19446
|
+
pad,
|
|
19447
|
+
padBaseThickness
|
|
19448
|
+
}) {
|
|
19449
|
+
if (pad.shape === "rect") {
|
|
19450
|
+
return Manifold.cube([pad.width, pad.height, padBaseThickness], true);
|
|
19451
|
+
} else if (pad.shape === "circle" && pad.radius) {
|
|
19452
|
+
return Manifold.cylinder(padBaseThickness, pad.radius, -1, 32, true);
|
|
19453
|
+
}
|
|
19454
|
+
return null;
|
|
19455
|
+
}
|
|
19456
|
+
|
|
19457
|
+
// src/utils/manifold/process-smt-pads.ts
|
|
19458
|
+
var COPPER_COLOR3 = new THREE9.Color(...colors.copper);
|
|
19459
|
+
function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
19460
|
+
const smtPadGeoms = [];
|
|
19461
|
+
const smtPads = su10(circuitJson).pcb_smtpad.list();
|
|
19462
|
+
smtPads.forEach((pad, index) => {
|
|
19463
|
+
const padBaseThickness = DEFAULT_SMT_PAD_THICKNESS;
|
|
19464
|
+
const zPos = pad.layer === "bottom" ? -pcbThickness / 2 - padBaseThickness / 2 - MANIFOLD_Z_OFFSET : pcbThickness / 2 + padBaseThickness / 2 + MANIFOLD_Z_OFFSET;
|
|
19465
|
+
let padManifoldOp = createPadManifoldOp({
|
|
19466
|
+
Manifold,
|
|
19467
|
+
pad,
|
|
19468
|
+
padBaseThickness
|
|
19469
|
+
});
|
|
19470
|
+
if (padManifoldOp) {
|
|
19471
|
+
manifoldInstancesForCleanup.push(padManifoldOp);
|
|
19472
|
+
const translatedPad = padManifoldOp.translate([pad.x, pad.y, zPos]);
|
|
19473
|
+
manifoldInstancesForCleanup.push(translatedPad);
|
|
19474
|
+
const threeGeom = manifoldMeshToThreeGeometry(translatedPad.getMesh());
|
|
19475
|
+
smtPadGeoms.push({
|
|
19476
|
+
key: `pad-${pad.pcb_smtpad_id || index}`,
|
|
19477
|
+
geometry: threeGeom,
|
|
19478
|
+
color: COPPER_COLOR3
|
|
19479
|
+
});
|
|
19480
|
+
}
|
|
19481
|
+
});
|
|
19482
|
+
return { smtPadGeoms };
|
|
19483
|
+
}
|
|
19484
|
+
|
|
19485
|
+
// src/utils/manifold/create-manifold-board.ts
|
|
19312
19486
|
var arePointsClockwise2 = (points) => {
|
|
19313
19487
|
let area = 0;
|
|
19314
19488
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -19321,54 +19495,70 @@ var arePointsClockwise2 = (points) => {
|
|
|
19321
19495
|
const signedArea = area / 2;
|
|
19322
19496
|
return signedArea <= 0;
|
|
19323
19497
|
};
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19498
|
+
function createManifoldBoard(Manifold, CrossSection, boardData, pcbThickness, manifoldInstancesForCleanup) {
|
|
19499
|
+
let boardOp;
|
|
19500
|
+
if (boardData.outline && boardData.outline.length >= 3) {
|
|
19501
|
+
let outlineVec2 = boardData.outline.map((p) => [
|
|
19502
|
+
p.x,
|
|
19503
|
+
p.y
|
|
19504
|
+
]);
|
|
19505
|
+
if (arePointsClockwise2(outlineVec2)) {
|
|
19506
|
+
outlineVec2 = outlineVec2.reverse();
|
|
19507
|
+
}
|
|
19508
|
+
const crossSection = CrossSection.ofPolygons([outlineVec2]);
|
|
19509
|
+
manifoldInstancesForCleanup.push(crossSection);
|
|
19510
|
+
boardOp = Manifold.extrude(
|
|
19511
|
+
crossSection,
|
|
19512
|
+
pcbThickness,
|
|
19513
|
+
void 0,
|
|
19514
|
+
// nDivisions
|
|
19515
|
+
void 0,
|
|
19516
|
+
// twistDegrees
|
|
19517
|
+
void 0,
|
|
19518
|
+
// scaleTop
|
|
19519
|
+
true
|
|
19520
|
+
// center (for Z-axis)
|
|
19521
|
+
);
|
|
19522
|
+
} else {
|
|
19523
|
+
if (boardData.outline && boardData.outline.length > 0) {
|
|
19524
|
+
console.warn(
|
|
19525
|
+
"Board outline has fewer than 3 points, falling back to rectangular board."
|
|
19526
|
+
);
|
|
19527
|
+
}
|
|
19528
|
+
boardOp = Manifold.cube(
|
|
19529
|
+
[boardData.width, boardData.height, pcbThickness],
|
|
19530
|
+
true
|
|
19531
|
+
// center (for all axes)
|
|
19532
|
+
);
|
|
19533
|
+
}
|
|
19534
|
+
manifoldInstancesForCleanup.push(boardOp);
|
|
19535
|
+
boardOp = boardOp.translate([boardData.center.x, boardData.center.y, 0]);
|
|
19536
|
+
manifoldInstancesForCleanup.push(boardOp);
|
|
19537
|
+
return boardOp;
|
|
19538
|
+
}
|
|
19539
|
+
|
|
19540
|
+
// src/hooks/useManifoldBoardBuilder.ts
|
|
19333
19541
|
var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
19334
|
-
const [
|
|
19335
|
-
const [
|
|
19336
|
-
new THREE7.Color(
|
|
19337
|
-
colors.fr4Green[0],
|
|
19338
|
-
colors.fr4Green[1],
|
|
19339
|
-
colors.fr4Green[2]
|
|
19340
|
-
)
|
|
19341
|
-
);
|
|
19342
|
-
const [otherComponentGeoms, setOtherComponentGeoms] = useState7([]);
|
|
19343
|
-
const [topTraceTexture, setTopTraceTexture] = useState7(null);
|
|
19344
|
-
const [bottomTraceTexture, setBottomTraceTexture] = useState7(null);
|
|
19345
|
-
const [topSilkscreenTexture, setTopSilkscreenTexture] = useState7(null);
|
|
19346
|
-
const [bottomSilkscreenTexture, setBottomSilkscreenTexture] = useState7(null);
|
|
19542
|
+
const [geoms, setGeoms] = useState7(null);
|
|
19543
|
+
const [textures, setTextures] = useState7(null);
|
|
19347
19544
|
const [pcbThickness, setPcbThickness] = useState7(null);
|
|
19348
19545
|
const [error, setError] = useState7(null);
|
|
19349
19546
|
const [isLoading, setIsLoading] = useState7(true);
|
|
19350
19547
|
const manifoldInstancesForCleanup = useRef6([]);
|
|
19351
19548
|
const boardData = useMemo6(() => {
|
|
19352
19549
|
if (!circuitJson) return null;
|
|
19353
|
-
const boards =
|
|
19550
|
+
const boards = su11(circuitJson).pcb_board.list();
|
|
19354
19551
|
if (boards.length === 0) {
|
|
19355
19552
|
return null;
|
|
19356
19553
|
}
|
|
19357
19554
|
return boards[0];
|
|
19358
19555
|
}, [circuitJson]);
|
|
19359
|
-
function isCircleHole(hole) {
|
|
19360
|
-
return (hole.shape === "circle" || hole.hole_shape === "circle") && typeof hole.hole_diameter === "number";
|
|
19361
|
-
}
|
|
19362
19556
|
useEffect5(() => {
|
|
19363
19557
|
if (!manifoldJSModule || !circuitJson || !boardData) {
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
setTopTraceTexture(null);
|
|
19367
|
-
setBottomTraceTexture(null);
|
|
19368
|
-
setTopSilkscreenTexture(null);
|
|
19369
|
-
setBottomSilkscreenTexture(null);
|
|
19558
|
+
setGeoms(null);
|
|
19559
|
+
setTextures(null);
|
|
19370
19560
|
setPcbThickness(null);
|
|
19371
|
-
if (circuitJson &&
|
|
19561
|
+
if (circuitJson && su11(circuitJson).pcb_board.list().length === 0) {
|
|
19372
19562
|
setError("No pcb_board found in circuitJson.");
|
|
19373
19563
|
}
|
|
19374
19564
|
setIsLoading(false);
|
|
@@ -19381,100 +19571,44 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
19381
19571
|
manifoldInstancesForCleanup.current.forEach((inst) => inst.delete());
|
|
19382
19572
|
manifoldInstancesForCleanup.current = [];
|
|
19383
19573
|
let boardManifold = null;
|
|
19384
|
-
const
|
|
19574
|
+
const currentGeoms = {};
|
|
19575
|
+
const currentTextures = {};
|
|
19385
19576
|
try {
|
|
19386
19577
|
const currentPcbThickness = boardData.thickness || 1.6;
|
|
19387
19578
|
setPcbThickness(currentPcbThickness);
|
|
19388
|
-
let currentBoardOp
|
|
19389
|
-
|
|
19390
|
-
|
|
19391
|
-
|
|
19392
|
-
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
19396
|
-
|
|
19397
|
-
|
|
19398
|
-
|
|
19399
|
-
|
|
19400
|
-
|
|
19401
|
-
|
|
19402
|
-
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
|
|
19409
|
-
|
|
19410
|
-
|
|
19411
|
-
|
|
19412
|
-
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
);
|
|
19421
|
-
}
|
|
19422
|
-
manifoldInstancesForCleanup.current.push(currentBoardOp);
|
|
19423
|
-
currentBoardOp = currentBoardOp.translate([
|
|
19424
|
-
boardData.center.x,
|
|
19425
|
-
boardData.center.y,
|
|
19426
|
-
0
|
|
19427
|
-
]);
|
|
19428
|
-
const pcbHoles = su5(circuitJson).pcb_hole.list();
|
|
19429
|
-
const pcbPlatedHoles = su5(circuitJson).pcb_plated_hole.list();
|
|
19430
|
-
const pcbVias = su5(circuitJson).pcb_via.list();
|
|
19431
|
-
const allHoleDrills = [];
|
|
19432
|
-
pcbHoles.forEach((hole) => {
|
|
19433
|
-
if (isCircleHole(hole)) {
|
|
19434
|
-
const translatedDrill = createCircleHoleDrill({
|
|
19435
|
-
Manifold,
|
|
19436
|
-
x: hole.x,
|
|
19437
|
-
y: hole.y,
|
|
19438
|
-
diameter: hole.hole_diameter,
|
|
19439
|
-
thickness: currentPcbThickness,
|
|
19440
|
-
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19441
|
-
});
|
|
19442
|
-
manifoldInstancesForCleanup.current.push(translatedDrill);
|
|
19443
|
-
allHoleDrills.push(translatedDrill);
|
|
19444
|
-
}
|
|
19445
|
-
});
|
|
19446
|
-
pcbPlatedHoles.forEach((ph) => {
|
|
19447
|
-
if (ph.shape === "circle") {
|
|
19448
|
-
const translatedDrill = createPlatedHoleDrill({
|
|
19449
|
-
Manifold,
|
|
19450
|
-
x: ph.x,
|
|
19451
|
-
y: ph.y,
|
|
19452
|
-
outerDiameter: ph.outer_diameter,
|
|
19453
|
-
thickness: currentPcbThickness,
|
|
19454
|
-
zOffset: MANIFOLD_Z_OFFSET,
|
|
19455
|
-
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19456
|
-
});
|
|
19457
|
-
manifoldInstancesForCleanup.current.push(translatedDrill);
|
|
19458
|
-
allHoleDrills.push(translatedDrill);
|
|
19459
|
-
}
|
|
19460
|
-
});
|
|
19461
|
-
pcbVias.forEach((via) => {
|
|
19462
|
-
if (typeof via.outer_diameter === "number") {
|
|
19463
|
-
const translatedDrill = createPlatedHoleDrill({
|
|
19464
|
-
Manifold,
|
|
19465
|
-
x: via.x,
|
|
19466
|
-
y: via.y,
|
|
19467
|
-
outerDiameter: via.outer_diameter,
|
|
19468
|
-
thickness: currentPcbThickness,
|
|
19469
|
-
zOffset: MANIFOLD_Z_OFFSET,
|
|
19470
|
-
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19471
|
-
});
|
|
19472
|
-
manifoldInstancesForCleanup.current.push(translatedDrill);
|
|
19473
|
-
allHoleDrills.push(translatedDrill);
|
|
19474
|
-
}
|
|
19475
|
-
});
|
|
19476
|
-
if (allHoleDrills.length > 0) {
|
|
19477
|
-
const unionedDrills = Manifold.union(allHoleDrills);
|
|
19579
|
+
let currentBoardOp = createManifoldBoard(
|
|
19580
|
+
Manifold,
|
|
19581
|
+
CrossSection,
|
|
19582
|
+
boardData,
|
|
19583
|
+
currentPcbThickness,
|
|
19584
|
+
manifoldInstancesForCleanup.current
|
|
19585
|
+
);
|
|
19586
|
+
const allBoardDrills = [];
|
|
19587
|
+
const { nonPlatedHoleBoardDrills } = processNonPlatedHolesForManifold(
|
|
19588
|
+
Manifold,
|
|
19589
|
+
circuitJson,
|
|
19590
|
+
currentPcbThickness,
|
|
19591
|
+
manifoldInstancesForCleanup.current
|
|
19592
|
+
);
|
|
19593
|
+
allBoardDrills.push(...nonPlatedHoleBoardDrills);
|
|
19594
|
+
const { platedHoleBoardDrills, platedHoleCopperGeoms } = processPlatedHolesForManifold(
|
|
19595
|
+
Manifold,
|
|
19596
|
+
circuitJson,
|
|
19597
|
+
currentPcbThickness,
|
|
19598
|
+
manifoldInstancesForCleanup.current
|
|
19599
|
+
);
|
|
19600
|
+
allBoardDrills.push(...platedHoleBoardDrills);
|
|
19601
|
+
currentGeoms.platedHoles = platedHoleCopperGeoms;
|
|
19602
|
+
const { viaBoardDrills, viaCopperGeoms } = processViasForManifold(
|
|
19603
|
+
Manifold,
|
|
19604
|
+
circuitJson,
|
|
19605
|
+
currentPcbThickness,
|
|
19606
|
+
manifoldInstancesForCleanup.current
|
|
19607
|
+
);
|
|
19608
|
+
allBoardDrills.push(...viaBoardDrills);
|
|
19609
|
+
currentGeoms.vias = viaCopperGeoms;
|
|
19610
|
+
if (allBoardDrills.length > 0) {
|
|
19611
|
+
const unionedDrills = Manifold.union(allBoardDrills);
|
|
19478
19612
|
manifoldInstancesForCleanup.current.push(unionedDrills);
|
|
19479
19613
|
const nextBoard = currentBoardOp.subtract(unionedDrills);
|
|
19480
19614
|
manifoldInstancesForCleanup.current.push(nextBoard);
|
|
@@ -19484,165 +19618,63 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
19484
19618
|
if (boardManifold) {
|
|
19485
19619
|
const boardThreeMesh = boardManifold.getMesh();
|
|
19486
19620
|
const finalBoardGeom = manifoldMeshToThreeGeometry(boardThreeMesh);
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19621
|
+
const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Green;
|
|
19622
|
+
currentGeoms.board = {
|
|
19623
|
+
geometry: finalBoardGeom,
|
|
19624
|
+
color: new THREE10.Color(
|
|
19625
|
+
matColorArray[0],
|
|
19626
|
+
matColorArray[1],
|
|
19627
|
+
matColorArray[2]
|
|
19628
|
+
)
|
|
19629
|
+
};
|
|
19490
19630
|
}
|
|
19491
|
-
const
|
|
19492
|
-
|
|
19493
|
-
|
|
19631
|
+
const { smtPadGeoms } = processSmtPadsForManifold(
|
|
19632
|
+
Manifold,
|
|
19633
|
+
circuitJson,
|
|
19634
|
+
currentPcbThickness,
|
|
19635
|
+
manifoldInstancesForCleanup.current
|
|
19494
19636
|
);
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
const copperPartThickness = currentPcbThickness + 2 * MANIFOLD_Z_OFFSET;
|
|
19498
|
-
let platedPart = Manifold.cylinder(
|
|
19499
|
-
copperPartThickness,
|
|
19500
|
-
ph.outer_diameter / 2,
|
|
19501
|
-
-1,
|
|
19502
|
-
SMOOTH_CIRCLE_SEGMENTS,
|
|
19503
|
-
true
|
|
19504
|
-
);
|
|
19505
|
-
manifoldInstancesForCleanup.current.push(platedPart);
|
|
19506
|
-
const drill = Manifold.cylinder(
|
|
19507
|
-
copperPartThickness * 1.05,
|
|
19508
|
-
ph.hole_diameter / 2,
|
|
19509
|
-
-1,
|
|
19510
|
-
SMOOTH_CIRCLE_SEGMENTS,
|
|
19511
|
-
true
|
|
19512
|
-
);
|
|
19513
|
-
manifoldInstancesForCleanup.current.push(drill);
|
|
19514
|
-
const finalPlatedPartOp = platedPart.subtract(drill);
|
|
19515
|
-
manifoldInstancesForCleanup.current.push(finalPlatedPartOp);
|
|
19516
|
-
const translatedPlatedPart = finalPlatedPartOp.translate([
|
|
19517
|
-
ph.x,
|
|
19518
|
-
ph.y,
|
|
19519
|
-
0
|
|
19520
|
-
]);
|
|
19521
|
-
manifoldInstancesForCleanup.current.push(translatedPlatedPart);
|
|
19522
|
-
const copperMesh = translatedPlatedPart.getMesh();
|
|
19523
|
-
const copperGeom = manifoldMeshToThreeGeometry(copperMesh);
|
|
19524
|
-
newOtherGeoms.push({
|
|
19525
|
-
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
19526
|
-
geometry: copperGeom,
|
|
19527
|
-
color: COPPER_COLOR,
|
|
19528
|
-
manifoldSource: translatedPlatedPart
|
|
19529
|
-
});
|
|
19530
|
-
}
|
|
19531
|
-
});
|
|
19532
|
-
const smtPads = su5(circuitJson).pcb_smtpad.list();
|
|
19533
|
-
smtPads.forEach((pad, index) => {
|
|
19534
|
-
const padBaseThickness = DEFAULT_SMT_PAD_THICKNESS;
|
|
19535
|
-
const zPos = pad.layer === "bottom" ? -currentPcbThickness / 2 - padBaseThickness / 2 - MANIFOLD_Z_OFFSET : currentPcbThickness / 2 + padBaseThickness / 2 + MANIFOLD_Z_OFFSET;
|
|
19536
|
-
let padManifoldOp = createPadManifoldOp({
|
|
19537
|
-
Manifold,
|
|
19538
|
-
pad,
|
|
19539
|
-
padBaseThickness
|
|
19540
|
-
});
|
|
19541
|
-
if (padManifoldOp) {
|
|
19542
|
-
manifoldInstancesForCleanup.current.push(padManifoldOp);
|
|
19543
|
-
const translatedPad = padManifoldOp.translate([pad.x, pad.y, zPos]);
|
|
19544
|
-
manifoldInstancesForCleanup.current.push(translatedPad);
|
|
19545
|
-
const padMesh = translatedPad.getMesh();
|
|
19546
|
-
const padGeom = manifoldMeshToThreeGeometry(padMesh);
|
|
19547
|
-
newOtherGeoms.push({
|
|
19548
|
-
key: `pad-${pad.pcb_smtpad_id || index}`,
|
|
19549
|
-
geometry: padGeom,
|
|
19550
|
-
color: COPPER_COLOR,
|
|
19551
|
-
manifoldSource: translatedPad
|
|
19552
|
-
});
|
|
19553
|
-
}
|
|
19554
|
-
});
|
|
19555
|
-
pcbVias.forEach((via, index) => {
|
|
19556
|
-
if (typeof via.outer_diameter === "number" && typeof via.hole_diameter === "number") {
|
|
19557
|
-
const translatedViaCopper = createViaCopper({
|
|
19558
|
-
Manifold,
|
|
19559
|
-
x: via.x,
|
|
19560
|
-
y: via.y,
|
|
19561
|
-
outerDiameter: via.outer_diameter,
|
|
19562
|
-
holeDiameter: via.hole_diameter,
|
|
19563
|
-
thickness: currentPcbThickness,
|
|
19564
|
-
zOffset: MANIFOLD_Z_OFFSET,
|
|
19565
|
-
segments: SMOOTH_CIRCLE_SEGMENTS
|
|
19566
|
-
});
|
|
19567
|
-
manifoldInstancesForCleanup.current.push(translatedViaCopper);
|
|
19568
|
-
const viaMesh = translatedViaCopper.getMesh();
|
|
19569
|
-
const viaGeom = manifoldMeshToThreeGeometry(viaMesh);
|
|
19570
|
-
newOtherGeoms.push({
|
|
19571
|
-
key: `via-${via.pcb_via_id || index}`,
|
|
19572
|
-
geometry: viaGeom,
|
|
19573
|
-
color: COPPER_COLOR,
|
|
19574
|
-
manifoldSource: translatedViaCopper
|
|
19575
|
-
});
|
|
19576
|
-
}
|
|
19577
|
-
});
|
|
19578
|
-
const pcbTraces = su5(circuitJson).pcb_trace.list();
|
|
19637
|
+
currentGeoms.smtPads = smtPadGeoms;
|
|
19638
|
+
setGeoms(currentGeoms);
|
|
19579
19639
|
const traceColorArr = tracesMaterialColors[boardData.material] ?? colors.fr4GreenSolderWithMask;
|
|
19580
19640
|
const traceColor = `rgb(${Math.round(traceColorArr[0] * 255)}, ${Math.round(traceColorArr[1] * 255)}, ${Math.round(traceColorArr[2] * 255)})`;
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
createTraceTextureForLayer({
|
|
19596
|
-
layer: "bottom",
|
|
19597
|
-
pcbTraces,
|
|
19598
|
-
boardData,
|
|
19599
|
-
traceColor,
|
|
19600
|
-
traceTextureResolution: TRACE_TEXTURE_RESOLUTION,
|
|
19601
|
-
allPcbVias,
|
|
19602
|
-
allPcbPlatedHoles
|
|
19603
|
-
})
|
|
19604
|
-
);
|
|
19605
|
-
const pcbSilkscreenTexts = su5(circuitJson).pcb_silkscreen_text.list();
|
|
19606
|
-
const pcbSilkscreenPaths = su5(circuitJson).pcb_silkscreen_path.list();
|
|
19641
|
+
currentTextures.topTrace = createTraceTextureForLayer({
|
|
19642
|
+
layer: "top",
|
|
19643
|
+
circuitJson,
|
|
19644
|
+
boardData,
|
|
19645
|
+
traceColor,
|
|
19646
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
19647
|
+
});
|
|
19648
|
+
currentTextures.bottomTrace = createTraceTextureForLayer({
|
|
19649
|
+
layer: "bottom",
|
|
19650
|
+
circuitJson,
|
|
19651
|
+
boardData,
|
|
19652
|
+
traceColor,
|
|
19653
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
19654
|
+
});
|
|
19607
19655
|
const silkscreenColor = "rgb(255,255,255)";
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
|
|
19621
|
-
|
|
19622
|
-
|
|
19623
|
-
boardData,
|
|
19624
|
-
silkscreenColor,
|
|
19625
|
-
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
19626
|
-
})
|
|
19627
|
-
);
|
|
19628
|
-
setOtherComponentGeoms(
|
|
19629
|
-
newOtherGeoms.map((g) => ({
|
|
19630
|
-
key: g.key,
|
|
19631
|
-
geometry: g.geometry,
|
|
19632
|
-
color: g.color
|
|
19633
|
-
}))
|
|
19634
|
-
);
|
|
19656
|
+
currentTextures.topSilkscreen = createSilkscreenTextureForLayer({
|
|
19657
|
+
layer: "top",
|
|
19658
|
+
circuitJson,
|
|
19659
|
+
boardData,
|
|
19660
|
+
silkscreenColor,
|
|
19661
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
19662
|
+
});
|
|
19663
|
+
currentTextures.bottomSilkscreen = createSilkscreenTextureForLayer({
|
|
19664
|
+
layer: "bottom",
|
|
19665
|
+
circuitJson,
|
|
19666
|
+
boardData,
|
|
19667
|
+
silkscreenColor,
|
|
19668
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
19669
|
+
});
|
|
19670
|
+
setTextures(currentTextures);
|
|
19635
19671
|
} catch (e) {
|
|
19636
19672
|
console.error("Error processing geometry with Manifold in hook:", e);
|
|
19637
19673
|
setError(
|
|
19638
19674
|
e.message || "An unknown error occurred while processing geometry in hook."
|
|
19639
19675
|
);
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
setTopTraceTexture(null);
|
|
19643
|
-
setBottomTraceTexture(null);
|
|
19644
|
-
setTopSilkscreenTexture(null);
|
|
19645
|
-
setBottomSilkscreenTexture(null);
|
|
19676
|
+
setGeoms(null);
|
|
19677
|
+
setTextures(null);
|
|
19646
19678
|
} finally {
|
|
19647
19679
|
setIsLoading(false);
|
|
19648
19680
|
}
|
|
@@ -19652,13 +19684,8 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
19652
19684
|
};
|
|
19653
19685
|
}, [manifoldJSModule, circuitJson, boardData]);
|
|
19654
19686
|
return {
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
otherComponentGeoms,
|
|
19658
|
-
topTraceTexture,
|
|
19659
|
-
bottomTraceTexture,
|
|
19660
|
-
topSilkscreenTexture,
|
|
19661
|
-
bottomSilkscreenTexture,
|
|
19687
|
+
geoms,
|
|
19688
|
+
textures,
|
|
19662
19689
|
pcbThickness,
|
|
19663
19690
|
error,
|
|
19664
19691
|
isLoading,
|
|
@@ -19666,6 +19693,102 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
19666
19693
|
};
|
|
19667
19694
|
};
|
|
19668
19695
|
|
|
19696
|
+
// src/utils/manifold/create-three-geometry-meshes.ts
|
|
19697
|
+
import * as THREE11 from "three";
|
|
19698
|
+
function createGeometryMeshes(geoms) {
|
|
19699
|
+
const meshes = [];
|
|
19700
|
+
if (!geoms) return meshes;
|
|
19701
|
+
if (geoms.board && geoms.board.geometry) {
|
|
19702
|
+
const mesh = new THREE11.Mesh(
|
|
19703
|
+
geoms.board.geometry,
|
|
19704
|
+
new THREE11.MeshStandardMaterial({
|
|
19705
|
+
color: geoms.board.color,
|
|
19706
|
+
side: THREE11.DoubleSide,
|
|
19707
|
+
flatShading: true
|
|
19708
|
+
})
|
|
19709
|
+
);
|
|
19710
|
+
mesh.name = "board-geom";
|
|
19711
|
+
meshes.push(mesh);
|
|
19712
|
+
}
|
|
19713
|
+
const createMeshesFromArray = (geomArray) => {
|
|
19714
|
+
if (geomArray) {
|
|
19715
|
+
geomArray.forEach((comp) => {
|
|
19716
|
+
const mesh = new THREE11.Mesh(
|
|
19717
|
+
comp.geometry,
|
|
19718
|
+
new THREE11.MeshStandardMaterial({
|
|
19719
|
+
color: comp.color,
|
|
19720
|
+
side: THREE11.DoubleSide,
|
|
19721
|
+
flatShading: true
|
|
19722
|
+
// Consistent with board
|
|
19723
|
+
})
|
|
19724
|
+
);
|
|
19725
|
+
mesh.name = comp.key;
|
|
19726
|
+
meshes.push(mesh);
|
|
19727
|
+
});
|
|
19728
|
+
}
|
|
19729
|
+
};
|
|
19730
|
+
createMeshesFromArray(geoms.platedHoles);
|
|
19731
|
+
createMeshesFromArray(geoms.smtPads);
|
|
19732
|
+
createMeshesFromArray(geoms.vias);
|
|
19733
|
+
return meshes;
|
|
19734
|
+
}
|
|
19735
|
+
|
|
19736
|
+
// src/utils/manifold/create-three-texture-meshes.ts
|
|
19737
|
+
import * as THREE12 from "three";
|
|
19738
|
+
function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
19739
|
+
const meshes = [];
|
|
19740
|
+
if (!textures || !boardData || pcbThickness === null) return meshes;
|
|
19741
|
+
const createTexturePlane = (texture, yOffset, isBottomLayer, keySuffix) => {
|
|
19742
|
+
if (!texture) return null;
|
|
19743
|
+
const planeGeom = new THREE12.PlaneGeometry(boardData.width, boardData.height);
|
|
19744
|
+
const material = new THREE12.MeshBasicMaterial({
|
|
19745
|
+
map: texture,
|
|
19746
|
+
transparent: true,
|
|
19747
|
+
side: THREE12.DoubleSide,
|
|
19748
|
+
depthWrite: false
|
|
19749
|
+
// Important for layers to avoid z-fighting issues with board itself
|
|
19750
|
+
});
|
|
19751
|
+
const mesh = new THREE12.Mesh(planeGeom, material);
|
|
19752
|
+
mesh.position.set(boardData.center.x, boardData.center.y, yOffset);
|
|
19753
|
+
if (isBottomLayer) {
|
|
19754
|
+
mesh.rotation.set(Math.PI, 0, 0);
|
|
19755
|
+
}
|
|
19756
|
+
mesh.name = `${isBottomLayer ? "bottom" : "top"}-${keySuffix}-texture-plane`;
|
|
19757
|
+
return mesh;
|
|
19758
|
+
};
|
|
19759
|
+
const topTraceMesh = createTexturePlane(
|
|
19760
|
+
textures.topTrace,
|
|
19761
|
+
pcbThickness / 2 + 0.015,
|
|
19762
|
+
// Offset similar to CadViewerManifold
|
|
19763
|
+
false,
|
|
19764
|
+
"trace"
|
|
19765
|
+
);
|
|
19766
|
+
if (topTraceMesh) meshes.push(topTraceMesh);
|
|
19767
|
+
const topSilkscreenMesh = createTexturePlane(
|
|
19768
|
+
textures.topSilkscreen,
|
|
19769
|
+
pcbThickness / 2 + 0.017,
|
|
19770
|
+
// Slightly above trace
|
|
19771
|
+
false,
|
|
19772
|
+
"silkscreen"
|
|
19773
|
+
);
|
|
19774
|
+
if (topSilkscreenMesh) meshes.push(topSilkscreenMesh);
|
|
19775
|
+
const bottomTraceMesh = createTexturePlane(
|
|
19776
|
+
textures.bottomTrace,
|
|
19777
|
+
-pcbThickness / 2 - 0.015,
|
|
19778
|
+
true,
|
|
19779
|
+
"trace"
|
|
19780
|
+
);
|
|
19781
|
+
if (bottomTraceMesh) meshes.push(bottomTraceMesh);
|
|
19782
|
+
const bottomSilkscreenMesh = createTexturePlane(
|
|
19783
|
+
textures.bottomSilkscreen,
|
|
19784
|
+
-pcbThickness / 2 - 0.017,
|
|
19785
|
+
true,
|
|
19786
|
+
"silkscreen"
|
|
19787
|
+
);
|
|
19788
|
+
if (bottomSilkscreenMesh) meshes.push(bottomSilkscreenMesh);
|
|
19789
|
+
return meshes;
|
|
19790
|
+
}
|
|
19791
|
+
|
|
19669
19792
|
// src/CadViewerManifold.tsx
|
|
19670
19793
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
19671
19794
|
var CadViewerManifold = ({
|
|
@@ -19689,20 +19812,20 @@ var CadViewerManifold = ({
|
|
|
19689
19812
|
});
|
|
19690
19813
|
}, []);
|
|
19691
19814
|
const {
|
|
19692
|
-
|
|
19693
|
-
|
|
19694
|
-
otherComponentGeoms,
|
|
19695
|
-
topTraceTexture,
|
|
19696
|
-
bottomTraceTexture,
|
|
19697
|
-
topSilkscreenTexture,
|
|
19698
|
-
bottomSilkscreenTexture,
|
|
19815
|
+
geoms,
|
|
19816
|
+
textures,
|
|
19699
19817
|
pcbThickness,
|
|
19700
19818
|
error: builderError,
|
|
19701
19819
|
isLoading: builderIsLoading,
|
|
19702
19820
|
boardData
|
|
19703
19821
|
} = useManifoldBoardBuilder(manifoldJSModule, circuitJson);
|
|
19822
|
+
const geometryMeshes = useMemo7(() => createGeometryMeshes(geoms), [geoms]);
|
|
19823
|
+
const textureMeshes = useMemo7(
|
|
19824
|
+
() => createTextureMeshes(textures, boardData, pcbThickness),
|
|
19825
|
+
[textures, boardData, pcbThickness]
|
|
19826
|
+
);
|
|
19704
19827
|
const cadComponents = useMemo7(
|
|
19705
|
-
() => circuitJson ?
|
|
19828
|
+
() => circuitJson ? su12(circuitJson).cad_component.list() : [],
|
|
19706
19829
|
[circuitJson]
|
|
19707
19830
|
);
|
|
19708
19831
|
const initialCameraPosition = useMemo7(() => {
|
|
@@ -19750,12 +19873,9 @@ var CadViewerManifold = ({
|
|
|
19750
19873
|
}
|
|
19751
19874
|
);
|
|
19752
19875
|
}
|
|
19753
|
-
if (builderIsLoading || !boardData) {
|
|
19876
|
+
if (builderIsLoading || !boardData || !geoms || !textures) {
|
|
19754
19877
|
return /* @__PURE__ */ jsx11("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
|
|
19755
19878
|
}
|
|
19756
|
-
if (!boardThreeGeom) {
|
|
19757
|
-
return /* @__PURE__ */ jsx11("div", { style: { padding: "1em" }, children: "Preparing board display..." });
|
|
19758
|
-
}
|
|
19759
19879
|
return /* @__PURE__ */ jsxs8(
|
|
19760
19880
|
CadViewerContainer,
|
|
19761
19881
|
{
|
|
@@ -19763,112 +19883,8 @@ var CadViewerManifold = ({
|
|
|
19763
19883
|
autoRotateDisabled,
|
|
19764
19884
|
clickToInteractEnabled,
|
|
19765
19885
|
children: [
|
|
19766
|
-
/* @__PURE__ */ jsx11("
|
|
19767
|
-
|
|
19768
|
-
{
|
|
19769
|
-
color: boardColor,
|
|
19770
|
-
side: THREE8.DoubleSide,
|
|
19771
|
-
flatShading: true
|
|
19772
|
-
}
|
|
19773
|
-
) }),
|
|
19774
|
-
topTraceTexture && boardData && pcbThickness !== null && /* @__PURE__ */ jsxs8(
|
|
19775
|
-
"mesh",
|
|
19776
|
-
{
|
|
19777
|
-
position: [
|
|
19778
|
-
boardData.center.x,
|
|
19779
|
-
boardData.center.y,
|
|
19780
|
-
pcbThickness / 2 + 0.015
|
|
19781
|
-
],
|
|
19782
|
-
children: [
|
|
19783
|
-
/* @__PURE__ */ jsx11("planeGeometry", { args: [boardData.width, boardData.height] }),
|
|
19784
|
-
/* @__PURE__ */ jsx11(
|
|
19785
|
-
"meshBasicMaterial",
|
|
19786
|
-
{
|
|
19787
|
-
map: topTraceTexture,
|
|
19788
|
-
transparent: true,
|
|
19789
|
-
side: THREE8.DoubleSide,
|
|
19790
|
-
depthWrite: false
|
|
19791
|
-
}
|
|
19792
|
-
)
|
|
19793
|
-
]
|
|
19794
|
-
}
|
|
19795
|
-
),
|
|
19796
|
-
topSilkscreenTexture && boardData && pcbThickness !== null && /* @__PURE__ */ jsxs8(
|
|
19797
|
-
"mesh",
|
|
19798
|
-
{
|
|
19799
|
-
position: [
|
|
19800
|
-
boardData.center.x,
|
|
19801
|
-
boardData.center.y,
|
|
19802
|
-
pcbThickness / 2 + 0.017
|
|
19803
|
-
],
|
|
19804
|
-
children: [
|
|
19805
|
-
/* @__PURE__ */ jsx11("planeGeometry", { args: [boardData.width, boardData.height] }),
|
|
19806
|
-
/* @__PURE__ */ jsx11(
|
|
19807
|
-
"meshBasicMaterial",
|
|
19808
|
-
{
|
|
19809
|
-
map: topSilkscreenTexture,
|
|
19810
|
-
transparent: true,
|
|
19811
|
-
side: THREE8.DoubleSide,
|
|
19812
|
-
depthWrite: false
|
|
19813
|
-
}
|
|
19814
|
-
)
|
|
19815
|
-
]
|
|
19816
|
-
}
|
|
19817
|
-
),
|
|
19818
|
-
bottomTraceTexture && boardData && pcbThickness !== null && /* @__PURE__ */ jsxs8(
|
|
19819
|
-
"mesh",
|
|
19820
|
-
{
|
|
19821
|
-
position: [
|
|
19822
|
-
boardData.center.x,
|
|
19823
|
-
boardData.center.y,
|
|
19824
|
-
-pcbThickness / 2 - 0.015
|
|
19825
|
-
],
|
|
19826
|
-
rotation: [Math.PI, 0, 0],
|
|
19827
|
-
children: [
|
|
19828
|
-
/* @__PURE__ */ jsx11("planeGeometry", { args: [boardData.width, boardData.height] }),
|
|
19829
|
-
/* @__PURE__ */ jsx11(
|
|
19830
|
-
"meshBasicMaterial",
|
|
19831
|
-
{
|
|
19832
|
-
map: bottomTraceTexture,
|
|
19833
|
-
transparent: true,
|
|
19834
|
-
side: THREE8.DoubleSide,
|
|
19835
|
-
depthWrite: false
|
|
19836
|
-
}
|
|
19837
|
-
)
|
|
19838
|
-
]
|
|
19839
|
-
}
|
|
19840
|
-
),
|
|
19841
|
-
bottomSilkscreenTexture && boardData && pcbThickness !== null && /* @__PURE__ */ jsxs8(
|
|
19842
|
-
"mesh",
|
|
19843
|
-
{
|
|
19844
|
-
position: [
|
|
19845
|
-
boardData.center.x,
|
|
19846
|
-
boardData.center.y,
|
|
19847
|
-
-pcbThickness / 2 - 0.017
|
|
19848
|
-
],
|
|
19849
|
-
rotation: [Math.PI, 0, 0],
|
|
19850
|
-
children: [
|
|
19851
|
-
/* @__PURE__ */ jsx11("planeGeometry", { args: [boardData.width, boardData.height] }),
|
|
19852
|
-
/* @__PURE__ */ jsx11(
|
|
19853
|
-
"meshBasicMaterial",
|
|
19854
|
-
{
|
|
19855
|
-
map: bottomSilkscreenTexture,
|
|
19856
|
-
transparent: true,
|
|
19857
|
-
side: THREE8.DoubleSide,
|
|
19858
|
-
depthWrite: false
|
|
19859
|
-
}
|
|
19860
|
-
)
|
|
19861
|
-
]
|
|
19862
|
-
}
|
|
19863
|
-
),
|
|
19864
|
-
otherComponentGeoms.map((comp) => /* @__PURE__ */ jsx11("mesh", { geometry: comp.geometry, children: /* @__PURE__ */ jsx11(
|
|
19865
|
-
"meshStandardMaterial",
|
|
19866
|
-
{
|
|
19867
|
-
color: comp.color,
|
|
19868
|
-
side: THREE8.DoubleSide,
|
|
19869
|
-
flatShading: true
|
|
19870
|
-
}
|
|
19871
|
-
) }, comp.key)),
|
|
19886
|
+
geometryMeshes.map((mesh, index) => /* @__PURE__ */ jsx11("primitive", { object: mesh }, `${mesh.name}-${index}`)),
|
|
19887
|
+
textureMeshes.map((mesh, index) => /* @__PURE__ */ jsx11("primitive", { object: mesh }, `${mesh.name}-${index}`)),
|
|
19872
19888
|
cadComponents.map((cad_component) => /* @__PURE__ */ jsx11(
|
|
19873
19889
|
ThreeErrorBoundary,
|
|
19874
19890
|
{
|
|
@@ -20031,12 +20047,12 @@ var CadViewer = (props) => {
|
|
|
20031
20047
|
|
|
20032
20048
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
20033
20049
|
var import_debug = __toESM(require_browser(), 1);
|
|
20034
|
-
import { su as
|
|
20035
|
-
import * as
|
|
20050
|
+
import { su as su13 } from "@tscircuit/soup-util";
|
|
20051
|
+
import * as THREE16 from "three";
|
|
20036
20052
|
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
|
|
20037
20053
|
|
|
20038
20054
|
// src/utils/create-geometry-from-polygons.ts
|
|
20039
|
-
import * as
|
|
20055
|
+
import * as THREE13 from "three";
|
|
20040
20056
|
import { BufferGeometry as BufferGeometry4, Float32BufferAttribute as Float32BufferAttribute4 } from "three";
|
|
20041
20057
|
function createGeometryFromPolygons(polygons) {
|
|
20042
20058
|
const geometry = new BufferGeometry4();
|
|
@@ -20050,12 +20066,12 @@ function createGeometryFromPolygons(polygons) {
|
|
|
20050
20066
|
...polygon2.vertices[i + 1]
|
|
20051
20067
|
// Third vertex
|
|
20052
20068
|
);
|
|
20053
|
-
const v1 = new
|
|
20054
|
-
const v2 = new
|
|
20055
|
-
const v3 = new
|
|
20056
|
-
const normal = new
|
|
20057
|
-
new
|
|
20058
|
-
new
|
|
20069
|
+
const v1 = new THREE13.Vector3(...polygon2.vertices[0]);
|
|
20070
|
+
const v2 = new THREE13.Vector3(...polygon2.vertices[i]);
|
|
20071
|
+
const v3 = new THREE13.Vector3(...polygon2.vertices[i + 1]);
|
|
20072
|
+
const normal = new THREE13.Vector3().crossVectors(
|
|
20073
|
+
new THREE13.Vector3().subVectors(v2, v1),
|
|
20074
|
+
new THREE13.Vector3().subVectors(v3, v1)
|
|
20059
20075
|
).normalize();
|
|
20060
20076
|
normals.push(
|
|
20061
20077
|
normal.x,
|
|
@@ -20081,22 +20097,22 @@ import { Footprinter3d as Footprinter3d2 } from "jscad-electronics";
|
|
|
20081
20097
|
import { convertCSGToThreeGeom as convertCSGToThreeGeom2 } from "jscad-fiber/three";
|
|
20082
20098
|
import { createJSCADRenderer as createJSCADRenderer2 } from "jscad-fiber";
|
|
20083
20099
|
import { executeJscadOperations as executeJscadOperations2, jscadPlanner as jscadPlanner2 } from "jscad-planner";
|
|
20084
|
-
import * as
|
|
20100
|
+
import * as THREE15 from "three";
|
|
20085
20101
|
|
|
20086
20102
|
// src/utils/load-model.ts
|
|
20087
|
-
import * as
|
|
20103
|
+
import * as THREE14 from "three";
|
|
20088
20104
|
import { OBJLoader as OBJLoader3 } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
20089
20105
|
import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
|
|
20090
20106
|
async function load3DModel(url) {
|
|
20091
20107
|
if (url.endsWith(".stl")) {
|
|
20092
20108
|
const loader = new STLLoader2();
|
|
20093
20109
|
const geometry = await loader.loadAsync(url);
|
|
20094
|
-
const material = new
|
|
20110
|
+
const material = new THREE14.MeshStandardMaterial({
|
|
20095
20111
|
color: 8947848,
|
|
20096
20112
|
metalness: 0.5,
|
|
20097
20113
|
roughness: 0.5
|
|
20098
20114
|
});
|
|
20099
|
-
return new
|
|
20115
|
+
return new THREE14.Mesh(geometry, material);
|
|
20100
20116
|
}
|
|
20101
20117
|
if (url.endsWith(".obj")) {
|
|
20102
20118
|
const loader = new OBJLoader3();
|
|
@@ -20123,9 +20139,9 @@ async function renderComponent(component, scene) {
|
|
|
20123
20139
|
}
|
|
20124
20140
|
if (component.rotation) {
|
|
20125
20141
|
model.rotation.set(
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20142
|
+
THREE15.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
20143
|
+
THREE15.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
20144
|
+
THREE15.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
20129
20145
|
);
|
|
20130
20146
|
}
|
|
20131
20147
|
scene.add(model);
|
|
@@ -20138,13 +20154,13 @@ async function renderComponent(component, scene) {
|
|
|
20138
20154
|
component.model_jscad
|
|
20139
20155
|
);
|
|
20140
20156
|
const threeGeom = convertCSGToThreeGeom2(jscadObject);
|
|
20141
|
-
const material2 = new
|
|
20157
|
+
const material2 = new THREE15.MeshStandardMaterial({
|
|
20142
20158
|
color: 8947848,
|
|
20143
20159
|
metalness: 0.5,
|
|
20144
20160
|
roughness: 0.5,
|
|
20145
|
-
side:
|
|
20161
|
+
side: THREE15.DoubleSide
|
|
20146
20162
|
});
|
|
20147
|
-
const mesh2 = new
|
|
20163
|
+
const mesh2 = new THREE15.Mesh(threeGeom, material2);
|
|
20148
20164
|
if (component.position) {
|
|
20149
20165
|
mesh2.position.set(
|
|
20150
20166
|
component.position.x ?? 0,
|
|
@@ -20154,9 +20170,9 @@ async function renderComponent(component, scene) {
|
|
|
20154
20170
|
}
|
|
20155
20171
|
if (component.rotation) {
|
|
20156
20172
|
mesh2.rotation.set(
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20173
|
+
THREE15.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
20174
|
+
THREE15.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
20175
|
+
THREE15.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
20160
20176
|
);
|
|
20161
20177
|
}
|
|
20162
20178
|
scene.add(mesh2);
|
|
@@ -20169,13 +20185,13 @@ async function renderComponent(component, scene) {
|
|
|
20169
20185
|
for (const operation of jscadOperations) {
|
|
20170
20186
|
const jscadObject = executeJscadOperations2(import_modeling2.default, operation);
|
|
20171
20187
|
const threeGeom = convertCSGToThreeGeom2(jscadObject);
|
|
20172
|
-
const material2 = new
|
|
20188
|
+
const material2 = new THREE15.MeshStandardMaterial({
|
|
20173
20189
|
color: 4473924,
|
|
20174
20190
|
metalness: 0.2,
|
|
20175
20191
|
roughness: 0.8,
|
|
20176
|
-
side:
|
|
20192
|
+
side: THREE15.DoubleSide
|
|
20177
20193
|
});
|
|
20178
|
-
const mesh2 = new
|
|
20194
|
+
const mesh2 = new THREE15.Mesh(threeGeom, material2);
|
|
20179
20195
|
if (component.position) {
|
|
20180
20196
|
mesh2.position.set(
|
|
20181
20197
|
component.position.x ?? 0,
|
|
@@ -20185,22 +20201,22 @@ async function renderComponent(component, scene) {
|
|
|
20185
20201
|
}
|
|
20186
20202
|
if (component.rotation) {
|
|
20187
20203
|
mesh2.rotation.set(
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
|
|
20204
|
+
THREE15.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
20205
|
+
THREE15.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
20206
|
+
THREE15.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
20191
20207
|
);
|
|
20192
20208
|
}
|
|
20193
20209
|
scene.add(mesh2);
|
|
20194
20210
|
}
|
|
20195
20211
|
return;
|
|
20196
20212
|
}
|
|
20197
|
-
const geometry = new
|
|
20198
|
-
const material = new
|
|
20213
|
+
const geometry = new THREE15.BoxGeometry(0.5, 0.5, 0.5);
|
|
20214
|
+
const material = new THREE15.MeshStandardMaterial({
|
|
20199
20215
|
color: 16711680,
|
|
20200
20216
|
transparent: true,
|
|
20201
20217
|
opacity: 0.25
|
|
20202
20218
|
});
|
|
20203
|
-
const mesh = new
|
|
20219
|
+
const mesh = new THREE15.Mesh(geometry, material);
|
|
20204
20220
|
if (component.position) {
|
|
20205
20221
|
mesh.position.set(
|
|
20206
20222
|
component.position.x ?? 0,
|
|
@@ -20221,11 +20237,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
20221
20237
|
padding = 20,
|
|
20222
20238
|
zoom = 1.5
|
|
20223
20239
|
} = options;
|
|
20224
|
-
const scene = new
|
|
20240
|
+
const scene = new THREE16.Scene();
|
|
20225
20241
|
const renderer = new SVGRenderer();
|
|
20226
20242
|
renderer.setSize(width, height);
|
|
20227
|
-
renderer.setClearColor(new
|
|
20228
|
-
const camera = new
|
|
20243
|
+
renderer.setClearColor(new THREE16.Color(backgroundColor), 1);
|
|
20244
|
+
const camera = new THREE16.OrthographicCamera();
|
|
20229
20245
|
const aspect = width / height;
|
|
20230
20246
|
const frustumSize = 100;
|
|
20231
20247
|
const halfFrustumSize = frustumSize / 2 / zoom;
|
|
@@ -20239,14 +20255,14 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
20239
20255
|
camera.position.set(position.x, position.y, position.z);
|
|
20240
20256
|
camera.up.set(0, 1, 0);
|
|
20241
20257
|
const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
|
|
20242
|
-
camera.lookAt(new
|
|
20258
|
+
camera.lookAt(new THREE16.Vector3(lookAt.x, lookAt.y, lookAt.z));
|
|
20243
20259
|
camera.updateProjectionMatrix();
|
|
20244
|
-
const ambientLight = new
|
|
20260
|
+
const ambientLight = new THREE16.AmbientLight(16777215, Math.PI / 2);
|
|
20245
20261
|
scene.add(ambientLight);
|
|
20246
|
-
const pointLight = new
|
|
20262
|
+
const pointLight = new THREE16.PointLight(16777215, Math.PI / 4);
|
|
20247
20263
|
pointLight.position.set(-10, -10, 10);
|
|
20248
20264
|
scene.add(pointLight);
|
|
20249
|
-
const components =
|
|
20265
|
+
const components = su13(circuitJson).cad_component.list();
|
|
20250
20266
|
for (const component of components) {
|
|
20251
20267
|
await renderComponent(component, scene);
|
|
20252
20268
|
}
|
|
@@ -20254,8 +20270,8 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
20254
20270
|
if (boardGeom) {
|
|
20255
20271
|
for (const geom of boardGeom) {
|
|
20256
20272
|
const geometry = createGeometryFromPolygons(geom.polygons);
|
|
20257
|
-
const material = new
|
|
20258
|
-
color: new
|
|
20273
|
+
const material = new THREE16.MeshStandardMaterial({
|
|
20274
|
+
color: new THREE16.Color(
|
|
20259
20275
|
geom.color?.[0] ?? 0,
|
|
20260
20276
|
geom.color?.[1] ?? 0,
|
|
20261
20277
|
geom.color?.[2] ?? 0
|
|
@@ -20264,18 +20280,18 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
20264
20280
|
roughness: 0.8,
|
|
20265
20281
|
opacity: 0.9,
|
|
20266
20282
|
transparent: true,
|
|
20267
|
-
side:
|
|
20283
|
+
side: THREE16.DoubleSide
|
|
20268
20284
|
});
|
|
20269
|
-
const mesh = new
|
|
20285
|
+
const mesh = new THREE16.Mesh(geometry, material);
|
|
20270
20286
|
scene.add(mesh);
|
|
20271
20287
|
}
|
|
20272
20288
|
}
|
|
20273
|
-
const gridHelper = new
|
|
20289
|
+
const gridHelper = new THREE16.GridHelper(100, 100);
|
|
20274
20290
|
gridHelper.rotation.x = Math.PI / 2;
|
|
20275
20291
|
scene.add(gridHelper);
|
|
20276
|
-
const box = new
|
|
20277
|
-
const center = box.getCenter(new
|
|
20278
|
-
const size = box.getSize(new
|
|
20292
|
+
const box = new THREE16.Box3().setFromObject(scene);
|
|
20293
|
+
const center = box.getCenter(new THREE16.Vector3());
|
|
20294
|
+
const size = box.getSize(new THREE16.Vector3());
|
|
20279
20295
|
scene.position.sub(center);
|
|
20280
20296
|
const maxDim = Math.max(size.x, size.y, size.z);
|
|
20281
20297
|
if (maxDim > 0) {
|