@tscircuit/3d-viewer 0.0.414 → 0.0.416
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +635 -284
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14228,15 +14228,15 @@ var require_browser = __commonJS({
|
|
|
14228
14228
|
});
|
|
14229
14229
|
|
|
14230
14230
|
// src/CadViewer.tsx
|
|
14231
|
-
import { useState as
|
|
14231
|
+
import { useState as useState18, useCallback as useCallback9, useRef as useRef9, useEffect as useEffect24 } from "react";
|
|
14232
14232
|
|
|
14233
14233
|
// src/CadViewerJscad.tsx
|
|
14234
14234
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
14235
|
-
import { forwardRef as forwardRef3, useMemo as
|
|
14235
|
+
import { forwardRef as forwardRef3, useMemo as useMemo18 } from "react";
|
|
14236
14236
|
|
|
14237
14237
|
// src/AnyCadComponent.tsx
|
|
14238
14238
|
import { su } from "@tscircuit/circuit-json-util";
|
|
14239
|
-
import { useMemo as
|
|
14239
|
+
import { useMemo as useMemo7, useState as useState6, useCallback as useCallback3 } from "react";
|
|
14240
14240
|
|
|
14241
14241
|
// src/ContainerWithTooltip.tsx
|
|
14242
14242
|
import { useEffect as useEffect2 } from "react";
|
|
@@ -26440,15 +26440,87 @@ var Html = ({ children, position, style }) => {
|
|
|
26440
26440
|
return portal;
|
|
26441
26441
|
};
|
|
26442
26442
|
|
|
26443
|
+
// src/contexts/LayerVisibilityContext.tsx
|
|
26444
|
+
import {
|
|
26445
|
+
createContext as createContext3,
|
|
26446
|
+
useContext as useContext3,
|
|
26447
|
+
useState as useState5,
|
|
26448
|
+
useCallback as useCallback2,
|
|
26449
|
+
useMemo as useMemo6
|
|
26450
|
+
} from "react";
|
|
26451
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
26452
|
+
var defaultVisibility = {
|
|
26453
|
+
boardBody: true,
|
|
26454
|
+
topCopper: true,
|
|
26455
|
+
bottomCopper: true,
|
|
26456
|
+
adhesive: false,
|
|
26457
|
+
solderPaste: false,
|
|
26458
|
+
topSilkscreen: true,
|
|
26459
|
+
bottomSilkscreen: true,
|
|
26460
|
+
topMask: true,
|
|
26461
|
+
bottomMask: true,
|
|
26462
|
+
throughHoleModels: true,
|
|
26463
|
+
smtModels: true,
|
|
26464
|
+
virtualModels: false,
|
|
26465
|
+
modelsNotInPosFile: false,
|
|
26466
|
+
modelsMarkedDNP: false,
|
|
26467
|
+
modelBoundingBoxes: false,
|
|
26468
|
+
threedAxis: false,
|
|
26469
|
+
backgroundStart: true,
|
|
26470
|
+
backgroundEnd: true
|
|
26471
|
+
};
|
|
26472
|
+
var LayerVisibilityContext = createContext3(void 0);
|
|
26473
|
+
var LayerVisibilityProvider = ({ children }) => {
|
|
26474
|
+
const [visibility, setVisibility] = useState5(defaultVisibility);
|
|
26475
|
+
const toggleLayer = useCallback2((layer) => {
|
|
26476
|
+
setVisibility((prev) => ({
|
|
26477
|
+
...prev,
|
|
26478
|
+
[layer]: !prev[layer]
|
|
26479
|
+
}));
|
|
26480
|
+
}, []);
|
|
26481
|
+
const setLayerVisibility = useCallback2(
|
|
26482
|
+
(layer, visible) => {
|
|
26483
|
+
setVisibility((prev) => ({
|
|
26484
|
+
...prev,
|
|
26485
|
+
[layer]: visible
|
|
26486
|
+
}));
|
|
26487
|
+
},
|
|
26488
|
+
[]
|
|
26489
|
+
);
|
|
26490
|
+
const resetToDefaults = useCallback2(() => {
|
|
26491
|
+
setVisibility(defaultVisibility);
|
|
26492
|
+
}, []);
|
|
26493
|
+
const value = useMemo6(
|
|
26494
|
+
() => ({
|
|
26495
|
+
visibility,
|
|
26496
|
+
toggleLayer,
|
|
26497
|
+
setLayerVisibility,
|
|
26498
|
+
resetToDefaults
|
|
26499
|
+
}),
|
|
26500
|
+
[visibility, toggleLayer, setLayerVisibility, resetToDefaults]
|
|
26501
|
+
);
|
|
26502
|
+
return /* @__PURE__ */ jsx8(LayerVisibilityContext.Provider, { value, children });
|
|
26503
|
+
};
|
|
26504
|
+
var useLayerVisibility = () => {
|
|
26505
|
+
const context = useContext3(LayerVisibilityContext);
|
|
26506
|
+
if (!context) {
|
|
26507
|
+
throw new Error(
|
|
26508
|
+
"useLayerVisibility must be used within a LayerVisibilityProvider"
|
|
26509
|
+
);
|
|
26510
|
+
}
|
|
26511
|
+
return context;
|
|
26512
|
+
};
|
|
26513
|
+
|
|
26443
26514
|
// src/AnyCadComponent.tsx
|
|
26444
|
-
import { Fragment as Fragment3, jsx as
|
|
26515
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
26445
26516
|
var AnyCadComponent = ({
|
|
26446
26517
|
cad_component: cad_component2,
|
|
26447
26518
|
circuitJson
|
|
26448
26519
|
}) => {
|
|
26449
|
-
const [isHovered, setIsHovered] =
|
|
26450
|
-
const
|
|
26451
|
-
const
|
|
26520
|
+
const [isHovered, setIsHovered] = useState6(false);
|
|
26521
|
+
const { visibility } = useLayerVisibility();
|
|
26522
|
+
const [hoverPosition, setHoverPosition] = useState6(null);
|
|
26523
|
+
const handleHover = useCallback3((e) => {
|
|
26452
26524
|
if (e?.mousePosition) {
|
|
26453
26525
|
setIsHovered(true);
|
|
26454
26526
|
setHoverPosition(e.mousePosition);
|
|
@@ -26457,11 +26529,11 @@ var AnyCadComponent = ({
|
|
|
26457
26529
|
setHoverPosition(null);
|
|
26458
26530
|
}
|
|
26459
26531
|
}, []);
|
|
26460
|
-
const handleUnhover =
|
|
26532
|
+
const handleUnhover = useCallback3(() => {
|
|
26461
26533
|
setIsHovered(false);
|
|
26462
26534
|
setHoverPosition(null);
|
|
26463
26535
|
}, []);
|
|
26464
|
-
const componentName =
|
|
26536
|
+
const componentName = useMemo7(() => {
|
|
26465
26537
|
return su(circuitJson).source_component.getUsing({
|
|
26466
26538
|
source_component_id: cad_component2.source_component_id
|
|
26467
26539
|
})?.name;
|
|
@@ -26475,7 +26547,7 @@ var AnyCadComponent = ({
|
|
|
26475
26547
|
) : void 0;
|
|
26476
26548
|
let modelComponent = null;
|
|
26477
26549
|
if (url) {
|
|
26478
|
-
modelComponent = /* @__PURE__ */
|
|
26550
|
+
modelComponent = /* @__PURE__ */ jsx9(
|
|
26479
26551
|
MixedStlModel,
|
|
26480
26552
|
{
|
|
26481
26553
|
url,
|
|
@@ -26493,7 +26565,7 @@ var AnyCadComponent = ({
|
|
|
26493
26565
|
cad_component2.cad_component_id
|
|
26494
26566
|
);
|
|
26495
26567
|
} else if (gltfUrl) {
|
|
26496
|
-
modelComponent = /* @__PURE__ */
|
|
26568
|
+
modelComponent = /* @__PURE__ */ jsx9(
|
|
26497
26569
|
GltfModel,
|
|
26498
26570
|
{
|
|
26499
26571
|
gltfUrl,
|
|
@@ -26511,7 +26583,7 @@ var AnyCadComponent = ({
|
|
|
26511
26583
|
cad_component2.cad_component_id
|
|
26512
26584
|
);
|
|
26513
26585
|
} else if (cad_component2.model_jscad) {
|
|
26514
|
-
modelComponent = /* @__PURE__ */
|
|
26586
|
+
modelComponent = /* @__PURE__ */ jsx9(
|
|
26515
26587
|
JscadModel,
|
|
26516
26588
|
{
|
|
26517
26589
|
jscadPlan: cad_component2.model_jscad,
|
|
@@ -26524,7 +26596,7 @@ var AnyCadComponent = ({
|
|
|
26524
26596
|
cad_component2.cad_component_id
|
|
26525
26597
|
);
|
|
26526
26598
|
} else if (cad_component2.footprinter_string) {
|
|
26527
|
-
modelComponent = /* @__PURE__ */
|
|
26599
|
+
modelComponent = /* @__PURE__ */ jsx9(
|
|
26528
26600
|
FootprinterModel,
|
|
26529
26601
|
{
|
|
26530
26602
|
positionOffset: cad_component2.position ? [
|
|
@@ -26541,9 +26613,12 @@ var AnyCadComponent = ({
|
|
|
26541
26613
|
}
|
|
26542
26614
|
);
|
|
26543
26615
|
}
|
|
26616
|
+
if (!visibility.smtModels) {
|
|
26617
|
+
return null;
|
|
26618
|
+
}
|
|
26544
26619
|
return /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
26545
26620
|
modelComponent,
|
|
26546
|
-
isHovered && hoverPosition ? /* @__PURE__ */
|
|
26621
|
+
isHovered && hoverPosition ? /* @__PURE__ */ jsx9(
|
|
26547
26622
|
Html,
|
|
26548
26623
|
{
|
|
26549
26624
|
position: hoverPosition,
|
|
@@ -26568,15 +26643,15 @@ var AnyCadComponent = ({
|
|
|
26568
26643
|
// src/CadViewerContainer.tsx
|
|
26569
26644
|
import {
|
|
26570
26645
|
forwardRef as forwardRef2,
|
|
26571
|
-
useMemo as
|
|
26572
|
-
useState as
|
|
26646
|
+
useMemo as useMemo14,
|
|
26647
|
+
useState as useState8
|
|
26573
26648
|
} from "react";
|
|
26574
26649
|
import * as THREE13 from "three";
|
|
26575
26650
|
|
|
26576
26651
|
// package.json
|
|
26577
26652
|
var package_default = {
|
|
26578
26653
|
name: "@tscircuit/3d-viewer",
|
|
26579
|
-
version: "0.0.
|
|
26654
|
+
version: "0.0.415",
|
|
26580
26655
|
main: "./dist/index.js",
|
|
26581
26656
|
module: "./dist/index.js",
|
|
26582
26657
|
type: "module",
|
|
@@ -26655,11 +26730,11 @@ var package_default = {
|
|
|
26655
26730
|
};
|
|
26656
26731
|
|
|
26657
26732
|
// src/three-components/cube-with-labeled-sides.tsx
|
|
26658
|
-
import { useEffect as
|
|
26733
|
+
import { useEffect as useEffect11, useMemo as useMemo9 } from "react";
|
|
26659
26734
|
import * as THREE8 from "three";
|
|
26660
26735
|
|
|
26661
26736
|
// src/react-three/Text.tsx
|
|
26662
|
-
import { useEffect as
|
|
26737
|
+
import { useEffect as useEffect10, useMemo as useMemo8 } from "react";
|
|
26663
26738
|
import { Text as TroikaText } from "troika-three-text";
|
|
26664
26739
|
var Text = ({
|
|
26665
26740
|
children,
|
|
@@ -26674,7 +26749,7 @@ var Text = ({
|
|
|
26674
26749
|
depthOffset
|
|
26675
26750
|
}) => {
|
|
26676
26751
|
const { rootObject } = useThree();
|
|
26677
|
-
const mesh =
|
|
26752
|
+
const mesh = useMemo8(() => {
|
|
26678
26753
|
const textMesh = new TroikaText();
|
|
26679
26754
|
textMesh.text = children;
|
|
26680
26755
|
if (position) textMesh.position.fromArray(position);
|
|
@@ -26699,7 +26774,7 @@ var Text = ({
|
|
|
26699
26774
|
anchorY,
|
|
26700
26775
|
depthOffset
|
|
26701
26776
|
]);
|
|
26702
|
-
|
|
26777
|
+
useEffect10(() => {
|
|
26703
26778
|
const parentObject = parent || rootObject;
|
|
26704
26779
|
if (!parentObject || !mesh) return;
|
|
26705
26780
|
parentObject.add(mesh);
|
|
@@ -26712,7 +26787,7 @@ var Text = ({
|
|
|
26712
26787
|
};
|
|
26713
26788
|
|
|
26714
26789
|
// src/three-components/cube-with-labeled-sides.tsx
|
|
26715
|
-
import { Fragment as Fragment4, jsx as
|
|
26790
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
26716
26791
|
if (typeof window !== "undefined") {
|
|
26717
26792
|
window.TSCI_MAIN_CAMERA_ROTATION = new THREE8.Euler(0, 0, 0);
|
|
26718
26793
|
}
|
|
@@ -26727,7 +26802,7 @@ function computePointInFront(rotationVector, distance2) {
|
|
|
26727
26802
|
}
|
|
26728
26803
|
var CubeWithLabeledSides = ({}) => {
|
|
26729
26804
|
const { camera, scene } = useThree();
|
|
26730
|
-
|
|
26805
|
+
useEffect11(() => {
|
|
26731
26806
|
if (!scene) return;
|
|
26732
26807
|
const ambientLight = new THREE8.AmbientLight(16777215, Math.PI / 2);
|
|
26733
26808
|
scene.add(ambientLight);
|
|
@@ -26742,7 +26817,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26742
26817
|
camera.position.copy(cameraPosition);
|
|
26743
26818
|
camera.lookAt(0, 0, 0);
|
|
26744
26819
|
});
|
|
26745
|
-
const group =
|
|
26820
|
+
const group = useMemo9(() => {
|
|
26746
26821
|
const g = new THREE8.Group();
|
|
26747
26822
|
g.rotation.fromArray([Math.PI / 2, 0, 0]);
|
|
26748
26823
|
const box = new THREE8.Mesh(
|
|
@@ -26757,7 +26832,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26757
26832
|
g.add(edges);
|
|
26758
26833
|
return g;
|
|
26759
26834
|
}, []);
|
|
26760
|
-
|
|
26835
|
+
useEffect11(() => {
|
|
26761
26836
|
if (!scene) return;
|
|
26762
26837
|
scene.add(group);
|
|
26763
26838
|
return () => {
|
|
@@ -26765,7 +26840,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26765
26840
|
};
|
|
26766
26841
|
}, [scene, group]);
|
|
26767
26842
|
return /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26768
|
-
/* @__PURE__ */
|
|
26843
|
+
/* @__PURE__ */ jsx10(
|
|
26769
26844
|
Text,
|
|
26770
26845
|
{
|
|
26771
26846
|
parent: group,
|
|
@@ -26775,7 +26850,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26775
26850
|
children: "Front"
|
|
26776
26851
|
}
|
|
26777
26852
|
),
|
|
26778
|
-
/* @__PURE__ */
|
|
26853
|
+
/* @__PURE__ */ jsx10(
|
|
26779
26854
|
Text,
|
|
26780
26855
|
{
|
|
26781
26856
|
parent: group,
|
|
@@ -26786,7 +26861,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26786
26861
|
children: "Back"
|
|
26787
26862
|
}
|
|
26788
26863
|
),
|
|
26789
|
-
/* @__PURE__ */
|
|
26864
|
+
/* @__PURE__ */ jsx10(
|
|
26790
26865
|
Text,
|
|
26791
26866
|
{
|
|
26792
26867
|
parent: group,
|
|
@@ -26797,7 +26872,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26797
26872
|
children: "Right"
|
|
26798
26873
|
}
|
|
26799
26874
|
),
|
|
26800
|
-
/* @__PURE__ */
|
|
26875
|
+
/* @__PURE__ */ jsx10(
|
|
26801
26876
|
Text,
|
|
26802
26877
|
{
|
|
26803
26878
|
parent: group,
|
|
@@ -26808,7 +26883,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26808
26883
|
children: "Left"
|
|
26809
26884
|
}
|
|
26810
26885
|
),
|
|
26811
|
-
/* @__PURE__ */
|
|
26886
|
+
/* @__PURE__ */ jsx10(
|
|
26812
26887
|
Text,
|
|
26813
26888
|
{
|
|
26814
26889
|
parent: group,
|
|
@@ -26819,7 +26894,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26819
26894
|
children: "Top"
|
|
26820
26895
|
}
|
|
26821
26896
|
),
|
|
26822
|
-
/* @__PURE__ */
|
|
26897
|
+
/* @__PURE__ */ jsx10(
|
|
26823
26898
|
Text,
|
|
26824
26899
|
{
|
|
26825
26900
|
parent: group,
|
|
@@ -26836,12 +26911,12 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
26836
26911
|
// src/react-three/Canvas.tsx
|
|
26837
26912
|
import {
|
|
26838
26913
|
useRef as useRef4,
|
|
26839
|
-
useEffect as
|
|
26840
|
-
useState as
|
|
26841
|
-
useCallback as
|
|
26914
|
+
useEffect as useEffect12,
|
|
26915
|
+
useState as useState7,
|
|
26916
|
+
useCallback as useCallback4,
|
|
26842
26917
|
forwardRef,
|
|
26843
26918
|
useImperativeHandle,
|
|
26844
|
-
useMemo as
|
|
26919
|
+
useMemo as useMemo10
|
|
26845
26920
|
} from "react";
|
|
26846
26921
|
import * as THREE10 from "three";
|
|
26847
26922
|
|
|
@@ -26859,23 +26934,23 @@ var configureRenderer = (renderer) => {
|
|
|
26859
26934
|
};
|
|
26860
26935
|
|
|
26861
26936
|
// src/react-three/Canvas.tsx
|
|
26862
|
-
import { jsx as
|
|
26937
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
26863
26938
|
var Canvas = forwardRef(
|
|
26864
26939
|
({ children, scene: sceneProps, camera: cameraProps, style }, ref) => {
|
|
26865
26940
|
const mountRef = useRef4(null);
|
|
26866
|
-
const [contextState, setContextState] =
|
|
26941
|
+
const [contextState, setContextState] = useState7(
|
|
26867
26942
|
null
|
|
26868
26943
|
);
|
|
26869
26944
|
const frameListeners = useRef4(
|
|
26870
26945
|
[]
|
|
26871
26946
|
);
|
|
26872
|
-
const addFrameListener =
|
|
26947
|
+
const addFrameListener = useCallback4(
|
|
26873
26948
|
(listener) => {
|
|
26874
26949
|
frameListeners.current.push(listener);
|
|
26875
26950
|
},
|
|
26876
26951
|
[]
|
|
26877
26952
|
);
|
|
26878
|
-
const removeFrameListener =
|
|
26953
|
+
const removeFrameListener = useCallback4(
|
|
26879
26954
|
(listener) => {
|
|
26880
26955
|
frameListeners.current = frameListeners.current.filter(
|
|
26881
26956
|
(l) => l !== listener
|
|
@@ -26883,13 +26958,13 @@ var Canvas = forwardRef(
|
|
|
26883
26958
|
},
|
|
26884
26959
|
[]
|
|
26885
26960
|
);
|
|
26886
|
-
const scene =
|
|
26961
|
+
const scene = useMemo10(() => new THREE10.Scene(), []);
|
|
26887
26962
|
if (sceneProps?.up) {
|
|
26888
26963
|
scene.up.set(sceneProps.up.x, sceneProps.up.y, sceneProps.up.z);
|
|
26889
26964
|
}
|
|
26890
26965
|
const rootObject = useRef4(new THREE10.Object3D());
|
|
26891
26966
|
useImperativeHandle(ref, () => rootObject.current);
|
|
26892
|
-
|
|
26967
|
+
useEffect12(() => {
|
|
26893
26968
|
if (!mountRef.current) return;
|
|
26894
26969
|
removeExistingCanvases(mountRef.current);
|
|
26895
26970
|
const renderer = new THREE10.WebGLRenderer({ antialias: true, alpha: true });
|
|
@@ -26961,12 +27036,12 @@ var Canvas = forwardRef(
|
|
|
26961
27036
|
}
|
|
26962
27037
|
};
|
|
26963
27038
|
}, [scene, addFrameListener, removeFrameListener]);
|
|
26964
|
-
return /* @__PURE__ */
|
|
27039
|
+
return /* @__PURE__ */ jsx11("div", { ref: mountRef, style: { width: "100%", height: "100%", ...style }, children: contextState && /* @__PURE__ */ jsx11(ThreeContext.Provider, { value: contextState, children: /* @__PURE__ */ jsx11(HoverProvider, { children }) }) });
|
|
26965
27040
|
}
|
|
26966
27041
|
);
|
|
26967
27042
|
|
|
26968
27043
|
// src/react-three/OrbitControls.tsx
|
|
26969
|
-
import { useEffect as
|
|
27044
|
+
import { useEffect as useEffect13, useMemo as useMemo11 } from "react";
|
|
26970
27045
|
import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
26971
27046
|
var OrbitControls = ({
|
|
26972
27047
|
autoRotate,
|
|
@@ -26980,11 +27055,11 @@ var OrbitControls = ({
|
|
|
26980
27055
|
target
|
|
26981
27056
|
}) => {
|
|
26982
27057
|
const { camera, renderer } = useThree();
|
|
26983
|
-
const controls =
|
|
27058
|
+
const controls = useMemo11(() => {
|
|
26984
27059
|
if (!camera || !renderer) return null;
|
|
26985
27060
|
return new ThreeOrbitControls(camera, renderer.domElement);
|
|
26986
27061
|
}, [camera, renderer]);
|
|
26987
|
-
|
|
27062
|
+
useEffect13(() => {
|
|
26988
27063
|
if (!controls) return;
|
|
26989
27064
|
controls.autoRotate = autoRotate || false;
|
|
26990
27065
|
controls.autoRotateSpeed = autoRotateSpeed || 1;
|
|
@@ -27009,14 +27084,14 @@ var OrbitControls = ({
|
|
|
27009
27084
|
dampingFactor,
|
|
27010
27085
|
target
|
|
27011
27086
|
]);
|
|
27012
|
-
|
|
27087
|
+
useEffect13(() => {
|
|
27013
27088
|
if (!controls || !onStart) return;
|
|
27014
27089
|
controls.addEventListener("start", onStart);
|
|
27015
27090
|
return () => {
|
|
27016
27091
|
controls.removeEventListener("start", onStart);
|
|
27017
27092
|
};
|
|
27018
27093
|
}, [controls, onStart]);
|
|
27019
|
-
|
|
27094
|
+
useEffect13(() => {
|
|
27020
27095
|
if (!controls) return;
|
|
27021
27096
|
return () => {
|
|
27022
27097
|
controls.dispose();
|
|
@@ -27029,7 +27104,7 @@ var OrbitControls = ({
|
|
|
27029
27104
|
};
|
|
27030
27105
|
|
|
27031
27106
|
// src/react-three/Grid.tsx
|
|
27032
|
-
import { useEffect as
|
|
27107
|
+
import { useEffect as useEffect14, useMemo as useMemo12 } from "react";
|
|
27033
27108
|
import * as THREE11 from "three";
|
|
27034
27109
|
var vertexShader = `
|
|
27035
27110
|
varying vec3 worldPosition;
|
|
@@ -27075,7 +27150,7 @@ var Grid = ({
|
|
|
27075
27150
|
}) => {
|
|
27076
27151
|
const { scene, camera } = useThree();
|
|
27077
27152
|
const size2 = 1e3;
|
|
27078
|
-
const gridMesh =
|
|
27153
|
+
const gridMesh = useMemo12(() => {
|
|
27079
27154
|
const geometry = new THREE11.PlaneGeometry(size2, size2);
|
|
27080
27155
|
geometry.rotateX(-Math.PI / 2);
|
|
27081
27156
|
const material = new THREE11.ShaderMaterial({
|
|
@@ -27104,7 +27179,7 @@ var Grid = ({
|
|
|
27104
27179
|
gridMesh.position.set(camera.position.x, camera.position.y, 0);
|
|
27105
27180
|
}
|
|
27106
27181
|
});
|
|
27107
|
-
|
|
27182
|
+
useEffect14(() => {
|
|
27108
27183
|
if (!scene || !gridMesh) return;
|
|
27109
27184
|
scene.add(gridMesh);
|
|
27110
27185
|
return () => {
|
|
@@ -27121,21 +27196,21 @@ var Grid = ({
|
|
|
27121
27196
|
};
|
|
27122
27197
|
|
|
27123
27198
|
// src/react-three/Lights.tsx
|
|
27124
|
-
import { useEffect as
|
|
27199
|
+
import { useEffect as useEffect15, useMemo as useMemo13 } from "react";
|
|
27125
27200
|
import * as THREE12 from "three";
|
|
27126
27201
|
var Lights = () => {
|
|
27127
27202
|
const { scene } = useThree();
|
|
27128
|
-
const ambientLight =
|
|
27203
|
+
const ambientLight = useMemo13(
|
|
27129
27204
|
() => new THREE12.AmbientLight(16777215, Math.PI / 2),
|
|
27130
27205
|
[]
|
|
27131
27206
|
);
|
|
27132
|
-
const pointLight =
|
|
27207
|
+
const pointLight = useMemo13(() => {
|
|
27133
27208
|
const light = new THREE12.PointLight(16777215, Math.PI / 4);
|
|
27134
27209
|
light.position.set(-10, -10, 10);
|
|
27135
27210
|
light.decay = 0;
|
|
27136
27211
|
return light;
|
|
27137
27212
|
}, []);
|
|
27138
|
-
|
|
27213
|
+
useEffect15(() => {
|
|
27139
27214
|
if (!scene) return;
|
|
27140
27215
|
scene.add(ambientLight);
|
|
27141
27216
|
scene.add(pointLight);
|
|
@@ -27148,7 +27223,7 @@ var Lights = () => {
|
|
|
27148
27223
|
};
|
|
27149
27224
|
|
|
27150
27225
|
// src/CadViewerContainer.tsx
|
|
27151
|
-
import { jsx as
|
|
27226
|
+
import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
27152
27227
|
var RotationTracker = () => {
|
|
27153
27228
|
const { camera } = useThree();
|
|
27154
27229
|
useFrame(() => {
|
|
@@ -27168,10 +27243,10 @@ var CadViewerContainer = forwardRef2(
|
|
|
27168
27243
|
boardCenter,
|
|
27169
27244
|
onUserInteraction
|
|
27170
27245
|
}, ref) => {
|
|
27171
|
-
const [isInteractionEnabled, setIsInteractionEnabled] =
|
|
27246
|
+
const [isInteractionEnabled, setIsInteractionEnabled] = useState8(
|
|
27172
27247
|
!clickToInteractEnabled
|
|
27173
27248
|
);
|
|
27174
|
-
const gridSectionSize =
|
|
27249
|
+
const gridSectionSize = useMemo14(() => {
|
|
27175
27250
|
if (!boardDimensions) return 10;
|
|
27176
27251
|
const width10 = boardDimensions.width ?? 0;
|
|
27177
27252
|
const height10 = boardDimensions.height ?? 0;
|
|
@@ -27179,12 +27254,12 @@ var CadViewerContainer = forwardRef2(
|
|
|
27179
27254
|
const desired = largest * 1.5;
|
|
27180
27255
|
return desired > 10 ? desired : 10;
|
|
27181
27256
|
}, [boardDimensions]);
|
|
27182
|
-
const orbitTarget =
|
|
27257
|
+
const orbitTarget = useMemo14(() => {
|
|
27183
27258
|
if (!boardCenter) return void 0;
|
|
27184
27259
|
return [boardCenter.x, boardCenter.y, 0];
|
|
27185
27260
|
}, [boardCenter]);
|
|
27186
27261
|
return /* @__PURE__ */ jsxs4("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
|
|
27187
|
-
/* @__PURE__ */
|
|
27262
|
+
/* @__PURE__ */ jsx12(
|
|
27188
27263
|
"div",
|
|
27189
27264
|
{
|
|
27190
27265
|
style: {
|
|
@@ -27194,7 +27269,7 @@ var CadViewerContainer = forwardRef2(
|
|
|
27194
27269
|
width: 120,
|
|
27195
27270
|
height: 120
|
|
27196
27271
|
},
|
|
27197
|
-
children: /* @__PURE__ */
|
|
27272
|
+
children: /* @__PURE__ */ jsx12(
|
|
27198
27273
|
Canvas,
|
|
27199
27274
|
{
|
|
27200
27275
|
camera: {
|
|
@@ -27202,7 +27277,7 @@ var CadViewerContainer = forwardRef2(
|
|
|
27202
27277
|
position: [1, 1, 1]
|
|
27203
27278
|
},
|
|
27204
27279
|
style: { zIndex: 10 },
|
|
27205
|
-
children: /* @__PURE__ */
|
|
27280
|
+
children: /* @__PURE__ */ jsx12(CubeWithLabeledSides, {})
|
|
27206
27281
|
}
|
|
27207
27282
|
)
|
|
27208
27283
|
}
|
|
@@ -27214,8 +27289,8 @@ var CadViewerContainer = forwardRef2(
|
|
|
27214
27289
|
scene: { up: new THREE13.Vector3(0, 0, 1) },
|
|
27215
27290
|
camera: { up: [0, 0, 1], position: initialCameraPosition },
|
|
27216
27291
|
children: [
|
|
27217
|
-
/* @__PURE__ */
|
|
27218
|
-
isInteractionEnabled && /* @__PURE__ */
|
|
27292
|
+
/* @__PURE__ */ jsx12(RotationTracker, {}),
|
|
27293
|
+
isInteractionEnabled && /* @__PURE__ */ jsx12(
|
|
27219
27294
|
OrbitControls,
|
|
27220
27295
|
{
|
|
27221
27296
|
autoRotate: !autoRotateDisabled,
|
|
@@ -27229,8 +27304,8 @@ var CadViewerContainer = forwardRef2(
|
|
|
27229
27304
|
target: orbitTarget
|
|
27230
27305
|
}
|
|
27231
27306
|
),
|
|
27232
|
-
/* @__PURE__ */
|
|
27233
|
-
/* @__PURE__ */
|
|
27307
|
+
/* @__PURE__ */ jsx12(Lights, {}),
|
|
27308
|
+
/* @__PURE__ */ jsx12(
|
|
27234
27309
|
Grid,
|
|
27235
27310
|
{
|
|
27236
27311
|
rotation: [Math.PI / 2, 0, 0],
|
|
@@ -27262,7 +27337,7 @@ var CadViewerContainer = forwardRef2(
|
|
|
27262
27337
|
]
|
|
27263
27338
|
}
|
|
27264
27339
|
),
|
|
27265
|
-
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */
|
|
27340
|
+
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx12(
|
|
27266
27341
|
"button",
|
|
27267
27342
|
{
|
|
27268
27343
|
type: "button",
|
|
@@ -27281,7 +27356,7 @@ var CadViewerContainer = forwardRef2(
|
|
|
27281
27356
|
alignItems: "center",
|
|
27282
27357
|
justifyContent: "center"
|
|
27283
27358
|
},
|
|
27284
|
-
children: /* @__PURE__ */
|
|
27359
|
+
children: /* @__PURE__ */ jsx12(
|
|
27285
27360
|
"div",
|
|
27286
27361
|
{
|
|
27287
27362
|
style: {
|
|
@@ -27304,9 +27379,9 @@ var CadViewerContainer = forwardRef2(
|
|
|
27304
27379
|
|
|
27305
27380
|
// src/hooks/use-convert-children-to-soup.ts
|
|
27306
27381
|
import { Circuit } from "@tscircuit/core";
|
|
27307
|
-
import { useMemo as
|
|
27382
|
+
import { useMemo as useMemo15 } from "react";
|
|
27308
27383
|
var useConvertChildrenToCircuitJson = (children) => {
|
|
27309
|
-
return
|
|
27384
|
+
return useMemo15(() => {
|
|
27310
27385
|
if (!children) return [];
|
|
27311
27386
|
const circuit = new Circuit();
|
|
27312
27387
|
circuit.add(children);
|
|
@@ -27316,21 +27391,23 @@ var useConvertChildrenToCircuitJson = (children) => {
|
|
|
27316
27391
|
};
|
|
27317
27392
|
|
|
27318
27393
|
// src/hooks/use-stls-from-geom.ts
|
|
27319
|
-
import { useState as
|
|
27394
|
+
import { useState as useState9, useEffect as useEffect17 } from "react";
|
|
27320
27395
|
import stlSerializer from "@jscad/stl-serializer";
|
|
27321
27396
|
var useStlsFromGeom = (geom) => {
|
|
27322
|
-
const [stls, setStls] =
|
|
27323
|
-
const [loading, setLoading] =
|
|
27324
|
-
|
|
27397
|
+
const [stls, setStls] = useState9([]);
|
|
27398
|
+
const [loading, setLoading] = useState9(true);
|
|
27399
|
+
useEffect17(() => {
|
|
27325
27400
|
if (!geom) return;
|
|
27326
27401
|
const generateStls = async () => {
|
|
27327
27402
|
setLoading(true);
|
|
27328
27403
|
const geometries = Array.isArray(geom) ? geom : [geom];
|
|
27329
|
-
const stlPromises = geometries.map(async (g) => {
|
|
27404
|
+
const stlPromises = geometries.map(async (g, index) => {
|
|
27330
27405
|
const rawParts = stlSerializer.serialize({ binary: true }, [g]);
|
|
27331
27406
|
const blob = new Blob(rawParts);
|
|
27332
27407
|
const stlData = await blob.arrayBuffer();
|
|
27333
|
-
|
|
27408
|
+
const layerType = g.layerType;
|
|
27409
|
+
const inferredLayerType = layerType || (index === 0 ? "board" : void 0);
|
|
27410
|
+
return { stlData, color: g.color, layerType: inferredLayerType };
|
|
27334
27411
|
});
|
|
27335
27412
|
try {
|
|
27336
27413
|
const generatedStls = await Promise.all(stlPromises);
|
|
@@ -27348,7 +27425,7 @@ var useStlsFromGeom = (geom) => {
|
|
|
27348
27425
|
};
|
|
27349
27426
|
|
|
27350
27427
|
// src/hooks/useBoardGeomBuilder.ts
|
|
27351
|
-
import { useState as
|
|
27428
|
+
import { useState as useState10, useEffect as useEffect18, useRef as useRef6 } from "react";
|
|
27352
27429
|
|
|
27353
27430
|
// src/soup-to-3d/index.ts
|
|
27354
27431
|
var import_primitives2 = __toESM(require_primitives(), 1);
|
|
@@ -27475,7 +27552,7 @@ function extractRectBorderRadius(source) {
|
|
|
27475
27552
|
}
|
|
27476
27553
|
|
|
27477
27554
|
// src/geoms/plated-hole.ts
|
|
27478
|
-
var platedHoleLipHeight = 0.
|
|
27555
|
+
var platedHoleLipHeight = 0.02;
|
|
27479
27556
|
var RECT_PAD_SEGMENTS = 64;
|
|
27480
27557
|
var maybeClip = (geom, clipGeom) => clipGeom ? (0, import_booleans.intersect)(clipGeom, geom) : geom;
|
|
27481
27558
|
var createRectPadGeom = ({
|
|
@@ -27504,7 +27581,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27504
27581
|
const throughDrillHeight = ctx.pcbThickness + 2 * platedHoleLipHeight + 4 * M;
|
|
27505
27582
|
if (plated_hole.shape === "circle") {
|
|
27506
27583
|
const outerDiameter = plated_hole.outer_diameter ?? Math.max(plated_hole.hole_diameter, 0);
|
|
27507
|
-
const copperHeight = ctx.pcbThickness + 2 *
|
|
27584
|
+
const copperHeight = ctx.pcbThickness + 2 * platedHoleLipHeight;
|
|
27508
27585
|
const copperBody = (0, import_primitives3.cylinder)({
|
|
27509
27586
|
center: [plated_hole.x, plated_hole.y, 0],
|
|
27510
27587
|
radius: outerDiameter / 2,
|
|
@@ -27530,7 +27607,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27530
27607
|
createRectPadGeom({
|
|
27531
27608
|
width: padWidth,
|
|
27532
27609
|
height: padHeight,
|
|
27533
|
-
thickness: platedHoleLipHeight
|
|
27610
|
+
thickness: platedHoleLipHeight,
|
|
27534
27611
|
// Slightly thicker to ensure connection
|
|
27535
27612
|
center: [
|
|
27536
27613
|
plated_hole.x,
|
|
@@ -27544,7 +27621,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27544
27621
|
createRectPadGeom({
|
|
27545
27622
|
width: padWidth,
|
|
27546
27623
|
height: padHeight,
|
|
27547
|
-
thickness: platedHoleLipHeight
|
|
27624
|
+
thickness: platedHoleLipHeight,
|
|
27548
27625
|
// Slightly thicker to ensure connection
|
|
27549
27626
|
center: [
|
|
27550
27627
|
plated_hole.x,
|
|
@@ -27696,11 +27773,11 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27696
27773
|
size: shouldRotate ? [
|
|
27697
27774
|
holeHeight + 2 * barrelMargin,
|
|
27698
27775
|
rectLength + 2 * barrelMargin,
|
|
27699
|
-
ctx.pcbThickness + 0.
|
|
27776
|
+
ctx.pcbThickness + 0.02
|
|
27700
27777
|
] : [
|
|
27701
27778
|
rectLength + 2 * barrelMargin,
|
|
27702
27779
|
holeHeight + 2 * barrelMargin,
|
|
27703
|
-
ctx.pcbThickness
|
|
27780
|
+
ctx.pcbThickness
|
|
27704
27781
|
]
|
|
27705
27782
|
}),
|
|
27706
27783
|
(0, import_primitives3.cylinder)({
|
|
@@ -27714,8 +27791,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27714
27791
|
0
|
|
27715
27792
|
],
|
|
27716
27793
|
radius: holeRadius + barrelMargin,
|
|
27717
|
-
height: ctx.pcbThickness + 0.
|
|
27718
|
-
// extend slightly above/below PCB
|
|
27794
|
+
height: ctx.pcbThickness + 0.02
|
|
27719
27795
|
}),
|
|
27720
27796
|
(0, import_primitives3.cylinder)({
|
|
27721
27797
|
center: shouldRotate ? [
|
|
@@ -27728,7 +27804,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27728
27804
|
0
|
|
27729
27805
|
],
|
|
27730
27806
|
radius: holeRadius + barrelMargin,
|
|
27731
|
-
height: ctx.pcbThickness + 0.
|
|
27807
|
+
height: ctx.pcbThickness + 0.02
|
|
27732
27808
|
})
|
|
27733
27809
|
);
|
|
27734
27810
|
const holeCut = (0, import_booleans.union)(
|
|
@@ -27763,30 +27839,41 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27763
27839
|
height: throughDrillHeight * 1.1
|
|
27764
27840
|
})
|
|
27765
27841
|
);
|
|
27766
|
-
const
|
|
27842
|
+
const copperTopPad = createRectPadGeom({
|
|
27767
27843
|
width: padWidth,
|
|
27768
27844
|
height: padHeight,
|
|
27769
|
-
thickness:
|
|
27770
|
-
center: [
|
|
27845
|
+
thickness: platedHoleLipHeight,
|
|
27846
|
+
center: [
|
|
27847
|
+
plated_hole.x,
|
|
27848
|
+
plated_hole.y,
|
|
27849
|
+
ctx.pcbThickness / 2 + platedHoleLipHeight / 2 + M - 0.05
|
|
27850
|
+
],
|
|
27771
27851
|
borderRadius: rectBorderRadius
|
|
27772
27852
|
});
|
|
27773
|
-
const
|
|
27774
|
-
|
|
27775
|
-
|
|
27776
|
-
|
|
27777
|
-
|
|
27778
|
-
|
|
27779
|
-
|
|
27853
|
+
const copperBottomPad = createRectPadGeom({
|
|
27854
|
+
width: padWidth,
|
|
27855
|
+
height: padHeight,
|
|
27856
|
+
thickness: platedHoleLipHeight,
|
|
27857
|
+
center: [
|
|
27858
|
+
plated_hole.x,
|
|
27859
|
+
plated_hole.y,
|
|
27860
|
+
-ctx.pcbThickness / 2 - platedHoleLipHeight / 2 - M + 0.05
|
|
27861
|
+
],
|
|
27862
|
+
borderRadius: rectBorderRadius
|
|
27863
|
+
});
|
|
27864
|
+
const copperFill = (() => {
|
|
27865
|
+
const height10 = ctx.pcbThickness - platedHoleLipHeight * 2 - M * 2 + 0.1;
|
|
27866
|
+
const rect2d = (0, import_primitives3.roundedRectangle)({
|
|
27867
|
+
size: [padWidth, padHeight],
|
|
27868
|
+
roundRadius: rectBorderRadius || 0,
|
|
27869
|
+
segments: RECT_PAD_SEGMENTS
|
|
27780
27870
|
});
|
|
27781
|
-
|
|
27782
|
-
|
|
27783
|
-
|
|
27784
|
-
|
|
27785
|
-
);
|
|
27786
|
-
const
|
|
27787
|
-
-ctx.pcbThickness / 2 + platedHoleLipHeight / 2 - 0.05
|
|
27788
|
-
);
|
|
27789
|
-
const filledArea = (0, import_booleans.subtract)(mainFill, holeCut);
|
|
27871
|
+
const extruded = (0, import_extrusions2.extrudeLinear)({ height: height10 }, rect2d);
|
|
27872
|
+
return (0, import_transforms2.translate)([plated_hole.x, plated_hole.y, -height10 / 2], extruded);
|
|
27873
|
+
})();
|
|
27874
|
+
const copperTopPadCut = (0, import_booleans.subtract)(copperTopPad, holeCut);
|
|
27875
|
+
const copperBottomPadCut = (0, import_booleans.subtract)(copperBottomPad, holeCut);
|
|
27876
|
+
const copperFillCut = (0, import_booleans.subtract)(copperFill, holeCut);
|
|
27790
27877
|
const barrelHoleCut = (0, import_booleans.union)(
|
|
27791
27878
|
(0, import_primitives3.cuboid)({
|
|
27792
27879
|
center: [plated_hole.x + holeOffsetX, plated_hole.y + holeOffsetY, 0],
|
|
@@ -27820,9 +27907,11 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
27820
27907
|
})
|
|
27821
27908
|
);
|
|
27822
27909
|
const barrelWithHole = (0, import_booleans.subtract)(barrel, barrelHoleCut);
|
|
27823
|
-
const finalCopper = (
|
|
27824
|
-
|
|
27825
|
-
|
|
27910
|
+
const finalCopper = maybeClip(
|
|
27911
|
+
(0, import_booleans.union)(copperTopPadCut, copperBottomPadCut, copperFillCut, barrelWithHole),
|
|
27912
|
+
clipGeom
|
|
27913
|
+
);
|
|
27914
|
+
return (0, import_colors2.colorize)(colors.copper, finalCopper);
|
|
27826
27915
|
} else {
|
|
27827
27916
|
throw new Error(`Unsupported plated hole shape: ${plated_hole.shape}`);
|
|
27828
27917
|
}
|
|
@@ -28660,111 +28749,80 @@ var BoardGeomBuilder = class {
|
|
|
28660
28749
|
}
|
|
28661
28750
|
processHole(hole) {
|
|
28662
28751
|
if (!this.boardGeom) return;
|
|
28752
|
+
const holeDepth = this.ctx.pcbThickness * 1.5;
|
|
28753
|
+
const copperInset = 0.02;
|
|
28663
28754
|
if (hole.hole_shape === "round" || hole.hole_shape === "circle") {
|
|
28664
28755
|
const cyGeom = (0, import_primitives6.cylinder)({
|
|
28665
28756
|
center: [hole.x, hole.y, 0],
|
|
28666
28757
|
radius: hole.hole_diameter / 2 + M,
|
|
28667
|
-
|
|
28668
|
-
height: this.ctx.pcbThickness * 1.5
|
|
28669
|
-
// Ensure it cuts through
|
|
28758
|
+
height: holeDepth
|
|
28670
28759
|
});
|
|
28671
28760
|
this.boardGeom = (0, import_booleans3.subtract)(this.boardGeom, cyGeom);
|
|
28672
28761
|
this.padGeoms = this.padGeoms.map(
|
|
28673
28762
|
(pg) => (0, import_colors4.colorize)(colors.copper, (0, import_booleans3.subtract)(pg, cyGeom))
|
|
28674
28763
|
);
|
|
28675
|
-
|
|
28764
|
+
const copperCut = (0, import_primitives6.cylinder)({
|
|
28765
|
+
center: [hole.x, hole.y, 0],
|
|
28766
|
+
radius: hole.hole_diameter / 2 + M / 2,
|
|
28767
|
+
height: holeDepth
|
|
28768
|
+
});
|
|
28769
|
+
this.platedHoleGeoms = this.platedHoleGeoms.map(
|
|
28770
|
+
(phg) => (0, import_colors4.colorize)(colors.copper, (0, import_booleans3.subtract)(phg, copperCut))
|
|
28771
|
+
);
|
|
28772
|
+
} else if (hole.hole_shape === "pill" || hole.hole_shape === "rotated_pill") {
|
|
28676
28773
|
const holeWidth = hole.hole_width;
|
|
28677
28774
|
const holeHeight = hole.hole_height;
|
|
28678
28775
|
const holeRadius = Math.min(holeWidth, holeHeight) / 2;
|
|
28679
28776
|
const rectLength = Math.abs(holeWidth - holeHeight);
|
|
28777
|
+
const isRotated = hole.hole_shape === "rotated_pill";
|
|
28680
28778
|
let pillHole;
|
|
28681
28779
|
if (holeWidth > holeHeight) {
|
|
28682
28780
|
pillHole = (0, import_booleans3.union)(
|
|
28683
28781
|
(0, import_primitives6.cuboid)({
|
|
28684
28782
|
center: [hole.x, hole.y, 0],
|
|
28685
|
-
size: [rectLength, holeHeight,
|
|
28783
|
+
size: [rectLength, holeHeight, holeDepth]
|
|
28686
28784
|
}),
|
|
28687
28785
|
(0, import_primitives6.cylinder)({
|
|
28688
28786
|
center: [hole.x - rectLength / 2, hole.y, 0],
|
|
28689
28787
|
radius: holeRadius,
|
|
28690
|
-
height:
|
|
28788
|
+
height: holeDepth
|
|
28691
28789
|
}),
|
|
28692
28790
|
(0, import_primitives6.cylinder)({
|
|
28693
28791
|
center: [hole.x + rectLength / 2, hole.y, 0],
|
|
28694
28792
|
radius: holeRadius,
|
|
28695
|
-
height:
|
|
28793
|
+
height: holeDepth
|
|
28696
28794
|
})
|
|
28697
28795
|
);
|
|
28698
28796
|
} else {
|
|
28699
28797
|
pillHole = (0, import_booleans3.union)(
|
|
28700
28798
|
(0, import_primitives6.cuboid)({
|
|
28701
28799
|
center: [hole.x, hole.y, 0],
|
|
28702
|
-
size: [holeWidth, rectLength,
|
|
28800
|
+
size: [holeWidth, rectLength, holeDepth]
|
|
28703
28801
|
}),
|
|
28704
28802
|
(0, import_primitives6.cylinder)({
|
|
28705
28803
|
center: [hole.x, hole.y - rectLength / 2, 0],
|
|
28706
28804
|
radius: holeRadius,
|
|
28707
|
-
height:
|
|
28805
|
+
height: holeDepth
|
|
28708
28806
|
}),
|
|
28709
28807
|
(0, import_primitives6.cylinder)({
|
|
28710
28808
|
center: [hole.x, hole.y + rectLength / 2, 0],
|
|
28711
28809
|
radius: holeRadius,
|
|
28712
|
-
height:
|
|
28810
|
+
height: holeDepth
|
|
28713
28811
|
})
|
|
28714
28812
|
);
|
|
28715
28813
|
}
|
|
28716
|
-
|
|
28717
|
-
|
|
28718
|
-
|
|
28719
|
-
);
|
|
28720
|
-
} else if (hole.hole_shape === "rotated_pill") {
|
|
28721
|
-
const holeWidth = hole.hole_width;
|
|
28722
|
-
const holeHeight = hole.hole_height;
|
|
28723
|
-
const holeRadius = Math.min(holeWidth, holeHeight) / 2;
|
|
28724
|
-
const rectLength = Math.abs(holeWidth - holeHeight);
|
|
28725
|
-
let pillHole;
|
|
28726
|
-
if (holeWidth > holeHeight) {
|
|
28727
|
-
pillHole = (0, import_booleans3.union)(
|
|
28728
|
-
(0, import_primitives6.cuboid)({
|
|
28729
|
-
center: [0, 0, 0],
|
|
28730
|
-
size: [rectLength, holeHeight, this.ctx.pcbThickness * 1.5]
|
|
28731
|
-
}),
|
|
28732
|
-
(0, import_primitives6.cylinder)({
|
|
28733
|
-
center: [-rectLength / 2, 0, 0],
|
|
28734
|
-
radius: holeRadius,
|
|
28735
|
-
height: this.ctx.pcbThickness * 1.5
|
|
28736
|
-
}),
|
|
28737
|
-
(0, import_primitives6.cylinder)({
|
|
28738
|
-
center: [rectLength / 2, 0, 0],
|
|
28739
|
-
radius: holeRadius,
|
|
28740
|
-
height: this.ctx.pcbThickness * 1.5
|
|
28741
|
-
})
|
|
28742
|
-
);
|
|
28743
|
-
} else {
|
|
28744
|
-
pillHole = (0, import_booleans3.union)(
|
|
28745
|
-
(0, import_primitives6.cuboid)({
|
|
28746
|
-
center: [0, 0, 0],
|
|
28747
|
-
size: [holeWidth, rectLength, this.ctx.pcbThickness * 1.5]
|
|
28748
|
-
}),
|
|
28749
|
-
(0, import_primitives6.cylinder)({
|
|
28750
|
-
center: [0, -rectLength / 2, 0],
|
|
28751
|
-
radius: holeRadius,
|
|
28752
|
-
height: this.ctx.pcbThickness * 1.5
|
|
28753
|
-
}),
|
|
28754
|
-
(0, import_primitives6.cylinder)({
|
|
28755
|
-
center: [0, rectLength / 2, 0],
|
|
28756
|
-
radius: holeRadius,
|
|
28757
|
-
height: this.ctx.pcbThickness * 1.5
|
|
28758
|
-
})
|
|
28759
|
-
);
|
|
28814
|
+
if (isRotated) {
|
|
28815
|
+
const rotationRadians = hole.ccw_rotation * Math.PI / 180;
|
|
28816
|
+
pillHole = (0, import_transforms4.rotateZ)(rotationRadians, pillHole);
|
|
28760
28817
|
}
|
|
28761
|
-
const rotationRadians = hole.ccw_rotation * Math.PI / 180;
|
|
28762
|
-
pillHole = (0, import_transforms4.rotateZ)(rotationRadians, pillHole);
|
|
28763
|
-
pillHole = (0, import_transforms4.translate)([hole.x, hole.y, 0], pillHole);
|
|
28764
28818
|
this.boardGeom = (0, import_booleans3.subtract)(this.boardGeom, pillHole);
|
|
28765
28819
|
this.padGeoms = this.padGeoms.map(
|
|
28766
28820
|
(pg) => (0, import_colors4.colorize)(colors.copper, (0, import_booleans3.subtract)(pg, pillHole))
|
|
28767
28821
|
);
|
|
28822
|
+
const copperPill = (0, import_expansions3.expand)({ delta: -copperInset }, pillHole);
|
|
28823
|
+
this.platedHoleGeoms = this.platedHoleGeoms.map(
|
|
28824
|
+
(phg) => (0, import_colors4.colorize)(colors.copper, (0, import_booleans3.subtract)(phg, copperPill))
|
|
28825
|
+
);
|
|
28768
28826
|
}
|
|
28769
28827
|
}
|
|
28770
28828
|
processPad(pad2) {
|
|
@@ -28986,9 +29044,9 @@ var BoardGeomBuilder = class {
|
|
|
28986
29044
|
|
|
28987
29045
|
// src/hooks/useBoardGeomBuilder.ts
|
|
28988
29046
|
var useBoardGeomBuilder = (circuitJson) => {
|
|
28989
|
-
const [boardGeom, setBoardGeom] =
|
|
29047
|
+
const [boardGeom, setBoardGeom] = useState10(null);
|
|
28990
29048
|
const isProcessingRef = useRef6(false);
|
|
28991
|
-
|
|
29049
|
+
useEffect18(() => {
|
|
28992
29050
|
let isCancelled = false;
|
|
28993
29051
|
if (!circuitJson) {
|
|
28994
29052
|
setBoardGeom(null);
|
|
@@ -29031,17 +29089,17 @@ var useBoardGeomBuilder = (circuitJson) => {
|
|
|
29031
29089
|
};
|
|
29032
29090
|
|
|
29033
29091
|
// src/three-components/Error3d.tsx
|
|
29034
|
-
import { useState as
|
|
29092
|
+
import { useState as useState11, useCallback as useCallback5, useEffect as useEffect19, useMemo as useMemo16 } from "react";
|
|
29035
29093
|
import * as THREE14 from "three";
|
|
29036
|
-
import { Fragment as Fragment5, jsx as
|
|
29094
|
+
import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
29037
29095
|
var Error3d = ({
|
|
29038
29096
|
error,
|
|
29039
29097
|
cad_component: cad_component2
|
|
29040
29098
|
}) => {
|
|
29041
29099
|
const { rootObject } = useThree();
|
|
29042
|
-
const [isHovered, setIsHovered] =
|
|
29043
|
-
const [hoverPosition, setHoverPosition] =
|
|
29044
|
-
const handleHover =
|
|
29100
|
+
const [isHovered, setIsHovered] = useState11(false);
|
|
29101
|
+
const [hoverPosition, setHoverPosition] = useState11(null);
|
|
29102
|
+
const handleHover = useCallback5((e) => {
|
|
29045
29103
|
if (e?.mousePosition) {
|
|
29046
29104
|
setIsHovered(true);
|
|
29047
29105
|
setHoverPosition(e.mousePosition);
|
|
@@ -29050,11 +29108,11 @@ var Error3d = ({
|
|
|
29050
29108
|
setHoverPosition(null);
|
|
29051
29109
|
}
|
|
29052
29110
|
}, []);
|
|
29053
|
-
const handleUnhover =
|
|
29111
|
+
const handleUnhover = useCallback5(() => {
|
|
29054
29112
|
setIsHovered(false);
|
|
29055
29113
|
setHoverPosition(null);
|
|
29056
29114
|
}, []);
|
|
29057
|
-
const position =
|
|
29115
|
+
const position = useMemo16(() => {
|
|
29058
29116
|
if (cad_component2?.position) {
|
|
29059
29117
|
const p = [
|
|
29060
29118
|
cad_component2.position.x,
|
|
@@ -29065,12 +29123,12 @@ var Error3d = ({
|
|
|
29065
29123
|
}
|
|
29066
29124
|
return [0, 0, 0];
|
|
29067
29125
|
}, [cad_component2]);
|
|
29068
|
-
const group =
|
|
29126
|
+
const group = useMemo16(() => {
|
|
29069
29127
|
const g = new THREE14.Group();
|
|
29070
29128
|
g.position.fromArray(position);
|
|
29071
29129
|
return g;
|
|
29072
29130
|
}, [position]);
|
|
29073
|
-
|
|
29131
|
+
useEffect19(() => {
|
|
29074
29132
|
if (!rootObject) return;
|
|
29075
29133
|
rootObject.add(group);
|
|
29076
29134
|
return () => {
|
|
@@ -29086,8 +29144,8 @@ var Error3d = ({
|
|
|
29086
29144
|
onUnhover: handleUnhover,
|
|
29087
29145
|
object: group,
|
|
29088
29146
|
children: [
|
|
29089
|
-
/* @__PURE__ */
|
|
29090
|
-
/* @__PURE__ */
|
|
29147
|
+
/* @__PURE__ */ jsx13(ErrorBox, { parent: group }),
|
|
29148
|
+
/* @__PURE__ */ jsx13(
|
|
29091
29149
|
Text,
|
|
29092
29150
|
{
|
|
29093
29151
|
parent: group,
|
|
@@ -29102,7 +29160,7 @@ var Error3d = ({
|
|
|
29102
29160
|
]
|
|
29103
29161
|
}
|
|
29104
29162
|
),
|
|
29105
|
-
isHovered && hoverPosition ? /* @__PURE__ */
|
|
29163
|
+
isHovered && hoverPosition ? /* @__PURE__ */ jsx13(
|
|
29106
29164
|
Html,
|
|
29107
29165
|
{
|
|
29108
29166
|
position: hoverPosition,
|
|
@@ -29125,7 +29183,7 @@ var Error3d = ({
|
|
|
29125
29183
|
] });
|
|
29126
29184
|
};
|
|
29127
29185
|
var ErrorBox = ({ parent }) => {
|
|
29128
|
-
const mesh =
|
|
29186
|
+
const mesh = useMemo16(() => {
|
|
29129
29187
|
const m = new THREE14.Mesh(
|
|
29130
29188
|
new THREE14.BoxGeometry(0.5, 0.5, 0.5),
|
|
29131
29189
|
new THREE14.MeshStandardMaterial({
|
|
@@ -29139,7 +29197,7 @@ var ErrorBox = ({ parent }) => {
|
|
|
29139
29197
|
m.rotation.fromArray([Math.PI / 4, Math.PI / 4, 0]);
|
|
29140
29198
|
return m;
|
|
29141
29199
|
}, []);
|
|
29142
|
-
|
|
29200
|
+
useEffect19(() => {
|
|
29143
29201
|
parent.add(mesh);
|
|
29144
29202
|
return () => {
|
|
29145
29203
|
parent.remove(mesh);
|
|
@@ -29149,7 +29207,7 @@ var ErrorBox = ({ parent }) => {
|
|
|
29149
29207
|
};
|
|
29150
29208
|
|
|
29151
29209
|
// src/three-components/STLModel.tsx
|
|
29152
|
-
import { useState as
|
|
29210
|
+
import { useState as useState12, useEffect as useEffect20, useMemo as useMemo17 } from "react";
|
|
29153
29211
|
import * as THREE15 from "three";
|
|
29154
29212
|
import { STLLoader } from "three-stdlib";
|
|
29155
29213
|
function STLModel({
|
|
@@ -29160,8 +29218,8 @@ function STLModel({
|
|
|
29160
29218
|
opacity = 1
|
|
29161
29219
|
}) {
|
|
29162
29220
|
const { rootObject } = useThree();
|
|
29163
|
-
const [geom, setGeom] =
|
|
29164
|
-
|
|
29221
|
+
const [geom, setGeom] = useState12(null);
|
|
29222
|
+
useEffect20(() => {
|
|
29165
29223
|
const loader = new STLLoader();
|
|
29166
29224
|
if (stlData) {
|
|
29167
29225
|
try {
|
|
@@ -29179,7 +29237,7 @@ function STLModel({
|
|
|
29179
29237
|
});
|
|
29180
29238
|
}
|
|
29181
29239
|
}, [stlUrl, stlData]);
|
|
29182
|
-
const mesh =
|
|
29240
|
+
const mesh = useMemo17(() => {
|
|
29183
29241
|
if (!geom) return null;
|
|
29184
29242
|
const material = new THREE15.MeshStandardMaterial({
|
|
29185
29243
|
color: Array.isArray(color) ? new THREE15.Color(color[0], color[1], color[2]) : color,
|
|
@@ -29188,7 +29246,7 @@ function STLModel({
|
|
|
29188
29246
|
});
|
|
29189
29247
|
return new THREE15.Mesh(geom, material);
|
|
29190
29248
|
}, [geom, color, opacity]);
|
|
29191
|
-
|
|
29249
|
+
useEffect20(() => {
|
|
29192
29250
|
if (!rootObject || !mesh) return;
|
|
29193
29251
|
rootObject.add(mesh);
|
|
29194
29252
|
return () => {
|
|
@@ -29204,9 +29262,36 @@ function STLModel({
|
|
|
29204
29262
|
return null;
|
|
29205
29263
|
}
|
|
29206
29264
|
|
|
29265
|
+
// src/three-components/VisibleSTLModel.tsx
|
|
29266
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
29267
|
+
function VisibleSTLModel({
|
|
29268
|
+
stlData,
|
|
29269
|
+
color,
|
|
29270
|
+
opacity = 1,
|
|
29271
|
+
layerType
|
|
29272
|
+
}) {
|
|
29273
|
+
const { visibility } = useLayerVisibility();
|
|
29274
|
+
let shouldShow = true;
|
|
29275
|
+
if (layerType === "board") {
|
|
29276
|
+
shouldShow = visibility.boardBody;
|
|
29277
|
+
} else if (layerType === "top-copper") {
|
|
29278
|
+
shouldShow = visibility.topCopper;
|
|
29279
|
+
} else if (layerType === "bottom-copper") {
|
|
29280
|
+
shouldShow = visibility.bottomCopper;
|
|
29281
|
+
} else if (layerType === "top-silkscreen") {
|
|
29282
|
+
shouldShow = visibility.topSilkscreen;
|
|
29283
|
+
} else if (layerType === "bottom-silkscreen") {
|
|
29284
|
+
shouldShow = visibility.bottomSilkscreen;
|
|
29285
|
+
}
|
|
29286
|
+
if (!shouldShow) {
|
|
29287
|
+
return null;
|
|
29288
|
+
}
|
|
29289
|
+
return /* @__PURE__ */ jsx14(STLModel, { stlData, color, opacity });
|
|
29290
|
+
}
|
|
29291
|
+
|
|
29207
29292
|
// src/three-components/ThreeErrorBoundary.tsx
|
|
29208
|
-
import
|
|
29209
|
-
var ThreeErrorBoundary = class extends
|
|
29293
|
+
import React11 from "react";
|
|
29294
|
+
var ThreeErrorBoundary = class extends React11.Component {
|
|
29210
29295
|
constructor(props) {
|
|
29211
29296
|
super(props);
|
|
29212
29297
|
this.state = { hasError: false, error: null };
|
|
@@ -29223,7 +29308,7 @@ var ThreeErrorBoundary = class extends React10.Component {
|
|
|
29223
29308
|
};
|
|
29224
29309
|
|
|
29225
29310
|
// src/CadViewerJscad.tsx
|
|
29226
|
-
import { jsx as
|
|
29311
|
+
import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
29227
29312
|
var CadViewerJscad = forwardRef3(
|
|
29228
29313
|
({
|
|
29229
29314
|
soup,
|
|
@@ -29234,12 +29319,12 @@ var CadViewerJscad = forwardRef3(
|
|
|
29234
29319
|
onUserInteraction
|
|
29235
29320
|
}, ref) => {
|
|
29236
29321
|
const childrenSoup = useConvertChildrenToCircuitJson(children);
|
|
29237
|
-
const internalCircuitJson =
|
|
29322
|
+
const internalCircuitJson = useMemo18(() => {
|
|
29238
29323
|
const cj = soup ?? circuitJson;
|
|
29239
29324
|
return cj ?? childrenSoup;
|
|
29240
29325
|
}, [soup, circuitJson, childrenSoup]);
|
|
29241
29326
|
const boardGeom = useBoardGeomBuilder(internalCircuitJson);
|
|
29242
|
-
const initialCameraPosition =
|
|
29327
|
+
const initialCameraPosition = useMemo18(() => {
|
|
29243
29328
|
if (!internalCircuitJson) return [5, 5, 5];
|
|
29244
29329
|
try {
|
|
29245
29330
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29258,7 +29343,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
29258
29343
|
return [5, 5, 5];
|
|
29259
29344
|
}
|
|
29260
29345
|
}, [internalCircuitJson]);
|
|
29261
|
-
const boardDimensions =
|
|
29346
|
+
const boardDimensions = useMemo18(() => {
|
|
29262
29347
|
if (!internalCircuitJson) return void 0;
|
|
29263
29348
|
try {
|
|
29264
29349
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29269,7 +29354,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
29269
29354
|
return void 0;
|
|
29270
29355
|
}
|
|
29271
29356
|
}, [internalCircuitJson]);
|
|
29272
|
-
const boardCenter =
|
|
29357
|
+
const boardCenter = useMemo18(() => {
|
|
29273
29358
|
if (!internalCircuitJson) return void 0;
|
|
29274
29359
|
try {
|
|
29275
29360
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29293,20 +29378,21 @@ var CadViewerJscad = forwardRef3(
|
|
|
29293
29378
|
boardCenter,
|
|
29294
29379
|
onUserInteraction,
|
|
29295
29380
|
children: [
|
|
29296
|
-
boardStls.map(({ stlData, color }, index) => /* @__PURE__ */
|
|
29297
|
-
|
|
29381
|
+
boardStls.map(({ stlData, color, layerType }, index) => /* @__PURE__ */ jsx15(
|
|
29382
|
+
VisibleSTLModel,
|
|
29298
29383
|
{
|
|
29299
29384
|
stlData,
|
|
29300
29385
|
color,
|
|
29301
|
-
opacity: index === 0 ? 0.95 : 1
|
|
29386
|
+
opacity: index === 0 ? 0.95 : 1,
|
|
29387
|
+
layerType
|
|
29302
29388
|
},
|
|
29303
|
-
`board-${index
|
|
29389
|
+
`board-${index}`
|
|
29304
29390
|
)),
|
|
29305
|
-
cad_components.map((cad_component2) => /* @__PURE__ */
|
|
29391
|
+
cad_components.map((cad_component2) => /* @__PURE__ */ jsx15(
|
|
29306
29392
|
ThreeErrorBoundary,
|
|
29307
29393
|
{
|
|
29308
|
-
fallback: ({ error }) => /* @__PURE__ */
|
|
29309
|
-
children: /* @__PURE__ */
|
|
29394
|
+
fallback: ({ error }) => /* @__PURE__ */ jsx15(Error3d, { cad_component: cad_component2, error }),
|
|
29395
|
+
children: /* @__PURE__ */ jsx15(
|
|
29310
29396
|
AnyCadComponent,
|
|
29311
29397
|
{
|
|
29312
29398
|
cad_component: cad_component2,
|
|
@@ -29325,10 +29411,10 @@ var CadViewerJscad = forwardRef3(
|
|
|
29325
29411
|
|
|
29326
29412
|
// src/CadViewerManifold.tsx
|
|
29327
29413
|
import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
29328
|
-
import { useEffect as
|
|
29414
|
+
import { useEffect as useEffect22, useMemo as useMemo20, useState as useState15 } from "react";
|
|
29329
29415
|
|
|
29330
29416
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
29331
|
-
import { useState as
|
|
29417
|
+
import { useState as useState14, useEffect as useEffect21, useMemo as useMemo19, useRef as useRef7 } from "react";
|
|
29332
29418
|
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
29333
29419
|
import * as THREE23 from "three";
|
|
29334
29420
|
|
|
@@ -29771,6 +29857,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
29771
29857
|
const platedHoleBoardDrills = [];
|
|
29772
29858
|
const pcbPlatedHoles = su8(circuitJson).pcb_plated_hole.list();
|
|
29773
29859
|
const platedHoleCopperGeoms = [];
|
|
29860
|
+
const platedHoleCopperOpsForSubtract = [];
|
|
29774
29861
|
const createPillOp = (width10, height10, depth) => {
|
|
29775
29862
|
const pillOp = createRoundedRectPrism({
|
|
29776
29863
|
Manifold,
|
|
@@ -29827,6 +29914,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
29827
29914
|
manifoldInstancesForCleanup.push(clipped);
|
|
29828
29915
|
finalCopperOp = clipped;
|
|
29829
29916
|
}
|
|
29917
|
+
platedHoleCopperOpsForSubtract.push(finalCopperOp);
|
|
29830
29918
|
const threeGeom = manifoldMeshToThreeGeometry(finalCopperOp.getMesh());
|
|
29831
29919
|
platedHoleCopperGeoms.push({
|
|
29832
29920
|
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
@@ -29878,9 +29966,17 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
29878
29966
|
}
|
|
29879
29967
|
const translatedPlatedPart = finalPlatedPartOp.translate([ph.x, ph.y, 0]);
|
|
29880
29968
|
manifoldInstancesForCleanup.push(translatedPlatedPart);
|
|
29881
|
-
|
|
29882
|
-
|
|
29883
|
-
|
|
29969
|
+
let finalCopperOp = translatedPlatedPart;
|
|
29970
|
+
if (boardClipVolume) {
|
|
29971
|
+
const clipped = Manifold.intersection([
|
|
29972
|
+
translatedPlatedPart,
|
|
29973
|
+
boardClipVolume
|
|
29974
|
+
]);
|
|
29975
|
+
manifoldInstancesForCleanup.push(clipped);
|
|
29976
|
+
finalCopperOp = clipped;
|
|
29977
|
+
}
|
|
29978
|
+
platedHoleCopperOpsForSubtract.push(finalCopperOp);
|
|
29979
|
+
const threeGeom = manifoldMeshToThreeGeometry(finalCopperOp.getMesh());
|
|
29884
29980
|
platedHoleCopperGeoms.push({
|
|
29885
29981
|
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
29886
29982
|
geometry: threeGeom,
|
|
@@ -29921,14 +30017,14 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
29921
30017
|
Manifold,
|
|
29922
30018
|
width: padWidth,
|
|
29923
30019
|
height: padHeight,
|
|
29924
|
-
thickness: padThickness
|
|
30020
|
+
thickness: padThickness,
|
|
29925
30021
|
borderRadius: rectBorderRadius
|
|
29926
30022
|
}).translate([0, 0, pcbThickness / 2 - padThickness / 2 + 0.05]);
|
|
29927
30023
|
const bottomPad = createRoundedRectPrism({
|
|
29928
30024
|
Manifold,
|
|
29929
30025
|
width: padWidth,
|
|
29930
30026
|
height: padHeight,
|
|
29931
|
-
thickness: padThickness
|
|
30027
|
+
thickness: padThickness,
|
|
29932
30028
|
borderRadius: rectBorderRadius
|
|
29933
30029
|
}).translate([0, 0, -pcbThickness / 2 + padThickness / 2 - 0.05]);
|
|
29934
30030
|
manifoldInstancesForCleanup.push(topPad, bottomPad);
|
|
@@ -29966,6 +30062,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
29966
30062
|
manifoldInstancesForCleanup.push(clipped);
|
|
29967
30063
|
finalCopperOp = clipped;
|
|
29968
30064
|
}
|
|
30065
|
+
platedHoleCopperOpsForSubtract.push(finalCopperOp);
|
|
29969
30066
|
const threeGeom = manifoldMeshToThreeGeometry(finalCopperOp.getMesh());
|
|
29970
30067
|
platedHoleCopperGeoms.push({
|
|
29971
30068
|
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
@@ -30005,14 +30102,14 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
30005
30102
|
Manifold,
|
|
30006
30103
|
width: padWidth,
|
|
30007
30104
|
height: padHeight,
|
|
30008
|
-
thickness: padThickness
|
|
30105
|
+
thickness: padThickness,
|
|
30009
30106
|
borderRadius: rectBorderRadius
|
|
30010
30107
|
}).translate([0, 0, pcbThickness / 2 - padThickness / 2 + 0.05]);
|
|
30011
30108
|
const bottomPad = createRoundedRectPrism({
|
|
30012
30109
|
Manifold,
|
|
30013
30110
|
width: padWidth,
|
|
30014
30111
|
height: padHeight,
|
|
30015
|
-
thickness: padThickness
|
|
30112
|
+
thickness: padThickness,
|
|
30016
30113
|
borderRadius: rectBorderRadius
|
|
30017
30114
|
}).translate([0, 0, -pcbThickness / 2 + padThickness / 2 - 0.05]);
|
|
30018
30115
|
manifoldInstancesForCleanup.push(topPad, bottomPad);
|
|
@@ -30054,6 +30151,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
30054
30151
|
manifoldInstancesForCleanup.push(clipped);
|
|
30055
30152
|
finalCopperOp = clipped;
|
|
30056
30153
|
}
|
|
30154
|
+
platedHoleCopperOpsForSubtract.push(finalCopperOp);
|
|
30057
30155
|
const threeGeom = manifoldMeshToThreeGeometry(finalCopperOp.getMesh());
|
|
30058
30156
|
platedHoleCopperGeoms.push({
|
|
30059
30157
|
key: `ph-${ph.pcb_plated_hole_id || index}`,
|
|
@@ -30062,7 +30160,12 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
30062
30160
|
});
|
|
30063
30161
|
}
|
|
30064
30162
|
});
|
|
30065
|
-
|
|
30163
|
+
let platedHoleSubtractOp = void 0;
|
|
30164
|
+
if (platedHoleCopperOpsForSubtract.length > 0) {
|
|
30165
|
+
platedHoleSubtractOp = Manifold.union(platedHoleCopperOpsForSubtract);
|
|
30166
|
+
manifoldInstancesForCleanup.push(platedHoleSubtractOp);
|
|
30167
|
+
}
|
|
30168
|
+
return { platedHoleBoardDrills, platedHoleCopperGeoms, platedHoleSubtractOp };
|
|
30066
30169
|
}
|
|
30067
30170
|
|
|
30068
30171
|
// src/utils/manifold/process-vias.ts
|
|
@@ -30182,7 +30285,7 @@ function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifold
|
|
|
30182
30285
|
}
|
|
30183
30286
|
const threeGeom = manifoldMeshToThreeGeometry(finalPadOp.getMesh());
|
|
30184
30287
|
smtPadGeoms.push({
|
|
30185
|
-
key: `
|
|
30288
|
+
key: `smt_pad-${pad2.layer || "top"}-${pad2.pcb_smtpad_id || index}`,
|
|
30186
30289
|
geometry: threeGeom,
|
|
30187
30290
|
color: COPPER_COLOR3
|
|
30188
30291
|
});
|
|
@@ -30521,20 +30624,20 @@ function processCutoutsForManifold(Manifold, CrossSection, circuitJson, pcbThick
|
|
|
30521
30624
|
|
|
30522
30625
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
30523
30626
|
var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
30524
|
-
const [geoms, setGeoms] =
|
|
30525
|
-
const [textures, setTextures] =
|
|
30526
|
-
const [pcbThickness, setPcbThickness] =
|
|
30527
|
-
const [error, setError] =
|
|
30528
|
-
const [isLoading, setIsLoading] =
|
|
30627
|
+
const [geoms, setGeoms] = useState14(null);
|
|
30628
|
+
const [textures, setTextures] = useState14(null);
|
|
30629
|
+
const [pcbThickness, setPcbThickness] = useState14(null);
|
|
30630
|
+
const [error, setError] = useState14(null);
|
|
30631
|
+
const [isLoading, setIsLoading] = useState14(true);
|
|
30529
30632
|
const manifoldInstancesForCleanup = useRef7([]);
|
|
30530
|
-
const boardData =
|
|
30633
|
+
const boardData = useMemo19(() => {
|
|
30531
30634
|
const boards = su12(circuitJson).pcb_board.list();
|
|
30532
30635
|
if (boards.length === 0) {
|
|
30533
30636
|
return null;
|
|
30534
30637
|
}
|
|
30535
30638
|
return boards[0];
|
|
30536
30639
|
}, [circuitJson]);
|
|
30537
|
-
|
|
30640
|
+
useEffect21(() => {
|
|
30538
30641
|
if (!manifoldJSModule || !boardData) {
|
|
30539
30642
|
setGeoms(null);
|
|
30540
30643
|
setTextures(null);
|
|
@@ -30615,7 +30718,12 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30615
30718
|
manifoldInstancesForCleanup.current
|
|
30616
30719
|
);
|
|
30617
30720
|
allBoardDrills.push(...nonPlatedHoleBoardDrills);
|
|
30618
|
-
const {
|
|
30721
|
+
const {
|
|
30722
|
+
platedHoleBoardDrills,
|
|
30723
|
+
platedHoleCopperGeoms,
|
|
30724
|
+
// NEW: bring in platedHoleSubtractOp
|
|
30725
|
+
platedHoleSubtractOp
|
|
30726
|
+
} = processPlatedHolesForManifold(
|
|
30619
30727
|
Manifold,
|
|
30620
30728
|
circuitJson,
|
|
30621
30729
|
currentPcbThickness,
|
|
@@ -30636,9 +30744,28 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30636
30744
|
if (allBoardDrills.length > 0) {
|
|
30637
30745
|
holeUnion = Manifold.union(allBoardDrills);
|
|
30638
30746
|
manifoldInstancesForCleanup.current.push(holeUnion);
|
|
30639
|
-
const
|
|
30747
|
+
const totalSubtractionOps = platedHoleSubtractOp ? Manifold.union([holeUnion, platedHoleSubtractOp]) : holeUnion;
|
|
30748
|
+
manifoldInstancesForCleanup.current.push(totalSubtractionOps);
|
|
30749
|
+
const nextBoardAfterDrills = currentBoardOp.subtract(totalSubtractionOps);
|
|
30640
30750
|
manifoldInstancesForCleanup.current.push(nextBoardAfterDrills);
|
|
30641
30751
|
currentBoardOp = nextBoardAfterDrills;
|
|
30752
|
+
if (platedHoleSubtractOp) {
|
|
30753
|
+
const cutPlatedCopper = platedHoleSubtractOp.subtract(holeUnion);
|
|
30754
|
+
manifoldInstancesForCleanup.current.push(cutPlatedCopper);
|
|
30755
|
+
const cutPlatedMesh = cutPlatedCopper.getMesh();
|
|
30756
|
+
const cutPlatedGeom = manifoldMeshToThreeGeometry(cutPlatedMesh);
|
|
30757
|
+
currentGeoms.platedHoles = [
|
|
30758
|
+
{
|
|
30759
|
+
key: "plated-holes-union",
|
|
30760
|
+
geometry: cutPlatedGeom,
|
|
30761
|
+
color: new THREE23.Color(
|
|
30762
|
+
colors.copper[0],
|
|
30763
|
+
colors.copper[1],
|
|
30764
|
+
colors.copper[2]
|
|
30765
|
+
)
|
|
30766
|
+
}
|
|
30767
|
+
];
|
|
30768
|
+
}
|
|
30642
30769
|
}
|
|
30643
30770
|
const { cutoutOps } = processCutoutsForManifold(
|
|
30644
30771
|
Manifold,
|
|
@@ -30880,21 +31007,64 @@ function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
|
30880
31007
|
}
|
|
30881
31008
|
|
|
30882
31009
|
// src/CadViewerManifold.tsx
|
|
30883
|
-
import { jsx as
|
|
31010
|
+
import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
30884
31011
|
var BoardMeshes = ({
|
|
30885
31012
|
geometryMeshes,
|
|
30886
31013
|
textureMeshes
|
|
30887
31014
|
}) => {
|
|
30888
31015
|
const { rootObject } = useThree();
|
|
30889
|
-
|
|
31016
|
+
const { visibility } = useLayerVisibility();
|
|
31017
|
+
useEffect22(() => {
|
|
30890
31018
|
if (!rootObject) return;
|
|
30891
|
-
geometryMeshes.forEach((mesh) =>
|
|
30892
|
-
|
|
31019
|
+
geometryMeshes.forEach((mesh) => {
|
|
31020
|
+
let shouldShow = true;
|
|
31021
|
+
if (mesh.name === "board-geom") {
|
|
31022
|
+
shouldShow = visibility.boardBody;
|
|
31023
|
+
} else if (mesh.name.includes("smt_pad")) {
|
|
31024
|
+
if (mesh.name.includes("smt_pad-top")) {
|
|
31025
|
+
shouldShow = visibility.topCopper;
|
|
31026
|
+
} else if (mesh.name.includes("smt_pad-bottom")) {
|
|
31027
|
+
shouldShow = visibility.bottomCopper;
|
|
31028
|
+
} else {
|
|
31029
|
+
shouldShow = visibility.topCopper || visibility.bottomCopper;
|
|
31030
|
+
}
|
|
31031
|
+
} else if (mesh.name.includes("plated_hole") || mesh.name.includes("via")) {
|
|
31032
|
+
shouldShow = visibility.topCopper || visibility.bottomCopper;
|
|
31033
|
+
} else if (mesh.name.includes("copper_pour")) {
|
|
31034
|
+
shouldShow = visibility.topCopper || visibility.bottomCopper;
|
|
31035
|
+
}
|
|
31036
|
+
if (shouldShow) {
|
|
31037
|
+
rootObject.add(mesh);
|
|
31038
|
+
}
|
|
31039
|
+
});
|
|
31040
|
+
textureMeshes.forEach((mesh) => {
|
|
31041
|
+
let shouldShow = true;
|
|
31042
|
+
if (mesh.name.includes("top-trace")) {
|
|
31043
|
+
shouldShow = visibility.topCopper;
|
|
31044
|
+
} else if (mesh.name.includes("bottom-trace")) {
|
|
31045
|
+
shouldShow = visibility.bottomCopper;
|
|
31046
|
+
} else if (mesh.name.includes("top-silkscreen")) {
|
|
31047
|
+
shouldShow = visibility.topSilkscreen;
|
|
31048
|
+
} else if (mesh.name.includes("bottom-silkscreen")) {
|
|
31049
|
+
shouldShow = visibility.bottomSilkscreen;
|
|
31050
|
+
}
|
|
31051
|
+
if (shouldShow) {
|
|
31052
|
+
rootObject.add(mesh);
|
|
31053
|
+
}
|
|
31054
|
+
});
|
|
30893
31055
|
return () => {
|
|
30894
|
-
geometryMeshes.forEach((mesh) =>
|
|
30895
|
-
|
|
31056
|
+
geometryMeshes.forEach((mesh) => {
|
|
31057
|
+
if (mesh.parent === rootObject) {
|
|
31058
|
+
rootObject.remove(mesh);
|
|
31059
|
+
}
|
|
31060
|
+
});
|
|
31061
|
+
textureMeshes.forEach((mesh) => {
|
|
31062
|
+
if (mesh.parent === rootObject) {
|
|
31063
|
+
rootObject.remove(mesh);
|
|
31064
|
+
}
|
|
31065
|
+
});
|
|
30896
31066
|
};
|
|
30897
|
-
}, [rootObject, geometryMeshes, textureMeshes]);
|
|
31067
|
+
}, [rootObject, geometryMeshes, textureMeshes, visibility]);
|
|
30898
31068
|
return null;
|
|
30899
31069
|
};
|
|
30900
31070
|
var MANIFOLD_CDN_BASE_URL = "https://cdn.jsdelivr.net/npm/manifold-3d@3.2.1";
|
|
@@ -30906,12 +31076,12 @@ var CadViewerManifold = ({
|
|
|
30906
31076
|
children
|
|
30907
31077
|
}) => {
|
|
30908
31078
|
const childrenCircuitJson = useConvertChildrenToCircuitJson(children);
|
|
30909
|
-
const circuitJson =
|
|
31079
|
+
const circuitJson = useMemo20(() => {
|
|
30910
31080
|
return circuitJsonProp ?? childrenCircuitJson;
|
|
30911
31081
|
}, [circuitJsonProp, childrenCircuitJson]);
|
|
30912
|
-
const [manifoldJSModule, setManifoldJSModule] =
|
|
30913
|
-
const [manifoldLoadingError, setManifoldLoadingError] =
|
|
30914
|
-
|
|
31082
|
+
const [manifoldJSModule, setManifoldJSModule] = useState15(null);
|
|
31083
|
+
const [manifoldLoadingError, setManifoldLoadingError] = useState15(null);
|
|
31084
|
+
useEffect22(() => {
|
|
30915
31085
|
if (window.ManifoldModule && typeof window.ManifoldModule === "object" && window.ManifoldModule.setup) {
|
|
30916
31086
|
setManifoldJSModule(window.ManifoldModule);
|
|
30917
31087
|
return;
|
|
@@ -30981,27 +31151,27 @@ try {
|
|
|
30981
31151
|
isLoading: builderIsLoading,
|
|
30982
31152
|
boardData
|
|
30983
31153
|
} = useManifoldBoardBuilder(manifoldJSModule, circuitJson);
|
|
30984
|
-
const geometryMeshes =
|
|
30985
|
-
const textureMeshes =
|
|
31154
|
+
const geometryMeshes = useMemo20(() => createGeometryMeshes(geoms), [geoms]);
|
|
31155
|
+
const textureMeshes = useMemo20(
|
|
30986
31156
|
() => createTextureMeshes(textures, boardData, pcbThickness),
|
|
30987
31157
|
[textures, boardData, pcbThickness]
|
|
30988
31158
|
);
|
|
30989
|
-
const cadComponents =
|
|
31159
|
+
const cadComponents = useMemo20(
|
|
30990
31160
|
() => su13(circuitJson).cad_component.list(),
|
|
30991
31161
|
[circuitJson]
|
|
30992
31162
|
);
|
|
30993
|
-
const boardDimensions =
|
|
31163
|
+
const boardDimensions = useMemo20(() => {
|
|
30994
31164
|
if (!boardData) return void 0;
|
|
30995
31165
|
const { width: width10 = 0, height: height10 = 0 } = boardData;
|
|
30996
31166
|
return { width: width10, height: height10 };
|
|
30997
31167
|
}, [boardData]);
|
|
30998
|
-
const boardCenter =
|
|
31168
|
+
const boardCenter = useMemo20(() => {
|
|
30999
31169
|
if (!boardData) return void 0;
|
|
31000
31170
|
const { center } = boardData;
|
|
31001
31171
|
if (!center) return void 0;
|
|
31002
31172
|
return { x: center.x, y: center.y };
|
|
31003
31173
|
}, [boardData]);
|
|
31004
|
-
const initialCameraPosition =
|
|
31174
|
+
const initialCameraPosition = useMemo20(() => {
|
|
31005
31175
|
if (!boardData) return [5, 5, 5];
|
|
31006
31176
|
const { width: width10 = 0, height: height10 = 0 } = boardData;
|
|
31007
31177
|
const safeWidth = Math.max(width10, 1);
|
|
@@ -31027,7 +31197,7 @@ try {
|
|
|
31027
31197
|
);
|
|
31028
31198
|
}
|
|
31029
31199
|
if (!manifoldJSModule) {
|
|
31030
|
-
return /* @__PURE__ */
|
|
31200
|
+
return /* @__PURE__ */ jsx16("div", { style: { padding: "1em" }, children: "Loading Manifold module..." });
|
|
31031
31201
|
}
|
|
31032
31202
|
if (builderError) {
|
|
31033
31203
|
return /* @__PURE__ */ jsxs7(
|
|
@@ -31047,7 +31217,7 @@ try {
|
|
|
31047
31217
|
);
|
|
31048
31218
|
}
|
|
31049
31219
|
if (builderIsLoading) {
|
|
31050
|
-
return /* @__PURE__ */
|
|
31220
|
+
return /* @__PURE__ */ jsx16("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
|
|
31051
31221
|
}
|
|
31052
31222
|
return /* @__PURE__ */ jsxs7(
|
|
31053
31223
|
CadViewerContainer,
|
|
@@ -31059,18 +31229,18 @@ try {
|
|
|
31059
31229
|
boardCenter,
|
|
31060
31230
|
onUserInteraction,
|
|
31061
31231
|
children: [
|
|
31062
|
-
/* @__PURE__ */
|
|
31232
|
+
/* @__PURE__ */ jsx16(
|
|
31063
31233
|
BoardMeshes,
|
|
31064
31234
|
{
|
|
31065
31235
|
geometryMeshes,
|
|
31066
31236
|
textureMeshes
|
|
31067
31237
|
}
|
|
31068
31238
|
),
|
|
31069
|
-
cadComponents.map((cad_component2) => /* @__PURE__ */
|
|
31239
|
+
cadComponents.map((cad_component2) => /* @__PURE__ */ jsx16(
|
|
31070
31240
|
ThreeErrorBoundary,
|
|
31071
31241
|
{
|
|
31072
|
-
fallback: ({ error }) => /* @__PURE__ */
|
|
31073
|
-
children: /* @__PURE__ */
|
|
31242
|
+
fallback: ({ error }) => /* @__PURE__ */ jsx16(Error3d, { cad_component: cad_component2, error }),
|
|
31243
|
+
children: /* @__PURE__ */ jsx16(
|
|
31074
31244
|
AnyCadComponent,
|
|
31075
31245
|
{
|
|
31076
31246
|
cad_component: cad_component2,
|
|
@@ -31087,10 +31257,10 @@ try {
|
|
|
31087
31257
|
var CadViewerManifold_default = CadViewerManifold;
|
|
31088
31258
|
|
|
31089
31259
|
// src/hooks/useContextMenu.ts
|
|
31090
|
-
import { useState as
|
|
31260
|
+
import { useState as useState16, useCallback as useCallback7, useRef as useRef8, useEffect as useEffect23 } from "react";
|
|
31091
31261
|
var useContextMenu = ({ containerRef }) => {
|
|
31092
|
-
const [menuVisible, setMenuVisible] =
|
|
31093
|
-
const [menuPos, setMenuPos] =
|
|
31262
|
+
const [menuVisible, setMenuVisible] = useState16(false);
|
|
31263
|
+
const [menuPos, setMenuPos] = useState16({
|
|
31094
31264
|
x: 0,
|
|
31095
31265
|
y: 0
|
|
31096
31266
|
});
|
|
@@ -31104,7 +31274,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31104
31274
|
longPressTimeoutRef.current = null;
|
|
31105
31275
|
}
|
|
31106
31276
|
};
|
|
31107
|
-
const handleContextMenu =
|
|
31277
|
+
const handleContextMenu = useCallback7(
|
|
31108
31278
|
(e) => {
|
|
31109
31279
|
e.preventDefault();
|
|
31110
31280
|
const eventX = typeof e.clientX === "number" ? e.clientX : 0;
|
|
@@ -31130,7 +31300,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31130
31300
|
},
|
|
31131
31301
|
[setMenuPos, setMenuVisible]
|
|
31132
31302
|
);
|
|
31133
|
-
const handleTouchStart =
|
|
31303
|
+
const handleTouchStart = useCallback7(
|
|
31134
31304
|
(e) => {
|
|
31135
31305
|
if (e.touches.length === 1) {
|
|
31136
31306
|
const touch = e.touches[0];
|
|
@@ -31163,7 +31333,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31163
31333
|
},
|
|
31164
31334
|
[containerRef]
|
|
31165
31335
|
);
|
|
31166
|
-
const handleTouchMove =
|
|
31336
|
+
const handleTouchMove = useCallback7((e) => {
|
|
31167
31337
|
if (!interactionOriginPosRef.current || e.touches.length !== 1) {
|
|
31168
31338
|
return;
|
|
31169
31339
|
}
|
|
@@ -31181,7 +31351,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31181
31351
|
clearLongPressTimeout();
|
|
31182
31352
|
}
|
|
31183
31353
|
}, []);
|
|
31184
|
-
const handleTouchEnd =
|
|
31354
|
+
const handleTouchEnd = useCallback7(() => {
|
|
31185
31355
|
clearLongPressTimeout();
|
|
31186
31356
|
setTimeout(() => {
|
|
31187
31357
|
if (interactionOriginPosRef.current) {
|
|
@@ -31189,13 +31359,13 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31189
31359
|
}
|
|
31190
31360
|
}, 0);
|
|
31191
31361
|
}, []);
|
|
31192
|
-
const handleClickAway =
|
|
31362
|
+
const handleClickAway = useCallback7((e) => {
|
|
31193
31363
|
const target = e.target;
|
|
31194
31364
|
if (menuRef.current && !menuRef.current.contains(target)) {
|
|
31195
31365
|
setMenuVisible(false);
|
|
31196
31366
|
}
|
|
31197
31367
|
}, []);
|
|
31198
|
-
|
|
31368
|
+
useEffect23(() => {
|
|
31199
31369
|
if (menuVisible) {
|
|
31200
31370
|
document.addEventListener("mousedown", handleClickAway);
|
|
31201
31371
|
document.addEventListener("touchstart", handleClickAway);
|
|
@@ -31229,10 +31399,10 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31229
31399
|
};
|
|
31230
31400
|
|
|
31231
31401
|
// src/hooks/useGlobalDownloadGltf.ts
|
|
31232
|
-
import { useCallback as
|
|
31402
|
+
import { useCallback as useCallback8 } from "react";
|
|
31233
31403
|
import { GLTFExporter } from "three-stdlib";
|
|
31234
31404
|
var useGlobalDownloadGltf = () => {
|
|
31235
|
-
return
|
|
31405
|
+
return useCallback8(() => {
|
|
31236
31406
|
const root = window.__TSCIRCUIT_THREE_OBJECT;
|
|
31237
31407
|
if (!root) return;
|
|
31238
31408
|
const exporter = new GLTFExporter();
|
|
@@ -31257,13 +31427,190 @@ var useGlobalDownloadGltf = () => {
|
|
|
31257
31427
|
}, []);
|
|
31258
31428
|
};
|
|
31259
31429
|
|
|
31430
|
+
// src/components/AppearanceMenu.tsx
|
|
31431
|
+
import { useState as useState17 } from "react";
|
|
31432
|
+
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
31433
|
+
var menuItemStyle = {
|
|
31434
|
+
padding: "8px 18px",
|
|
31435
|
+
cursor: "pointer",
|
|
31436
|
+
display: "flex",
|
|
31437
|
+
alignItems: "center",
|
|
31438
|
+
gap: 10,
|
|
31439
|
+
color: "#f5f6fa",
|
|
31440
|
+
fontWeight: 400,
|
|
31441
|
+
fontSize: 14,
|
|
31442
|
+
transition: "background 0.1s"
|
|
31443
|
+
};
|
|
31444
|
+
var checkmarkStyle = {
|
|
31445
|
+
width: 20
|
|
31446
|
+
};
|
|
31447
|
+
var handleMouseOver = (e) => {
|
|
31448
|
+
e.currentTarget.style.background = "#2d313a";
|
|
31449
|
+
};
|
|
31450
|
+
var handleMouseOut = (e) => {
|
|
31451
|
+
e.currentTarget.style.background = "transparent";
|
|
31452
|
+
};
|
|
31453
|
+
var AppearanceMenu = () => {
|
|
31454
|
+
const { visibility, toggleLayer } = useLayerVisibility();
|
|
31455
|
+
const [showSubmenu, setShowSubmenu] = useState17(false);
|
|
31456
|
+
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
31457
|
+
/* @__PURE__ */ jsx17(
|
|
31458
|
+
"div",
|
|
31459
|
+
{
|
|
31460
|
+
style: {
|
|
31461
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
31462
|
+
margin: "8px 0"
|
|
31463
|
+
}
|
|
31464
|
+
}
|
|
31465
|
+
),
|
|
31466
|
+
/* @__PURE__ */ jsxs8(
|
|
31467
|
+
"div",
|
|
31468
|
+
{
|
|
31469
|
+
style: {
|
|
31470
|
+
padding: "8px 18px",
|
|
31471
|
+
fontSize: 14,
|
|
31472
|
+
color: "#f5f6fa",
|
|
31473
|
+
fontWeight: 400,
|
|
31474
|
+
cursor: "pointer",
|
|
31475
|
+
display: "flex",
|
|
31476
|
+
alignItems: "center",
|
|
31477
|
+
justifyContent: "space-between",
|
|
31478
|
+
transition: "background 0.1s",
|
|
31479
|
+
position: "relative"
|
|
31480
|
+
},
|
|
31481
|
+
onMouseEnter: () => setShowSubmenu(true),
|
|
31482
|
+
onMouseLeave: () => setShowSubmenu(false),
|
|
31483
|
+
onMouseOver: handleMouseOver,
|
|
31484
|
+
onMouseOut: handleMouseOut,
|
|
31485
|
+
children: [
|
|
31486
|
+
/* @__PURE__ */ jsx17("span", { children: "Appearance" }),
|
|
31487
|
+
/* @__PURE__ */ jsx17(
|
|
31488
|
+
"span",
|
|
31489
|
+
{
|
|
31490
|
+
style: {
|
|
31491
|
+
fontSize: 10,
|
|
31492
|
+
transform: showSubmenu ? "rotate(90deg)" : "rotate(0deg)",
|
|
31493
|
+
transition: "transform 0.2s",
|
|
31494
|
+
display: "inline-block"
|
|
31495
|
+
},
|
|
31496
|
+
children: "\u25B6"
|
|
31497
|
+
}
|
|
31498
|
+
),
|
|
31499
|
+
showSubmenu && /* @__PURE__ */ jsxs8(
|
|
31500
|
+
"div",
|
|
31501
|
+
{
|
|
31502
|
+
style: {
|
|
31503
|
+
position: "absolute",
|
|
31504
|
+
left: "100%",
|
|
31505
|
+
top: 0,
|
|
31506
|
+
minWidth: 200,
|
|
31507
|
+
background: "#23272f",
|
|
31508
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
31509
|
+
borderRadius: 6,
|
|
31510
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.4)",
|
|
31511
|
+
zIndex: 1e3,
|
|
31512
|
+
marginTop: 8,
|
|
31513
|
+
marginBottom: 8
|
|
31514
|
+
},
|
|
31515
|
+
onMouseEnter: () => setShowSubmenu(true),
|
|
31516
|
+
onMouseLeave: () => setShowSubmenu(false),
|
|
31517
|
+
onClick: (e) => e.stopPropagation(),
|
|
31518
|
+
children: [
|
|
31519
|
+
/* @__PURE__ */ jsxs8(
|
|
31520
|
+
"div",
|
|
31521
|
+
{
|
|
31522
|
+
style: menuItemStyle,
|
|
31523
|
+
onClick: () => toggleLayer("boardBody"),
|
|
31524
|
+
onMouseOver: handleMouseOver,
|
|
31525
|
+
onMouseOut: handleMouseOut,
|
|
31526
|
+
children: [
|
|
31527
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.boardBody ? "\u2714" : "" }),
|
|
31528
|
+
"Board Body"
|
|
31529
|
+
]
|
|
31530
|
+
}
|
|
31531
|
+
),
|
|
31532
|
+
/* @__PURE__ */ jsxs8(
|
|
31533
|
+
"div",
|
|
31534
|
+
{
|
|
31535
|
+
style: menuItemStyle,
|
|
31536
|
+
onClick: () => toggleLayer("topCopper"),
|
|
31537
|
+
onMouseOver: handleMouseOver,
|
|
31538
|
+
onMouseOut: handleMouseOut,
|
|
31539
|
+
children: [
|
|
31540
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.topCopper ? "\u2714" : "" }),
|
|
31541
|
+
"Top Copper"
|
|
31542
|
+
]
|
|
31543
|
+
}
|
|
31544
|
+
),
|
|
31545
|
+
/* @__PURE__ */ jsxs8(
|
|
31546
|
+
"div",
|
|
31547
|
+
{
|
|
31548
|
+
style: menuItemStyle,
|
|
31549
|
+
onClick: () => toggleLayer("bottomCopper"),
|
|
31550
|
+
onMouseOver: handleMouseOver,
|
|
31551
|
+
onMouseOut: handleMouseOut,
|
|
31552
|
+
children: [
|
|
31553
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.bottomCopper ? "\u2714" : "" }),
|
|
31554
|
+
"Bottom Copper"
|
|
31555
|
+
]
|
|
31556
|
+
}
|
|
31557
|
+
),
|
|
31558
|
+
/* @__PURE__ */ jsxs8(
|
|
31559
|
+
"div",
|
|
31560
|
+
{
|
|
31561
|
+
style: menuItemStyle,
|
|
31562
|
+
onClick: () => toggleLayer("topSilkscreen"),
|
|
31563
|
+
onMouseOver: handleMouseOver,
|
|
31564
|
+
onMouseOut: handleMouseOut,
|
|
31565
|
+
children: [
|
|
31566
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.topSilkscreen ? "\u2714" : "" }),
|
|
31567
|
+
"Top Silkscreen"
|
|
31568
|
+
]
|
|
31569
|
+
}
|
|
31570
|
+
),
|
|
31571
|
+
/* @__PURE__ */ jsxs8(
|
|
31572
|
+
"div",
|
|
31573
|
+
{
|
|
31574
|
+
style: menuItemStyle,
|
|
31575
|
+
onClick: () => toggleLayer("bottomSilkscreen"),
|
|
31576
|
+
onMouseOver: handleMouseOver,
|
|
31577
|
+
onMouseOut: handleMouseOut,
|
|
31578
|
+
children: [
|
|
31579
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.bottomSilkscreen ? "\u2714" : "" }),
|
|
31580
|
+
"Bottom Silkscreen"
|
|
31581
|
+
]
|
|
31582
|
+
}
|
|
31583
|
+
),
|
|
31584
|
+
/* @__PURE__ */ jsxs8(
|
|
31585
|
+
"div",
|
|
31586
|
+
{
|
|
31587
|
+
style: menuItemStyle,
|
|
31588
|
+
onClick: () => toggleLayer("smtModels"),
|
|
31589
|
+
onMouseOver: handleMouseOver,
|
|
31590
|
+
onMouseOut: handleMouseOut,
|
|
31591
|
+
children: [
|
|
31592
|
+
/* @__PURE__ */ jsx17("span", { style: checkmarkStyle, children: visibility.smtModels ? "\u2714" : "" }),
|
|
31593
|
+
"CAD Models"
|
|
31594
|
+
]
|
|
31595
|
+
}
|
|
31596
|
+
)
|
|
31597
|
+
]
|
|
31598
|
+
}
|
|
31599
|
+
)
|
|
31600
|
+
]
|
|
31601
|
+
}
|
|
31602
|
+
)
|
|
31603
|
+
] });
|
|
31604
|
+
};
|
|
31605
|
+
|
|
31260
31606
|
// src/CadViewer.tsx
|
|
31261
|
-
import { jsx as
|
|
31262
|
-
var
|
|
31263
|
-
const [engine, setEngine] =
|
|
31607
|
+
import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
31608
|
+
var CadViewerInner = (props) => {
|
|
31609
|
+
const [engine, setEngine] = useState18("manifold");
|
|
31264
31610
|
const containerRef = useRef9(null);
|
|
31265
|
-
const [autoRotate, setAutoRotate] =
|
|
31266
|
-
const [autoRotateUserToggled, setAutoRotateUserToggled] =
|
|
31611
|
+
const [autoRotate, setAutoRotate] = useState18(true);
|
|
31612
|
+
const [autoRotateUserToggled, setAutoRotateUserToggled] = useState18(false);
|
|
31613
|
+
const { visibility, toggleLayer } = useLayerVisibility();
|
|
31267
31614
|
const {
|
|
31268
31615
|
menuVisible,
|
|
31269
31616
|
menuPos,
|
|
@@ -31273,12 +31620,12 @@ var CadViewer = (props) => {
|
|
|
31273
31620
|
} = useContextMenu({ containerRef });
|
|
31274
31621
|
const autoRotateUserToggledRef = useRef9(autoRotateUserToggled);
|
|
31275
31622
|
autoRotateUserToggledRef.current = autoRotateUserToggled;
|
|
31276
|
-
const handleUserInteraction =
|
|
31623
|
+
const handleUserInteraction = useCallback9(() => {
|
|
31277
31624
|
if (!autoRotateUserToggledRef.current) {
|
|
31278
31625
|
setAutoRotate(false);
|
|
31279
31626
|
}
|
|
31280
31627
|
}, []);
|
|
31281
|
-
const toggleAutoRotate =
|
|
31628
|
+
const toggleAutoRotate = useCallback9(() => {
|
|
31282
31629
|
setAutoRotate((prev) => !prev);
|
|
31283
31630
|
setAutoRotateUserToggled(true);
|
|
31284
31631
|
}, []);
|
|
@@ -31287,17 +31634,17 @@ var CadViewer = (props) => {
|
|
|
31287
31634
|
setEngine(newEngine);
|
|
31288
31635
|
setMenuVisible(false);
|
|
31289
31636
|
};
|
|
31290
|
-
|
|
31637
|
+
useEffect24(() => {
|
|
31291
31638
|
const stored = window.localStorage.getItem("cadViewerEngine");
|
|
31292
31639
|
if (stored === "jscad" || stored === "manifold") {
|
|
31293
31640
|
setEngine(stored);
|
|
31294
31641
|
}
|
|
31295
31642
|
}, []);
|
|
31296
|
-
|
|
31643
|
+
useEffect24(() => {
|
|
31297
31644
|
window.localStorage.setItem("cadViewerEngine", engine);
|
|
31298
31645
|
}, [engine]);
|
|
31299
31646
|
const viewerKey = props.circuitJson ? JSON.stringify(props.circuitJson) : void 0;
|
|
31300
|
-
return /* @__PURE__ */
|
|
31647
|
+
return /* @__PURE__ */ jsxs9(
|
|
31301
31648
|
"div",
|
|
31302
31649
|
{
|
|
31303
31650
|
ref: containerRef,
|
|
@@ -31313,14 +31660,14 @@ var CadViewer = (props) => {
|
|
|
31313
31660
|
},
|
|
31314
31661
|
...contextMenuEventHandlers,
|
|
31315
31662
|
children: [
|
|
31316
|
-
engine === "jscad" ? /* @__PURE__ */
|
|
31663
|
+
engine === "jscad" ? /* @__PURE__ */ jsx18(
|
|
31317
31664
|
CadViewerJscad,
|
|
31318
31665
|
{
|
|
31319
31666
|
...props,
|
|
31320
31667
|
autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
|
|
31321
31668
|
onUserInteraction: handleUserInteraction
|
|
31322
31669
|
}
|
|
31323
|
-
) : /* @__PURE__ */
|
|
31670
|
+
) : /* @__PURE__ */ jsx18(
|
|
31324
31671
|
CadViewerManifold_default,
|
|
31325
31672
|
{
|
|
31326
31673
|
...props,
|
|
@@ -31328,7 +31675,7 @@ var CadViewer = (props) => {
|
|
|
31328
31675
|
onUserInteraction: handleUserInteraction
|
|
31329
31676
|
}
|
|
31330
31677
|
),
|
|
31331
|
-
/* @__PURE__ */
|
|
31678
|
+
/* @__PURE__ */ jsxs9(
|
|
31332
31679
|
"div",
|
|
31333
31680
|
{
|
|
31334
31681
|
style: {
|
|
@@ -31345,11 +31692,11 @@ var CadViewer = (props) => {
|
|
|
31345
31692
|
},
|
|
31346
31693
|
children: [
|
|
31347
31694
|
"Engine: ",
|
|
31348
|
-
/* @__PURE__ */
|
|
31695
|
+
/* @__PURE__ */ jsx18("b", { children: engine === "jscad" ? "JSCAD" : "Manifold" })
|
|
31349
31696
|
]
|
|
31350
31697
|
}
|
|
31351
31698
|
),
|
|
31352
|
-
menuVisible && /* @__PURE__ */
|
|
31699
|
+
menuVisible && /* @__PURE__ */ jsxs9(
|
|
31353
31700
|
"div",
|
|
31354
31701
|
{
|
|
31355
31702
|
ref: menuRef,
|
|
@@ -31370,7 +31717,7 @@ var CadViewer = (props) => {
|
|
|
31370
31717
|
transition: "opacity 0.1s"
|
|
31371
31718
|
},
|
|
31372
31719
|
children: [
|
|
31373
|
-
/* @__PURE__ */
|
|
31720
|
+
/* @__PURE__ */ jsxs9(
|
|
31374
31721
|
"div",
|
|
31375
31722
|
{
|
|
31376
31723
|
style: {
|
|
@@ -31391,7 +31738,7 @@ var CadViewer = (props) => {
|
|
|
31391
31738
|
"Switch to ",
|
|
31392
31739
|
engine === "jscad" ? "Manifold" : "JSCAD",
|
|
31393
31740
|
" Engine",
|
|
31394
|
-
/* @__PURE__ */
|
|
31741
|
+
/* @__PURE__ */ jsx18(
|
|
31395
31742
|
"span",
|
|
31396
31743
|
{
|
|
31397
31744
|
style: {
|
|
@@ -31406,7 +31753,7 @@ var CadViewer = (props) => {
|
|
|
31406
31753
|
]
|
|
31407
31754
|
}
|
|
31408
31755
|
),
|
|
31409
|
-
/* @__PURE__ */
|
|
31756
|
+
/* @__PURE__ */ jsxs9(
|
|
31410
31757
|
"div",
|
|
31411
31758
|
{
|
|
31412
31759
|
style: {
|
|
@@ -31427,12 +31774,12 @@ var CadViewer = (props) => {
|
|
|
31427
31774
|
onMouseOver: (e) => e.currentTarget.style.background = "#2d313a",
|
|
31428
31775
|
onMouseOut: (e) => e.currentTarget.style.background = "transparent",
|
|
31429
31776
|
children: [
|
|
31430
|
-
/* @__PURE__ */
|
|
31777
|
+
/* @__PURE__ */ jsx18("span", { style: { marginRight: 8 }, children: autoRotate ? "\u2714" : "" }),
|
|
31431
31778
|
"Auto rotate"
|
|
31432
31779
|
]
|
|
31433
31780
|
}
|
|
31434
31781
|
),
|
|
31435
|
-
/* @__PURE__ */
|
|
31782
|
+
/* @__PURE__ */ jsx18(
|
|
31436
31783
|
"div",
|
|
31437
31784
|
{
|
|
31438
31785
|
style: {
|
|
@@ -31455,7 +31802,8 @@ var CadViewer = (props) => {
|
|
|
31455
31802
|
children: "Download GLTF"
|
|
31456
31803
|
}
|
|
31457
31804
|
),
|
|
31458
|
-
/* @__PURE__ */
|
|
31805
|
+
/* @__PURE__ */ jsx18(AppearanceMenu, {}),
|
|
31806
|
+
/* @__PURE__ */ jsx18(
|
|
31459
31807
|
"div",
|
|
31460
31808
|
{
|
|
31461
31809
|
style: {
|
|
@@ -31465,7 +31813,7 @@ var CadViewer = (props) => {
|
|
|
31465
31813
|
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
31466
31814
|
marginTop: "8px"
|
|
31467
31815
|
},
|
|
31468
|
-
children: /* @__PURE__ */
|
|
31816
|
+
children: /* @__PURE__ */ jsxs9(
|
|
31469
31817
|
"span",
|
|
31470
31818
|
{
|
|
31471
31819
|
style: {
|
|
@@ -31490,6 +31838,9 @@ var CadViewer = (props) => {
|
|
|
31490
31838
|
viewerKey
|
|
31491
31839
|
);
|
|
31492
31840
|
};
|
|
31841
|
+
var CadViewer = (props) => {
|
|
31842
|
+
return /* @__PURE__ */ jsx18(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx18(CadViewerInner, { ...props }) });
|
|
31843
|
+
};
|
|
31493
31844
|
|
|
31494
31845
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
31495
31846
|
var import_debug = __toESM(require_browser(), 1);
|
|
@@ -31770,10 +32121,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
31770
32121
|
|
|
31771
32122
|
// src/hooks/exporter/gltf.ts
|
|
31772
32123
|
import { GLTFExporter as GLTFExporter2 } from "three-stdlib";
|
|
31773
|
-
import { useEffect as
|
|
32124
|
+
import { useEffect as useEffect25, useState as useState19, useMemo as useMemo21, useCallback as useCallback10 } from "react";
|
|
31774
32125
|
function useSaveGltfAs(options = {}) {
|
|
31775
32126
|
const parse = useParser(options);
|
|
31776
|
-
const link =
|
|
32127
|
+
const link = useMemo21(() => document.createElement("a"), []);
|
|
31777
32128
|
const saveAs = async (filename) => {
|
|
31778
32129
|
const name = filename ?? options.filename ?? "";
|
|
31779
32130
|
if (options.binary == null) options.binary = name.endsWith(".glb");
|
|
@@ -31783,7 +32134,7 @@ function useSaveGltfAs(options = {}) {
|
|
|
31783
32134
|
link.dispatchEvent(new MouseEvent("click"));
|
|
31784
32135
|
URL.revokeObjectURL(url);
|
|
31785
32136
|
};
|
|
31786
|
-
|
|
32137
|
+
useEffect25(
|
|
31787
32138
|
() => () => {
|
|
31788
32139
|
link.remove();
|
|
31789
32140
|
instance = null;
|
|
@@ -31791,24 +32142,24 @@ function useSaveGltfAs(options = {}) {
|
|
|
31791
32142
|
[]
|
|
31792
32143
|
);
|
|
31793
32144
|
let instance;
|
|
31794
|
-
const ref =
|
|
32145
|
+
const ref = useCallback10((obj3D) => {
|
|
31795
32146
|
instance = obj3D;
|
|
31796
32147
|
}, []);
|
|
31797
32148
|
return [ref, saveAs];
|
|
31798
32149
|
}
|
|
31799
32150
|
function useExportGltfUrl(options = {}) {
|
|
31800
32151
|
const parse = useParser(options);
|
|
31801
|
-
const [url, setUrl] =
|
|
31802
|
-
const [error, setError] =
|
|
31803
|
-
const ref =
|
|
32152
|
+
const [url, setUrl] = useState19();
|
|
32153
|
+
const [error, setError] = useState19();
|
|
32154
|
+
const ref = useCallback10(
|
|
31804
32155
|
(instance) => parse(instance).then(setUrl).catch(setError),
|
|
31805
32156
|
[]
|
|
31806
32157
|
);
|
|
31807
|
-
|
|
32158
|
+
useEffect25(() => () => URL.revokeObjectURL(url), [url]);
|
|
31808
32159
|
return [ref, url, error];
|
|
31809
32160
|
}
|
|
31810
32161
|
function useParser(options = {}) {
|
|
31811
|
-
const exporter =
|
|
32162
|
+
const exporter = useMemo21(() => new GLTFExporter2(), []);
|
|
31812
32163
|
return (instance) => {
|
|
31813
32164
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
31814
32165
|
exporter.parse(
|