@tscircuit/3d-viewer 0.0.432 → 0.0.434
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 +170 -49
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ interface ManifoldGeoms {
|
|
|
48
48
|
geometry: THREE.BufferGeometry;
|
|
49
49
|
color: THREE.Color;
|
|
50
50
|
material: PcbBoard["material"];
|
|
51
|
+
isFaux?: boolean;
|
|
51
52
|
};
|
|
52
53
|
platedHoles?: Array<{
|
|
53
54
|
key: string;
|
|
@@ -83,6 +84,7 @@ interface UseManifoldBoardBuilderResult {
|
|
|
83
84
|
error: string | null;
|
|
84
85
|
isLoading: boolean;
|
|
85
86
|
boardData: PcbBoard | null;
|
|
87
|
+
isFauxBoard: boolean;
|
|
86
88
|
}
|
|
87
89
|
declare const useManifoldBoardBuilder: (manifoldJSModule: ManifoldToplevel | null, circuitJson: AnyCircuitElement[]) => UseManifoldBoardBuilderResult;
|
|
88
90
|
|
package/dist/index.js
CHANGED
|
@@ -14231,7 +14231,7 @@ var require_browser = __commonJS({
|
|
|
14231
14231
|
import { useState as useState33, useCallback as useCallback20, useRef as useRef23, useEffect as useEffect39 } from "react";
|
|
14232
14232
|
|
|
14233
14233
|
// src/CadViewerJscad.tsx
|
|
14234
|
-
import { su as
|
|
14234
|
+
import { su as su6 } from "@tscircuit/circuit-json-util";
|
|
14235
14235
|
import { forwardRef as forwardRef3, useMemo as useMemo19 } from "react";
|
|
14236
14236
|
|
|
14237
14237
|
// src/AnyCadComponent.tsx
|
|
@@ -28174,7 +28174,7 @@ import * as THREE14 from "three";
|
|
|
28174
28174
|
// package.json
|
|
28175
28175
|
var package_default = {
|
|
28176
28176
|
name: "@tscircuit/3d-viewer",
|
|
28177
|
-
version: "0.0.
|
|
28177
|
+
version: "0.0.433",
|
|
28178
28178
|
main: "./dist/index.js",
|
|
28179
28179
|
module: "./dist/index.js",
|
|
28180
28180
|
type: "module",
|
|
@@ -31449,6 +31449,93 @@ var ThreeErrorBoundary = class extends React11.Component {
|
|
|
31449
31449
|
}
|
|
31450
31450
|
};
|
|
31451
31451
|
|
|
31452
|
+
// src/utils/preprocess-circuit-json.ts
|
|
31453
|
+
import { su as su5 } from "@tscircuit/circuit-json-util";
|
|
31454
|
+
|
|
31455
|
+
// src/utils/create-faux-board.ts
|
|
31456
|
+
import { su as su4, getBoundsOfPcbElements } from "@tscircuit/circuit-json-util";
|
|
31457
|
+
function createFauxBoard(circuitJson) {
|
|
31458
|
+
const cadComponents = su4(circuitJson).cad_component.list();
|
|
31459
|
+
const pads = su4(circuitJson).pcb_smtpad.list();
|
|
31460
|
+
const holes = su4(circuitJson).pcb_hole.list();
|
|
31461
|
+
const platedHoles = su4(circuitJson).pcb_plated_hole.list();
|
|
31462
|
+
const vias = su4(circuitJson).pcb_via.list();
|
|
31463
|
+
if (cadComponents.length === 0 && pads.length === 0 && holes.length === 0 && platedHoles.length === 0 && vias.length === 0) {
|
|
31464
|
+
return null;
|
|
31465
|
+
}
|
|
31466
|
+
const pcbElements = [...holes, ...platedHoles, ...vias, ...pads];
|
|
31467
|
+
const bounds = getBoundsOfPcbElements(pcbElements);
|
|
31468
|
+
let minX = bounds.minX;
|
|
31469
|
+
let maxX = bounds.maxX;
|
|
31470
|
+
let minY = bounds.minY;
|
|
31471
|
+
let maxY = bounds.maxY;
|
|
31472
|
+
for (const component of cadComponents) {
|
|
31473
|
+
if (component.position) {
|
|
31474
|
+
const x = component.position.x;
|
|
31475
|
+
const y = component.position.y;
|
|
31476
|
+
minX = Math.min(minX, x);
|
|
31477
|
+
maxX = Math.max(maxX, x);
|
|
31478
|
+
minY = Math.min(minY, y);
|
|
31479
|
+
maxY = Math.max(maxY, y);
|
|
31480
|
+
}
|
|
31481
|
+
}
|
|
31482
|
+
if (minX === Infinity) {
|
|
31483
|
+
minX = -10;
|
|
31484
|
+
maxX = 10;
|
|
31485
|
+
minY = -10;
|
|
31486
|
+
maxY = 10;
|
|
31487
|
+
}
|
|
31488
|
+
const padding = 2;
|
|
31489
|
+
const halfWidth = Math.max(Math.abs(minX), Math.abs(maxX)) + padding;
|
|
31490
|
+
const halfHeight = Math.max(Math.abs(minY), Math.abs(maxY)) + padding;
|
|
31491
|
+
const width10 = Math.max(2 * halfWidth, 10);
|
|
31492
|
+
const height10 = Math.max(2 * halfHeight, 10);
|
|
31493
|
+
const fauxBoard = {
|
|
31494
|
+
type: "pcb_board",
|
|
31495
|
+
pcb_board_id: "faux-board",
|
|
31496
|
+
center: { x: 0, y: 0 },
|
|
31497
|
+
// Always center at origin like real boards
|
|
31498
|
+
width: width10,
|
|
31499
|
+
height: height10,
|
|
31500
|
+
thickness: 1.6,
|
|
31501
|
+
// standard thickness
|
|
31502
|
+
material: "fr4",
|
|
31503
|
+
num_layers: 2
|
|
31504
|
+
// No outline - will use rectangular shape
|
|
31505
|
+
};
|
|
31506
|
+
return fauxBoard;
|
|
31507
|
+
}
|
|
31508
|
+
|
|
31509
|
+
// src/utils/preprocess-circuit-json.ts
|
|
31510
|
+
function addFauxBoardIfNeeded(circuitJson) {
|
|
31511
|
+
const boards = su5(circuitJson).pcb_board.list();
|
|
31512
|
+
if (boards.length > 0) {
|
|
31513
|
+
return circuitJson;
|
|
31514
|
+
}
|
|
31515
|
+
const fauxBoard = createFauxBoard(circuitJson);
|
|
31516
|
+
if (!fauxBoard) {
|
|
31517
|
+
return circuitJson;
|
|
31518
|
+
}
|
|
31519
|
+
const boardThickness = fauxBoard.thickness;
|
|
31520
|
+
const componentZ = boardThickness / 2;
|
|
31521
|
+
const processedCircuitJson = circuitJson.map((element) => {
|
|
31522
|
+
if (element.type === "cad_component") {
|
|
31523
|
+
const cadComponent = element;
|
|
31524
|
+
if (cadComponent.position) {
|
|
31525
|
+
return {
|
|
31526
|
+
...cadComponent,
|
|
31527
|
+
position: {
|
|
31528
|
+
...cadComponent.position,
|
|
31529
|
+
z: componentZ
|
|
31530
|
+
}
|
|
31531
|
+
};
|
|
31532
|
+
}
|
|
31533
|
+
}
|
|
31534
|
+
return element;
|
|
31535
|
+
});
|
|
31536
|
+
return [...processedCircuitJson, fauxBoard];
|
|
31537
|
+
}
|
|
31538
|
+
|
|
31452
31539
|
// src/CadViewerJscad.tsx
|
|
31453
31540
|
import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
31454
31541
|
var CadViewerJscad = forwardRef3(
|
|
@@ -31464,13 +31551,13 @@ var CadViewerJscad = forwardRef3(
|
|
|
31464
31551
|
const childrenSoup = useConvertChildrenToCircuitJson(children);
|
|
31465
31552
|
const internalCircuitJson = useMemo19(() => {
|
|
31466
31553
|
const cj = soup ?? circuitJson;
|
|
31467
|
-
return cj ?? childrenSoup;
|
|
31554
|
+
return addFauxBoardIfNeeded(cj ?? childrenSoup);
|
|
31468
31555
|
}, [soup, circuitJson, childrenSoup]);
|
|
31469
31556
|
const boardGeom = useBoardGeomBuilder(internalCircuitJson);
|
|
31470
31557
|
const initialCameraPosition = useMemo19(() => {
|
|
31471
31558
|
if (!internalCircuitJson) return [5, -5, 5];
|
|
31472
31559
|
try {
|
|
31473
|
-
const board =
|
|
31560
|
+
const board = su6(internalCircuitJson).pcb_board.list()[0];
|
|
31474
31561
|
if (!board) return [5, -5, 5];
|
|
31475
31562
|
const { width: width10, height: height10 } = board;
|
|
31476
31563
|
if (!width10 && !height10) {
|
|
@@ -31493,10 +31580,19 @@ var CadViewerJscad = forwardRef3(
|
|
|
31493
31580
|
return [5, -5, 5];
|
|
31494
31581
|
}
|
|
31495
31582
|
}, [internalCircuitJson]);
|
|
31583
|
+
const isFauxBoard = useMemo19(() => {
|
|
31584
|
+
if (!internalCircuitJson) return false;
|
|
31585
|
+
try {
|
|
31586
|
+
const board = su6(internalCircuitJson).pcb_board.list()[0];
|
|
31587
|
+
return !!board && board.pcb_board_id === "faux-board";
|
|
31588
|
+
} catch (e) {
|
|
31589
|
+
return false;
|
|
31590
|
+
}
|
|
31591
|
+
}, [internalCircuitJson]);
|
|
31496
31592
|
const boardDimensions = useMemo19(() => {
|
|
31497
31593
|
if (!internalCircuitJson) return void 0;
|
|
31498
31594
|
try {
|
|
31499
|
-
const board =
|
|
31595
|
+
const board = su6(internalCircuitJson).pcb_board.list()[0];
|
|
31500
31596
|
if (!board) return void 0;
|
|
31501
31597
|
return { width: board.width ?? 0, height: board.height ?? 0 };
|
|
31502
31598
|
} catch (e) {
|
|
@@ -31507,7 +31603,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
31507
31603
|
const boardCenter = useMemo19(() => {
|
|
31508
31604
|
if (!internalCircuitJson) return void 0;
|
|
31509
31605
|
try {
|
|
31510
|
-
const board =
|
|
31606
|
+
const board = su6(internalCircuitJson).pcb_board.list()[0];
|
|
31511
31607
|
if (!board || !board.center) return void 0;
|
|
31512
31608
|
return { x: board.center.x, y: board.center.y };
|
|
31513
31609
|
} catch (e) {
|
|
@@ -31516,7 +31612,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
31516
31612
|
}
|
|
31517
31613
|
}, [internalCircuitJson]);
|
|
31518
31614
|
const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
|
|
31519
|
-
const cad_components =
|
|
31615
|
+
const cad_components = su6(internalCircuitJson).cad_component.list();
|
|
31520
31616
|
return /* @__PURE__ */ jsxs6(
|
|
31521
31617
|
CadViewerContainer,
|
|
31522
31618
|
{
|
|
@@ -31534,7 +31630,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
31534
31630
|
{
|
|
31535
31631
|
stlData,
|
|
31536
31632
|
color,
|
|
31537
|
-
opacity: index2 === 0 ? 0.95 : 1,
|
|
31633
|
+
opacity: index2 === 0 ? isFauxBoard ? 0.8 : 0.95 : 1,
|
|
31538
31634
|
layerType
|
|
31539
31635
|
},
|
|
31540
31636
|
`board-${index2}`
|
|
@@ -31561,12 +31657,12 @@ var CadViewerJscad = forwardRef3(
|
|
|
31561
31657
|
);
|
|
31562
31658
|
|
|
31563
31659
|
// src/CadViewerManifold.tsx
|
|
31564
|
-
import { su as
|
|
31660
|
+
import { su as su15 } from "@tscircuit/circuit-json-util";
|
|
31565
31661
|
import { useEffect as useEffect22, useMemo as useMemo21, useState as useState15 } from "react";
|
|
31566
31662
|
|
|
31567
31663
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
31568
31664
|
import { useState as useState14, useEffect as useEffect21, useMemo as useMemo20, useRef as useRef8 } from "react";
|
|
31569
|
-
import { su as
|
|
31665
|
+
import { su as su14 } from "@tscircuit/circuit-json-util";
|
|
31570
31666
|
import * as THREE24 from "three";
|
|
31571
31667
|
|
|
31572
31668
|
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
@@ -31592,7 +31688,7 @@ function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
|
31592
31688
|
|
|
31593
31689
|
// src/utils/trace-texture.ts
|
|
31594
31690
|
import * as THREE18 from "three";
|
|
31595
|
-
import { su as
|
|
31691
|
+
import { su as su7 } from "@tscircuit/circuit-json-util";
|
|
31596
31692
|
function isWireRoutePoint(point2) {
|
|
31597
31693
|
return point2 && point2.route_type === "wire" && typeof point2.layer === "string" && typeof point2.width === "number";
|
|
31598
31694
|
}
|
|
@@ -31603,9 +31699,9 @@ function createTraceTextureForLayer({
|
|
|
31603
31699
|
traceColor,
|
|
31604
31700
|
traceTextureResolution
|
|
31605
31701
|
}) {
|
|
31606
|
-
const pcbTraces =
|
|
31607
|
-
const allPcbVias =
|
|
31608
|
-
const allPcbPlatedHoles =
|
|
31702
|
+
const pcbTraces = su7(circuitJson).pcb_trace.list();
|
|
31703
|
+
const allPcbVias = su7(circuitJson).pcb_via.list();
|
|
31704
|
+
const allPcbPlatedHoles = su7(
|
|
31609
31705
|
circuitJson
|
|
31610
31706
|
).pcb_plated_hole.list();
|
|
31611
31707
|
const tracesOnLayer = pcbTraces.filter(
|
|
@@ -31686,7 +31782,7 @@ function createTraceTextureForLayer({
|
|
|
31686
31782
|
// src/utils/silkscreen-texture.ts
|
|
31687
31783
|
var import_text2 = __toESM(require_text(), 1);
|
|
31688
31784
|
import * as THREE19 from "three";
|
|
31689
|
-
import { su as
|
|
31785
|
+
import { su as su8 } from "@tscircuit/circuit-json-util";
|
|
31690
31786
|
function createSilkscreenTextureForLayer({
|
|
31691
31787
|
layer,
|
|
31692
31788
|
circuitJson,
|
|
@@ -31694,11 +31790,11 @@ function createSilkscreenTextureForLayer({
|
|
|
31694
31790
|
silkscreenColor = "rgb(255,255,255)",
|
|
31695
31791
|
traceTextureResolution
|
|
31696
31792
|
}) {
|
|
31697
|
-
const pcbSilkscreenTexts =
|
|
31698
|
-
const pcbSilkscreenPaths =
|
|
31699
|
-
const pcbSilkscreenLines =
|
|
31700
|
-
const pcbSilkscreenRects =
|
|
31701
|
-
const pcbSilkscreenCircles =
|
|
31793
|
+
const pcbSilkscreenTexts = su8(circuitJson).pcb_silkscreen_text.list();
|
|
31794
|
+
const pcbSilkscreenPaths = su8(circuitJson).pcb_silkscreen_path.list();
|
|
31795
|
+
const pcbSilkscreenLines = su8(circuitJson).pcb_silkscreen_line.list();
|
|
31796
|
+
const pcbSilkscreenRects = su8(circuitJson).pcb_silkscreen_rect.list();
|
|
31797
|
+
const pcbSilkscreenCircles = su8(circuitJson).pcb_silkscreen_circle.list();
|
|
31702
31798
|
const textsOnLayer = pcbSilkscreenTexts.filter((t) => t.layer === layer);
|
|
31703
31799
|
const pathsOnLayer = pcbSilkscreenPaths.filter((p) => p.layer === layer);
|
|
31704
31800
|
const linesOnLayer = pcbSilkscreenLines.filter((l) => l.layer === layer);
|
|
@@ -31953,7 +32049,7 @@ function createSilkscreenTextureForLayer({
|
|
|
31953
32049
|
}
|
|
31954
32050
|
|
|
31955
32051
|
// src/utils/manifold/process-non-plated-holes.ts
|
|
31956
|
-
import { su as
|
|
32052
|
+
import { su as su9 } from "@tscircuit/circuit-json-util";
|
|
31957
32053
|
|
|
31958
32054
|
// src/utils/hole-geoms.ts
|
|
31959
32055
|
function createCircleHoleDrill({
|
|
@@ -32080,7 +32176,7 @@ function isRotatedPillHole(hole) {
|
|
|
32080
32176
|
}
|
|
32081
32177
|
function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
32082
32178
|
const nonPlatedHoleBoardDrills = [];
|
|
32083
|
-
const pcbHoles =
|
|
32179
|
+
const pcbHoles = su9(circuitJson).pcb_hole.list();
|
|
32084
32180
|
const createPillOp = (width10, height10, depth) => {
|
|
32085
32181
|
const pillOp = createRoundedRectPrism({
|
|
32086
32182
|
Manifold,
|
|
@@ -32129,13 +32225,13 @@ function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, m
|
|
|
32129
32225
|
}
|
|
32130
32226
|
|
|
32131
32227
|
// src/utils/manifold/process-plated-holes.ts
|
|
32132
|
-
import { su as
|
|
32228
|
+
import { su as su10 } from "@tscircuit/circuit-json-util";
|
|
32133
32229
|
import * as THREE20 from "three";
|
|
32134
32230
|
var COPPER_COLOR = new THREE20.Color(...colors.copper);
|
|
32135
32231
|
var PLATED_HOLE_LIP_HEIGHT = 0.05;
|
|
32136
32232
|
function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
32137
32233
|
const platedHoleBoardDrills = [];
|
|
32138
|
-
const pcbPlatedHoles =
|
|
32234
|
+
const pcbPlatedHoles = su10(circuitJson).pcb_plated_hole.list();
|
|
32139
32235
|
const platedHoleCopperGeoms = [];
|
|
32140
32236
|
const platedHoleCopperOpsForSubtract = [];
|
|
32141
32237
|
const createPillOp = (width10, height10, depth) => {
|
|
@@ -32448,7 +32544,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
32448
32544
|
}
|
|
32449
32545
|
|
|
32450
32546
|
// src/utils/manifold/process-vias.ts
|
|
32451
|
-
import { su as
|
|
32547
|
+
import { su as su11 } from "@tscircuit/circuit-json-util";
|
|
32452
32548
|
import * as THREE21 from "three";
|
|
32453
32549
|
|
|
32454
32550
|
// src/utils/via-geoms.ts
|
|
@@ -32485,7 +32581,7 @@ function createViaCopper({
|
|
|
32485
32581
|
var COPPER_COLOR2 = new THREE21.Color(...colors.copper);
|
|
32486
32582
|
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
32487
32583
|
const viaBoardDrills = [];
|
|
32488
|
-
const pcbVias =
|
|
32584
|
+
const pcbVias = su11(circuitJson).pcb_via.list();
|
|
32489
32585
|
const viaCopperGeoms = [];
|
|
32490
32586
|
pcbVias.forEach((via, index2) => {
|
|
32491
32587
|
if (typeof via.outer_diameter === "number") {
|
|
@@ -32534,12 +32630,12 @@ function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldIns
|
|
|
32534
32630
|
}
|
|
32535
32631
|
|
|
32536
32632
|
// src/utils/manifold/process-smt-pads.ts
|
|
32537
|
-
import { su as
|
|
32633
|
+
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
32538
32634
|
import * as THREE22 from "three";
|
|
32539
32635
|
var COPPER_COLOR3 = new THREE22.Color(...colors.copper);
|
|
32540
32636
|
function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, holeUnion, boardClipVolume) {
|
|
32541
32637
|
const smtPadGeoms = [];
|
|
32542
|
-
const smtPads =
|
|
32638
|
+
const smtPads = su12(circuitJson).pcb_smtpad.list();
|
|
32543
32639
|
smtPads.forEach((pad2, index2) => {
|
|
32544
32640
|
const padBaseThickness = DEFAULT_SMT_PAD_THICKNESS;
|
|
32545
32641
|
const zPos = pad2.layer === "bottom" ? -pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper : pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper;
|
|
@@ -32805,7 +32901,7 @@ function processCopperPoursForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
32805
32901
|
}
|
|
32806
32902
|
|
|
32807
32903
|
// src/utils/manifold/process-cutouts.ts
|
|
32808
|
-
import { su as
|
|
32904
|
+
import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
32809
32905
|
var arePointsClockwise5 = (points) => {
|
|
32810
32906
|
let area = 0;
|
|
32811
32907
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -32820,7 +32916,7 @@ var arePointsClockwise5 = (points) => {
|
|
|
32820
32916
|
};
|
|
32821
32917
|
function processCutoutsForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
|
|
32822
32918
|
const cutoutOps = [];
|
|
32823
|
-
const pcbCutouts =
|
|
32919
|
+
const pcbCutouts = su13(circuitJson).pcb_cutout.list();
|
|
32824
32920
|
for (const cutout of pcbCutouts) {
|
|
32825
32921
|
let cutoutOp;
|
|
32826
32922
|
const cutoutHeight = pcbThickness * 1.5;
|
|
@@ -32912,11 +33008,12 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
32912
33008
|
const [isLoading, setIsLoading] = useState14(true);
|
|
32913
33009
|
const manifoldInstancesForCleanup = useRef8([]);
|
|
32914
33010
|
const boardData = useMemo20(() => {
|
|
32915
|
-
const boards =
|
|
32916
|
-
|
|
32917
|
-
|
|
32918
|
-
|
|
32919
|
-
|
|
33011
|
+
const boards = su14(circuitJson).pcb_board.list();
|
|
33012
|
+
return boards.length > 0 ? boards[0] : null;
|
|
33013
|
+
}, [circuitJson]);
|
|
33014
|
+
const isFauxBoard = useMemo20(() => {
|
|
33015
|
+
const boards = su14(circuitJson).pcb_board.list();
|
|
33016
|
+
return boards.length > 0 && boards[0].pcb_board_id === "faux-board";
|
|
32920
33017
|
}, [circuitJson]);
|
|
32921
33018
|
useEffect21(() => {
|
|
32922
33019
|
if (!manifoldJSModule || !boardData) {
|
|
@@ -33084,7 +33181,8 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
33084
33181
|
matColorArray[1],
|
|
33085
33182
|
matColorArray[2]
|
|
33086
33183
|
),
|
|
33087
|
-
material: boardData.material
|
|
33184
|
+
material: boardData.material,
|
|
33185
|
+
isFaux: isFauxBoard
|
|
33088
33186
|
};
|
|
33089
33187
|
}
|
|
33090
33188
|
const { smtPadGeoms } = processSmtPadsForManifold(
|
|
@@ -33161,7 +33259,8 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
33161
33259
|
pcbThickness,
|
|
33162
33260
|
error,
|
|
33163
33261
|
isLoading,
|
|
33164
|
-
boardData
|
|
33262
|
+
boardData,
|
|
33263
|
+
isFauxBoard
|
|
33165
33264
|
};
|
|
33166
33265
|
};
|
|
33167
33266
|
|
|
@@ -33174,7 +33273,8 @@ var DEFAULT_SIDE = THREE25.DoubleSide;
|
|
|
33174
33273
|
var createBoardMaterial = ({
|
|
33175
33274
|
material,
|
|
33176
33275
|
color,
|
|
33177
|
-
side = DEFAULT_SIDE
|
|
33276
|
+
side = DEFAULT_SIDE,
|
|
33277
|
+
isFaux = false
|
|
33178
33278
|
}) => {
|
|
33179
33279
|
if (material === "fr4") {
|
|
33180
33280
|
return new THREE25.MeshPhysicalMaterial({
|
|
@@ -33186,8 +33286,8 @@ var createBoardMaterial = ({
|
|
|
33186
33286
|
ior: 1.45,
|
|
33187
33287
|
sheen: 0,
|
|
33188
33288
|
clearcoat: 0,
|
|
33189
|
-
transparent:
|
|
33190
|
-
opacity: 1,
|
|
33289
|
+
transparent: isFaux,
|
|
33290
|
+
opacity: isFaux ? 0.6 : 1,
|
|
33191
33291
|
flatShading: true
|
|
33192
33292
|
});
|
|
33193
33293
|
}
|
|
@@ -33198,7 +33298,7 @@ var createBoardMaterial = ({
|
|
|
33198
33298
|
metalness: 0.1,
|
|
33199
33299
|
roughness: 0.8,
|
|
33200
33300
|
transparent: true,
|
|
33201
|
-
opacity: 0.9
|
|
33301
|
+
opacity: isFaux ? 0.6 : 0.9
|
|
33202
33302
|
});
|
|
33203
33303
|
};
|
|
33204
33304
|
|
|
@@ -33212,7 +33312,8 @@ function createGeometryMeshes(geoms) {
|
|
|
33212
33312
|
createBoardMaterial({
|
|
33213
33313
|
material: geoms.board.material,
|
|
33214
33314
|
color: geoms.board.color,
|
|
33215
|
-
side: THREE26.DoubleSide
|
|
33315
|
+
side: THREE26.DoubleSide,
|
|
33316
|
+
isFaux: geoms.board.isFaux
|
|
33216
33317
|
})
|
|
33217
33318
|
);
|
|
33218
33319
|
mesh.name = "board-geom";
|
|
@@ -33371,7 +33472,8 @@ var CadViewerManifold = ({
|
|
|
33371
33472
|
}) => {
|
|
33372
33473
|
const childrenCircuitJson = useConvertChildrenToCircuitJson(children);
|
|
33373
33474
|
const circuitJson = useMemo21(() => {
|
|
33374
|
-
|
|
33475
|
+
const rawCircuitJson = circuitJsonProp ?? childrenCircuitJson;
|
|
33476
|
+
return addFauxBoardIfNeeded(rawCircuitJson);
|
|
33375
33477
|
}, [circuitJsonProp, childrenCircuitJson]);
|
|
33376
33478
|
const [manifoldJSModule, setManifoldJSModule] = useState15(null);
|
|
33377
33479
|
const [manifoldLoadingError, setManifoldLoadingError] = useState15(null);
|
|
@@ -33451,7 +33553,7 @@ try {
|
|
|
33451
33553
|
[textures, boardData, pcbThickness]
|
|
33452
33554
|
);
|
|
33453
33555
|
const cadComponents = useMemo21(
|
|
33454
|
-
() =>
|
|
33556
|
+
() => su15(circuitJson).cad_component.list(),
|
|
33455
33557
|
[circuitJson]
|
|
33456
33558
|
);
|
|
33457
33559
|
const boardDimensions = useMemo21(() => {
|
|
@@ -33663,9 +33765,16 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
33663
33765
|
}, []);
|
|
33664
33766
|
const handleClickAway = useCallback8((e) => {
|
|
33665
33767
|
const target = e.target;
|
|
33666
|
-
if (menuRef.current &&
|
|
33667
|
-
|
|
33768
|
+
if (menuRef.current && menuRef.current.contains(target)) {
|
|
33769
|
+
return;
|
|
33770
|
+
}
|
|
33771
|
+
const isInRadixPortal = target.closest?.(
|
|
33772
|
+
"[data-radix-popper-content-wrapper], [data-radix-dropdown-menu-content], [data-radix-dropdown-menu-sub-content]"
|
|
33773
|
+
);
|
|
33774
|
+
if (isInRadixPortal) {
|
|
33775
|
+
return;
|
|
33668
33776
|
}
|
|
33777
|
+
setMenuVisible(false);
|
|
33669
33778
|
}, []);
|
|
33670
33779
|
useEffect23(() => {
|
|
33671
33780
|
if (menuVisible) {
|
|
@@ -39245,6 +39354,7 @@ var AppearanceMenu = () => {
|
|
|
39245
39354
|
},
|
|
39246
39355
|
onMouseEnter: () => setHoveredItem("appearance"),
|
|
39247
39356
|
onMouseLeave: () => setHoveredItem(null),
|
|
39357
|
+
onTouchStart: () => setHoveredItem("appearance"),
|
|
39248
39358
|
children: [
|
|
39249
39359
|
/* @__PURE__ */ jsx32("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
|
|
39250
39360
|
/* @__PURE__ */ jsx32(
|
|
@@ -39283,6 +39393,7 @@ var AppearanceMenu = () => {
|
|
|
39283
39393
|
},
|
|
39284
39394
|
onMouseEnter: () => setHoveredItem("boardBody"),
|
|
39285
39395
|
onMouseLeave: () => setHoveredItem(null),
|
|
39396
|
+
onTouchStart: () => setHoveredItem("boardBody"),
|
|
39286
39397
|
children: [
|
|
39287
39398
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39288
39399
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
|
|
@@ -39303,6 +39414,7 @@ var AppearanceMenu = () => {
|
|
|
39303
39414
|
},
|
|
39304
39415
|
onMouseEnter: () => setHoveredItem("topCopper"),
|
|
39305
39416
|
onMouseLeave: () => setHoveredItem(null),
|
|
39417
|
+
onTouchStart: () => setHoveredItem("topCopper"),
|
|
39306
39418
|
children: [
|
|
39307
39419
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39308
39420
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
|
|
@@ -39323,6 +39435,7 @@ var AppearanceMenu = () => {
|
|
|
39323
39435
|
},
|
|
39324
39436
|
onMouseEnter: () => setHoveredItem("bottomCopper"),
|
|
39325
39437
|
onMouseLeave: () => setHoveredItem(null),
|
|
39438
|
+
onTouchStart: () => setHoveredItem("bottomCopper"),
|
|
39326
39439
|
children: [
|
|
39327
39440
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39328
39441
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
|
|
@@ -39343,6 +39456,7 @@ var AppearanceMenu = () => {
|
|
|
39343
39456
|
},
|
|
39344
39457
|
onMouseEnter: () => setHoveredItem("topSilkscreen"),
|
|
39345
39458
|
onMouseLeave: () => setHoveredItem(null),
|
|
39459
|
+
onTouchStart: () => setHoveredItem("topSilkscreen"),
|
|
39346
39460
|
children: [
|
|
39347
39461
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39348
39462
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
|
|
@@ -39363,6 +39477,7 @@ var AppearanceMenu = () => {
|
|
|
39363
39477
|
},
|
|
39364
39478
|
onMouseEnter: () => setHoveredItem("bottomSilkscreen"),
|
|
39365
39479
|
onMouseLeave: () => setHoveredItem(null),
|
|
39480
|
+
onTouchStart: () => setHoveredItem("bottomSilkscreen"),
|
|
39366
39481
|
children: [
|
|
39367
39482
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39368
39483
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
|
|
@@ -39383,6 +39498,7 @@ var AppearanceMenu = () => {
|
|
|
39383
39498
|
},
|
|
39384
39499
|
onMouseEnter: () => setHoveredItem("smtModels"),
|
|
39385
39500
|
onMouseLeave: () => setHoveredItem(null),
|
|
39501
|
+
onTouchStart: () => setHoveredItem("smtModels"),
|
|
39386
39502
|
children: [
|
|
39387
39503
|
/* @__PURE__ */ jsx32("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx32(CheckIcon, {}) }),
|
|
39388
39504
|
/* @__PURE__ */ jsx32("span", { style: { display: "flex", alignItems: "center" }, children: "CAD Models" })
|
|
@@ -39512,6 +39628,7 @@ var ContextMenu = ({
|
|
|
39512
39628
|
},
|
|
39513
39629
|
onMouseEnter: () => setHoveredItem("camera"),
|
|
39514
39630
|
onMouseLeave: () => setHoveredItem(null),
|
|
39631
|
+
onTouchStart: () => setHoveredItem("camera"),
|
|
39515
39632
|
children: [
|
|
39516
39633
|
/* @__PURE__ */ jsx33(
|
|
39517
39634
|
"span",
|
|
@@ -39558,6 +39675,7 @@ var ContextMenu = ({
|
|
|
39558
39675
|
},
|
|
39559
39676
|
onMouseEnter: () => setHoveredItem(option),
|
|
39560
39677
|
onMouseLeave: () => setHoveredItem(null),
|
|
39678
|
+
onTouchStart: () => setHoveredItem(option),
|
|
39561
39679
|
children: [
|
|
39562
39680
|
/* @__PURE__ */ jsx33("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx33(DotIcon, {}) }),
|
|
39563
39681
|
/* @__PURE__ */ jsx33("span", { style: { display: "flex", alignItems: "center" }, children: option })
|
|
@@ -39583,6 +39701,7 @@ var ContextMenu = ({
|
|
|
39583
39701
|
},
|
|
39584
39702
|
onMouseEnter: () => setHoveredItem("autorotate"),
|
|
39585
39703
|
onMouseLeave: () => setHoveredItem(null),
|
|
39704
|
+
onTouchStart: () => setHoveredItem("autorotate"),
|
|
39586
39705
|
children: [
|
|
39587
39706
|
/* @__PURE__ */ jsx33("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx33(CheckIcon, {}) }),
|
|
39588
39707
|
/* @__PURE__ */ jsx33("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
|
|
@@ -39602,6 +39721,7 @@ var ContextMenu = ({
|
|
|
39602
39721
|
onSelect: onDownloadGltf,
|
|
39603
39722
|
onMouseEnter: () => setHoveredItem("download"),
|
|
39604
39723
|
onMouseLeave: () => setHoveredItem(null),
|
|
39724
|
+
onTouchStart: () => setHoveredItem("download"),
|
|
39605
39725
|
children: /* @__PURE__ */ jsx33("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
|
|
39606
39726
|
}
|
|
39607
39727
|
),
|
|
@@ -39621,6 +39741,7 @@ var ContextMenu = ({
|
|
|
39621
39741
|
},
|
|
39622
39742
|
onMouseEnter: () => setHoveredItem("engine"),
|
|
39623
39743
|
onMouseLeave: () => setHoveredItem(null),
|
|
39744
|
+
onTouchStart: () => setHoveredItem("engine"),
|
|
39624
39745
|
children: [
|
|
39625
39746
|
/* @__PURE__ */ jsxs9("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: [
|
|
39626
39747
|
"Switch to ",
|
|
@@ -39853,7 +39974,7 @@ var CadViewer = (props) => {
|
|
|
39853
39974
|
|
|
39854
39975
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
39855
39976
|
var import_debug = __toESM(require_browser(), 1);
|
|
39856
|
-
import { su as
|
|
39977
|
+
import { su as su16 } from "@tscircuit/circuit-json-util";
|
|
39857
39978
|
import * as THREE31 from "three";
|
|
39858
39979
|
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
|
|
39859
39980
|
|
|
@@ -40082,11 +40203,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
40082
40203
|
const pointLight = new THREE31.PointLight(16777215, Math.PI / 4);
|
|
40083
40204
|
pointLight.position.set(-10, -10, 10);
|
|
40084
40205
|
scene.add(pointLight);
|
|
40085
|
-
const components =
|
|
40206
|
+
const components = su16(circuitJson).cad_component.list();
|
|
40086
40207
|
for (const component of components) {
|
|
40087
40208
|
await renderComponent(component, scene);
|
|
40088
40209
|
}
|
|
40089
|
-
const boardData =
|
|
40210
|
+
const boardData = su16(circuitJson).pcb_board.list()[0];
|
|
40090
40211
|
const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
|
|
40091
40212
|
if (boardGeom) {
|
|
40092
40213
|
for (const geom of boardGeom) {
|