@tscircuit/3d-viewer 0.0.80 → 0.0.82
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 +20 -4
- package/dist/index.js +121 -59
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { GLTFExporterOptions } from 'three-stdlib';
|
|
2
4
|
import { AnySoupElement } from '@tscircuit/soup';
|
|
3
5
|
|
|
6
|
+
type Options = Omit<GLTFExporterOptions, "animations" | "includeCustomExtensions">;
|
|
7
|
+
declare function useSaveGltfAs(options?: Options & {
|
|
8
|
+
filename?: string;
|
|
9
|
+
}): [
|
|
10
|
+
ref3D: React.ForwardedRef<THREE.Object3D>,
|
|
11
|
+
saveAs: (filename?: string) => Promise<void>
|
|
12
|
+
];
|
|
13
|
+
declare function useExportGltfUrl(options?: Options): [
|
|
14
|
+
ref3D: React.ForwardedRef<THREE.Object3D>,
|
|
15
|
+
url: string | undefined,
|
|
16
|
+
error: ErrorEvent | undefined
|
|
17
|
+
];
|
|
18
|
+
|
|
4
19
|
interface Props {
|
|
5
20
|
soup?: AnySoupElement[];
|
|
6
|
-
children?: any;
|
|
7
21
|
}
|
|
8
|
-
declare const CadViewer:
|
|
22
|
+
declare const CadViewer: React.ForwardRefExoticComponent<Props & {
|
|
23
|
+
children?: React.ReactNode | undefined;
|
|
24
|
+
} & React.RefAttributes<THREE.Object3D<THREE.Object3DEventMap>>>;
|
|
9
25
|
|
|
10
|
-
export { CadViewer };
|
|
26
|
+
export { CadViewer, useExportGltfUrl, useSaveGltfAs };
|
package/dist/index.js
CHANGED
|
@@ -30,15 +30,77 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.tsx
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
-
CadViewer: () => CadViewer
|
|
33
|
+
CadViewer: () => CadViewer,
|
|
34
|
+
useExportGltfUrl: () => useExportGltfUrl,
|
|
35
|
+
useSaveGltfAs: () => useSaveGltfAs
|
|
34
36
|
});
|
|
35
37
|
module.exports = __toCommonJS(src_exports);
|
|
36
38
|
|
|
39
|
+
// src/hooks/exporter/gltf.ts
|
|
40
|
+
var import_three_stdlib = require("three-stdlib");
|
|
41
|
+
var import_react = require("react");
|
|
42
|
+
function useSaveGltfAs(options = {}) {
|
|
43
|
+
const parse = useParser(options);
|
|
44
|
+
const link = (0, import_react.useMemo)(() => document.createElement("a"), []);
|
|
45
|
+
const saveAs = async (filename) => {
|
|
46
|
+
const name = filename ?? options.filename ?? "";
|
|
47
|
+
if (options.binary == null) options.binary = name.endsWith(".glb");
|
|
48
|
+
const url = await parse(instance);
|
|
49
|
+
link.download = name;
|
|
50
|
+
link.href = url;
|
|
51
|
+
link.dispatchEvent(new MouseEvent("click"));
|
|
52
|
+
URL.revokeObjectURL(url);
|
|
53
|
+
};
|
|
54
|
+
(0, import_react.useEffect)(
|
|
55
|
+
() => () => {
|
|
56
|
+
link.remove();
|
|
57
|
+
instance = null;
|
|
58
|
+
},
|
|
59
|
+
[]
|
|
60
|
+
);
|
|
61
|
+
let instance;
|
|
62
|
+
const ref = (0, import_react.useCallback)((obj3D) => {
|
|
63
|
+
instance = obj3D;
|
|
64
|
+
}, []);
|
|
65
|
+
return [ref, saveAs];
|
|
66
|
+
}
|
|
67
|
+
function useExportGltfUrl(options = {}) {
|
|
68
|
+
const parse = useParser(options);
|
|
69
|
+
const [url, setUrl] = (0, import_react.useState)();
|
|
70
|
+
const [error, setError] = (0, import_react.useState)();
|
|
71
|
+
const ref = (0, import_react.useCallback)(
|
|
72
|
+
(instance) => parse(instance).then(setUrl).catch(setError),
|
|
73
|
+
[]
|
|
74
|
+
);
|
|
75
|
+
(0, import_react.useEffect)(() => () => URL.revokeObjectURL(url), [url]);
|
|
76
|
+
return [ref, url, error];
|
|
77
|
+
}
|
|
78
|
+
function useParser(options = {}) {
|
|
79
|
+
const exporter = (0, import_react.useMemo)(() => new import_three_stdlib.GLTFExporter(), []);
|
|
80
|
+
return (instance) => {
|
|
81
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
82
|
+
exporter.parse(
|
|
83
|
+
instance,
|
|
84
|
+
(gltf) => {
|
|
85
|
+
const type = options.binary ? "gltf-binary" : "gltf+json";
|
|
86
|
+
const blob = new Blob(
|
|
87
|
+
[gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],
|
|
88
|
+
{ type: `model/${type}` }
|
|
89
|
+
);
|
|
90
|
+
resolve(URL.createObjectURL(blob));
|
|
91
|
+
},
|
|
92
|
+
reject,
|
|
93
|
+
options
|
|
94
|
+
);
|
|
95
|
+
return promise;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
37
99
|
// src/hooks/use-convert-children-to-soup.ts
|
|
38
100
|
var import_core = require("@tscircuit/core");
|
|
39
|
-
var
|
|
101
|
+
var import_react2 = require("react");
|
|
40
102
|
var useConvertChildrenToSoup = (children, defaultSoup) => {
|
|
41
|
-
return (0,
|
|
103
|
+
return (0, import_react2.useMemo)(() => {
|
|
42
104
|
if (!children) return;
|
|
43
105
|
const circuit = new import_core.Circuit();
|
|
44
106
|
circuit.add(children);
|
|
@@ -49,7 +111,7 @@ var useConvertChildrenToSoup = (children, defaultSoup) => {
|
|
|
49
111
|
|
|
50
112
|
// src/CadViewer.tsx
|
|
51
113
|
var import_soup_util2 = require("@tscircuit/soup-util");
|
|
52
|
-
var
|
|
114
|
+
var import_react12 = require("react");
|
|
53
115
|
|
|
54
116
|
// src/soup-to-3d/index.ts
|
|
55
117
|
var import_soup_util = require("@tscircuit/soup-util");
|
|
@@ -477,7 +539,7 @@ var createBoardGeomFromSoup = (soup) => {
|
|
|
477
539
|
};
|
|
478
540
|
|
|
479
541
|
// src/hooks/use-stls-from-geom.ts
|
|
480
|
-
var
|
|
542
|
+
var import_react3 = require("react");
|
|
481
543
|
var import_stl_serializer = __toESM(require("@jscad/stl-serializer"));
|
|
482
544
|
function blobToBase64Url(blob) {
|
|
483
545
|
return new Promise((resolve, reject) => {
|
|
@@ -490,9 +552,9 @@ function blobToBase64Url(blob) {
|
|
|
490
552
|
});
|
|
491
553
|
}
|
|
492
554
|
var useStlsFromGeom = (geom) => {
|
|
493
|
-
const [stls, setStls] = (0,
|
|
494
|
-
const [loading, setLoading] = (0,
|
|
495
|
-
(0,
|
|
555
|
+
const [stls, setStls] = (0, import_react3.useState)([]);
|
|
556
|
+
const [loading, setLoading] = (0, import_react3.useState)(true);
|
|
557
|
+
(0, import_react3.useEffect)(() => {
|
|
496
558
|
if (!geom) return;
|
|
497
559
|
const generateStls = async () => {
|
|
498
560
|
setLoading(true);
|
|
@@ -520,8 +582,8 @@ var useStlsFromGeom = (geom) => {
|
|
|
520
582
|
|
|
521
583
|
// src/three-components/STLModel.tsx
|
|
522
584
|
var import_fiber = require("@react-three/fiber");
|
|
523
|
-
var
|
|
524
|
-
var
|
|
585
|
+
var import_react4 = require("react");
|
|
586
|
+
var import_three_stdlib2 = require("three-stdlib");
|
|
525
587
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
526
588
|
function STLModel({
|
|
527
589
|
stlUrl,
|
|
@@ -529,8 +591,8 @@ function STLModel({
|
|
|
529
591
|
color,
|
|
530
592
|
opacity = 1
|
|
531
593
|
}) {
|
|
532
|
-
const geom = (0, import_fiber.useLoader)(
|
|
533
|
-
const mesh = (0,
|
|
594
|
+
const geom = (0, import_fiber.useLoader)(import_three_stdlib2.STLLoader, stlUrl);
|
|
595
|
+
const mesh = (0, import_react4.useRef)();
|
|
534
596
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("mesh", { ref: mesh, children: [
|
|
535
597
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("primitive", { object: geom, attach: "geometry" }),
|
|
536
598
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -551,7 +613,7 @@ var import_fiber3 = require("@react-three/fiber");
|
|
|
551
613
|
// package.json
|
|
552
614
|
var package_default = {
|
|
553
615
|
name: "@tscircuit/3d-viewer",
|
|
554
|
-
version: "0.0.
|
|
616
|
+
version: "0.0.81",
|
|
555
617
|
main: "./dist/index.js",
|
|
556
618
|
files: [
|
|
557
619
|
"dist"
|
|
@@ -575,7 +637,7 @@ var package_default = {
|
|
|
575
637
|
"@react-three/drei": "^9.115.0",
|
|
576
638
|
"@react-three/fiber": "^8.16.8",
|
|
577
639
|
"@tscircuit/core": "^0.0.251",
|
|
578
|
-
"@tscircuit/props": "^0.0.
|
|
640
|
+
"@tscircuit/props": "^0.0.125",
|
|
579
641
|
"@tscircuit/react-fiber": "^1.1.29",
|
|
580
642
|
"@tscircuit/soup": "^0.0.69",
|
|
581
643
|
"@tscircuit/soup-util": "^0.0.26",
|
|
@@ -592,25 +654,25 @@ var package_default = {
|
|
|
592
654
|
devDependencies: {
|
|
593
655
|
"@biomejs/biome": "^1.8.3",
|
|
594
656
|
"@chromatic-com/storybook": "^1.5.0",
|
|
595
|
-
"@storybook/addon-essentials": "^8.
|
|
596
|
-
"@storybook/addon-interactions": "^8.
|
|
597
|
-
"@storybook/addon-links": "^8.
|
|
598
|
-
"@storybook/addon-onboarding": "^8.
|
|
599
|
-
"@storybook/blocks": "^8.
|
|
600
|
-
"@storybook/builder-vite": "^8.
|
|
601
|
-
"@storybook/react": "^8.
|
|
602
|
-
"@storybook/react-vite": "^8.
|
|
603
|
-
"@storybook/test": "^8.
|
|
657
|
+
"@storybook/addon-essentials": "^8.4.7",
|
|
658
|
+
"@storybook/addon-interactions": "^8.4.7",
|
|
659
|
+
"@storybook/addon-links": "^8.4.7",
|
|
660
|
+
"@storybook/addon-onboarding": "^8.4.7",
|
|
661
|
+
"@storybook/blocks": "^8.4.7",
|
|
662
|
+
"@storybook/builder-vite": "^8.4.7",
|
|
663
|
+
"@storybook/react": "^8.4.7",
|
|
664
|
+
"@storybook/react-vite": "^8.4.7",
|
|
665
|
+
"@storybook/test": "^8.4.7",
|
|
604
666
|
"@types/react": "^18.3.3",
|
|
605
667
|
"@types/react-dom": "^18.3.0",
|
|
606
|
-
"@vitejs/plugin-react": "^4.3.
|
|
668
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
607
669
|
"circuit-json": "^0.0.116",
|
|
608
670
|
"circuit-to-svg": "^0.0.91",
|
|
609
|
-
storybook: "^8.
|
|
671
|
+
storybook: "^8.4.7",
|
|
610
672
|
"strip-ansi": "^7.1.0",
|
|
611
673
|
tsup: "^8.1.0",
|
|
612
|
-
typescript: "^5.
|
|
613
|
-
vite: "^5.
|
|
674
|
+
typescript: "^5.7.2",
|
|
675
|
+
vite: "^5.4.11",
|
|
614
676
|
"vite-tsconfig-paths": "^4.3.2"
|
|
615
677
|
}
|
|
616
678
|
};
|
|
@@ -618,7 +680,7 @@ var package_default = {
|
|
|
618
680
|
// src/three-components/cube-with-labeled-sides.tsx
|
|
619
681
|
var import_drei = require("@react-three/drei");
|
|
620
682
|
var import_fiber2 = require("@react-three/fiber");
|
|
621
|
-
var
|
|
683
|
+
var import_react5 = require("react");
|
|
622
684
|
var THREE = __toESM(require("three"));
|
|
623
685
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
624
686
|
if (typeof window !== "undefined") {
|
|
@@ -634,8 +696,8 @@ function computePointInFront(rotationVector, distance) {
|
|
|
634
696
|
return result;
|
|
635
697
|
}
|
|
636
698
|
var CubeWithLabeledSides = ({}) => {
|
|
637
|
-
const ref = (0,
|
|
638
|
-
const rotationTrackingRef = (0,
|
|
699
|
+
const ref = (0, import_react5.useRef)();
|
|
700
|
+
const rotationTrackingRef = (0, import_react5.useRef)({ lastRotation: new THREE.Euler() });
|
|
639
701
|
(0, import_fiber2.useFrame)((state, delta) => {
|
|
640
702
|
if (!ref.current) return;
|
|
641
703
|
const mainRot = window.TSCI_MAIN_CAMERA_ROTATION;
|
|
@@ -711,6 +773,7 @@ var CubeWithLabeledSides = ({}) => {
|
|
|
711
773
|
};
|
|
712
774
|
|
|
713
775
|
// src/CadViewerContainer.tsx
|
|
776
|
+
var import_react6 = require("react");
|
|
714
777
|
var import_drei3 = require("@react-three/drei");
|
|
715
778
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
716
779
|
var RotationTracker = () => {
|
|
@@ -719,10 +782,7 @@ var RotationTracker = () => {
|
|
|
719
782
|
});
|
|
720
783
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, {});
|
|
721
784
|
};
|
|
722
|
-
var CadViewerContainer = ({
|
|
723
|
-
children,
|
|
724
|
-
hoveredComponent
|
|
725
|
-
}) => {
|
|
785
|
+
var CadViewerContainer = (0, import_react6.forwardRef)(({ children, hoveredComponent }, ref) => {
|
|
726
786
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
|
|
727
787
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
728
788
|
"div",
|
|
@@ -776,7 +836,7 @@ var CadViewerContainer = ({
|
|
|
776
836
|
sectionSize: 10
|
|
777
837
|
}
|
|
778
838
|
),
|
|
779
|
-
children,
|
|
839
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("object3D", { ref, children }),
|
|
780
840
|
hoveredComponent && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
781
841
|
import_drei3.Html,
|
|
782
842
|
{
|
|
@@ -818,10 +878,10 @@ var CadViewerContainer = ({
|
|
|
818
878
|
}
|
|
819
879
|
)
|
|
820
880
|
] });
|
|
821
|
-
};
|
|
881
|
+
});
|
|
822
882
|
|
|
823
883
|
// src/ContainerWithTooltip.tsx
|
|
824
|
-
var
|
|
884
|
+
var import_react7 = require("react");
|
|
825
885
|
var THREE2 = __toESM(require("three"));
|
|
826
886
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
827
887
|
var Group = (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("group", { ...props });
|
|
@@ -831,8 +891,8 @@ var ContainerWithTooltip = ({
|
|
|
831
891
|
onHover,
|
|
832
892
|
position
|
|
833
893
|
}) => {
|
|
834
|
-
const lastValidPointRef = (0,
|
|
835
|
-
const handlePointerEnter = (0,
|
|
894
|
+
const lastValidPointRef = (0, import_react7.useRef)(null);
|
|
895
|
+
const handlePointerEnter = (0, import_react7.useCallback)(
|
|
836
896
|
(e) => {
|
|
837
897
|
e.stopPropagation();
|
|
838
898
|
try {
|
|
@@ -850,7 +910,7 @@ var ContainerWithTooltip = ({
|
|
|
850
910
|
},
|
|
851
911
|
[position]
|
|
852
912
|
);
|
|
853
|
-
const handlePointerLeave = (0,
|
|
913
|
+
const handlePointerLeave = (0, import_react7.useCallback)(
|
|
854
914
|
(e) => {
|
|
855
915
|
e.stopPropagation();
|
|
856
916
|
lastValidPointRef.current = null;
|
|
@@ -871,14 +931,14 @@ var ContainerWithTooltip = ({
|
|
|
871
931
|
var ContainerWithTooltip_default = ContainerWithTooltip;
|
|
872
932
|
|
|
873
933
|
// src/hooks/use-global-obj-loader.ts
|
|
874
|
-
var
|
|
875
|
-
var
|
|
934
|
+
var import_react8 = require("react");
|
|
935
|
+
var import_three_stdlib3 = require("three-stdlib");
|
|
876
936
|
if (typeof window !== "undefined" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {
|
|
877
937
|
window.TSCIRCUIT_OBJ_LOADER_CACHE = /* @__PURE__ */ new Map();
|
|
878
938
|
}
|
|
879
939
|
function useGlobalObjLoader(url) {
|
|
880
|
-
const [obj, setObj] = (0,
|
|
881
|
-
(0,
|
|
940
|
+
const [obj, setObj] = (0, import_react8.useState)(null);
|
|
941
|
+
(0, import_react8.useEffect)(() => {
|
|
882
942
|
if (!url) return;
|
|
883
943
|
const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE;
|
|
884
944
|
let hasUrlChanged = false;
|
|
@@ -888,7 +948,7 @@ function useGlobalObjLoader(url) {
|
|
|
888
948
|
const text = await response.text();
|
|
889
949
|
const mtlContent = text.match(/newmtl[\s\S]*?endmtl/g)?.join("\n").replace(/d 0\./g, "d 1.");
|
|
890
950
|
const objContent = text.replace(/newmtl[\s\S]*?endmtl/g, "");
|
|
891
|
-
const mtlLoader = new
|
|
951
|
+
const mtlLoader = new import_three_stdlib3.MTLLoader();
|
|
892
952
|
mtlLoader.setMaterialOptions({
|
|
893
953
|
invertTrProperty: true
|
|
894
954
|
});
|
|
@@ -899,7 +959,7 @@ function useGlobalObjLoader(url) {
|
|
|
899
959
|
),
|
|
900
960
|
"test.mtl"
|
|
901
961
|
);
|
|
902
|
-
const objLoader = new
|
|
962
|
+
const objLoader = new import_three_stdlib3.OBJLoader();
|
|
903
963
|
objLoader.setMaterials(materials);
|
|
904
964
|
return objLoader.parse(objContent);
|
|
905
965
|
} catch (error) {
|
|
@@ -968,7 +1028,7 @@ var import_jscad_planner = require("jscad-planner");
|
|
|
968
1028
|
var import_modeling = __toESM(require("@jscad/modeling"));
|
|
969
1029
|
var import_jscad_fiber = require("jscad-fiber");
|
|
970
1030
|
var THREE3 = __toESM(require("three"));
|
|
971
|
-
var
|
|
1031
|
+
var import_react9 = require("react");
|
|
972
1032
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
973
1033
|
var JscadModel = ({
|
|
974
1034
|
jscadPlan,
|
|
@@ -977,7 +1037,7 @@ var JscadModel = ({
|
|
|
977
1037
|
onHover,
|
|
978
1038
|
isHovered
|
|
979
1039
|
}) => {
|
|
980
|
-
const { threeGeom, material } = (0,
|
|
1040
|
+
const { threeGeom, material } = (0, import_react9.useMemo)(() => {
|
|
981
1041
|
const jscadObject = (0, import_jscad_planner.executeJscadOperations)(import_modeling.default, jscadPlan);
|
|
982
1042
|
const threeGeom2 = (0, import_jscad_fiber.convertCSGToThreeGeom)(jscadObject);
|
|
983
1043
|
const material2 = new THREE3.MeshStandardMaterial({
|
|
@@ -987,7 +1047,7 @@ var JscadModel = ({
|
|
|
987
1047
|
});
|
|
988
1048
|
return { threeGeom: threeGeom2, material: material2 };
|
|
989
1049
|
}, [jscadPlan]);
|
|
990
|
-
(0,
|
|
1050
|
+
(0, import_react9.useMemo)(() => {
|
|
991
1051
|
if (isHovered) {
|
|
992
1052
|
const color = new THREE3.Color(material.color.getHex());
|
|
993
1053
|
material.emissive.copy(color);
|
|
@@ -1021,7 +1081,7 @@ var JscadModel = ({
|
|
|
1021
1081
|
var import_jscad_electronics = require("jscad-electronics");
|
|
1022
1082
|
var import_jscad_fiber2 = require("jscad-fiber");
|
|
1023
1083
|
var import_jscad_planner2 = require("jscad-planner");
|
|
1024
|
-
var
|
|
1084
|
+
var import_react10 = require("react");
|
|
1025
1085
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1026
1086
|
var { createJSCADRoot } = (0, import_jscad_fiber2.createJSCADRenderer)(import_jscad_planner2.jscadPlanner);
|
|
1027
1087
|
var FootprinterModel = ({
|
|
@@ -1031,7 +1091,7 @@ var FootprinterModel = ({
|
|
|
1031
1091
|
onHover,
|
|
1032
1092
|
isHovered
|
|
1033
1093
|
}) => {
|
|
1034
|
-
const jscadOperations = (0,
|
|
1094
|
+
const jscadOperations = (0, import_react10.useMemo)(() => {
|
|
1035
1095
|
if (!footprint) return null;
|
|
1036
1096
|
const jscadOperations2 = [];
|
|
1037
1097
|
const root = createJSCADRoot(jscadOperations2);
|
|
@@ -1117,8 +1177,8 @@ var AnyCadComponent = ({
|
|
|
1117
1177
|
};
|
|
1118
1178
|
|
|
1119
1179
|
// src/three-components/ThreeErrorBoundary.tsx
|
|
1120
|
-
var
|
|
1121
|
-
var ThreeErrorBoundary = class extends
|
|
1180
|
+
var import_react11 = __toESM(require("react"));
|
|
1181
|
+
var ThreeErrorBoundary = class extends import_react11.default.Component {
|
|
1122
1182
|
constructor(props) {
|
|
1123
1183
|
super(props);
|
|
1124
1184
|
this.state = { hasError: false, error: null };
|
|
@@ -1200,17 +1260,17 @@ var Error3d = ({
|
|
|
1200
1260
|
|
|
1201
1261
|
// src/CadViewer.tsx
|
|
1202
1262
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1203
|
-
var CadViewer = ({ soup, children }) => {
|
|
1204
|
-
const [hoveredComponent, setHoveredComponent] = (0,
|
|
1263
|
+
var CadViewer = (0, import_react12.forwardRef)(({ soup, children }, ref) => {
|
|
1264
|
+
const [hoveredComponent, setHoveredComponent] = (0, import_react12.useState)(null);
|
|
1205
1265
|
soup ??= useConvertChildrenToSoup(children, soup);
|
|
1206
1266
|
if (!soup) return null;
|
|
1207
|
-
const boardGeom = (0,
|
|
1267
|
+
const boardGeom = (0, import_react12.useMemo)(() => {
|
|
1208
1268
|
if (!soup.some((e) => e.type === "pcb_board")) return null;
|
|
1209
1269
|
return createBoardGeomFromSoup(soup);
|
|
1210
1270
|
}, [soup]);
|
|
1211
1271
|
const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
|
|
1212
1272
|
const cad_components = (0, import_soup_util2.su)(soup).cad_component.list();
|
|
1213
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CadViewerContainer, { hoveredComponent, children: [
|
|
1273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CadViewerContainer, { ref, hoveredComponent, children: [
|
|
1214
1274
|
boardStls.map(({ stlUrl, color }, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1215
1275
|
STLModel,
|
|
1216
1276
|
{
|
|
@@ -1250,9 +1310,11 @@ var CadViewer = ({ soup, children }) => {
|
|
|
1250
1310
|
cad_component.cad_component_id
|
|
1251
1311
|
))
|
|
1252
1312
|
] });
|
|
1253
|
-
};
|
|
1313
|
+
});
|
|
1254
1314
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1255
1315
|
0 && (module.exports = {
|
|
1256
|
-
CadViewer
|
|
1316
|
+
CadViewer,
|
|
1317
|
+
useExportGltfUrl,
|
|
1318
|
+
useSaveGltfAs
|
|
1257
1319
|
});
|
|
1258
1320
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/hooks/use-convert-children-to-soup.ts","../src/CadViewer.tsx","../src/soup-to-3d/index.ts","../src/geoms/plated-hole.ts","../src/geoms/constants.ts","../src/geoms/create-board-with-outline.ts","../src/geoms/create-geoms-for-silkscreen-text.ts","../src/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../package.json","../src/three-components/cube-with-labeled-sides.tsx","../src/ContainerWithTooltip.tsx","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx","../src/three-components/JscadModel.tsx","../src/three-components/FootprinterModel.tsx","../src/utils/tuple.ts","../src/AnyCadComponent.tsx","../src/three-components/ThreeErrorBoundary.tsx","../src/three-components/Error3d.tsx"],"sourcesContent":["export { CadViewer } from \"./CadViewer\"\n","import { Circuit } from \"@tscircuit/core\"\nimport { useMemo } from \"react\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnyCircuitElement[],\n): AnyCircuitElement[] => {\n return useMemo(() => {\n if (!children) return\n const circuit = new Circuit()\n circuit.add(children)\n circuit.render()\n return circuit.getCircuitJson() as any\n }, [children])\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useEffect, useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\nimport { AnyCadComponent } from \"./AnyCadComponent\"\nimport { Text } from \"@react-three/drei\"\nimport { ThreeErrorBoundary } from \"./three-components/ThreeErrorBoundary\"\nimport { Error3d } from \"./three-components/Error3d\"\n\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n const [hoveredComponent, setHoveredComponent] = useState<null | {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n }>(null)\n soup ??= useConvertChildrenToSoup(children, soup) as any\n\n if (!soup) return null\n\n const boardGeom = useMemo(() => {\n if (!soup.some((e) => e.type === \"pcb_board\")) return null\n return createBoardGeomFromSoup(soup)\n }, [soup])\n\n const { stls: boardStls, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n return (\n <CadViewerContainer hoveredComponent={hoveredComponent}>\n {boardStls.map(({ stlUrl, color }, index) => (\n <STLModel\n key={stlUrl}\n stlUrl={stlUrl}\n color={color}\n opacity={index === 0 ? 0.95 : 1}\n />\n ))}\n {cad_components.map((cad_component) => (\n <ThreeErrorBoundary\n key={cad_component.cad_component_id}\n fallback={({ error }) => (\n <Error3d cad_component={cad_component} error={error} />\n )}\n >\n <AnyCadComponent\n key={cad_component.cad_component_id}\n onHover={(e) => {\n // TODO this should be done by onUnhover\n if (!e) {\n setHoveredComponent(null)\n }\n if (!e.mousePosition) return\n\n const componentName = su(soup as any).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\n setHoveredComponent({\n cad_component_id: cad_component.cad_component_id,\n name: componentName ?? \"<unknown>\",\n mousePosition: e.mousePosition,\n })\n }}\n cad_component={cad_component}\n isHovered={\n hoveredComponent?.cad_component_id ===\n cad_component.cad_component_id\n }\n />\n </ThreeErrorBoundary>\n ))}\n </CadViewerContainer>\n )\n}\n","import type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { AnySoupElement, PCBPlatedHole } from \"@tscircuit/soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\nimport { cuboid, cylinder, line } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { platedHole } from \"../geoms/plated-hole\"\nimport { M, colors } from \"../geoms/constants\"\nimport { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { expand } from \"@jscad/modeling/src/operations/expansions\"\nimport { createBoardWithOutline } from \"src/geoms/create-board-with-outline\"\nimport { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport { createSilkscreenTextGeoms } from \"src/geoms/create-geoms-for-silkscreen-text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\nexport const createBoardGeomFromSoup = (soup: AnySoupElement[]): Geom3[] => {\n const board = su(soup).pcb_board.list()[0]\n if (!board) {\n throw new Error(\"No pcb_board found\")\n }\n const plated_holes = su(soup).pcb_plated_hole.list()\n const holes = su(soup).pcb_hole.list()\n const pads = su(soup).pcb_smtpad.list()\n const traces = su(soup).pcb_trace.list()\n const pcb_vias = su(soup).pcb_via.list()\n const silkscreenTexts = su(soup).pcb_silkscreen_text.list()\n\n // PCB Board\n let boardGeom: Geom3\n if (board.outline && board.outline.length > 0)\n boardGeom = createBoardWithOutline(board.outline, 1.2)\n else boardGeom = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: Geom3[] = []\n const holeGeoms: Geom3[] = []\n const padGeoms: Geom3[] = []\n const traceGeoms: Geom3[] = []\n const ctx = {\n pcbThickness: 1.2,\n }\n\n const addPlatedHole = (plated_hole: PCBPlatedHole) => {\n if (plated_hole.shape === \"circle\") {\n const cyGeom = cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 + M,\n })\n\n boardGeom = subtract(boardGeom, cyGeom)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n } else if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const pillHole = union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.5]\n : [rectLength, holeHeight, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n )\n boardGeom = subtract(boardGeom, pillHole)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n }\n }\n\n for (const plated_hole of plated_holes) {\n addPlatedHole(plated_hole)\n }\n\n for (const hole of holes) {\n // @ts-expect-error\n if (hole.hole_shape === \"round\" || hole.hole_shape === \"circle\") {\n const cyGeom = cylinder({\n center: [hole.x, hole.y, 0],\n radius: hole.hole_diameter / 2 + M,\n })\n boardGeom = subtract(boardGeom, cyGeom)\n }\n }\n\n for (const pad of pads) {\n const layerSign = pad.layer === \"bottom\" ? -1 : 1\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n size: [pad.width, pad.height, M],\n }),\n )\n padGeoms.push(padGeom)\n } else if (pad.shape === \"circle\") {\n const padGeom = colorize(\n colors.copper,\n cylinder({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n radius: pad.radius,\n height: M,\n }),\n )\n padGeoms.push(padGeom)\n }\n }\n\n for (const { route: mixedRoute } of traces) {\n if (mixedRoute.length < 2) continue\n\n // Group routes by continuous segments\n const routeSegments: (typeof mixedRoute)[] = []\n let currentSegment: typeof mixedRoute = [mixedRoute[0]!]\n let currentLayer =\n mixedRoute[0]!.route_type === \"wire\" ? mixedRoute[0]!.layer : \"top\"\n\n for (let i = 1; i < mixedRoute.length; i++) {\n const point = mixedRoute[i]!\n\n if (point.route_type === \"via\") {\n // Complete current segment and start a new one\n routeSegments.push(currentSegment)\n currentSegment = [point]\n } else if (point.route_type === \"wire\" && point.layer !== currentLayer) {\n // Complete current segment and start a new one on a different layer\n routeSegments.push(currentSegment)\n currentLayer = point.layer\n currentSegment = [point]\n } else {\n currentSegment.push(point)\n }\n }\n\n // Add the last segment\n routeSegments.push(currentSegment)\n\n // Render each route segment\n for (const route of routeSegments) {\n if (route.length < 2) continue\n\n const linePath = line(route.map((p) => [p.x, p.y]))\n const layerSign =\n route[0]!.route_type === \"via\"\n ? route[0]!.to_layer === \"top\"\n ? 1\n : -1\n : route[0]!.layer === \"top\"\n ? 1\n : -1\n\n let traceGeom = translate(\n [0, 0, (layerSign * 1.2) / 2],\n extrudeLinear(\n { height: M * layerSign },\n expand({ delta: 0.1, corners: \"edge\" }, linePath),\n ),\n )\n\n // Modify via subtraction to preserve trace geometry\n const viaSubtractions = pcb_vias.map((via) =>\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n\n const holeSubtractions = plated_holes\n .filter((ph) => ph.shape === \"circle\")\n .map((ph) =>\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n\n // Subtract vias and holes without removing entire trace\n traceGeom = subtract(traceGeom, ...viaSubtractions, ...holeSubtractions)\n\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n }\n\n for (const via of pcb_vias) {\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: via.hole_diameter,\n outer_diameter: via.outer_diameter,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: \"\",\n })\n }\n // Add silkscreen text\n const silkscreenGeoms: Geom3[] = []\n for (const silkscreenText of silkscreenTexts) {\n const { textOutlines, xOffset, yOffset } = createSilkscreenTextGeoms(\n silkscreenText as PcbSilkscreenText,\n )\n\n for (let outline of textOutlines) {\n // Create path from outline points with alignment offset\n\n const alignedOutline = outline.map((point) => [\n point[0] + xOffset + silkscreenText.anchor_position.x,\n point[1] + yOffset + silkscreenText.anchor_position.y,\n ]) as Vec2[]\n const textPath = line(alignedOutline)\n\n // Scale expansion delta with font size\n const fontSize = silkscreenText.font_size || 0.25\n const expansionDelta = Math.min(\n Math.max(0.01, fontSize * 0.1),\n fontSize * 0.2, // Maximum cap scales with font size\n )\n const expandedPath = expand(\n {\n delta: expansionDelta,\n corners: \"round\",\n },\n textPath,\n )\n\n // Extrude and position the text with smaller height\n let textGeom = translate(\n [0, 0, 0.6], // Position above board\n extrudeLinear(\n { height: 0.012 }, // Thinner extrusion\n expandedPath,\n ),\n )\n\n // Color white like silkscreen\n textGeom = colorize([256, 256, 256], textGeom)\n\n silkscreenGeoms.push(textGeom)\n }\n }\n\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [\n boardGeom,\n ...platedHoleGeoms,\n ...padGeoms,\n ...traceGeoms,\n ...silkscreenGeoms,\n ]\n}\n","import type { PCBPlatedHole } from \"@tscircuit/soup\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport { cuboid, cylinder } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { M, colors } from \"./constants\"\nimport type { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext,\n): Geom3 => {\n if (!(plated_hole as PCBPlatedHole).shape) plated_hole.shape = \"circle\"\n if (plated_hole.shape === \"circle\") {\n return colorize(\n colors.copper,\n subtract(\n union(\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2,\n height: 1.2,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, -1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n ),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 - M,\n height: 1.5,\n }),\n ),\n )\n }\n if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n const outerHeight = shouldRotate\n ? plated_hole.outer_width || holeWidth + 0.2\n : plated_hole.outer_height || holeHeight + 0.2\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const mainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 0]\n : [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.2]\n : [rectLength, holeHeight, 1.2],\n })\n\n const leftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const rightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const outerMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 1.2 / 2]\n : [plated_hole.x, plated_hole.y, 1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const outerLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const outerRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, -1.2 / 2]\n : [plated_hole.x, plated_hole.y, -1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const bottomLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, -1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, -1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n return colorize(\n colors.copper,\n subtract(\n union(\n mainRect,\n leftCap,\n rightCap,\n outerMainRect,\n outerLeftCap,\n outerRightCap,\n bottomMainRect,\n bottomLeftCap,\n bottomRightCap,\n ),\n union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight - M, rectLength, 1.5]\n : [rectLength, holeHeight - M, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n ),\n ),\n )\n // biome-ignore lint/style/noUselessElse: <explanation>\n } else {\n throw new Error(`Unsupported plated hole shape: ${plated_hole.shape}`)\n }\n}\n","import type { RGB } from \"@jscad/modeling/src/colors\"\n\nexport const M = 0.01\n\nexport const colors = {\n copper: [0.9, 0.6, 0.2],\n fr4Green: [0x05 / 255, 0xa3 / 255, 0x2e / 255],\n fr4GreenSolderWithMask: [0x00 / 255, 0x98 / 255, 0x13 / 255],\n} satisfies Record<string, RGB>\n","import { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { polygon } from \"@jscad/modeling/src/primitives\"\nimport type { Geom2, Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport type { Point } from \"@tscircuit/soup\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\n\nconst arePointsClockwise = (points: Vec2[]): boolean => {\n let area = 0\n for (let i = 0; i < points.length; i++) {\n const j = (i + 1) % points.length\n area += points[i]![0] * points[j]![1]\n area -= points[j]![0] * points[i]![1]\n }\n const signedArea = area / 2\n return signedArea <= 0\n}\n\nexport const createBoardWithOutline = (points: Point[], depth = 1.2): Geom3 => {\n let outline: Vec2[] = points.map((point) => [point.x, point.y])\n\n if (arePointsClockwise(outline)) {\n outline = outline.reverse()\n }\n\n const shape: Geom2 = polygon({ points: outline })\n\n let board: Geom3 = extrudeLinear({ height: depth }, shape)\n\n board = translate([0, 0, -depth / 2], board)\n\n return board\n}\n","import { vectorText } from \"@jscad/modeling/src/text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\n\n// Generate 2D text outlines\nexport function createSilkscreenTextGeoms(silkscreenText: PcbSilkscreenText) {\n // Generate 2D text outlines\n const textOutlines = vectorText({\n height: silkscreenText.font_size,\n input: silkscreenText.text,\n })\n // Split number 8 and small e into two parts to fix visual issues\n textOutlines.forEach((outline) => {\n if (outline.length === 29) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 15),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(14, 29),\n )\n } else if (outline.length === 17) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 10),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(9, 17),\n )\n }\n })\n // Calculate text bounds and center point\n const points = textOutlines.flatMap((o) => o)\n const textBounds = {\n minX: Math.min(...points.map((p) => p[0])),\n maxX: Math.max(...points.map((p) => p[0])),\n minY: Math.min(...points.map((p) => p[1])),\n maxY: Math.max(...points.map((p) => p[1])),\n }\n const centerX = (textBounds.minX + textBounds.maxX) / 2\n const centerY = (textBounds.minY + textBounds.maxY) / 2\n\n // Calculate offset based on anchor alignment\n let xOffset = -centerX\n let yOffset = -centerY\n\n // Adjust for specific alignments\n if (silkscreenText.anchor_alignment?.includes(\"right\")) {\n xOffset = -textBounds.maxX\n } else if (silkscreenText.anchor_alignment?.includes(\"left\")) {\n xOffset = -textBounds.minX\n }\n\n if (silkscreenText.anchor_alignment?.includes(\"top\")) {\n yOffset = -textBounds.maxY\n } else if (silkscreenText.anchor_alignment?.includes(\"bottom\")) {\n yOffset = -textBounds.minY\n }\n\n return { textOutlines, xOffset, yOffset }\n}\n","import { useState, useEffect } from \"react\"\nimport stlSerializer from \"@jscad/stl-serializer\"\nimport { Geom3 } from \"@jscad/modeling/src/geometries/types\"\n\nfunction blobToBase64Url(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n resolve(reader.result as string)\n }\n reader.onerror = reject\n reader.readAsDataURL(blob)\n })\n}\n\ntype StlObj = { stlUrl: string; color: number[] }\n\nexport const useStlsFromGeom = (\n geom: Geom3[] | Geom3 | null,\n): {\n stls: StlObj[]\n loading: boolean\n} => {\n const [stls, setStls] = useState<StlObj[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n if (!geom) return\n const generateStls = async () => {\n setLoading(true)\n const geometries = Array.isArray(geom) ? geom : [geom]\n\n const stlPromises = geometries.map(async (g) => {\n const rawData = stlSerializer.serialize({ binary: true }, [g])\n const blobData = new Blob(rawData)\n const stlUrl = await blobToBase64Url(blobData)\n return { stlUrl, color: g.color! }\n })\n\n try {\n const generatedStls = await Promise.all(stlPromises)\n setStls(generatedStls)\n } catch (error) {\n console.error(\"Error generating STLs:\", error)\n setStls([])\n } finally {\n setLoading(false)\n }\n }\n\n generateStls()\n }, [geom])\n\n return { stls, loading }\n}\n","import { useLoader } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\n\nexport function STLModel({\n stlUrl,\n mtlUrl,\n color,\n opacity = 1,\n}: {\n stlUrl: string\n color?: any\n mtlUrl?: string\n opacity?: number\n}) {\n const geom = useLoader(STLLoader, stlUrl)\n const mesh = useRef<THREE.Mesh>()\n\n // TODO handle mtl url\n\n return (\n <mesh ref={mesh as any}>\n <primitive object={geom} attach=\"geometry\" />\n <meshStandardMaterial\n color={color}\n transparent={opacity !== 1}\n opacity={opacity}\n />\n {/* <Outlines thickness={0.05} color=\"black\" opacity={0.25} /> */}\n </mesh>\n )\n}\n","import { Grid, OrbitControls } from \"@react-three/drei\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport packageJson from \"../package.json\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\n\nexport const RotationTracker = () => {\n useFrame(({ camera }) => {\n window.TSCI_MAIN_CAMERA_ROTATION = camera.rotation\n })\n\n return <></>\n}\n\nimport { Html } from \"@react-three/drei\"\n\nexport const CadViewerContainer = ({\n children,\n hoveredComponent,\n}: {\n children: any\n hoveredComponent: {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n } | null\n}) => {\n return (\n <div style={{ position: \"relative\", width: \"100%\", height: \"100%\" }}>\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 120,\n height: 120,\n }}\n >\n <Canvas\n camera={{\n up: [0, 0, 1],\n position: [1, 1, 1],\n }}\n style={{ zIndex: 10 }}\n >\n <ambientLight intensity={Math.PI / 2} />\n <CubeWithLabeledSides />\n </Canvas>\n </div>\n <Canvas\n scene={{ up: [0, 0, 1] }}\n camera={{ up: [0, 0, 1], position: [5, 5, 5] }}\n >\n <RotationTracker />\n <OrbitControls autoRotate autoRotateSpeed={1} />\n <ambientLight intensity={Math.PI / 2} />\n <pointLight\n position={[-10, -10, 10]}\n decay={0}\n intensity={Math.PI / 4}\n />\n <Grid\n rotation={[Math.PI / 2, 0, 0]}\n infiniteGrid={true}\n cellSize={1}\n sectionSize={10}\n />\n {children}\n {hoveredComponent && (\n <Html\n position={hoveredComponent.mousePosition}\n style={{\n fontFamily: \"sans-serif\",\n transform: \"translate3d(50%, 50%, 0)\",\n backgroundColor: \"white\",\n padding: \"5px\",\n borderRadius: \"3px\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n }}\n >\n {hoveredComponent.name}\n </Html>\n )}\n </Canvas>\n <div\n style={{\n position: \"absolute\",\n right: 24,\n bottom: 24,\n fontFamily: \"sans-serif\",\n color: \"white\",\n WebkitTextStroke: \"0.5px rgba(0, 0, 0, 0.5)\",\n fontSize: 11,\n }}\n >\n @{packageJson.version}\n </div>\n </div>\n )\n}\n","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.79\",\n \"main\": \"./dist/index.js\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"start\": \"bun run storybook\",\n \"dev:old\": \"bunx --bun vite\",\n \"build\": \"tsup ./src/index.tsx --dts --sourcemap\",\n \"prepublish\": \"npm run build\",\n \"preview\": \"vite preview\",\n \"storybook\": \"storybook dev -p 6006\",\n \"build-storybook\": \"storybook build\",\n \"vercel-build\": \"bun run build-storybook\",\n \"format\": \"biome format . --write\",\n \"format:check\": \"biome format .\"\n },\n \"dependencies\": {\n \"@jscad/modeling\": \"^2.12.2\",\n \"@jscad/regl-renderer\": \"^2.6.9\",\n \"@jscad/stl-serializer\": \"^2.1.17\",\n \"@react-three/drei\": \"^9.115.0\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@tscircuit/core\": \"^0.0.251\",\n \"@tscircuit/props\": \"^0.0.124\",\n \"@tscircuit/react-fiber\": \"^1.1.29\",\n \"@tscircuit/soup\": \"^0.0.69\",\n \"@tscircuit/soup-util\": \"^0.0.26\",\n \"@types/three\": \"^0.165.0\",\n \"jscad-electronics\": \"^0.0.23\",\n \"jscad-fiber\": \"^0.0.76\",\n \"jscad-planner\": \"^0.0.11\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-use-gesture\": \"^9.1.3\",\n \"three\": \"^0.165.0\",\n \"three-stdlib\": \"^2.30.3\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.8.3\",\n \"@chromatic-com/storybook\": \"^1.5.0\",\n \"@storybook/addon-essentials\": \"^8.1.10\",\n \"@storybook/addon-interactions\": \"^8.1.10\",\n \"@storybook/addon-links\": \"^8.1.10\",\n \"@storybook/addon-onboarding\": \"^8.1.10\",\n \"@storybook/blocks\": \"^8.1.10\",\n \"@storybook/builder-vite\": \"^8.1.10\",\n \"@storybook/react\": \"^8.1.10\",\n \"@storybook/react-vite\": \"^8.1.10\",\n \"@storybook/test\": \"^8.1.10\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.1\",\n \"circuit-json\": \"^0.0.116\",\n \"circuit-to-svg\": \"^0.0.91\",\n \"storybook\": \"^8.1.10\",\n \"strip-ansi\": \"^7.1.0\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.5.3\",\n \"vite\": \"^5.3.1\",\n \"vite-tsconfig-paths\": \"^4.3.2\"\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport { useFrame } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\n\ndeclare global {\n interface Window {\n TSCI_MAIN_CAMERA_ROTATION: THREE.Euler\n }\n}\nif (typeof window !== \"undefined\") {\n window.TSCI_MAIN_CAMERA_ROTATION = new THREE.Euler(0, 0, 0)\n}\n\nfunction computePointInFront(rotationVector, distance) {\n // Create a quaternion from the rotation vector\n const quaternion = new THREE.Quaternion().setFromEuler(\n new THREE.Euler(rotationVector.x, rotationVector.y, rotationVector.z),\n )\n\n // Create a vector pointing forward (along the negative z-axis)\n const forwardVector = new THREE.Vector3(0, 0, 1)\n\n // Apply the rotation to the forward vector\n forwardVector.applyQuaternion(quaternion)\n\n // Scale the rotated vector by the distance\n const result = forwardVector.multiplyScalar(distance)\n\n return result\n}\n\nexport const CubeWithLabeledSides = ({}: any) => {\n const ref = useRef<THREE.Mesh>()\n const rotationTrackingRef = useRef({ lastRotation: new THREE.Euler() })\n useFrame((state, delta) => {\n if (!ref.current) return\n\n const mainRot = window.TSCI_MAIN_CAMERA_ROTATION\n\n // Use window.TSCI_CAMERA_ROTATION to compute the position of the camera\n const cameraPosition = computePointInFront(mainRot, 2)\n\n state.camera.position.copy(cameraPosition)\n state.camera.lookAt(0, 0, 0)\n })\n return (\n <mesh ref={ref as any} rotation={[Math.PI / 2, 0, 0]}>\n <boxGeometry args={[1, 1, 1]} />\n <meshStandardMaterial color=\"white\" />\n <Text position={[0, 0, 0.51]} fontSize={0.25} color=\"black\">\n Front\n </Text>\n <Text\n position={[0, 0, -0.51]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI, 0]}\n >\n Back\n </Text>\n <Text\n position={[0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI / 2, 0]}\n >\n Right\n </Text>\n <Text\n position={[-0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, -Math.PI / 2, 0]}\n >\n Left\n </Text>\n <Text\n position={[0, 0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[-Math.PI / 2, 0, 0]}\n >\n Top\n </Text>\n <Text\n position={[0, -0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[Math.PI / 2, 0, 0]}\n >\n Bottom\n </Text>\n <lineSegments\n args={[new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1))]}\n material={\n new THREE.LineBasicMaterial({\n color: 0x000000,\n linewidth: 2,\n })\n }\n />\n </mesh>\n )\n}\n","import { Html } from \"@react-three/drei\"\nimport { GroupProps, useThree } from \"@react-three/fiber\"\nimport { useRef, useCallback } from \"react\"\nimport type { Vector3 } from \"three\"\nimport * as THREE from \"three\"\n\nconst Group = (props: GroupProps) => <group {...props} />\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n position,\n}: {\n children: React.ReactNode\n position?: Vector3 | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const lastValidPointRef = useRef<THREE.Vector3 | null>(null)\n\n const handlePointerEnter = useCallback(\n (e: any) => {\n e.stopPropagation()\n\n try {\n // Fallback to event position if raycaster fails\n const point =\n e.point ||\n (e.intersections && e.intersections.length > 0\n ? e.intersections[0].point\n : null) ||\n (position\n ? new THREE.Vector3(...(position as [number, number, number]))\n : null)\n\n if (point) {\n lastValidPointRef.current = point\n onHover({ mousePosition: [point.x, point.y, point.z] })\n } else {\n onHover({})\n }\n } catch (error) {\n console.warn(\"Hover event error:\", error)\n onHover({})\n }\n },\n [position],\n )\n\n const handlePointerLeave = useCallback(\n (e: any) => {\n e.stopPropagation()\n lastValidPointRef.current = null\n\n // TODO REPLACE WITH onUnhover\n onHover(null)\n },\n [onHover],\n )\n\n return (\n <Group\n onPointerEnter={handlePointerEnter}\n onPointerMove={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </Group>\n )\n}\n\nexport default ContainerWithTooltip\n","import { useState, useEffect } from \"react\"\nimport type { Group } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\n// Define the type for our cache\ninterface CacheItem {\n promise: Promise<any>\n result: Group | null\n}\n\ndeclare global {\n interface Window {\n TSCIRCUIT_OBJ_LOADER_CACHE: Map<string, CacheItem>\n }\n}\n\n// Ensure the global cache exists\nif (typeof window !== \"undefined\" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {\n window.TSCIRCUIT_OBJ_LOADER_CACHE = new Map<string, CacheItem>()\n}\n\nexport function useGlobalObjLoader(url: string | null): Group | null | Error {\n const [obj, setObj] = useState<Group | null | Error>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n let hasUrlChanged = false\n\n async function loadAndParseObj() {\n try {\n const response = await fetch(url!)\n const text = await response.text()\n\n const mtlContent = text\n .match(/newmtl[\\s\\S]*?endmtl/g)\n ?.join(\"\\n\")!\n .replace(/d 0\\./g, \"d 1.\")!\n const objContent = text.replace(/newmtl[\\s\\S]*?endmtl/g, \"\")\n\n const mtlLoader = new MTLLoader()\n mtlLoader.setMaterialOptions({\n invertTrProperty: true,\n })\n const materials = mtlLoader.parse(\n mtlContent.replace(\n /Kd\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)/g,\n \"Kd $2 $2 $2\",\n ),\n \"test.mtl\",\n )\n\n const objLoader = new OBJLoader()\n objLoader.setMaterials(materials)\n return objLoader.parse(objContent)\n } catch (error) {\n return error as Error\n }\n }\n\n function loadUrl() {\n if (cache.has(url!)) {\n const cacheItem = cache.get(url!)!\n if (cacheItem.result) {\n // If we have a result, clone it\n return Promise.resolve(cacheItem.result.clone())\n }\n // If we're still loading, return the existing promise\n return cacheItem.promise.then((result) => result.clone())\n }\n // If it's not in the cache, create a new promise and cache it\n const promise = loadAndParseObj().then((result) => {\n if (result instanceof Error) {\n // If the result is an Error, return it\n return result\n }\n cache.set(url!, { ...cache.get(url!)!, result })\n return result\n })\n cache.set(url!, { promise, result: null })\n return promise\n }\n\n loadUrl()\n .then((result) => {\n if (hasUrlChanged) return\n setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n return () => {\n hasUrlChanged = true\n }\n }, [url])\n\n return obj\n}\n","import ContainerWithTooltip from \"src/ContainerWithTooltip\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport type { Euler, Vector3 } from \"three\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.25} />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n\n // Check if obj is valid before rendering\n if (obj instanceof Error) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.5} />\n <meshBasicMaterial color=\"red\" />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <primitive rotation={rotation} position={position} object={obj} />\n </ContainerWithTooltip>\n )\n}\n","import type { JscadOperation } from \"jscad-planner\"\nimport { executeJscadOperations } from \"jscad-planner\"\nimport jscad from \"@jscad/modeling\"\nimport { convertCSGToThreeGeom } from \"jscad-fiber\"\nimport * as THREE from \"three\"\nimport { useMemo } from \"react\"\nimport ContainerWithTooltip from \"src/ContainerWithTooltip\"\n\nexport const JscadModel = ({\n jscadPlan,\n positionOffset,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const { threeGeom, material } = useMemo(() => {\n const jscadObject = executeJscadOperations(jscad as any, jscadPlan)\n\n const threeGeom = convertCSGToThreeGeom(jscadObject)\n\n const material = new THREE.MeshStandardMaterial({\n vertexColors: true,\n side: THREE.DoubleSide, // Ensure both sides are visible\n })\n return { threeGeom, material }\n }, [jscadPlan])\n\n useMemo(() => {\n if (isHovered) {\n const color = new THREE.Color(material.color.getHex())\n material.emissive.copy(color)\n material.emissive.setRGB(0, 0, 1)\n material.emissiveIntensity = 0.2\n } else {\n material.emissiveIntensity = 0\n }\n }, [isHovered, material])\n if (!threeGeom) return null\n\n return (\n <ContainerWithTooltip\n isHovered={isHovered}\n onHover={onHover}\n position={positionOffset}\n >\n <mesh\n geometry={threeGeom}\n material={material}\n position={positionOffset}\n rotation={rotationOffset}\n />\n </ContainerWithTooltip>\n )\n}\n","import { Footprinter3d } from \"jscad-electronics\"\nimport { createJSCADRenderer } from \"jscad-fiber\"\nimport { jscadPlanner } from \"jscad-planner\"\nimport { useMemo } from \"react\"\nimport { JscadModel } from \"./JscadModel\"\n\nconst { createJSCADRoot } = createJSCADRenderer(jscadPlanner as any)\n\nexport const FootprinterModel = ({\n positionOffset,\n footprint,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const jscadOperations = useMemo(() => {\n if (!footprint) return null\n const jscadOperations: any[] = []\n const root = createJSCADRoot(jscadOperations)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadOperations\n }, [footprint])\n\n if (!jscadOperations) return null\n\n return (\n <>\n {jscadOperations.map((operation, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={operation}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\n","import type { AnyCircuitElement, CadComponent } from \"circuit-json\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\n\nexport const AnyCadComponent = ({\n cad_component,\n onHover = () => {},\n isHovered = false,\n}: {\n cad_component: CadComponent\n onHover?: (e: any) => void\n isHovered?: boolean\n}) => {\n const url = cad_component.model_obj_url ?? cad_component.model_stl_url\n const rotationOffset = cad_component.rotation\n ? tuple(\n (cad_component.rotation.x * Math.PI) / 180,\n (cad_component.rotation.y * Math.PI) / 180,\n (cad_component.rotation.z * Math.PI) / 180,\n )\n : undefined\n\n if (url) {\n return (\n <MixedStlModel\n key={cad_component.cad_component_id}\n url={url}\n position={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotation={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.model_jscad) {\n return (\n <JscadModel\n key={cad_component.cad_component_id}\n jscadPlan={cad_component.model_jscad as any}\n rotationOffset={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.footprinter_string) {\n return (\n <FootprinterModel\n positionOffset={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotationOffset={rotationOffset}\n footprint={cad_component.footprinter_string}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n}\n","import React from \"react\"\n\ninterface Props {\n children: React.ReactNode\n fallback: (props: { error: Error }) => any\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n}\n\nexport class ThreeErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error }\n }\n\n override render() {\n if (this.state.hasError && this.state.error) {\n return this.props.fallback({ error: this.state.error })\n }\n\n return this.props.children\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport type { CadComponent } from \"circuit-json\"\n\nexport const Error3d = ({\n error,\n cad_component,\n}: { error: any; cad_component?: CadComponent }) => {\n let position = [0, 0, 0]\n if (cad_component?.position) {\n position = [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n // make sure the position doesn't have any NaN values\n position = position.map((p) => (Number.isNaN(p) ? 0 : p))\n }\n return (\n <group\n // @ts-expect-error\n position={position}\n >\n <mesh\n renderOrder={-99999}\n rotation={[Math.PI / 4, Math.PI / 4, 0]}\n ref={(mesh) => {\n if (mesh) {\n mesh.renderOrder = 999999\n }\n }}\n >\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial\n depthTest={false}\n transparent\n color=\"red\"\n opacity={0.5}\n />\n </mesh>\n <Text\n scale={[0.1, 0.1, 0.1]}\n color=\"red\" // default\n anchorX=\"center\" // default\n anchorY=\"middle\" // default\n depthOffset={-99999}\n >\n {error.toString().slice(0, 50)}...\n </Text>\n </group>\n ) as any\n}\n"],"mappings":"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","names":["import_soup_util","import_react","import_transforms","import_primitives","import_colors","import_booleans","import_extrusions","import_primitives","import_react","stlSerializer","import_react","import_drei","import_fiber","import_fiber","import_react","import_jsx_runtime","import_drei","import_jsx_runtime","import_react","THREE","import_jsx_runtime","import_react","import_three_stdlib","import_jsx_runtime","THREE","import_react","import_jsx_runtime","jscad","threeGeom","material","import_jscad_fiber","import_jscad_planner","import_react","import_jsx_runtime","jscadOperations","import_jsx_runtime","import_react","React","import_drei","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/hooks/exporter/gltf.ts","../src/hooks/use-convert-children-to-soup.ts","../src/CadViewer.tsx","../src/soup-to-3d/index.ts","../src/geoms/plated-hole.ts","../src/geoms/constants.ts","../src/geoms/create-board-with-outline.ts","../src/geoms/create-geoms-for-silkscreen-text.ts","../src/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../package.json","../src/three-components/cube-with-labeled-sides.tsx","../src/ContainerWithTooltip.tsx","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx","../src/three-components/JscadModel.tsx","../src/three-components/FootprinterModel.tsx","../src/utils/tuple.ts","../src/AnyCadComponent.tsx","../src/three-components/ThreeErrorBoundary.tsx","../src/three-components/Error3d.tsx"],"sourcesContent":["export * from \"./hooks/index.ts\"\nexport { CadViewer } from \"./CadViewer.tsx\"\n","import type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { GLTFExporter, type GLTFExporterOptions } from \"three-stdlib\"\nimport { useEffect, useState, useMemo, useCallback } from \"react\"\n\ntype Options = Omit<\n GLTFExporterOptions,\n \"animations\" | \"includeCustomExtensions\"\n>\n\nexport function useSaveGltfAs(\n options = {} as Options & { filename?: string },\n): [\n ref3D: React.ForwardedRef<THREE.Object3D>,\n saveAs: (filename?: string) => Promise<void>,\n] {\n const parse = useParser(options)\n const link = useMemo(() => document.createElement(\"a\"), [])\n const saveAs = async (filename?: string) => {\n const name = filename ?? options.filename ?? \"\"\n if (options.binary == null) options.binary = name.endsWith(\".glb\")\n const url = await parse(instance!)\n link.download = name\n link.href = url\n link.dispatchEvent(new MouseEvent(\"click\"))\n URL.revokeObjectURL(url)\n }\n\n useEffect(\n () => () => {\n link.remove()\n instance = null\n },\n [],\n )\n\n let instance: THREE.Object3D | null\n const ref = useCallback((obj3D: THREE.Object3D | null) => {\n instance = obj3D!\n }, [])\n\n return [ref, saveAs]\n}\n\nexport function useExportGltfUrl(\n options = {} as Options,\n): [\n ref3D: React.ForwardedRef<THREE.Object3D>,\n url: string | undefined,\n error: ErrorEvent | undefined,\n] {\n const parse = useParser(options)\n const [url, setUrl] = useState<string>()\n const [error, setError] = useState<ErrorEvent>()\n const ref = useCallback(\n (instance: THREE.Object3D | null) =>\n parse(instance!).then(setUrl).catch(setError),\n [],\n )\n useEffect(() => () => URL.revokeObjectURL(url!), [url])\n return [ref, url, error]\n}\n\nfunction useParser(options = {} as Options) {\n const exporter = useMemo(() => new GLTFExporter(), [])\n return (instance: THREE.Object3D) => {\n const { promise, resolve, reject } = Promise.withResolvers<string>()\n exporter.parse(\n instance,\n (gltf) => {\n const type = options.binary ? \"gltf-binary\" : \"gltf+json\"\n const blob = new Blob(\n [gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],\n { type: `model/${type}` },\n )\n resolve(URL.createObjectURL(blob))\n },\n reject,\n options,\n )\n return promise\n }\n}\n","import { Circuit } from \"@tscircuit/core\"\nimport { useMemo } from \"react\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnyCircuitElement[],\n): AnyCircuitElement[] => {\n return useMemo(() => {\n if (!children) return\n const circuit = new Circuit()\n circuit.add(children)\n circuit.render()\n return circuit.getCircuitJson() as any\n }, [children])\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useEffect, useMemo, useState, forwardRef } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\nimport { AnyCadComponent } from \"./AnyCadComponent\"\nimport { Text } from \"@react-three/drei\"\nimport { ThreeErrorBoundary } from \"./three-components/ThreeErrorBoundary\"\nimport { Error3d } from \"./three-components/Error3d\"\n\ninterface Props {\n soup?: AnySoupElement[]\n}\n\nexport const CadViewer = forwardRef<\n THREE.Object3D,\n React.PropsWithChildren<Props>\n>(({ soup, children }, ref) => {\n const [hoveredComponent, setHoveredComponent] = useState<null | {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n }>(null)\n soup ??= useConvertChildrenToSoup(children, soup) as any\n\n if (!soup) return null\n\n const boardGeom = useMemo(() => {\n if (!soup.some((e) => e.type === \"pcb_board\")) return null\n return createBoardGeomFromSoup(soup)\n }, [soup])\n\n const { stls: boardStls, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n return (\n <CadViewerContainer ref={ref} hoveredComponent={hoveredComponent}>\n {boardStls.map(({ stlUrl, color }, index) => (\n <STLModel\n key={stlUrl}\n stlUrl={stlUrl}\n color={color}\n opacity={index === 0 ? 0.95 : 1}\n />\n ))}\n {cad_components.map((cad_component) => (\n <ThreeErrorBoundary\n key={cad_component.cad_component_id}\n fallback={({ error }) => (\n <Error3d cad_component={cad_component} error={error} />\n )}\n >\n <AnyCadComponent\n key={cad_component.cad_component_id}\n onHover={(e) => {\n // TODO this should be done by onUnhover\n if (!e) {\n setHoveredComponent(null)\n }\n if (!e.mousePosition) return\n\n const componentName = su(soup as any).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\n setHoveredComponent({\n cad_component_id: cad_component.cad_component_id,\n name: componentName ?? \"<unknown>\",\n mousePosition: e.mousePosition,\n })\n }}\n cad_component={cad_component}\n isHovered={\n hoveredComponent?.cad_component_id ===\n cad_component.cad_component_id\n }\n />\n </ThreeErrorBoundary>\n ))}\n </CadViewerContainer>\n )\n})\n","import type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { AnySoupElement, PCBPlatedHole } from \"@tscircuit/soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\nimport { cuboid, cylinder, line } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { platedHole } from \"../geoms/plated-hole\"\nimport { M, colors } from \"../geoms/constants\"\nimport { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { expand } from \"@jscad/modeling/src/operations/expansions\"\nimport { createBoardWithOutline } from \"src/geoms/create-board-with-outline\"\nimport { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport { createSilkscreenTextGeoms } from \"src/geoms/create-geoms-for-silkscreen-text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\nexport const createBoardGeomFromSoup = (soup: AnySoupElement[]): Geom3[] => {\n const board = su(soup).pcb_board.list()[0]\n if (!board) {\n throw new Error(\"No pcb_board found\")\n }\n const plated_holes = su(soup).pcb_plated_hole.list()\n const holes = su(soup).pcb_hole.list()\n const pads = su(soup).pcb_smtpad.list()\n const traces = su(soup).pcb_trace.list()\n const pcb_vias = su(soup).pcb_via.list()\n const silkscreenTexts = su(soup).pcb_silkscreen_text.list()\n\n // PCB Board\n let boardGeom: Geom3\n if (board.outline && board.outline.length > 0)\n boardGeom = createBoardWithOutline(board.outline, 1.2)\n else boardGeom = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: Geom3[] = []\n const holeGeoms: Geom3[] = []\n const padGeoms: Geom3[] = []\n const traceGeoms: Geom3[] = []\n const ctx = {\n pcbThickness: 1.2,\n }\n\n const addPlatedHole = (plated_hole: PCBPlatedHole) => {\n if (plated_hole.shape === \"circle\") {\n const cyGeom = cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 + M,\n })\n\n boardGeom = subtract(boardGeom, cyGeom)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n } else if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const pillHole = union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.5]\n : [rectLength, holeHeight, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n )\n boardGeom = subtract(boardGeom, pillHole)\n\n const platedHoleGeom = platedHole(plated_hole, ctx)\n platedHoleGeoms.push(platedHoleGeom)\n }\n }\n\n for (const plated_hole of plated_holes) {\n addPlatedHole(plated_hole)\n }\n\n for (const hole of holes) {\n // @ts-expect-error\n if (hole.hole_shape === \"round\" || hole.hole_shape === \"circle\") {\n const cyGeom = cylinder({\n center: [hole.x, hole.y, 0],\n radius: hole.hole_diameter / 2 + M,\n })\n boardGeom = subtract(boardGeom, cyGeom)\n }\n }\n\n for (const pad of pads) {\n const layerSign = pad.layer === \"bottom\" ? -1 : 1\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n size: [pad.width, pad.height, M],\n }),\n )\n padGeoms.push(padGeom)\n } else if (pad.shape === \"circle\") {\n const padGeom = colorize(\n colors.copper,\n cylinder({\n center: [pad.x, pad.y, (layerSign * 1.2) / 2 + layerSign * M],\n radius: pad.radius,\n height: M,\n }),\n )\n padGeoms.push(padGeom)\n }\n }\n\n for (const { route: mixedRoute } of traces) {\n if (mixedRoute.length < 2) continue\n\n // Group routes by continuous segments\n const routeSegments: (typeof mixedRoute)[] = []\n let currentSegment: typeof mixedRoute = [mixedRoute[0]!]\n let currentLayer =\n mixedRoute[0]!.route_type === \"wire\" ? mixedRoute[0]!.layer : \"top\"\n\n for (let i = 1; i < mixedRoute.length; i++) {\n const point = mixedRoute[i]!\n\n if (point.route_type === \"via\") {\n // Complete current segment and start a new one\n routeSegments.push(currentSegment)\n currentSegment = [point]\n } else if (point.route_type === \"wire\" && point.layer !== currentLayer) {\n // Complete current segment and start a new one on a different layer\n routeSegments.push(currentSegment)\n currentLayer = point.layer\n currentSegment = [point]\n } else {\n currentSegment.push(point)\n }\n }\n\n // Add the last segment\n routeSegments.push(currentSegment)\n\n // Render each route segment\n for (const route of routeSegments) {\n if (route.length < 2) continue\n\n const linePath = line(route.map((p) => [p.x, p.y]))\n const layerSign =\n route[0]!.route_type === \"via\"\n ? route[0]!.to_layer === \"top\"\n ? 1\n : -1\n : route[0]!.layer === \"top\"\n ? 1\n : -1\n\n let traceGeom = translate(\n [0, 0, (layerSign * 1.2) / 2],\n extrudeLinear(\n { height: M * layerSign },\n expand({ delta: 0.1, corners: \"edge\" }, linePath),\n ),\n )\n\n // Modify via subtraction to preserve trace geometry\n const viaSubtractions = pcb_vias.map((via) =>\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n\n const holeSubtractions = plated_holes\n .filter((ph) => ph.shape === \"circle\")\n .map((ph) =>\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n\n // Subtract vias and holes without removing entire trace\n traceGeom = subtract(traceGeom, ...viaSubtractions, ...holeSubtractions)\n\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n }\n\n for (const via of pcb_vias) {\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: via.hole_diameter,\n outer_diameter: via.outer_diameter,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: \"\",\n })\n }\n // Add silkscreen text\n const silkscreenGeoms: Geom3[] = []\n for (const silkscreenText of silkscreenTexts) {\n const { textOutlines, xOffset, yOffset } = createSilkscreenTextGeoms(\n silkscreenText as PcbSilkscreenText,\n )\n\n for (let outline of textOutlines) {\n // Create path from outline points with alignment offset\n\n const alignedOutline = outline.map((point) => [\n point[0] + xOffset + silkscreenText.anchor_position.x,\n point[1] + yOffset + silkscreenText.anchor_position.y,\n ]) as Vec2[]\n const textPath = line(alignedOutline)\n\n // Scale expansion delta with font size\n const fontSize = silkscreenText.font_size || 0.25\n const expansionDelta = Math.min(\n Math.max(0.01, fontSize * 0.1),\n fontSize * 0.2, // Maximum cap scales with font size\n )\n const expandedPath = expand(\n {\n delta: expansionDelta,\n corners: \"round\",\n },\n textPath,\n )\n\n // Extrude and position the text with smaller height\n let textGeom = translate(\n [0, 0, 0.6], // Position above board\n extrudeLinear(\n { height: 0.012 }, // Thinner extrusion\n expandedPath,\n ),\n )\n\n // Color white like silkscreen\n textGeom = colorize([256, 256, 256], textGeom)\n\n silkscreenGeoms.push(textGeom)\n }\n }\n\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [\n boardGeom,\n ...platedHoleGeoms,\n ...padGeoms,\n ...traceGeoms,\n ...silkscreenGeoms,\n ]\n}\n","import type { PCBPlatedHole } from \"@tscircuit/soup\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport { cuboid, cylinder } from \"@jscad/modeling/src/primitives\"\nimport { colorize } from \"@jscad/modeling/src/colors\"\nimport { subtract, union } from \"@jscad/modeling/src/operations/booleans\"\nimport { M, colors } from \"./constants\"\nimport type { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext,\n): Geom3 => {\n if (!(plated_hole as PCBPlatedHole).shape) plated_hole.shape = \"circle\"\n if (plated_hole.shape === \"circle\") {\n return colorize(\n colors.copper,\n subtract(\n union(\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2,\n height: 1.2,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n cylinder({\n center: [plated_hole.x, plated_hole.y, -1.2 / 2],\n radius: plated_hole.outer_diameter / 2,\n height: M,\n }),\n ),\n cylinder({\n center: [plated_hole.x, plated_hole.y, 0],\n radius: plated_hole.hole_diameter / 2 - M,\n height: 1.5,\n }),\n ),\n )\n }\n if (plated_hole.shape === \"pill\") {\n const shouldRotate = plated_hole.hole_height! > plated_hole.hole_width!\n\n const holeWidth = shouldRotate\n ? plated_hole.hole_height!\n : plated_hole.hole_width!\n const holeHeight = shouldRotate\n ? plated_hole.hole_width!\n : plated_hole.hole_height!\n const outerHeight = shouldRotate\n ? plated_hole.outer_width || holeWidth + 0.2\n : plated_hole.outer_height || holeHeight + 0.2\n\n const holeRadius = holeHeight / 2\n const rectLength = Math.abs(holeWidth - holeHeight)\n\n const mainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 0]\n : [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight, rectLength, 1.2]\n : [rectLength, holeHeight, 1.2],\n })\n\n const leftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const rightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2,\n })\n\n const outerMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, 1.2 / 2]\n : [plated_hole.x, plated_hole.y, 1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const outerLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const outerRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomMainRect = cuboid({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y, -1.2 / 2]\n : [plated_hole.x, plated_hole.y, -1.2 / 2],\n size: shouldRotate\n ? [outerHeight, rectLength, M]\n : [rectLength, outerHeight, M],\n })\n\n const bottomLeftCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, -1.2 / 2]\n : [plated_hole.x - rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n\n const bottomRightCap = cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, -1.2 / 2]\n : [plated_hole.x + rectLength / 2, plated_hole.y, -1.2 / 2],\n radius: outerHeight / 2,\n height: M,\n })\n return colorize(\n colors.copper,\n subtract(\n union(\n mainRect,\n leftCap,\n rightCap,\n outerMainRect,\n outerLeftCap,\n outerRightCap,\n bottomMainRect,\n bottomLeftCap,\n bottomRightCap,\n ),\n union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: shouldRotate\n ? [holeHeight - M, rectLength, 1.5]\n : [rectLength, holeHeight - M, 1.5],\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y - rectLength / 2, 0]\n : [plated_hole.x - rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n cylinder({\n center: shouldRotate\n ? [plated_hole.x, plated_hole.y + rectLength / 2, 0]\n : [plated_hole.x + rectLength / 2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5,\n }),\n ),\n ),\n )\n // biome-ignore lint/style/noUselessElse: <explanation>\n } else {\n throw new Error(`Unsupported plated hole shape: ${plated_hole.shape}`)\n }\n}\n","import type { RGB } from \"@jscad/modeling/src/colors\"\n\nexport const M = 0.01\n\nexport const colors = {\n copper: [0.9, 0.6, 0.2],\n fr4Green: [0x05 / 255, 0xa3 / 255, 0x2e / 255],\n fr4GreenSolderWithMask: [0x00 / 255, 0x98 / 255, 0x13 / 255],\n} satisfies Record<string, RGB>\n","import { extrudeLinear } from \"@jscad/modeling/src/operations/extrusions\"\nimport { polygon } from \"@jscad/modeling/src/primitives\"\nimport type { Geom2, Geom3 } from \"@jscad/modeling/src/geometries/types\"\nimport type { Vec2 } from \"@jscad/modeling/src/maths/types\"\nimport type { Point } from \"@tscircuit/soup\"\nimport { translate } from \"@jscad/modeling/src/operations/transforms\"\n\nconst arePointsClockwise = (points: Vec2[]): boolean => {\n let area = 0\n for (let i = 0; i < points.length; i++) {\n const j = (i + 1) % points.length\n area += points[i]![0] * points[j]![1]\n area -= points[j]![0] * points[i]![1]\n }\n const signedArea = area / 2\n return signedArea <= 0\n}\n\nexport const createBoardWithOutline = (points: Point[], depth = 1.2): Geom3 => {\n let outline: Vec2[] = points.map((point) => [point.x, point.y])\n\n if (arePointsClockwise(outline)) {\n outline = outline.reverse()\n }\n\n const shape: Geom2 = polygon({ points: outline })\n\n let board: Geom3 = extrudeLinear({ height: depth }, shape)\n\n board = translate([0, 0, -depth / 2], board)\n\n return board\n}\n","import { vectorText } from \"@jscad/modeling/src/text\"\nimport { PcbSilkscreenText } from \"circuit-json\"\n\n// Generate 2D text outlines\nexport function createSilkscreenTextGeoms(silkscreenText: PcbSilkscreenText) {\n // Generate 2D text outlines\n const textOutlines = vectorText({\n height: silkscreenText.font_size,\n input: silkscreenText.text,\n })\n // Split number 8 and small e into two parts to fix visual issues\n textOutlines.forEach((outline) => {\n if (outline.length === 29) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 15),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(14, 29),\n )\n } else if (outline.length === 17) {\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 1,\n outline.slice(0, 10),\n )\n textOutlines.splice(\n textOutlines.indexOf(outline),\n 0,\n outline.slice(9, 17),\n )\n }\n })\n // Calculate text bounds and center point\n const points = textOutlines.flatMap((o) => o)\n const textBounds = {\n minX: Math.min(...points.map((p) => p[0])),\n maxX: Math.max(...points.map((p) => p[0])),\n minY: Math.min(...points.map((p) => p[1])),\n maxY: Math.max(...points.map((p) => p[1])),\n }\n const centerX = (textBounds.minX + textBounds.maxX) / 2\n const centerY = (textBounds.minY + textBounds.maxY) / 2\n\n // Calculate offset based on anchor alignment\n let xOffset = -centerX\n let yOffset = -centerY\n\n // Adjust for specific alignments\n if (silkscreenText.anchor_alignment?.includes(\"right\")) {\n xOffset = -textBounds.maxX\n } else if (silkscreenText.anchor_alignment?.includes(\"left\")) {\n xOffset = -textBounds.minX\n }\n\n if (silkscreenText.anchor_alignment?.includes(\"top\")) {\n yOffset = -textBounds.maxY\n } else if (silkscreenText.anchor_alignment?.includes(\"bottom\")) {\n yOffset = -textBounds.minY\n }\n\n return { textOutlines, xOffset, yOffset }\n}\n","import { useState, useEffect } from \"react\"\nimport stlSerializer from \"@jscad/stl-serializer\"\nimport { Geom3 } from \"@jscad/modeling/src/geometries/types\"\n\nfunction blobToBase64Url(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n resolve(reader.result as string)\n }\n reader.onerror = reject\n reader.readAsDataURL(blob)\n })\n}\n\ntype StlObj = { stlUrl: string; color: number[] }\n\nexport const useStlsFromGeom = (\n geom: Geom3[] | Geom3 | null,\n): {\n stls: StlObj[]\n loading: boolean\n} => {\n const [stls, setStls] = useState<StlObj[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n if (!geom) return\n const generateStls = async () => {\n setLoading(true)\n const geometries = Array.isArray(geom) ? geom : [geom]\n\n const stlPromises = geometries.map(async (g) => {\n const rawData = stlSerializer.serialize({ binary: true }, [g])\n const blobData = new Blob(rawData)\n const stlUrl = await blobToBase64Url(blobData)\n return { stlUrl, color: g.color! }\n })\n\n try {\n const generatedStls = await Promise.all(stlPromises)\n setStls(generatedStls)\n } catch (error) {\n console.error(\"Error generating STLs:\", error)\n setStls([])\n } finally {\n setLoading(false)\n }\n }\n\n generateStls()\n }, [geom])\n\n return { stls, loading }\n}\n","import { useLoader } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\n\nexport function STLModel({\n stlUrl,\n mtlUrl,\n color,\n opacity = 1,\n}: {\n stlUrl: string\n color?: any\n mtlUrl?: string\n opacity?: number\n}) {\n const geom = useLoader(STLLoader, stlUrl)\n const mesh = useRef<THREE.Mesh>()\n\n // TODO handle mtl url\n\n return (\n <mesh ref={mesh as any}>\n <primitive object={geom} attach=\"geometry\" />\n <meshStandardMaterial\n color={color}\n transparent={opacity !== 1}\n opacity={opacity}\n />\n {/* <Outlines thickness={0.05} color=\"black\" opacity={0.25} /> */}\n </mesh>\n )\n}\n","import type * as React from \"react\"\nimport type * as THREE from \"three\"\nimport { useHelper, Grid, OrbitControls } from \"@react-three/drei\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport packageJson from \"../package.json\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\nimport { forwardRef, Suspense, useEffect, useRef } from \"react\"\n\nexport const RotationTracker = () => {\n useFrame(({ camera }) => {\n window.TSCI_MAIN_CAMERA_ROTATION = camera.rotation\n })\n\n return <></>\n}\n\nimport { Html } from \"@react-three/drei\"\n\ninterface Props {\n hoveredComponent: {\n cad_component_id: string\n name: string\n mousePosition: [number, number, number]\n } | null\n}\n\nexport const CadViewerContainer = forwardRef<\n THREE.Object3D,\n React.PropsWithChildren<Props>\n>(({ children, hoveredComponent }, ref) => {\n return (\n <div style={{ position: \"relative\", width: \"100%\", height: \"100%\" }}>\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 120,\n height: 120,\n }}\n >\n <Canvas\n camera={{\n up: [0, 0, 1],\n position: [1, 1, 1],\n }}\n style={{ zIndex: 10 }}\n >\n <ambientLight intensity={Math.PI / 2} />\n <CubeWithLabeledSides />\n </Canvas>\n </div>\n <Canvas\n scene={{ up: [0, 0, 1] }}\n camera={{ up: [0, 0, 1], position: [5, 5, 5] }}\n >\n <RotationTracker />\n <OrbitControls autoRotate autoRotateSpeed={1} />\n <ambientLight intensity={Math.PI / 2} />\n <pointLight\n position={[-10, -10, 10]}\n decay={0}\n intensity={Math.PI / 4}\n />\n <Grid\n rotation={[Math.PI / 2, 0, 0]}\n infiniteGrid={true}\n cellSize={1}\n sectionSize={10}\n />\n <object3D ref={ref}>{children}</object3D>\n {hoveredComponent && (\n <Html\n position={hoveredComponent.mousePosition}\n style={{\n fontFamily: \"sans-serif\",\n transform: \"translate3d(50%, 50%, 0)\",\n backgroundColor: \"white\",\n padding: \"5px\",\n borderRadius: \"3px\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n }}\n >\n {hoveredComponent.name}\n </Html>\n )}\n </Canvas>\n <div\n style={{\n position: \"absolute\",\n right: 24,\n bottom: 24,\n fontFamily: \"sans-serif\",\n color: \"white\",\n WebkitTextStroke: \"0.5px rgba(0, 0, 0, 0.5)\",\n fontSize: 11,\n }}\n >\n @{packageJson.version}\n </div>\n </div>\n )\n})\n","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.81\",\n \"main\": \"./dist/index.js\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"start\": \"bun run storybook\",\n \"dev:old\": \"bunx --bun vite\",\n \"build\": \"tsup ./src/index.tsx --dts --sourcemap\",\n \"prepublish\": \"npm run build\",\n \"preview\": \"vite preview\",\n \"storybook\": \"storybook dev -p 6006\",\n \"build-storybook\": \"storybook build\",\n \"vercel-build\": \"bun run build-storybook\",\n \"format\": \"biome format . --write\",\n \"format:check\": \"biome format .\"\n },\n \"dependencies\": {\n \"@jscad/modeling\": \"^2.12.2\",\n \"@jscad/regl-renderer\": \"^2.6.9\",\n \"@jscad/stl-serializer\": \"^2.1.17\",\n \"@react-three/drei\": \"^9.115.0\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@tscircuit/core\": \"^0.0.251\",\n \"@tscircuit/props\": \"^0.0.125\",\n \"@tscircuit/react-fiber\": \"^1.1.29\",\n \"@tscircuit/soup\": \"^0.0.69\",\n \"@tscircuit/soup-util\": \"^0.0.26\",\n \"@types/three\": \"^0.165.0\",\n \"jscad-electronics\": \"^0.0.23\",\n \"jscad-fiber\": \"^0.0.76\",\n \"jscad-planner\": \"^0.0.11\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-use-gesture\": \"^9.1.3\",\n \"three\": \"^0.165.0\",\n \"three-stdlib\": \"^2.30.3\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.8.3\",\n \"@chromatic-com/storybook\": \"^1.5.0\",\n \"@storybook/addon-essentials\": \"^8.4.7\",\n \"@storybook/addon-interactions\": \"^8.4.7\",\n \"@storybook/addon-links\": \"^8.4.7\",\n \"@storybook/addon-onboarding\": \"^8.4.7\",\n \"@storybook/blocks\": \"^8.4.7\",\n \"@storybook/builder-vite\": \"^8.4.7\",\n \"@storybook/react\": \"^8.4.7\",\n \"@storybook/react-vite\": \"^8.4.7\",\n \"@storybook/test\": \"^8.4.7\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"circuit-json\": \"^0.0.116\",\n \"circuit-to-svg\": \"^0.0.91\",\n \"storybook\": \"^8.4.7\",\n \"strip-ansi\": \"^7.1.0\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.7.2\",\n \"vite\": \"^5.4.11\",\n \"vite-tsconfig-paths\": \"^4.3.2\"\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport { useFrame } from \"@react-three/fiber\"\nimport { useRef } from \"react\"\nimport * as THREE from \"three\"\n\ndeclare global {\n interface Window {\n TSCI_MAIN_CAMERA_ROTATION: THREE.Euler\n }\n}\nif (typeof window !== \"undefined\") {\n window.TSCI_MAIN_CAMERA_ROTATION = new THREE.Euler(0, 0, 0)\n}\n\nfunction computePointInFront(rotationVector, distance) {\n // Create a quaternion from the rotation vector\n const quaternion = new THREE.Quaternion().setFromEuler(\n new THREE.Euler(rotationVector.x, rotationVector.y, rotationVector.z),\n )\n\n // Create a vector pointing forward (along the negative z-axis)\n const forwardVector = new THREE.Vector3(0, 0, 1)\n\n // Apply the rotation to the forward vector\n forwardVector.applyQuaternion(quaternion)\n\n // Scale the rotated vector by the distance\n const result = forwardVector.multiplyScalar(distance)\n\n return result\n}\n\nexport const CubeWithLabeledSides = ({}: any) => {\n const ref = useRef<THREE.Mesh>()\n const rotationTrackingRef = useRef({ lastRotation: new THREE.Euler() })\n useFrame((state, delta) => {\n if (!ref.current) return\n\n const mainRot = window.TSCI_MAIN_CAMERA_ROTATION\n\n // Use window.TSCI_CAMERA_ROTATION to compute the position of the camera\n const cameraPosition = computePointInFront(mainRot, 2)\n\n state.camera.position.copy(cameraPosition)\n state.camera.lookAt(0, 0, 0)\n })\n return (\n <mesh ref={ref as any} rotation={[Math.PI / 2, 0, 0]}>\n <boxGeometry args={[1, 1, 1]} />\n <meshStandardMaterial color=\"white\" />\n <Text position={[0, 0, 0.51]} fontSize={0.25} color=\"black\">\n Front\n </Text>\n <Text\n position={[0, 0, -0.51]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI, 0]}\n >\n Back\n </Text>\n <Text\n position={[0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, Math.PI / 2, 0]}\n >\n Right\n </Text>\n <Text\n position={[-0.51, 0, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[0, -Math.PI / 2, 0]}\n >\n Left\n </Text>\n <Text\n position={[0, 0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[-Math.PI / 2, 0, 0]}\n >\n Top\n </Text>\n <Text\n position={[0, -0.51, 0]}\n fontSize={0.25}\n color=\"black\"\n rotation={[Math.PI / 2, 0, 0]}\n >\n Bottom\n </Text>\n <lineSegments\n args={[new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1))]}\n material={\n new THREE.LineBasicMaterial({\n color: 0x000000,\n linewidth: 2,\n })\n }\n />\n </mesh>\n )\n}\n","import { Html } from \"@react-three/drei\"\nimport { GroupProps, useThree } from \"@react-three/fiber\"\nimport { useRef, useCallback } from \"react\"\nimport type { Vector3 } from \"three\"\nimport * as THREE from \"three\"\n\nconst Group = (props: GroupProps) => <group {...props} />\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n position,\n}: {\n children: React.ReactNode\n position?: Vector3 | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const lastValidPointRef = useRef<THREE.Vector3 | null>(null)\n\n const handlePointerEnter = useCallback(\n (e: any) => {\n e.stopPropagation()\n\n try {\n // Fallback to event position if raycaster fails\n const point =\n e.point ||\n (e.intersections && e.intersections.length > 0\n ? e.intersections[0].point\n : null) ||\n (position\n ? new THREE.Vector3(...(position as [number, number, number]))\n : null)\n\n if (point) {\n lastValidPointRef.current = point\n onHover({ mousePosition: [point.x, point.y, point.z] })\n } else {\n onHover({})\n }\n } catch (error) {\n console.warn(\"Hover event error:\", error)\n onHover({})\n }\n },\n [position],\n )\n\n const handlePointerLeave = useCallback(\n (e: any) => {\n e.stopPropagation()\n lastValidPointRef.current = null\n\n // TODO REPLACE WITH onUnhover\n onHover(null)\n },\n [onHover],\n )\n\n return (\n <Group\n onPointerEnter={handlePointerEnter}\n onPointerMove={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </Group>\n )\n}\n\nexport default ContainerWithTooltip\n","import { useState, useEffect } from \"react\"\nimport type { Group } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\n// Define the type for our cache\ninterface CacheItem {\n promise: Promise<any>\n result: Group | null\n}\n\ndeclare global {\n interface Window {\n TSCIRCUIT_OBJ_LOADER_CACHE: Map<string, CacheItem>\n }\n}\n\n// Ensure the global cache exists\nif (typeof window !== \"undefined\" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {\n window.TSCIRCUIT_OBJ_LOADER_CACHE = new Map<string, CacheItem>()\n}\n\nexport function useGlobalObjLoader(url: string | null): Group | null | Error {\n const [obj, setObj] = useState<Group | null | Error>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n let hasUrlChanged = false\n\n async function loadAndParseObj() {\n try {\n const response = await fetch(url!)\n const text = await response.text()\n\n const mtlContent = text\n .match(/newmtl[\\s\\S]*?endmtl/g)\n ?.join(\"\\n\")!\n .replace(/d 0\\./g, \"d 1.\")!\n const objContent = text.replace(/newmtl[\\s\\S]*?endmtl/g, \"\")\n\n const mtlLoader = new MTLLoader()\n mtlLoader.setMaterialOptions({\n invertTrProperty: true,\n })\n const materials = mtlLoader.parse(\n mtlContent.replace(\n /Kd\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)/g,\n \"Kd $2 $2 $2\",\n ),\n \"test.mtl\",\n )\n\n const objLoader = new OBJLoader()\n objLoader.setMaterials(materials)\n return objLoader.parse(objContent)\n } catch (error) {\n return error as Error\n }\n }\n\n function loadUrl() {\n if (cache.has(url!)) {\n const cacheItem = cache.get(url!)!\n if (cacheItem.result) {\n // If we have a result, clone it\n return Promise.resolve(cacheItem.result.clone())\n }\n // If we're still loading, return the existing promise\n return cacheItem.promise.then((result) => result.clone())\n }\n // If it's not in the cache, create a new promise and cache it\n const promise = loadAndParseObj().then((result) => {\n if (result instanceof Error) {\n // If the result is an Error, return it\n return result\n }\n cache.set(url!, { ...cache.get(url!)!, result })\n return result\n })\n cache.set(url!, { promise, result: null })\n return promise\n }\n\n loadUrl()\n .then((result) => {\n if (hasUrlChanged) return\n setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n return () => {\n hasUrlChanged = true\n }\n }, [url])\n\n return obj\n}\n","import ContainerWithTooltip from \"src/ContainerWithTooltip\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport type { Euler, Vector3 } from \"three\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.25} />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n\n // Check if obj is valid before rendering\n if (obj instanceof Error) {\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.5} />\n <meshBasicMaterial color=\"red\" />\n </mesh>\n </ContainerWithTooltip>\n )\n }\n return (\n <ContainerWithTooltip isHovered={isHovered} onHover={onHover}>\n <primitive rotation={rotation} position={position} object={obj} />\n </ContainerWithTooltip>\n )\n}\n","import type { JscadOperation } from \"jscad-planner\"\nimport { executeJscadOperations } from \"jscad-planner\"\nimport jscad from \"@jscad/modeling\"\nimport { convertCSGToThreeGeom } from \"jscad-fiber\"\nimport * as THREE from \"three\"\nimport { useMemo } from \"react\"\nimport ContainerWithTooltip from \"src/ContainerWithTooltip\"\n\nexport const JscadModel = ({\n jscadPlan,\n positionOffset,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const { threeGeom, material } = useMemo(() => {\n const jscadObject = executeJscadOperations(jscad as any, jscadPlan)\n\n const threeGeom = convertCSGToThreeGeom(jscadObject)\n\n const material = new THREE.MeshStandardMaterial({\n vertexColors: true,\n side: THREE.DoubleSide, // Ensure both sides are visible\n })\n return { threeGeom, material }\n }, [jscadPlan])\n\n useMemo(() => {\n if (isHovered) {\n const color = new THREE.Color(material.color.getHex())\n material.emissive.copy(color)\n material.emissive.setRGB(0, 0, 1)\n material.emissiveIntensity = 0.2\n } else {\n material.emissiveIntensity = 0\n }\n }, [isHovered, material])\n if (!threeGeom) return null\n\n return (\n <ContainerWithTooltip\n isHovered={isHovered}\n onHover={onHover}\n position={positionOffset}\n >\n <mesh\n geometry={threeGeom}\n material={material}\n position={positionOffset}\n rotation={rotationOffset}\n />\n </ContainerWithTooltip>\n )\n}\n","import { Footprinter3d } from \"jscad-electronics\"\nimport { createJSCADRenderer } from \"jscad-fiber\"\nimport { jscadPlanner } from \"jscad-planner\"\nimport { useMemo } from \"react\"\nimport { JscadModel } from \"./JscadModel\"\n\nconst { createJSCADRoot } = createJSCADRenderer(jscadPlanner as any)\n\nexport const FootprinterModel = ({\n positionOffset,\n footprint,\n rotationOffset,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n onHover: (e: any) => void\n isHovered: boolean\n}) => {\n const jscadOperations = useMemo(() => {\n if (!footprint) return null\n const jscadOperations: any[] = []\n const root = createJSCADRoot(jscadOperations)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadOperations\n }, [footprint])\n\n if (!jscadOperations) return null\n\n return (\n <>\n {jscadOperations.map((operation, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={operation}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\n","import type { AnyCircuitElement, CadComponent } from \"circuit-json\"\nimport { useConvertChildrenToSoup } from \"./hooks/use-convert-children-to-soup\"\nimport { su } from \"@tscircuit/soup-util\"\nimport { useMemo, useState } from \"react\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport { useStlsFromGeom } from \"./hooks/use-stls-from-geom\"\nimport { STLModel } from \"./three-components/STLModel\"\nimport { CadViewerContainer } from \"./CadViewerContainer\"\nimport { MixedStlModel } from \"./three-components/MixedStlModel\"\nimport { Euler } from \"three\"\nimport { JscadModel } from \"./three-components/JscadModel\"\nimport { Footprinter3d } from \"jscad-electronics\"\nimport { FootprinterModel } from \"./three-components/FootprinterModel\"\nimport { tuple } from \"./utils/tuple\"\n\nexport const AnyCadComponent = ({\n cad_component,\n onHover = () => {},\n isHovered = false,\n}: {\n cad_component: CadComponent\n onHover?: (e: any) => void\n isHovered?: boolean\n}) => {\n const url = cad_component.model_obj_url ?? cad_component.model_stl_url\n const rotationOffset = cad_component.rotation\n ? tuple(\n (cad_component.rotation.x * Math.PI) / 180,\n (cad_component.rotation.y * Math.PI) / 180,\n (cad_component.rotation.z * Math.PI) / 180,\n )\n : undefined\n\n if (url) {\n return (\n <MixedStlModel\n key={cad_component.cad_component_id}\n url={url}\n position={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotation={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.model_jscad) {\n return (\n <JscadModel\n key={cad_component.cad_component_id}\n jscadPlan={cad_component.model_jscad as any}\n rotationOffset={rotationOffset}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n\n if (cad_component.footprinter_string) {\n return (\n <FootprinterModel\n positionOffset={\n cad_component.position\n ? [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n : undefined\n }\n rotationOffset={rotationOffset}\n footprint={cad_component.footprinter_string}\n onHover={onHover}\n isHovered={isHovered}\n />\n )\n }\n}\n","import React from \"react\"\n\ninterface Props {\n children: React.ReactNode\n fallback: (props: { error: Error }) => any\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n}\n\nexport class ThreeErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error }\n }\n\n override render() {\n if (this.state.hasError && this.state.error) {\n return this.props.fallback({ error: this.state.error })\n }\n\n return this.props.children\n }\n}\n","import { Text } from \"@react-three/drei\"\nimport type { CadComponent } from \"circuit-json\"\n\nexport const Error3d = ({\n error,\n cad_component,\n}: { error: any; cad_component?: CadComponent }) => {\n let position = [0, 0, 0]\n if (cad_component?.position) {\n position = [\n cad_component.position.x,\n cad_component.position.y,\n cad_component.position.z,\n ]\n // make sure the position doesn't have any NaN values\n position = position.map((p) => (Number.isNaN(p) ? 0 : p))\n }\n return (\n <group\n // @ts-expect-error\n position={position}\n >\n <mesh\n renderOrder={-99999}\n rotation={[Math.PI / 4, Math.PI / 4, 0]}\n ref={(mesh) => {\n if (mesh) {\n mesh.renderOrder = 999999\n }\n }}\n >\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial\n depthTest={false}\n transparent\n color=\"red\"\n opacity={0.5}\n />\n </mesh>\n <Text\n scale={[0.1, 0.1, 0.1]}\n color=\"red\" // default\n anchorX=\"center\" // default\n anchorY=\"middle\" // default\n depthOffset={-99999}\n >\n {error.toString().slice(0, 50)}...\n </Text>\n </group>\n ) as any\n}\n"],"mappings":"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","names":["import_react","import_soup_util","import_react","import_transforms","import_primitives","import_colors","import_booleans","import_extrusions","import_primitives","import_react","stlSerializer","import_react","import_three_stdlib","import_drei","import_fiber","import_fiber","import_react","import_jsx_runtime","import_react","import_drei","import_jsx_runtime","import_react","THREE","import_jsx_runtime","import_react","import_three_stdlib","import_jsx_runtime","THREE","import_react","import_jsx_runtime","jscad","threeGeom","material","import_jscad_fiber","import_jscad_planner","import_react","import_jsx_runtime","jscadOperations","import_jsx_runtime","import_react","React","import_drei","import_jsx_runtime","import_jsx_runtime"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/3d-viewer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.82",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@react-three/drei": "^9.115.0",
|
|
25
25
|
"@react-three/fiber": "^8.16.8",
|
|
26
26
|
"@tscircuit/core": "^0.0.251",
|
|
27
|
-
"@tscircuit/props": "^0.0.
|
|
27
|
+
"@tscircuit/props": "^0.0.125",
|
|
28
28
|
"@tscircuit/react-fiber": "^1.1.29",
|
|
29
29
|
"@tscircuit/soup": "^0.0.69",
|
|
30
30
|
"@tscircuit/soup-util": "^0.0.26",
|
|
@@ -41,25 +41,25 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@biomejs/biome": "^1.8.3",
|
|
43
43
|
"@chromatic-com/storybook": "^1.5.0",
|
|
44
|
-
"@storybook/addon-essentials": "^8.
|
|
45
|
-
"@storybook/addon-interactions": "^8.
|
|
46
|
-
"@storybook/addon-links": "^8.
|
|
47
|
-
"@storybook/addon-onboarding": "^8.
|
|
48
|
-
"@storybook/blocks": "^8.
|
|
49
|
-
"@storybook/builder-vite": "^8.
|
|
50
|
-
"@storybook/react": "^8.
|
|
51
|
-
"@storybook/react-vite": "^8.
|
|
52
|
-
"@storybook/test": "^8.
|
|
44
|
+
"@storybook/addon-essentials": "^8.4.7",
|
|
45
|
+
"@storybook/addon-interactions": "^8.4.7",
|
|
46
|
+
"@storybook/addon-links": "^8.4.7",
|
|
47
|
+
"@storybook/addon-onboarding": "^8.4.7",
|
|
48
|
+
"@storybook/blocks": "^8.4.7",
|
|
49
|
+
"@storybook/builder-vite": "^8.4.7",
|
|
50
|
+
"@storybook/react": "^8.4.7",
|
|
51
|
+
"@storybook/react-vite": "^8.4.7",
|
|
52
|
+
"@storybook/test": "^8.4.7",
|
|
53
53
|
"@types/react": "^18.3.3",
|
|
54
54
|
"@types/react-dom": "^18.3.0",
|
|
55
|
-
"@vitejs/plugin-react": "^4.3.
|
|
55
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
56
56
|
"circuit-json": "^0.0.116",
|
|
57
57
|
"circuit-to-svg": "^0.0.91",
|
|
58
|
-
"storybook": "^8.
|
|
58
|
+
"storybook": "^8.4.7",
|
|
59
59
|
"strip-ansi": "^7.1.0",
|
|
60
60
|
"tsup": "^8.1.0",
|
|
61
|
-
"typescript": "^5.
|
|
62
|
-
"vite": "^5.
|
|
61
|
+
"typescript": "^5.7.2",
|
|
62
|
+
"vite": "^5.4.11",
|
|
63
63
|
"vite-tsconfig-paths": "^4.3.2"
|
|
64
64
|
}
|
|
65
65
|
}
|