@tscircuit/3d-viewer 0.0.470 → 0.0.471
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 +2 -0
- package/dist/index.js +305 -133
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,8 @@ interface ManifoldTextures {
|
|
|
83
83
|
bottomSoldermask?: THREE.CanvasTexture | null;
|
|
84
84
|
topCopperText?: THREE.CanvasTexture | null;
|
|
85
85
|
bottomCopperText?: THREE.CanvasTexture | null;
|
|
86
|
+
topPanelOutlines?: THREE.CanvasTexture | null;
|
|
87
|
+
bottomPanelOutlines?: THREE.CanvasTexture | null;
|
|
86
88
|
}
|
|
87
89
|
interface UseManifoldBoardBuilderResult {
|
|
88
90
|
geoms: ManifoldGeoms | null;
|
package/dist/index.js
CHANGED
|
@@ -14229,10 +14229,10 @@ var require_browser = __commonJS({
|
|
|
14229
14229
|
|
|
14230
14230
|
// src/CadViewer.tsx
|
|
14231
14231
|
import { useState as useState35, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect43 } from "react";
|
|
14232
|
-
import * as
|
|
14232
|
+
import * as THREE33 from "three";
|
|
14233
14233
|
|
|
14234
14234
|
// src/CadViewerJscad.tsx
|
|
14235
|
-
import { su as
|
|
14235
|
+
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
14236
14236
|
import { forwardRef as forwardRef3, useMemo as useMemo20 } from "react";
|
|
14237
14237
|
|
|
14238
14238
|
// src/AnyCadComponent.tsx
|
|
@@ -28509,7 +28509,7 @@ import * as THREE15 from "three";
|
|
|
28509
28509
|
// package.json
|
|
28510
28510
|
var package_default = {
|
|
28511
28511
|
name: "@tscircuit/3d-viewer",
|
|
28512
|
-
version: "0.0.
|
|
28512
|
+
version: "0.0.470",
|
|
28513
28513
|
main: "./dist/index.js",
|
|
28514
28514
|
module: "./dist/index.js",
|
|
28515
28515
|
type: "module",
|
|
@@ -29782,6 +29782,10 @@ var createSimplifiedBoardGeom = (circuitJson) => {
|
|
|
29782
29782
|
let pcbThickness = 1.2;
|
|
29783
29783
|
if (panels.length > 0) {
|
|
29784
29784
|
boardOrPanel = panels[0];
|
|
29785
|
+
const firstBoardInPanel = boards.find(
|
|
29786
|
+
(b) => b.pcb_panel_id === boardOrPanel.pcb_panel_id
|
|
29787
|
+
);
|
|
29788
|
+
pcbThickness = firstBoardInPanel?.thickness ?? 1.2;
|
|
29785
29789
|
} else {
|
|
29786
29790
|
const boardsNotInPanel = boards.filter(
|
|
29787
29791
|
(b) => !b.pcb_panel_id
|
|
@@ -29807,7 +29811,10 @@ var createSimplifiedBoardGeom = (circuitJson) => {
|
|
|
29807
29811
|
center: [boardOrPanel.center.x, boardOrPanel.center.y, 0]
|
|
29808
29812
|
});
|
|
29809
29813
|
}
|
|
29810
|
-
const
|
|
29814
|
+
const materialName = "material" in boardOrPanel && boardOrPanel.material ? boardOrPanel.material : panels.length > 0 ? boards.find(
|
|
29815
|
+
(b) => b.pcb_panel_id === boardOrPanel.pcb_panel_id
|
|
29816
|
+
)?.material ?? "fr4" : "fr4";
|
|
29817
|
+
const material = boardMaterialColors[materialName] ?? colors.fr4Tan;
|
|
29811
29818
|
return [(0, import_colors.colorize)(material, boardGeom)];
|
|
29812
29819
|
};
|
|
29813
29820
|
var createBoardGeomFromCircuitJson = (circuitJson, opts = {}) => {
|
|
@@ -30612,16 +30619,18 @@ var BoardGeomBuilder = class {
|
|
|
30612
30619
|
const boards = su3(circuitJson).pcb_board.list();
|
|
30613
30620
|
if (panels.length > 0) {
|
|
30614
30621
|
const panel = panels[0];
|
|
30622
|
+
const firstBoardInPanel = boards.find(
|
|
30623
|
+
(b) => b.pcb_panel_id === panel.pcb_panel_id
|
|
30624
|
+
);
|
|
30615
30625
|
this.board = {
|
|
30616
30626
|
type: "pcb_board",
|
|
30617
30627
|
pcb_board_id: panel.pcb_panel_id,
|
|
30618
30628
|
center: panel.center,
|
|
30619
30629
|
width: panel.width,
|
|
30620
30630
|
height: panel.height,
|
|
30621
|
-
thickness: 1.6,
|
|
30622
|
-
|
|
30623
|
-
|
|
30624
|
-
num_layers: 2
|
|
30631
|
+
thickness: firstBoardInPanel?.thickness ?? 1.6,
|
|
30632
|
+
material: firstBoardInPanel?.material ?? "fr4",
|
|
30633
|
+
num_layers: firstBoardInPanel?.num_layers ?? 2
|
|
30625
30634
|
};
|
|
30626
30635
|
} else {
|
|
30627
30636
|
const boardsNotInPanel = boards.filter((b) => !b.pcb_panel_id);
|
|
@@ -31618,8 +31627,8 @@ var ThreeErrorBoundary = class extends React11.Component {
|
|
|
31618
31627
|
|
|
31619
31628
|
// src/three-components/JscadBoardTextures.tsx
|
|
31620
31629
|
import { useEffect as useEffect22, useMemo as useMemo19 } from "react";
|
|
31621
|
-
import * as
|
|
31622
|
-
import { su as
|
|
31630
|
+
import * as THREE23 from "three";
|
|
31631
|
+
import { su as su9 } from "@tscircuit/circuit-json-util";
|
|
31623
31632
|
|
|
31624
31633
|
// src/utils/soldermask-texture.ts
|
|
31625
31634
|
import * as THREE18 from "three";
|
|
@@ -33088,6 +33097,72 @@ function createCopperTextTextureForLayer({
|
|
|
33088
33097
|
return texture;
|
|
33089
33098
|
}
|
|
33090
33099
|
|
|
33100
|
+
// src/utils/panel-outline-texture.ts
|
|
33101
|
+
import * as THREE22 from "three";
|
|
33102
|
+
import { su as su8 } from "@tscircuit/circuit-json-util";
|
|
33103
|
+
function createPanelOutlineTextureForLayer({
|
|
33104
|
+
layer,
|
|
33105
|
+
circuitJson,
|
|
33106
|
+
panelData,
|
|
33107
|
+
outlineColor = "black",
|
|
33108
|
+
traceTextureResolution
|
|
33109
|
+
}) {
|
|
33110
|
+
const boardsInPanel = su8(circuitJson).pcb_board.list().filter((b) => b.pcb_panel_id === panelData.pcb_board_id);
|
|
33111
|
+
if (boardsInPanel.length === 0) {
|
|
33112
|
+
return null;
|
|
33113
|
+
}
|
|
33114
|
+
const canvas = document.createElement("canvas");
|
|
33115
|
+
const canvasWidth = Math.floor(panelData.width * traceTextureResolution);
|
|
33116
|
+
const canvasHeight = Math.floor(panelData.height * traceTextureResolution);
|
|
33117
|
+
canvas.width = canvasWidth;
|
|
33118
|
+
canvas.height = canvasHeight;
|
|
33119
|
+
const ctx = canvas.getContext("2d");
|
|
33120
|
+
if (!ctx) return null;
|
|
33121
|
+
if (layer === "bottom") {
|
|
33122
|
+
ctx.translate(0, canvasHeight);
|
|
33123
|
+
ctx.scale(1, -1);
|
|
33124
|
+
}
|
|
33125
|
+
ctx.strokeStyle = outlineColor;
|
|
33126
|
+
ctx.lineWidth = 0.05 * traceTextureResolution;
|
|
33127
|
+
const canvasXFromPcb = (pcbX) => (pcbX - panelData.center.x + panelData.width / 2) * traceTextureResolution;
|
|
33128
|
+
const canvasYFromPcb = (pcbY) => (-(pcbY - panelData.center.y) + panelData.height / 2) * traceTextureResolution;
|
|
33129
|
+
boardsInPanel.forEach((board) => {
|
|
33130
|
+
if (board.outline && board.outline.length >= 2) {
|
|
33131
|
+
ctx.beginPath();
|
|
33132
|
+
board.outline.forEach((point2, index2) => {
|
|
33133
|
+
const x = canvasXFromPcb(point2.x);
|
|
33134
|
+
const y = canvasYFromPcb(point2.y);
|
|
33135
|
+
if (index2 === 0) {
|
|
33136
|
+
ctx.moveTo(x, y);
|
|
33137
|
+
} else {
|
|
33138
|
+
ctx.lineTo(x, y);
|
|
33139
|
+
}
|
|
33140
|
+
});
|
|
33141
|
+
ctx.closePath();
|
|
33142
|
+
ctx.stroke();
|
|
33143
|
+
} else {
|
|
33144
|
+
const width10 = board.width;
|
|
33145
|
+
const height10 = board.height;
|
|
33146
|
+
const { x: centerX, y: centerY } = board.center;
|
|
33147
|
+
const x = canvasXFromPcb(centerX - width10 / 2);
|
|
33148
|
+
const y = canvasYFromPcb(centerY + height10 / 2);
|
|
33149
|
+
ctx.strokeRect(
|
|
33150
|
+
x,
|
|
33151
|
+
y,
|
|
33152
|
+
width10 * traceTextureResolution,
|
|
33153
|
+
height10 * traceTextureResolution
|
|
33154
|
+
);
|
|
33155
|
+
}
|
|
33156
|
+
});
|
|
33157
|
+
const texture = new THREE22.CanvasTexture(canvas);
|
|
33158
|
+
texture.generateMipmaps = true;
|
|
33159
|
+
texture.minFilter = THREE22.LinearMipmapLinearFilter;
|
|
33160
|
+
texture.magFilter = THREE22.LinearFilter;
|
|
33161
|
+
texture.anisotropy = 16;
|
|
33162
|
+
texture.needsUpdate = true;
|
|
33163
|
+
return texture;
|
|
33164
|
+
}
|
|
33165
|
+
|
|
33091
33166
|
// src/three-components/JscadBoardTextures.tsx
|
|
33092
33167
|
function JscadBoardTextures({
|
|
33093
33168
|
circuitJson,
|
|
@@ -33096,8 +33171,30 @@ function JscadBoardTextures({
|
|
|
33096
33171
|
const { rootObject } = useThree();
|
|
33097
33172
|
const { visibility } = useLayerVisibility();
|
|
33098
33173
|
const boardData = useMemo19(() => {
|
|
33099
|
-
const
|
|
33100
|
-
|
|
33174
|
+
const panels = circuitJson.filter(
|
|
33175
|
+
(e) => e.type === "pcb_panel"
|
|
33176
|
+
);
|
|
33177
|
+
const boards = su9(circuitJson).pcb_board.list();
|
|
33178
|
+
if (panels.length > 0) {
|
|
33179
|
+
const panel = panels[0];
|
|
33180
|
+
const firstBoardInPanel = boards.find(
|
|
33181
|
+
(b) => b.pcb_panel_id === panel.pcb_panel_id
|
|
33182
|
+
);
|
|
33183
|
+
return {
|
|
33184
|
+
type: "pcb_board",
|
|
33185
|
+
pcb_board_id: panel.pcb_panel_id,
|
|
33186
|
+
center: panel.center,
|
|
33187
|
+
width: panel.width,
|
|
33188
|
+
height: panel.height,
|
|
33189
|
+
thickness: firstBoardInPanel?.thickness ?? 1.6,
|
|
33190
|
+
material: firstBoardInPanel?.material ?? "fr4",
|
|
33191
|
+
num_layers: firstBoardInPanel?.num_layers ?? 2
|
|
33192
|
+
};
|
|
33193
|
+
}
|
|
33194
|
+
const boardsNotInPanel = boards.filter(
|
|
33195
|
+
(b) => !b.pcb_panel_id
|
|
33196
|
+
);
|
|
33197
|
+
return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
|
|
33101
33198
|
}, [circuitJson]);
|
|
33102
33199
|
const textures = useMemo19(() => {
|
|
33103
33200
|
if (!boardData || !boardData.width || !boardData.height) return null;
|
|
@@ -33162,28 +33259,40 @@ function JscadBoardTextures({
|
|
|
33162
33259
|
boardData,
|
|
33163
33260
|
copperColor: `rgb(${Math.round(colors.copper[0] * 255)}, ${Math.round(colors.copper[1] * 255)}, ${Math.round(colors.copper[2] * 255)})`,
|
|
33164
33261
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
33262
|
+
}),
|
|
33263
|
+
topPanelOutlines: createPanelOutlineTextureForLayer({
|
|
33264
|
+
layer: "top",
|
|
33265
|
+
circuitJson,
|
|
33266
|
+
panelData: boardData,
|
|
33267
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
33268
|
+
}),
|
|
33269
|
+
bottomPanelOutlines: createPanelOutlineTextureForLayer({
|
|
33270
|
+
layer: "bottom",
|
|
33271
|
+
circuitJson,
|
|
33272
|
+
panelData: boardData,
|
|
33273
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
33165
33274
|
})
|
|
33166
33275
|
};
|
|
33167
33276
|
}, [circuitJson, boardData]);
|
|
33168
33277
|
useEffect22(() => {
|
|
33169
33278
|
if (!rootObject || !boardData || !textures) return;
|
|
33170
33279
|
const meshes = [];
|
|
33171
|
-
const createTexturePlane = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false) => {
|
|
33280
|
+
const createTexturePlane = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false, depthWrite = false) => {
|
|
33172
33281
|
if (!texture) return null;
|
|
33173
|
-
const planeGeom = new
|
|
33282
|
+
const planeGeom = new THREE23.PlaneGeometry(
|
|
33174
33283
|
boardData.width,
|
|
33175
33284
|
boardData.height
|
|
33176
33285
|
);
|
|
33177
|
-
const material = new
|
|
33286
|
+
const material = new THREE23.MeshBasicMaterial({
|
|
33178
33287
|
map: texture,
|
|
33179
33288
|
transparent: true,
|
|
33180
|
-
side:
|
|
33181
|
-
depthWrite
|
|
33289
|
+
side: THREE23.DoubleSide,
|
|
33290
|
+
depthWrite,
|
|
33182
33291
|
polygonOffset: usePolygonOffset,
|
|
33183
33292
|
polygonOffsetFactor: usePolygonOffset ? -1 : 0,
|
|
33184
33293
|
polygonOffsetUnits: usePolygonOffset ? -1 : 0
|
|
33185
33294
|
});
|
|
33186
|
-
const mesh = new
|
|
33295
|
+
const mesh = new THREE23.Mesh(planeGeom, material);
|
|
33187
33296
|
mesh.position.set(boardData.center.x, boardData.center.y, zOffset);
|
|
33188
33297
|
if (isBottomLayer) {
|
|
33189
33298
|
mesh.rotation.set(Math.PI, 0, 0);
|
|
@@ -33290,13 +33399,41 @@ function JscadBoardTextures({
|
|
|
33290
33399
|
rootObject.add(bottomCopperTextMesh);
|
|
33291
33400
|
}
|
|
33292
33401
|
}
|
|
33402
|
+
if (visibility.boardBody) {
|
|
33403
|
+
const topPanelOutlinesMesh = createTexturePlane(
|
|
33404
|
+
textures.topPanelOutlines,
|
|
33405
|
+
pcbThickness / 2 + SURFACE_OFFSET + 3e-3,
|
|
33406
|
+
// Above silkscreen
|
|
33407
|
+
false,
|
|
33408
|
+
"jscad-top-panel-outlines",
|
|
33409
|
+
false,
|
|
33410
|
+
true
|
|
33411
|
+
);
|
|
33412
|
+
if (topPanelOutlinesMesh) {
|
|
33413
|
+
meshes.push(topPanelOutlinesMesh);
|
|
33414
|
+
rootObject.add(topPanelOutlinesMesh);
|
|
33415
|
+
}
|
|
33416
|
+
const bottomPanelOutlinesMesh = createTexturePlane(
|
|
33417
|
+
textures.bottomPanelOutlines,
|
|
33418
|
+
-pcbThickness / 2 - SURFACE_OFFSET - 3e-3,
|
|
33419
|
+
// Below bottom silkscreen
|
|
33420
|
+
true,
|
|
33421
|
+
"jscad-bottom-panel-outlines",
|
|
33422
|
+
false,
|
|
33423
|
+
true
|
|
33424
|
+
);
|
|
33425
|
+
if (bottomPanelOutlinesMesh) {
|
|
33426
|
+
meshes.push(bottomPanelOutlinesMesh);
|
|
33427
|
+
rootObject.add(bottomPanelOutlinesMesh);
|
|
33428
|
+
}
|
|
33429
|
+
}
|
|
33293
33430
|
return () => {
|
|
33294
33431
|
meshes.forEach((mesh) => {
|
|
33295
33432
|
if (mesh.parent === rootObject) {
|
|
33296
33433
|
rootObject.remove(mesh);
|
|
33297
33434
|
}
|
|
33298
33435
|
mesh.geometry.dispose();
|
|
33299
|
-
if (mesh.material instanceof
|
|
33436
|
+
if (mesh.material instanceof THREE23.Material) {
|
|
33300
33437
|
mesh.material.dispose();
|
|
33301
33438
|
}
|
|
33302
33439
|
});
|
|
@@ -33306,16 +33443,16 @@ function JscadBoardTextures({
|
|
|
33306
33443
|
}
|
|
33307
33444
|
|
|
33308
33445
|
// src/utils/preprocess-circuit-json.ts
|
|
33309
|
-
import { su as
|
|
33446
|
+
import { su as su11 } from "@tscircuit/circuit-json-util";
|
|
33310
33447
|
|
|
33311
33448
|
// src/utils/create-faux-board.ts
|
|
33312
|
-
import { su as
|
|
33449
|
+
import { su as su10, getBoundsOfPcbElements } from "@tscircuit/circuit-json-util";
|
|
33313
33450
|
function createFauxBoard(circuitJson) {
|
|
33314
|
-
const cadComponents =
|
|
33315
|
-
const pads =
|
|
33316
|
-
const holes =
|
|
33317
|
-
const platedHoles =
|
|
33318
|
-
const vias =
|
|
33451
|
+
const cadComponents = su10(circuitJson).cad_component.list();
|
|
33452
|
+
const pads = su10(circuitJson).pcb_smtpad.list();
|
|
33453
|
+
const holes = su10(circuitJson).pcb_hole.list();
|
|
33454
|
+
const platedHoles = su10(circuitJson).pcb_plated_hole.list();
|
|
33455
|
+
const vias = su10(circuitJson).pcb_via.list();
|
|
33319
33456
|
if (cadComponents.length === 0 && pads.length === 0 && holes.length === 0 && platedHoles.length === 0 && vias.length === 0) {
|
|
33320
33457
|
return null;
|
|
33321
33458
|
}
|
|
@@ -33364,7 +33501,7 @@ function createFauxBoard(circuitJson) {
|
|
|
33364
33501
|
|
|
33365
33502
|
// src/utils/preprocess-circuit-json.ts
|
|
33366
33503
|
function addFauxBoardIfNeeded(circuitJson) {
|
|
33367
|
-
const boards =
|
|
33504
|
+
const boards = su11(circuitJson).pcb_board.list();
|
|
33368
33505
|
if (boards.length > 0) {
|
|
33369
33506
|
return circuitJson;
|
|
33370
33507
|
}
|
|
@@ -33414,7 +33551,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
33414
33551
|
const initialCameraPosition = useMemo20(() => {
|
|
33415
33552
|
if (!internalCircuitJson) return [5, -5, 5];
|
|
33416
33553
|
try {
|
|
33417
|
-
const board =
|
|
33554
|
+
const board = su12(internalCircuitJson).pcb_board.list()[0];
|
|
33418
33555
|
if (!board) return [5, -5, 5];
|
|
33419
33556
|
const { width: width10, height: height10 } = board;
|
|
33420
33557
|
if (!width10 && !height10) {
|
|
@@ -33440,7 +33577,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
33440
33577
|
const isFauxBoard = useMemo20(() => {
|
|
33441
33578
|
if (!internalCircuitJson) return false;
|
|
33442
33579
|
try {
|
|
33443
|
-
const board =
|
|
33580
|
+
const board = su12(internalCircuitJson).pcb_board.list()[0];
|
|
33444
33581
|
return !!board && board.pcb_board_id === "faux-board";
|
|
33445
33582
|
} catch (e) {
|
|
33446
33583
|
return false;
|
|
@@ -33449,7 +33586,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
33449
33586
|
const boardDimensions = useMemo20(() => {
|
|
33450
33587
|
if (!internalCircuitJson) return void 0;
|
|
33451
33588
|
try {
|
|
33452
|
-
const board =
|
|
33589
|
+
const board = su12(internalCircuitJson).pcb_board.list()[0];
|
|
33453
33590
|
if (!board) return void 0;
|
|
33454
33591
|
return { width: board.width ?? 0, height: board.height ?? 0 };
|
|
33455
33592
|
} catch (e) {
|
|
@@ -33460,7 +33597,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
33460
33597
|
const boardCenter = useMemo20(() => {
|
|
33461
33598
|
if (!internalCircuitJson) return void 0;
|
|
33462
33599
|
try {
|
|
33463
|
-
const board =
|
|
33600
|
+
const board = su12(internalCircuitJson).pcb_board.list()[0];
|
|
33464
33601
|
if (!board || !board.center) return void 0;
|
|
33465
33602
|
return { x: board.center.x, y: board.center.y };
|
|
33466
33603
|
} catch (e) {
|
|
@@ -33470,7 +33607,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
33470
33607
|
}, [internalCircuitJson]);
|
|
33471
33608
|
const pcbThickness = usePcbThickness(internalCircuitJson);
|
|
33472
33609
|
const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
|
|
33473
|
-
const cad_components =
|
|
33610
|
+
const cad_components = su12(internalCircuitJson).cad_component.list();
|
|
33474
33611
|
return /* @__PURE__ */ jsxs5(
|
|
33475
33612
|
CadViewerContainer,
|
|
33476
33613
|
{
|
|
@@ -33522,13 +33659,13 @@ var CadViewerJscad = forwardRef3(
|
|
|
33522
33659
|
);
|
|
33523
33660
|
|
|
33524
33661
|
// src/CadViewerManifold.tsx
|
|
33525
|
-
import { su as
|
|
33662
|
+
import { su as su19 } from "@tscircuit/circuit-json-util";
|
|
33526
33663
|
import { useEffect as useEffect24, useMemo as useMemo22, useState as useState15 } from "react";
|
|
33527
33664
|
|
|
33528
33665
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
33529
33666
|
import { useState as useState14, useEffect as useEffect23, useMemo as useMemo21, useRef as useRef9 } from "react";
|
|
33530
|
-
import { su as
|
|
33531
|
-
import * as
|
|
33667
|
+
import { su as su18 } from "@tscircuit/circuit-json-util";
|
|
33668
|
+
import * as THREE29 from "three";
|
|
33532
33669
|
|
|
33533
33670
|
// src/utils/manifold/create-manifold-board.ts
|
|
33534
33671
|
var arePointsClockwise3 = (points) => {
|
|
@@ -33589,17 +33726,17 @@ function createManifoldBoard(Manifold, CrossSection, boardData, pcbThickness, ma
|
|
|
33589
33726
|
}
|
|
33590
33727
|
|
|
33591
33728
|
// src/utils/manifold/process-copper-pours.ts
|
|
33592
|
-
import * as
|
|
33729
|
+
import * as THREE25 from "three";
|
|
33593
33730
|
|
|
33594
33731
|
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
33595
|
-
import * as
|
|
33732
|
+
import * as THREE24 from "three";
|
|
33596
33733
|
function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
33597
|
-
const geometry = new
|
|
33734
|
+
const geometry = new THREE24.BufferGeometry();
|
|
33598
33735
|
geometry.setAttribute(
|
|
33599
33736
|
"position",
|
|
33600
|
-
new
|
|
33737
|
+
new THREE24.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
|
|
33601
33738
|
);
|
|
33602
|
-
geometry.setIndex(new
|
|
33739
|
+
geometry.setIndex(new THREE24.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
|
|
33603
33740
|
if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
|
|
33604
33741
|
for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
|
|
33605
33742
|
const start = manifoldMesh.runIndex[i];
|
|
@@ -33772,7 +33909,7 @@ function processCopperPoursForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
33772
33909
|
}
|
|
33773
33910
|
const covered = pour.covered_with_solder_mask !== false;
|
|
33774
33911
|
const pourColorArr = covered ? tracesMaterialColors[boardMaterial] ?? colors.fr4TracesWithoutMaskTan : colors.copper;
|
|
33775
|
-
const pourColor = new
|
|
33912
|
+
const pourColor = new THREE25.Color(...pourColorArr);
|
|
33776
33913
|
const threeGeom = manifoldMeshToThreeGeometry(pourOp.getMesh());
|
|
33777
33914
|
copperPourGeoms.push({
|
|
33778
33915
|
key: `coppour-${pour.pcb_copper_pour_id}`,
|
|
@@ -33785,7 +33922,7 @@ function processCopperPoursForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
33785
33922
|
}
|
|
33786
33923
|
|
|
33787
33924
|
// src/utils/manifold/process-cutouts.ts
|
|
33788
|
-
import { su as
|
|
33925
|
+
import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
33789
33926
|
|
|
33790
33927
|
// src/utils/pad-geoms.ts
|
|
33791
33928
|
var RECT_PAD_SEGMENTS2 = 64;
|
|
@@ -33877,7 +34014,7 @@ var arePointsClockwise5 = (points) => {
|
|
|
33877
34014
|
};
|
|
33878
34015
|
function processCutoutsForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
33879
34016
|
const cutoutOps = [];
|
|
33880
|
-
const pcbCutouts =
|
|
34017
|
+
const pcbCutouts = su13(circuitJson).pcb_cutout.list();
|
|
33881
34018
|
for (const cutout of pcbCutouts) {
|
|
33882
34019
|
let cutoutOp;
|
|
33883
34020
|
const cutoutHeight = pcbThickness * 1.5;
|
|
@@ -33972,7 +34109,7 @@ function processCutoutsForManifold(Manifold, CrossSection, circuitJson, pcbThick
|
|
|
33972
34109
|
}
|
|
33973
34110
|
|
|
33974
34111
|
// src/utils/manifold/process-non-plated-holes.ts
|
|
33975
|
-
import { su as
|
|
34112
|
+
import { su as su14 } from "@tscircuit/circuit-json-util";
|
|
33976
34113
|
|
|
33977
34114
|
// src/utils/hole-geoms.ts
|
|
33978
34115
|
function createCircleHoleDrill({
|
|
@@ -34024,7 +34161,7 @@ function isRotatedPillHole(hole) {
|
|
|
34024
34161
|
}
|
|
34025
34162
|
function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
34026
34163
|
const nonPlatedHoleBoardDrills = [];
|
|
34027
|
-
const pcbHoles =
|
|
34164
|
+
const pcbHoles = su14(circuitJson).pcb_hole.list();
|
|
34028
34165
|
const createPillOp = (width10, height10, depth) => {
|
|
34029
34166
|
const pillOp = createRoundedRectPrism({
|
|
34030
34167
|
Manifold,
|
|
@@ -34073,8 +34210,8 @@ function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, m
|
|
|
34073
34210
|
}
|
|
34074
34211
|
|
|
34075
34212
|
// src/utils/manifold/process-plated-holes.ts
|
|
34076
|
-
import { su as
|
|
34077
|
-
import * as
|
|
34213
|
+
import { su as su15 } from "@tscircuit/circuit-json-util";
|
|
34214
|
+
import * as THREE26 from "three";
|
|
34078
34215
|
var arePointsClockwise6 = (points) => {
|
|
34079
34216
|
let area = 0;
|
|
34080
34217
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -34095,11 +34232,11 @@ var createEllipsePoints = (width10, height10, segments) => {
|
|
|
34095
34232
|
}
|
|
34096
34233
|
return points;
|
|
34097
34234
|
};
|
|
34098
|
-
var COPPER_COLOR = new
|
|
34235
|
+
var COPPER_COLOR = new THREE26.Color(...colors.copper);
|
|
34099
34236
|
var PLATED_HOLE_LIP_HEIGHT = 0.05;
|
|
34100
34237
|
function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
34101
34238
|
const platedHoleBoardDrills = [];
|
|
34102
|
-
const pcbPlatedHoles =
|
|
34239
|
+
const pcbPlatedHoles = su15(circuitJson).pcb_plated_hole.list();
|
|
34103
34240
|
const platedHoleCopperGeoms = [];
|
|
34104
34241
|
const platedHoleCopperOpsForSubtract = [];
|
|
34105
34242
|
const createPillOp = (width10, height10, depth) => {
|
|
@@ -34668,12 +34805,12 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
34668
34805
|
}
|
|
34669
34806
|
|
|
34670
34807
|
// src/utils/manifold/process-smt-pads.ts
|
|
34671
|
-
import { su as
|
|
34672
|
-
import * as
|
|
34673
|
-
var COPPER_COLOR2 = new
|
|
34808
|
+
import { su as su16 } from "@tscircuit/circuit-json-util";
|
|
34809
|
+
import * as THREE27 from "three";
|
|
34810
|
+
var COPPER_COLOR2 = new THREE27.Color(...colors.copper);
|
|
34674
34811
|
function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, holeUnion, boardClipVolume) {
|
|
34675
34812
|
const smtPadGeoms = [];
|
|
34676
|
-
const smtPads =
|
|
34813
|
+
const smtPads = su16(circuitJson).pcb_smtpad.list();
|
|
34677
34814
|
smtPads.forEach((pad2, index2) => {
|
|
34678
34815
|
const padBaseThickness = DEFAULT_SMT_PAD_THICKNESS;
|
|
34679
34816
|
const zPos = pad2.layer === "bottom" ? -pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper : pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper;
|
|
@@ -34708,8 +34845,8 @@ function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifold
|
|
|
34708
34845
|
}
|
|
34709
34846
|
|
|
34710
34847
|
// src/utils/manifold/process-vias.ts
|
|
34711
|
-
import { su as
|
|
34712
|
-
import * as
|
|
34848
|
+
import { su as su17 } from "@tscircuit/circuit-json-util";
|
|
34849
|
+
import * as THREE28 from "three";
|
|
34713
34850
|
|
|
34714
34851
|
// src/utils/via-geoms.ts
|
|
34715
34852
|
function createViaCopper2({
|
|
@@ -34762,10 +34899,10 @@ function createViaCopper2({
|
|
|
34762
34899
|
}
|
|
34763
34900
|
|
|
34764
34901
|
// src/utils/manifold/process-vias.ts
|
|
34765
|
-
var COPPER_COLOR3 = new
|
|
34902
|
+
var COPPER_COLOR3 = new THREE28.Color(...colors.copper);
|
|
34766
34903
|
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
34767
34904
|
const viaBoardDrills = [];
|
|
34768
|
-
const pcbVias =
|
|
34905
|
+
const pcbVias = su17(circuitJson).pcb_via.list();
|
|
34769
34906
|
const viaCopperGeoms = [];
|
|
34770
34907
|
pcbVias.forEach((via, index2) => {
|
|
34771
34908
|
if (typeof via.hole_diameter === "number") {
|
|
@@ -34825,26 +34962,28 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
34825
34962
|
const panels = circuitJson.filter(
|
|
34826
34963
|
(e) => e.type === "pcb_panel"
|
|
34827
34964
|
);
|
|
34828
|
-
const boards =
|
|
34965
|
+
const boards = su18(circuitJson).pcb_board.list();
|
|
34829
34966
|
if (panels.length > 0) {
|
|
34830
34967
|
const panel = panels[0];
|
|
34968
|
+
const firstBoardInPanel = boards.find(
|
|
34969
|
+
(b) => b.pcb_panel_id === panel.pcb_panel_id
|
|
34970
|
+
);
|
|
34831
34971
|
return {
|
|
34832
34972
|
type: "pcb_board",
|
|
34833
34973
|
pcb_board_id: panel.pcb_panel_id,
|
|
34834
34974
|
center: panel.center,
|
|
34835
34975
|
width: panel.width,
|
|
34836
34976
|
height: panel.height,
|
|
34837
|
-
thickness: 1.6,
|
|
34838
|
-
|
|
34839
|
-
|
|
34840
|
-
num_layers: 2
|
|
34977
|
+
thickness: firstBoardInPanel?.thickness ?? 1.6,
|
|
34978
|
+
material: firstBoardInPanel?.material ?? "fr4",
|
|
34979
|
+
num_layers: firstBoardInPanel?.num_layers ?? 2
|
|
34841
34980
|
};
|
|
34842
34981
|
}
|
|
34843
34982
|
const boardsNotInPanel = boards.filter((b) => !b.pcb_panel_id);
|
|
34844
34983
|
return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
|
|
34845
34984
|
}, [circuitJson]);
|
|
34846
34985
|
const isFauxBoard = useMemo21(() => {
|
|
34847
|
-
const boards =
|
|
34986
|
+
const boards = su18(circuitJson).pcb_board.list();
|
|
34848
34987
|
return boards.length > 0 && boards[0].pcb_board_id === "faux-board";
|
|
34849
34988
|
}, [circuitJson]);
|
|
34850
34989
|
useEffect23(() => {
|
|
@@ -34979,7 +35118,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
34979
35118
|
{
|
|
34980
35119
|
key: "plated-holes-union",
|
|
34981
35120
|
geometry: cutPlatedGeom,
|
|
34982
|
-
color: new
|
|
35121
|
+
color: new THREE29.Color(
|
|
34983
35122
|
colors.copper[0],
|
|
34984
35123
|
colors.copper[1],
|
|
34985
35124
|
colors.copper[2]
|
|
@@ -35009,7 +35148,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
35009
35148
|
const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Tan;
|
|
35010
35149
|
currentGeoms.board = {
|
|
35011
35150
|
geometry: finalBoardGeom,
|
|
35012
|
-
color: new
|
|
35151
|
+
color: new THREE29.Color(
|
|
35013
35152
|
matColorArray[0],
|
|
35014
35153
|
matColorArray[1],
|
|
35015
35154
|
matColorArray[2]
|
|
@@ -35118,6 +35257,18 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
35118
35257
|
copperColor,
|
|
35119
35258
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
35120
35259
|
});
|
|
35260
|
+
currentTextures.topPanelOutlines = createPanelOutlineTextureForLayer({
|
|
35261
|
+
layer: "top",
|
|
35262
|
+
circuitJson,
|
|
35263
|
+
panelData: boardData,
|
|
35264
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
35265
|
+
});
|
|
35266
|
+
currentTextures.bottomPanelOutlines = createPanelOutlineTextureForLayer({
|
|
35267
|
+
layer: "bottom",
|
|
35268
|
+
circuitJson,
|
|
35269
|
+
panelData: boardData,
|
|
35270
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
35271
|
+
});
|
|
35121
35272
|
setTextures(currentTextures);
|
|
35122
35273
|
} catch (e) {
|
|
35123
35274
|
console.error("Error processing geometry with Manifold in hook:", e);
|
|
@@ -35146,11 +35297,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
35146
35297
|
};
|
|
35147
35298
|
|
|
35148
35299
|
// src/utils/manifold/create-three-geometry-meshes.ts
|
|
35149
|
-
import * as
|
|
35300
|
+
import * as THREE31 from "three";
|
|
35150
35301
|
|
|
35151
35302
|
// src/utils/create-board-material.ts
|
|
35152
|
-
import * as
|
|
35153
|
-
var DEFAULT_SIDE =
|
|
35303
|
+
import * as THREE30 from "three";
|
|
35304
|
+
var DEFAULT_SIDE = THREE30.DoubleSide;
|
|
35154
35305
|
var createBoardMaterial = ({
|
|
35155
35306
|
material,
|
|
35156
35307
|
color,
|
|
@@ -35158,7 +35309,7 @@ var createBoardMaterial = ({
|
|
|
35158
35309
|
isFaux = false
|
|
35159
35310
|
}) => {
|
|
35160
35311
|
if (material === "fr4") {
|
|
35161
|
-
return new
|
|
35312
|
+
return new THREE30.MeshPhysicalMaterial({
|
|
35162
35313
|
color,
|
|
35163
35314
|
side,
|
|
35164
35315
|
metalness: 0,
|
|
@@ -35172,7 +35323,7 @@ var createBoardMaterial = ({
|
|
|
35172
35323
|
flatShading: true
|
|
35173
35324
|
});
|
|
35174
35325
|
}
|
|
35175
|
-
return new
|
|
35326
|
+
return new THREE30.MeshStandardMaterial({
|
|
35176
35327
|
color,
|
|
35177
35328
|
side,
|
|
35178
35329
|
flatShading: true,
|
|
@@ -35188,12 +35339,12 @@ function createGeometryMeshes(geoms) {
|
|
|
35188
35339
|
const meshes = [];
|
|
35189
35340
|
if (!geoms) return meshes;
|
|
35190
35341
|
if (geoms.board && geoms.board.geometry) {
|
|
35191
|
-
const mesh = new
|
|
35342
|
+
const mesh = new THREE31.Mesh(
|
|
35192
35343
|
geoms.board.geometry,
|
|
35193
35344
|
createBoardMaterial({
|
|
35194
35345
|
material: geoms.board.material,
|
|
35195
35346
|
color: geoms.board.color,
|
|
35196
|
-
side:
|
|
35347
|
+
side: THREE31.DoubleSide,
|
|
35197
35348
|
isFaux: geoms.board.isFaux
|
|
35198
35349
|
})
|
|
35199
35350
|
);
|
|
@@ -35203,11 +35354,11 @@ function createGeometryMeshes(geoms) {
|
|
|
35203
35354
|
const createMeshesFromArray = (geomArray) => {
|
|
35204
35355
|
if (geomArray) {
|
|
35205
35356
|
geomArray.forEach((comp) => {
|
|
35206
|
-
const mesh = new
|
|
35357
|
+
const mesh = new THREE31.Mesh(
|
|
35207
35358
|
comp.geometry,
|
|
35208
|
-
new
|
|
35359
|
+
new THREE31.MeshStandardMaterial({
|
|
35209
35360
|
color: comp.color,
|
|
35210
|
-
side:
|
|
35361
|
+
side: THREE31.DoubleSide,
|
|
35211
35362
|
flatShading: true,
|
|
35212
35363
|
// Consistent with board
|
|
35213
35364
|
polygonOffset: true,
|
|
@@ -35228,25 +35379,24 @@ function createGeometryMeshes(geoms) {
|
|
|
35228
35379
|
}
|
|
35229
35380
|
|
|
35230
35381
|
// src/utils/manifold/create-three-texture-meshes.ts
|
|
35231
|
-
import * as
|
|
35382
|
+
import * as THREE32 from "three";
|
|
35232
35383
|
function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
35233
35384
|
const meshes = [];
|
|
35234
35385
|
if (!textures || !boardData || pcbThickness === null) return meshes;
|
|
35235
35386
|
const createTexturePlane = (texture, yOffset, isBottomLayer, keySuffix, usePolygonOffset = false, renderOrder = 0) => {
|
|
35236
35387
|
if (!texture) return null;
|
|
35237
|
-
const planeGeom = new
|
|
35238
|
-
const material = new
|
|
35388
|
+
const planeGeom = new THREE32.PlaneGeometry(boardData.width, boardData.height);
|
|
35389
|
+
const material = new THREE32.MeshBasicMaterial({
|
|
35239
35390
|
map: texture,
|
|
35240
35391
|
transparent: true,
|
|
35241
|
-
side:
|
|
35242
|
-
depthWrite:
|
|
35243
|
-
// Important for layers to avoid z-fighting issues with board itself
|
|
35392
|
+
side: THREE32.DoubleSide,
|
|
35393
|
+
depthWrite: keySuffix === "panel-outlines",
|
|
35244
35394
|
polygonOffset: usePolygonOffset,
|
|
35245
35395
|
polygonOffsetFactor: usePolygonOffset ? -4 : 0,
|
|
35246
35396
|
// Increased for better z-fighting prevention
|
|
35247
35397
|
polygonOffsetUnits: usePolygonOffset ? -4 : 0
|
|
35248
35398
|
});
|
|
35249
|
-
const mesh = new
|
|
35399
|
+
const mesh = new THREE32.Mesh(planeGeom, material);
|
|
35250
35400
|
mesh.position.set(boardData.center.x, boardData.center.y, yOffset);
|
|
35251
35401
|
if (isBottomLayer) {
|
|
35252
35402
|
mesh.rotation.set(Math.PI, 0, 0);
|
|
@@ -35362,6 +35512,26 @@ function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
|
35362
35512
|
// Render after soldermask
|
|
35363
35513
|
);
|
|
35364
35514
|
if (bottomCopperTextMesh) meshes.push(bottomCopperTextMesh);
|
|
35515
|
+
const topPanelOutlinesMesh = createTexturePlane(
|
|
35516
|
+
textures.topPanelOutlines,
|
|
35517
|
+
pcbThickness / 2 + 4e-3,
|
|
35518
|
+
// Above silkscreen
|
|
35519
|
+
false,
|
|
35520
|
+
"panel-outlines",
|
|
35521
|
+
false,
|
|
35522
|
+
4
|
|
35523
|
+
);
|
|
35524
|
+
if (topPanelOutlinesMesh) meshes.push(topPanelOutlinesMesh);
|
|
35525
|
+
const bottomPanelOutlinesMesh = createTexturePlane(
|
|
35526
|
+
textures.bottomPanelOutlines,
|
|
35527
|
+
-pcbThickness / 2 - 4e-3,
|
|
35528
|
+
// Below bottom silkscreen
|
|
35529
|
+
true,
|
|
35530
|
+
"panel-outlines",
|
|
35531
|
+
false,
|
|
35532
|
+
4
|
|
35533
|
+
);
|
|
35534
|
+
if (bottomPanelOutlinesMesh) meshes.push(bottomPanelOutlinesMesh);
|
|
35365
35535
|
return meshes;
|
|
35366
35536
|
}
|
|
35367
35537
|
|
|
@@ -35418,6 +35588,8 @@ var BoardMeshes = ({
|
|
|
35418
35588
|
shouldShow = visibility.topCopper;
|
|
35419
35589
|
} else if (mesh.name.includes("bottom-copper-text")) {
|
|
35420
35590
|
shouldShow = visibility.bottomCopper;
|
|
35591
|
+
} else if (mesh.name.includes("panel-outlines")) {
|
|
35592
|
+
shouldShow = visibility.boardBody;
|
|
35421
35593
|
}
|
|
35422
35594
|
if (shouldShow) {
|
|
35423
35595
|
rootObject.add(mesh);
|
|
@@ -35530,7 +35702,7 @@ try {
|
|
|
35530
35702
|
[textures, boardData, pcbThickness]
|
|
35531
35703
|
);
|
|
35532
35704
|
const cadComponents = useMemo22(
|
|
35533
|
-
() =>
|
|
35705
|
+
() => su19(circuitJson).cad_component.list(),
|
|
35534
35706
|
[circuitJson]
|
|
35535
35707
|
);
|
|
35536
35708
|
const boardDimensions = useMemo22(() => {
|
|
@@ -42272,7 +42444,7 @@ var KeyboardShortcutsDialog = ({
|
|
|
42272
42444
|
|
|
42273
42445
|
// src/CadViewer.tsx
|
|
42274
42446
|
import { jsx as jsx37, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
42275
|
-
var DEFAULT_TARGET = new
|
|
42447
|
+
var DEFAULT_TARGET = new THREE33.Vector3(0, 0, 0);
|
|
42276
42448
|
var INITIAL_CAMERA_POSITION = [5, -5, 5];
|
|
42277
42449
|
var CadViewerInner = (props) => {
|
|
42278
42450
|
const [engine, setEngine] = useState35("manifold");
|
|
@@ -42538,12 +42710,12 @@ var CadViewer = (props) => {
|
|
|
42538
42710
|
|
|
42539
42711
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
42540
42712
|
var import_debug = __toESM(require_browser(), 1);
|
|
42541
|
-
import { su as
|
|
42542
|
-
import * as
|
|
42713
|
+
import { su as su20 } from "@tscircuit/circuit-json-util";
|
|
42714
|
+
import * as THREE37 from "three";
|
|
42543
42715
|
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
|
|
42544
42716
|
|
|
42545
42717
|
// src/utils/create-geometry-from-polygons.ts
|
|
42546
|
-
import * as
|
|
42718
|
+
import * as THREE34 from "three";
|
|
42547
42719
|
import { BufferGeometry as BufferGeometry3, Float32BufferAttribute as Float32BufferAttribute2 } from "three";
|
|
42548
42720
|
function createGeometryFromPolygons(polygons) {
|
|
42549
42721
|
const geometry = new BufferGeometry3();
|
|
@@ -42557,12 +42729,12 @@ function createGeometryFromPolygons(polygons) {
|
|
|
42557
42729
|
...polygon3.vertices[i + 1]
|
|
42558
42730
|
// Third vertex
|
|
42559
42731
|
);
|
|
42560
|
-
const v1 = new
|
|
42561
|
-
const v2 = new
|
|
42562
|
-
const v3 = new
|
|
42563
|
-
const normal = new
|
|
42564
|
-
new
|
|
42565
|
-
new
|
|
42732
|
+
const v1 = new THREE34.Vector3(...polygon3.vertices[0]);
|
|
42733
|
+
const v2 = new THREE34.Vector3(...polygon3.vertices[i]);
|
|
42734
|
+
const v3 = new THREE34.Vector3(...polygon3.vertices[i + 1]);
|
|
42735
|
+
const normal = new THREE34.Vector3().crossVectors(
|
|
42736
|
+
new THREE34.Vector3().subVectors(v2, v1),
|
|
42737
|
+
new THREE34.Vector3().subVectors(v3, v1)
|
|
42566
42738
|
).normalize();
|
|
42567
42739
|
normals.push(
|
|
42568
42740
|
normal.x,
|
|
@@ -42586,10 +42758,10 @@ function createGeometryFromPolygons(polygons) {
|
|
|
42586
42758
|
var import_modeling2 = __toESM(require_src(), 1);
|
|
42587
42759
|
var import_jscad_planner2 = __toESM(require_dist(), 1);
|
|
42588
42760
|
var jscadModeling2 = __toESM(require_src(), 1);
|
|
42589
|
-
import * as
|
|
42761
|
+
import * as THREE36 from "three";
|
|
42590
42762
|
|
|
42591
42763
|
// src/utils/load-model.ts
|
|
42592
|
-
import * as
|
|
42764
|
+
import * as THREE35 from "three";
|
|
42593
42765
|
import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
42594
42766
|
import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
42595
42767
|
import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
|
|
@@ -42597,12 +42769,12 @@ async function load3DModel(url) {
|
|
|
42597
42769
|
if (url.endsWith(".stl")) {
|
|
42598
42770
|
const loader = new STLLoader2();
|
|
42599
42771
|
const geometry = await loader.loadAsync(url);
|
|
42600
|
-
const material = new
|
|
42772
|
+
const material = new THREE35.MeshStandardMaterial({
|
|
42601
42773
|
color: 8947848,
|
|
42602
42774
|
metalness: 0.5,
|
|
42603
42775
|
roughness: 0.5
|
|
42604
42776
|
});
|
|
42605
|
-
return new
|
|
42777
|
+
return new THREE35.Mesh(geometry, material);
|
|
42606
42778
|
}
|
|
42607
42779
|
if (url.endsWith(".obj")) {
|
|
42608
42780
|
const loader = new OBJLoader2();
|
|
@@ -42635,9 +42807,9 @@ async function renderComponent(component, scene) {
|
|
|
42635
42807
|
}
|
|
42636
42808
|
if (component.rotation) {
|
|
42637
42809
|
model.rotation.set(
|
|
42638
|
-
|
|
42639
|
-
|
|
42640
|
-
|
|
42810
|
+
THREE36.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42811
|
+
THREE36.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42812
|
+
THREE36.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42641
42813
|
);
|
|
42642
42814
|
}
|
|
42643
42815
|
scene.add(model);
|
|
@@ -42651,13 +42823,13 @@ async function renderComponent(component, scene) {
|
|
|
42651
42823
|
);
|
|
42652
42824
|
if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
|
|
42653
42825
|
const threeGeom = convertCSGToThreeGeom(jscadObject);
|
|
42654
|
-
const material2 = new
|
|
42826
|
+
const material2 = new THREE36.MeshStandardMaterial({
|
|
42655
42827
|
color: 8947848,
|
|
42656
42828
|
metalness: 0.5,
|
|
42657
42829
|
roughness: 0.5,
|
|
42658
|
-
side:
|
|
42830
|
+
side: THREE36.DoubleSide
|
|
42659
42831
|
});
|
|
42660
|
-
const mesh2 = new
|
|
42832
|
+
const mesh2 = new THREE36.Mesh(threeGeom, material2);
|
|
42661
42833
|
if (component.position) {
|
|
42662
42834
|
mesh2.position.set(
|
|
42663
42835
|
component.position.x ?? 0,
|
|
@@ -42667,9 +42839,9 @@ async function renderComponent(component, scene) {
|
|
|
42667
42839
|
}
|
|
42668
42840
|
if (component.rotation) {
|
|
42669
42841
|
mesh2.rotation.set(
|
|
42670
|
-
|
|
42671
|
-
|
|
42672
|
-
|
|
42842
|
+
THREE36.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42843
|
+
THREE36.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42844
|
+
THREE36.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42673
42845
|
);
|
|
42674
42846
|
}
|
|
42675
42847
|
scene.add(mesh2);
|
|
@@ -42686,17 +42858,17 @@ async function renderComponent(component, scene) {
|
|
|
42686
42858
|
if (!geom || !geom.polygons && !geom.sides) {
|
|
42687
42859
|
continue;
|
|
42688
42860
|
}
|
|
42689
|
-
const color = new
|
|
42861
|
+
const color = new THREE36.Color(geomInfo.color);
|
|
42690
42862
|
color.convertLinearToSRGB();
|
|
42691
42863
|
const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
|
|
42692
42864
|
const threeGeom = convertCSGToThreeGeom(geomWithColor);
|
|
42693
|
-
const material2 = new
|
|
42865
|
+
const material2 = new THREE36.MeshStandardMaterial({
|
|
42694
42866
|
vertexColors: true,
|
|
42695
42867
|
metalness: 0.2,
|
|
42696
42868
|
roughness: 0.8,
|
|
42697
|
-
side:
|
|
42869
|
+
side: THREE36.DoubleSide
|
|
42698
42870
|
});
|
|
42699
|
-
const mesh2 = new
|
|
42871
|
+
const mesh2 = new THREE36.Mesh(threeGeom, material2);
|
|
42700
42872
|
if (component.position) {
|
|
42701
42873
|
mesh2.position.set(
|
|
42702
42874
|
component.position.x ?? 0,
|
|
@@ -42706,22 +42878,22 @@ async function renderComponent(component, scene) {
|
|
|
42706
42878
|
}
|
|
42707
42879
|
if (component.rotation) {
|
|
42708
42880
|
mesh2.rotation.set(
|
|
42709
|
-
|
|
42710
|
-
|
|
42711
|
-
|
|
42881
|
+
THREE36.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
42882
|
+
THREE36.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
42883
|
+
THREE36.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
42712
42884
|
);
|
|
42713
42885
|
}
|
|
42714
42886
|
scene.add(mesh2);
|
|
42715
42887
|
}
|
|
42716
42888
|
return;
|
|
42717
42889
|
}
|
|
42718
|
-
const geometry = new
|
|
42719
|
-
const material = new
|
|
42890
|
+
const geometry = new THREE36.BoxGeometry(0.5, 0.5, 0.5);
|
|
42891
|
+
const material = new THREE36.MeshStandardMaterial({
|
|
42720
42892
|
color: 16711680,
|
|
42721
42893
|
transparent: true,
|
|
42722
42894
|
opacity: 0.25
|
|
42723
42895
|
});
|
|
42724
|
-
const mesh = new
|
|
42896
|
+
const mesh = new THREE36.Mesh(geometry, material);
|
|
42725
42897
|
if (component.position) {
|
|
42726
42898
|
mesh.position.set(
|
|
42727
42899
|
component.position.x ?? 0,
|
|
@@ -42742,11 +42914,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42742
42914
|
padding = 20,
|
|
42743
42915
|
zoom = 1.5
|
|
42744
42916
|
} = options;
|
|
42745
|
-
const scene = new
|
|
42917
|
+
const scene = new THREE37.Scene();
|
|
42746
42918
|
const renderer = new SVGRenderer();
|
|
42747
42919
|
renderer.setSize(width10, height10);
|
|
42748
|
-
renderer.setClearColor(new
|
|
42749
|
-
const camera = new
|
|
42920
|
+
renderer.setClearColor(new THREE37.Color(backgroundColor), 1);
|
|
42921
|
+
const camera = new THREE37.OrthographicCamera();
|
|
42750
42922
|
const aspect = width10 / height10;
|
|
42751
42923
|
const frustumSize = 100;
|
|
42752
42924
|
const halfFrustumSize = frustumSize / 2 / zoom;
|
|
@@ -42760,22 +42932,22 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42760
42932
|
camera.position.set(position.x, position.y, position.z);
|
|
42761
42933
|
camera.up.set(0, 1, 0);
|
|
42762
42934
|
const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
|
|
42763
|
-
camera.lookAt(new
|
|
42935
|
+
camera.lookAt(new THREE37.Vector3(lookAt.x, lookAt.y, lookAt.z));
|
|
42764
42936
|
camera.updateProjectionMatrix();
|
|
42765
|
-
const ambientLight = new
|
|
42937
|
+
const ambientLight = new THREE37.AmbientLight(16777215, Math.PI / 2);
|
|
42766
42938
|
scene.add(ambientLight);
|
|
42767
|
-
const pointLight = new
|
|
42939
|
+
const pointLight = new THREE37.PointLight(16777215, Math.PI / 4);
|
|
42768
42940
|
pointLight.position.set(-10, -10, 10);
|
|
42769
42941
|
scene.add(pointLight);
|
|
42770
|
-
const components =
|
|
42942
|
+
const components = su20(circuitJson).cad_component.list();
|
|
42771
42943
|
for (const component of components) {
|
|
42772
42944
|
await renderComponent(component, scene);
|
|
42773
42945
|
}
|
|
42774
|
-
const boardData =
|
|
42946
|
+
const boardData = su20(circuitJson).pcb_board.list()[0];
|
|
42775
42947
|
const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
|
|
42776
42948
|
if (boardGeom) {
|
|
42777
42949
|
const solderMaskColor = colors.fr4SolderMaskGreen;
|
|
42778
|
-
const baseColor = new
|
|
42950
|
+
const baseColor = new THREE37.Color(
|
|
42779
42951
|
solderMaskColor[0],
|
|
42780
42952
|
solderMaskColor[1],
|
|
42781
42953
|
solderMaskColor[2]
|
|
@@ -42787,28 +42959,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
42787
42959
|
const material = createBoardMaterial({
|
|
42788
42960
|
material: boardData?.material,
|
|
42789
42961
|
color: baseColor,
|
|
42790
|
-
side:
|
|
42962
|
+
side: THREE37.DoubleSide
|
|
42791
42963
|
});
|
|
42792
|
-
const mesh = new
|
|
42964
|
+
const mesh = new THREE37.Mesh(geometry, material);
|
|
42793
42965
|
scene.add(mesh);
|
|
42794
42966
|
}
|
|
42795
42967
|
}
|
|
42796
|
-
const gridColor = new
|
|
42797
|
-
const gridHelper = new
|
|
42968
|
+
const gridColor = new THREE37.Color(8947848);
|
|
42969
|
+
const gridHelper = new THREE37.GridHelper(100, 100, gridColor, gridColor);
|
|
42798
42970
|
gridHelper.rotation.x = Math.PI / 2;
|
|
42799
42971
|
const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
|
|
42800
42972
|
for (const mat of materials) {
|
|
42801
42973
|
mat.transparent = true;
|
|
42802
42974
|
mat.opacity = 0.3;
|
|
42803
|
-
if (mat instanceof
|
|
42975
|
+
if (mat instanceof THREE37.LineBasicMaterial) {
|
|
42804
42976
|
mat.color = gridColor;
|
|
42805
42977
|
mat.vertexColors = false;
|
|
42806
42978
|
}
|
|
42807
42979
|
}
|
|
42808
42980
|
scene.add(gridHelper);
|
|
42809
|
-
const box = new
|
|
42810
|
-
const center = box.getCenter(new
|
|
42811
|
-
const size5 = box.getSize(new
|
|
42981
|
+
const box = new THREE37.Box3().setFromObject(scene);
|
|
42982
|
+
const center = box.getCenter(new THREE37.Vector3());
|
|
42983
|
+
const size5 = box.getSize(new THREE37.Vector3());
|
|
42812
42984
|
scene.position.sub(center);
|
|
42813
42985
|
const maxDim = Math.max(size5.x, size5.y, size5.z);
|
|
42814
42986
|
if (maxDim > 0) {
|