@tscircuit/3d-viewer 0.0.40 → 0.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +104 -73
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -49,7 +49,7 @@ var useConvertChildrenToSoup = (children, defaultSoup) => {
|
|
|
49
49
|
|
|
50
50
|
// src/CadViewer.tsx
|
|
51
51
|
var import_soup_util2 = require("@tscircuit/soup-util");
|
|
52
|
-
var
|
|
52
|
+
var import_react9 = require("react");
|
|
53
53
|
|
|
54
54
|
// src/soup-to-3d/index.ts
|
|
55
55
|
var import_soup_util = require("@tscircuit/soup-util");
|
|
@@ -104,52 +104,52 @@ var platedHole = (plated_hole, ctx) => {
|
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
if (plated_hole.shape === "pill") {
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const outerHeight = plated_hole.outer_height || holeHeight + 0.2;
|
|
107
|
+
const shouldRotate = plated_hole.hole_height > plated_hole.hole_width;
|
|
108
|
+
const holeWidth = shouldRotate ? plated_hole.hole_height : plated_hole.hole_width;
|
|
109
|
+
const holeHeight = shouldRotate ? plated_hole.hole_width : plated_hole.hole_height;
|
|
110
|
+
const outerHeight = shouldRotate ? plated_hole.outer_width || holeWidth + 0.2 : plated_hole.outer_height || holeHeight + 0.2;
|
|
111
111
|
const holeRadius = holeHeight / 2;
|
|
112
|
-
const
|
|
112
|
+
const rectLength = Math.abs(holeWidth - holeHeight);
|
|
113
113
|
const mainRect = (0, import_primitives.cuboid)({
|
|
114
|
-
center: [plated_hole.x, plated_hole.y, 0],
|
|
115
|
-
size:
|
|
114
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y, 0] : [plated_hole.x, plated_hole.y, 0],
|
|
115
|
+
size: shouldRotate ? [holeHeight, rectLength, 1.2] : [rectLength, holeHeight, 1.2]
|
|
116
116
|
});
|
|
117
117
|
const leftCap = (0, import_primitives.cylinder)({
|
|
118
|
-
center: [plated_hole.x -
|
|
118
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y - rectLength / 2, 0] : [plated_hole.x - rectLength / 2, plated_hole.y, 0],
|
|
119
119
|
radius: holeRadius,
|
|
120
120
|
height: 1.2
|
|
121
121
|
});
|
|
122
122
|
const rightCap = (0, import_primitives.cylinder)({
|
|
123
|
-
center: [plated_hole.x +
|
|
123
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y + rectLength / 2, 0] : [plated_hole.x + rectLength / 2, plated_hole.y, 0],
|
|
124
124
|
radius: holeRadius,
|
|
125
125
|
height: 1.2
|
|
126
126
|
});
|
|
127
127
|
const outerMainRect = (0, import_primitives.cuboid)({
|
|
128
|
-
center: [plated_hole.x, plated_hole.y, 1.2 / 2],
|
|
129
|
-
size:
|
|
128
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y, 1.2 / 2] : [plated_hole.x, plated_hole.y, 1.2 / 2],
|
|
129
|
+
size: shouldRotate ? [outerHeight, rectLength, M] : [rectLength, outerHeight, M]
|
|
130
130
|
});
|
|
131
131
|
const outerLeftCap = (0, import_primitives.cylinder)({
|
|
132
|
-
center: [plated_hole.x -
|
|
133
|
-
radius:
|
|
132
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y - rectLength / 2, 1.2 / 2] : [plated_hole.x - rectLength / 2, plated_hole.y, 1.2 / 2],
|
|
133
|
+
radius: outerHeight / 2,
|
|
134
134
|
height: M
|
|
135
135
|
});
|
|
136
136
|
const outerRightCap = (0, import_primitives.cylinder)({
|
|
137
|
-
center: [plated_hole.x +
|
|
138
|
-
radius:
|
|
137
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y + rectLength / 2, 1.2 / 2] : [plated_hole.x + rectLength / 2, plated_hole.y, 1.2 / 2],
|
|
138
|
+
radius: outerHeight / 2,
|
|
139
139
|
height: M
|
|
140
140
|
});
|
|
141
141
|
const bottomMainRect = (0, import_primitives.cuboid)({
|
|
142
|
-
center: [plated_hole.x, plated_hole.y, -1.2 / 2],
|
|
143
|
-
size:
|
|
142
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y, -1.2 / 2] : [plated_hole.x, plated_hole.y, -1.2 / 2],
|
|
143
|
+
size: shouldRotate ? [outerHeight, rectLength, M] : [rectLength, outerHeight, M]
|
|
144
144
|
});
|
|
145
145
|
const bottomLeftCap = (0, import_primitives.cylinder)({
|
|
146
|
-
center: [plated_hole.x -
|
|
147
|
-
radius:
|
|
146
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y - rectLength / 2, -1.2 / 2] : [plated_hole.x - rectLength / 2, plated_hole.y, -1.2 / 2],
|
|
147
|
+
radius: outerHeight / 2,
|
|
148
148
|
height: M
|
|
149
149
|
});
|
|
150
150
|
const bottomRightCap = (0, import_primitives.cylinder)({
|
|
151
|
-
center: [plated_hole.x +
|
|
152
|
-
radius:
|
|
151
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y + rectLength / 2, -1.2 / 2] : [plated_hole.x + rectLength / 2, plated_hole.y, -1.2 / 2],
|
|
152
|
+
radius: outerHeight / 2,
|
|
153
153
|
height: M
|
|
154
154
|
});
|
|
155
155
|
return (0, import_colors.colorize)(
|
|
@@ -166,22 +166,22 @@ var platedHole = (plated_hole, ctx) => {
|
|
|
166
166
|
bottomLeftCap,
|
|
167
167
|
bottomRightCap
|
|
168
168
|
),
|
|
169
|
-
|
|
169
|
+
(0, import_booleans.union)(
|
|
170
170
|
(0, import_primitives.cuboid)({
|
|
171
171
|
center: [plated_hole.x, plated_hole.y, 0],
|
|
172
|
-
size:
|
|
172
|
+
size: shouldRotate ? [holeHeight - M, rectLength, 1.5] : [rectLength, holeHeight - M, 1.5]
|
|
173
173
|
}),
|
|
174
174
|
(0, import_primitives.cylinder)({
|
|
175
|
-
center: [plated_hole.x -
|
|
175
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y - rectLength / 2, 0] : [plated_hole.x - rectLength / 2, plated_hole.y, 0],
|
|
176
176
|
radius: holeRadius - M,
|
|
177
177
|
height: 1.5
|
|
178
178
|
}),
|
|
179
179
|
(0, import_primitives.cylinder)({
|
|
180
|
-
center: [plated_hole.x +
|
|
180
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y + rectLength / 2, 0] : [plated_hole.x + rectLength / 2, plated_hole.y, 0],
|
|
181
181
|
radius: holeRadius - M,
|
|
182
182
|
height: 1.5
|
|
183
183
|
})
|
|
184
|
-
|
|
184
|
+
)
|
|
185
185
|
)
|
|
186
186
|
);
|
|
187
187
|
} else {
|
|
@@ -250,19 +250,23 @@ var createBoardGeomFromSoup = (soup) => {
|
|
|
250
250
|
const platedHoleGeom = platedHole(plated_hole, ctx);
|
|
251
251
|
platedHoleGeoms.push(platedHoleGeom);
|
|
252
252
|
} else if (plated_hole.shape === "pill") {
|
|
253
|
-
const
|
|
253
|
+
const shouldRotate = plated_hole.hole_height > plated_hole.hole_width;
|
|
254
|
+
const holeWidth = shouldRotate ? plated_hole.hole_height : plated_hole.hole_width;
|
|
255
|
+
const holeHeight = shouldRotate ? plated_hole.hole_width : plated_hole.hole_height;
|
|
256
|
+
const holeRadius = holeHeight / 2;
|
|
257
|
+
const rectLength = Math.abs(holeWidth - holeHeight);
|
|
254
258
|
const pillHole = (0, import_booleans2.union)(
|
|
255
259
|
(0, import_primitives3.cuboid)({
|
|
256
260
|
center: [plated_hole.x, plated_hole.y, 0],
|
|
257
|
-
size: [
|
|
261
|
+
size: shouldRotate ? [holeHeight, rectLength, 1.5] : [rectLength, holeHeight, 1.5]
|
|
258
262
|
}),
|
|
259
263
|
(0, import_primitives3.cylinder)({
|
|
260
|
-
center: [plated_hole.x
|
|
264
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y - rectLength / 2, 0] : [plated_hole.x - rectLength / 2, plated_hole.y, 0],
|
|
261
265
|
radius: holeRadius,
|
|
262
266
|
height: 1.5
|
|
263
267
|
}),
|
|
264
268
|
(0, import_primitives3.cylinder)({
|
|
265
|
-
center: [plated_hole.x
|
|
269
|
+
center: shouldRotate ? [plated_hole.x, plated_hole.y + rectLength / 2, 0] : [plated_hole.x + rectLength / 2, plated_hole.y, 0],
|
|
266
270
|
radius: holeRadius,
|
|
267
271
|
height: 1.5
|
|
268
272
|
})
|
|
@@ -455,7 +459,7 @@ var import_fiber3 = require("@react-three/fiber");
|
|
|
455
459
|
// package.json
|
|
456
460
|
var package_default = {
|
|
457
461
|
name: "@tscircuit/3d-viewer",
|
|
458
|
-
version: "0.0.
|
|
462
|
+
version: "0.0.41",
|
|
459
463
|
main: "./dist/index.js",
|
|
460
464
|
files: [
|
|
461
465
|
"dist"
|
|
@@ -467,7 +471,8 @@ var package_default = {
|
|
|
467
471
|
prepublish: "npm run build",
|
|
468
472
|
preview: "vite preview",
|
|
469
473
|
storybook: "storybook dev -p 6006",
|
|
470
|
-
"build-storybook": "storybook build"
|
|
474
|
+
"build-storybook": "storybook build",
|
|
475
|
+
format: "biome format . --write"
|
|
471
476
|
},
|
|
472
477
|
dependencies: {
|
|
473
478
|
"@jscad/modeling": "^2.12.2",
|
|
@@ -703,6 +708,9 @@ var CadViewerContainer = ({ children }) => {
|
|
|
703
708
|
|
|
704
709
|
// src/ContainerWithTooltip.tsx
|
|
705
710
|
var import_drei3 = require("@react-three/drei");
|
|
711
|
+
var import_fiber4 = require("@react-three/fiber");
|
|
712
|
+
var import_react5 = require("react");
|
|
713
|
+
var THREE2 = __toESM(require("three"));
|
|
706
714
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
707
715
|
var ContainerWithTooltip = ({
|
|
708
716
|
children,
|
|
@@ -712,45 +720,68 @@ var ContainerWithTooltip = ({
|
|
|
712
720
|
name,
|
|
713
721
|
position
|
|
714
722
|
}) => {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
children,
|
|
724
|
-
isHovered && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
725
|
-
import_drei3.Html,
|
|
726
|
-
{
|
|
727
|
-
position,
|
|
728
|
-
style: {
|
|
729
|
-
fontFamily: "sans-serif",
|
|
730
|
-
transform: "translate3d(50%, 50%, 0)",
|
|
731
|
-
backgroundColor: "white",
|
|
732
|
-
padding: "5px",
|
|
733
|
-
borderRadius: "3px",
|
|
734
|
-
pointerEvents: "none"
|
|
735
|
-
},
|
|
736
|
-
children: name
|
|
737
|
-
}
|
|
738
|
-
)
|
|
739
|
-
]
|
|
723
|
+
const [mousePosition, setMousePosition] = (0, import_react5.useState)([0, 0, 0]);
|
|
724
|
+
const { camera } = (0, import_fiber4.useThree)();
|
|
725
|
+
const mouseRef = (0, import_react5.useRef)(new THREE2.Vector2());
|
|
726
|
+
(0, import_fiber4.useFrame)(() => {
|
|
727
|
+
if (isHovered) {
|
|
728
|
+
const vector = new THREE2.Vector3(mouseRef.current.x, mouseRef.current.y, 0.5);
|
|
729
|
+
vector.unproject(camera);
|
|
730
|
+
setMousePosition([vector.x, vector.y, vector.z]);
|
|
740
731
|
}
|
|
741
|
-
);
|
|
732
|
+
});
|
|
733
|
+
const groupProps = {
|
|
734
|
+
position,
|
|
735
|
+
onPointerEnter: (e) => {
|
|
736
|
+
e.stopPropagation();
|
|
737
|
+
mouseRef.current.set(
|
|
738
|
+
e.clientX / window.innerWidth * 2 - 1,
|
|
739
|
+
-(e.clientY / window.innerHeight) * 2 + 1
|
|
740
|
+
);
|
|
741
|
+
onHover(componentId);
|
|
742
|
+
},
|
|
743
|
+
onPointerMove: (e) => {
|
|
744
|
+
e.stopPropagation();
|
|
745
|
+
mouseRef.current.set(
|
|
746
|
+
e.clientX / window.innerWidth * 2 - 1,
|
|
747
|
+
-(e.clientY / window.innerHeight) * 2 + 1
|
|
748
|
+
);
|
|
749
|
+
},
|
|
750
|
+
onPointerLeave: (e) => {
|
|
751
|
+
e.stopPropagation();
|
|
752
|
+
onHover(null);
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("group", { ...groupProps, children: [
|
|
756
|
+
children,
|
|
757
|
+
isHovered && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
758
|
+
import_drei3.Html,
|
|
759
|
+
{
|
|
760
|
+
position: mousePosition,
|
|
761
|
+
style: {
|
|
762
|
+
fontFamily: "sans-serif",
|
|
763
|
+
transform: "translate3d(50%, 50%, 0)",
|
|
764
|
+
backgroundColor: "white",
|
|
765
|
+
padding: "5px",
|
|
766
|
+
borderRadius: "3px",
|
|
767
|
+
pointerEvents: "none"
|
|
768
|
+
},
|
|
769
|
+
children: name
|
|
770
|
+
}
|
|
771
|
+
)
|
|
772
|
+
] });
|
|
742
773
|
};
|
|
743
774
|
var ContainerWithTooltip_default = ContainerWithTooltip;
|
|
744
775
|
|
|
745
776
|
// src/hooks/use-global-obj-loader.ts
|
|
746
|
-
var
|
|
777
|
+
var import_react6 = require("react");
|
|
747
778
|
var import_three_stdlib2 = require("three-stdlib");
|
|
748
779
|
if (typeof window !== "undefined" && !window.TSCIRCUIT_OBJ_LOADER_CACHE) {
|
|
749
780
|
window.TSCIRCUIT_OBJ_LOADER_CACHE = /* @__PURE__ */ new Map();
|
|
750
781
|
}
|
|
751
782
|
function useGlobalObjLoader(url) {
|
|
752
|
-
const [obj, setObj] = (0,
|
|
753
|
-
(0,
|
|
783
|
+
const [obj, setObj] = (0, import_react6.useState)(null);
|
|
784
|
+
(0, import_react6.useEffect)(() => {
|
|
754
785
|
if (!url) return;
|
|
755
786
|
const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE;
|
|
756
787
|
let hasUrlChanged = false;
|
|
@@ -868,8 +899,8 @@ function MixedStlModel({
|
|
|
868
899
|
var import_jscad_planner = require("jscad-planner");
|
|
869
900
|
var import_modeling = __toESM(require("@jscad/modeling"));
|
|
870
901
|
var import_jscad_fiber = require("jscad-fiber");
|
|
871
|
-
var
|
|
872
|
-
var
|
|
902
|
+
var THREE3 = __toESM(require("three"));
|
|
903
|
+
var import_react7 = require("react");
|
|
873
904
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
874
905
|
var JscadModel = ({
|
|
875
906
|
jscadPlan,
|
|
@@ -880,19 +911,19 @@ var JscadModel = ({
|
|
|
880
911
|
onHover,
|
|
881
912
|
isHovered
|
|
882
913
|
}) => {
|
|
883
|
-
const { threeGeom, material } = (0,
|
|
914
|
+
const { threeGeom, material } = (0, import_react7.useMemo)(() => {
|
|
884
915
|
const jscadObject = (0, import_jscad_planner.executeJscadOperations)(import_modeling.default, jscadPlan);
|
|
885
916
|
const threeGeom2 = (0, import_jscad_fiber.convertCSGToThreeGeom)(jscadObject);
|
|
886
|
-
const material2 = new
|
|
917
|
+
const material2 = new THREE3.MeshStandardMaterial({
|
|
887
918
|
vertexColors: true,
|
|
888
|
-
side:
|
|
919
|
+
side: THREE3.DoubleSide
|
|
889
920
|
// Ensure both sides are visible
|
|
890
921
|
});
|
|
891
922
|
return { threeGeom: threeGeom2, material: material2 };
|
|
892
923
|
}, [jscadPlan]);
|
|
893
|
-
(0,
|
|
924
|
+
(0, import_react7.useMemo)(() => {
|
|
894
925
|
if (isHovered) {
|
|
895
|
-
const color = new
|
|
926
|
+
const color = new THREE3.Color(material.color.getHex());
|
|
896
927
|
material.emissive.copy(color);
|
|
897
928
|
material.emissive.setRGB(0, 0, 1);
|
|
898
929
|
material.emissiveIntensity = 0.2;
|
|
@@ -926,7 +957,7 @@ var JscadModel = ({
|
|
|
926
957
|
var import_jscad_electronics = require("jscad-electronics");
|
|
927
958
|
var import_jscad_fiber2 = require("jscad-fiber");
|
|
928
959
|
var import_jscad_planner2 = require("jscad-planner");
|
|
929
|
-
var
|
|
960
|
+
var import_react8 = require("react");
|
|
930
961
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
931
962
|
var { createJSCADRoot } = (0, import_jscad_fiber2.createJSCADRenderer)(import_jscad_planner2.jscadPlanner);
|
|
932
963
|
var FootprinterModel = ({
|
|
@@ -938,7 +969,7 @@ var FootprinterModel = ({
|
|
|
938
969
|
onHover,
|
|
939
970
|
isHovered
|
|
940
971
|
}) => {
|
|
941
|
-
const jscadPlan = (0,
|
|
972
|
+
const jscadPlan = (0, import_react8.useMemo)(() => {
|
|
942
973
|
if (!footprint) return null;
|
|
943
974
|
const jscadPlan2 = [];
|
|
944
975
|
const root = createJSCADRoot(jscadPlan2);
|
|
@@ -967,10 +998,10 @@ var tuple = (...args) => args;
|
|
|
967
998
|
// src/CadViewer.tsx
|
|
968
999
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
969
1000
|
var CadViewer = ({ soup, children }) => {
|
|
970
|
-
const [hoveredComponent, setHoveredComponent] = (0,
|
|
1001
|
+
const [hoveredComponent, setHoveredComponent] = (0, import_react9.useState)(null);
|
|
971
1002
|
soup ??= useConvertChildrenToSoup(children, soup);
|
|
972
1003
|
if (!soup) return null;
|
|
973
|
-
const boardGeom = (0,
|
|
1004
|
+
const boardGeom = (0, import_react9.useMemo)(() => {
|
|
974
1005
|
if (!soup.some((e) => e.type === "pcb_board")) return null;
|
|
975
1006
|
return createBoardGeomFromSoup(soup);
|
|
976
1007
|
}, [soup]);
|
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/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"],"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 { 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\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n const [hoveredComponent, setHoveredComponent] = useState<string | null>(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, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n // TODO canvas/camera etc.\n return (\n <CadViewerContainer>\n {stls.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 const componentName = su(soup).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\n />\n )\n }\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\"\n\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\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 // Create pill-shaped hole in board\n const holeRadius = plated_hole.hole_height! / 2\n const pillHole = union(\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: [plated_hole.hole_width! - plated_hole.hole_height!, plated_hole.hole_height!, 1.5],\n }),\n cylinder({\n center: [plated_hole.x - (plated_hole.hole_width! - plated_hole.hole_height!) / 2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.5,\n }),\n cylinder({\n center: [plated_hole.x + (plated_hole.hole_width! - plated_hole.hole_height!) / 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 const subRoutes = mixedRoute.reduce(\n (c, p) => {\n // @ts-ignore\n const lastLayer = c.current?.[c.current.length - 1]?.layer\n if (\n p.route_type === \"via\" ||\n (p.route_type === \"wire\" && p.layer !== lastLayer)\n ) {\n if (c.current.length > 2) {\n c.allPrev.push(c.current)\n }\n c.current = p.route_type === \"wire\" ? [p] : []\n return c\n }\n c.current.push(p)\n return c\n },\n {\n current: [] as typeof mixedRoute,\n allPrev: [] as Array<typeof mixedRoute>,\n },\n )\n for (const route of subRoutes.allPrev.concat([subRoutes.current])) {\n // TODO break into segments based on layers\n const linePath = line(route.map((p) => [p.x, p.y]))\n\n const layer = route[0]!.route_type === \"wire\" ? route[0]!.layer : \"top\"\n const layerSign = layer === \"top\" ? 1 : -1\n // traceGeoms.push(traceGeom)\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 // HACK: Subtract all vias from every trace- this mostly is because the\n // vias aren't inside the route- we should probably pre-filter to make sure\n // that vias are only near the route\n for (const via of pcb_vias) {\n traceGeom = subtract(\n traceGeom,\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n }\n for (const ph of plated_holes) {\n if (ph.shape === \"circle\") {\n traceGeom = subtract(\n traceGeom,\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n }\n }\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\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [boardGeom, ...platedHoleGeoms, ...padGeoms, ...traceGeoms]\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 } if (plated_hole.shape === \"pill\") {\n const holeWidth = plated_hole.hole_width\n const holeHeight = plated_hole.hole_height\n const outerWidth = plated_hole.outer_width || holeWidth + 0.2\n const outerHeight = plated_hole.outer_height || holeHeight + 0.2\n const holeRadius = holeHeight / 2\n const outerRadius = outerHeight / 2\n\n // Create inner hole pill shape\n const mainRect = cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: [holeWidth - holeHeight, holeHeight, 1.2]\n })\n \n const leftCap = cylinder({\n center: [plated_hole.x - (holeWidth - holeHeight)/2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2\n })\n\n const rightCap = cylinder({\n center: [plated_hole.x + (holeWidth - holeHeight)/2, plated_hole.y, 0],\n radius: holeRadius,\n height: 1.2\n })\n\n // Create outer pads\n const outerMainRect = cuboid({\n center: [plated_hole.x, plated_hole.y, 1.2/2],\n size: [outerWidth - outerHeight, outerHeight, M]\n })\n\n const outerLeftCap = cylinder({\n center: [plated_hole.x - (outerWidth - outerHeight)/2, plated_hole.y, 1.2/2],\n radius: outerRadius,\n height: M\n })\n\n const outerRightCap = cylinder({\n center: [plated_hole.x + (outerWidth - outerHeight)/2, plated_hole.y, 1.2/2],\n radius: outerRadius,\n height: M\n })\n\n // Bottom pads\n const bottomMainRect = cuboid({\n center: [plated_hole.x, plated_hole.y, -1.2/2],\n size: [outerWidth - outerHeight, outerHeight, M]\n })\n\n const bottomLeftCap = cylinder({\n center: [plated_hole.x - (outerWidth - outerHeight)/2, plated_hole.y, -1.2/2],\n radius: outerRadius,\n height: M\n })\n\n const bottomRightCap = cylinder({\n center: [plated_hole.x + (outerWidth - outerHeight)/2, plated_hole.y, -1.2/2],\n radius: outerRadius,\n height: M\n })\n\n return colorize(\n colors.copper,\n subtract(\n union(\n mainRect, leftCap, rightCap,\n outerMainRect, outerLeftCap, outerRightCap,\n bottomMainRect, bottomLeftCap, bottomRightCap\n ),[\n cuboid({\n center: [plated_hole.x, plated_hole.y, 0],\n size: [holeWidth - holeHeight - M*2, holeHeight - M*2, 1.5]\n }),\n cylinder({\n center: [plated_hole.x - (holeWidth - holeHeight)/2, plated_hole.y, 0],\n radius: holeRadius - M,\n height: 1.5\n }),\n cylinder({\n center: [plated_hole.x + (holeWidth - holeHeight)/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}","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 { 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\nexport const CadViewerContainer = ({ children }: { children: any }) => {\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 // rotation: [-Math.PI / 2, 0, 0],\n // lookAt: new THREE.Vector3(0, 0, 0),\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 </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 // color: \"rgba(255, 255, 255, 0.75)\",\n // textShadow:\n // \"0px 0px 1px rgba(0, 0, 0, 0.5), 0px 0px 2px 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.39\",\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 },\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.136\",\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.21\",\n \"jscad-fiber\": \"^0.0.63\",\n \"jscad-planner\": \"^0.0.7\",\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.77\",\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 type { Vector3 } from \"three\"\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n componentId,\n name,\n position,\n}: {\n children: React.ReactNode\n componentId: string\n name: string\n position?: Vector3 | [number, number, number]\n onHover: (id: string | null) => void\n isHovered: boolean\n}) => {\n return (\n <group\n {...{\n onPointerOver: () => onHover(componentId),\n onPointerOut: () => onHover(null),\n }}\n >\n {children}\n {isHovered && (\n <Html\n position={position}\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 }}\n >\n {name}\n </Html>\n )}\n </group>\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}","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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => 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 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 componentId={componentId}\n name={name}\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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => void\n isHovered: boolean\n}) => {\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n const jscadPlan = useMemo(() => {\n if (!footprint) return null\n const jscadPlan: any[] = []\n const root = createJSCADRoot(jscadPlan)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadPlan\n }, [footprint])\n\n if (!jscadPlan) return null\n\n return (\n <>\n {jscadPlan.map((plan, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={plan}\n componentId={componentId}\n name={name}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\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_jsx_runtime","import_drei","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","jscadPlan","import_jsx_runtime"]}
|
|
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/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"],"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 { 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\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n const [hoveredComponent, setHoveredComponent] = useState<string | null>(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, loading } = useStlsFromGeom(boardGeom)\n\n const cad_components = su(soup).cad_component.list()\n\n // TODO canvas/camera etc.\n return (\n <CadViewerContainer>\n {stls.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 const componentName = su(soup).source_component.getUsing({\n source_component_id: cad_component.source_component_id,\n })?.name\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\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 componentId={cad_component.cad_component_id}\n name={componentName || cad_component.cad_component_id}\n onHover={setHoveredComponent}\n isHovered={hoveredComponent === cad_component.cad_component_id}\n />\n )\n }\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\"\n\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\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 const subRoutes = mixedRoute.reduce(\n (c, p) => {\n // @ts-ignore\n const lastLayer = c.current?.[c.current.length - 1]?.layer\n if (\n p.route_type === \"via\" ||\n (p.route_type === \"wire\" && p.layer !== lastLayer)\n ) {\n if (c.current.length > 2) {\n c.allPrev.push(c.current)\n }\n c.current = p.route_type === \"wire\" ? [p] : []\n return c\n }\n c.current.push(p)\n return c\n },\n {\n current: [] as typeof mixedRoute,\n allPrev: [] as Array<typeof mixedRoute>,\n },\n )\n for (const route of subRoutes.allPrev.concat([subRoutes.current])) {\n // TODO break into segments based on layers\n const linePath = line(route.map((p) => [p.x, p.y]))\n\n const layer = route[0]!.route_type === \"wire\" ? route[0]!.layer : \"top\"\n const layerSign = layer === \"top\" ? 1 : -1\n // traceGeoms.push(traceGeom)\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 // HACK: Subtract all vias from every trace- this mostly is because the\n // vias aren't inside the route- we should probably pre-filter to make sure\n // that vias are only near the route\n for (const via of pcb_vias) {\n traceGeom = subtract(\n traceGeom,\n cylinder({\n center: [via.x, via.y, 0],\n radius: via.outer_diameter / 2,\n height: 5,\n }),\n )\n }\n for (const ph of plated_holes) {\n if (ph.shape === \"circle\") {\n traceGeom = subtract(\n traceGeom,\n cylinder({\n center: [ph.x, ph.y, 0],\n radius: ph.outer_diameter / 2,\n height: 5,\n }),\n )\n }\n }\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\n // Colorize to a PCB green color: #05A32E\n boardGeom = colorize(colors.fr4Green, boardGeom)\n\n return [boardGeom, ...platedHoleGeoms, ...padGeoms, ...traceGeoms]\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 { 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\nexport const CadViewerContainer = ({ children }: { children: any }) => {\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 // rotation: [-Math.PI / 2, 0, 0],\n // lookAt: new THREE.Vector3(0, 0, 0),\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 </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 // color: \"rgba(255, 255, 255, 0.75)\",\n // textShadow:\n // \"0px 0px 1px rgba(0, 0, 0, 0.5), 0px 0px 2px 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.41\",\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 \"format\": \"biome format . --write\"\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.136\",\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.21\",\n \"jscad-fiber\": \"^0.0.63\",\n \"jscad-planner\": \"^0.0.7\",\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.77\",\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, useFrame, useThree } from \"@react-three/fiber\"\nimport { useRef, useState } from \"react\"\nimport type { Vector3 } from \"three\"\nimport * as THREE from \"three\"\n\nconst ContainerWithTooltip = ({\n children,\n isHovered,\n onHover,\n componentId,\n name,\n position,\n}: {\n children: React.ReactNode\n componentId: string\n name: string\n position?: Vector3 | [number, number, number]\n onHover: (id: string | null) => void\n isHovered: boolean\n}) => {\n const [mousePosition, setMousePosition] = useState<[number, number, number]>([0, 0, 0])\n const { camera } = useThree()\n const mouseRef = useRef(new THREE.Vector2())\n \n // Update tooltip position on every frame when hovered\n useFrame(() => {\n if (isHovered) {\n // Project the stored mouse coordinates into 3D space\n const vector = new THREE.Vector3(mouseRef.current.x, mouseRef.current.y, 0.5)\n vector.unproject(camera)\n setMousePosition([vector.x, vector.y, vector.z])\n }\n })\n\n const groupProps: GroupProps = {\n position,\n onPointerEnter: (e) => {\n e.stopPropagation()\n // Store normalized mouse coordinates\n mouseRef.current.set(\n (e.clientX / window.innerWidth) * 2 - 1,\n -(e.clientY / window.innerHeight) * 2 + 1\n )\n onHover(componentId)\n },\n onPointerMove: (e) => {\n e.stopPropagation()\n // Update normalized mouse coordinates\n mouseRef.current.set(\n (e.clientX / window.innerWidth) * 2 - 1,\n -(e.clientY / window.innerHeight) * 2 + 1\n )\n },\n onPointerLeave: (e) => {\n e.stopPropagation()\n onHover(null)\n }\n }\n\n return (\n <group {...groupProps}>\n {children}\n {isHovered && (\n <Html\n position={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 }}\n >\n {name}\n </Html>\n )}\n </group>\n )\n}\n\nexport default ContainerWithTooltip","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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => void\n isHovered: boolean\n}) {\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <ContainerWithTooltip\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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\n componentId={componentId}\n name={name}\n isHovered={isHovered}\n onHover={onHover}\n >\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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n jscadPlan: JscadOperation\n positionOffset?: [number, number, number]\n rotationOffset?: [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => 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 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 componentId={componentId}\n name={name}\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 componentId,\n name,\n onHover,\n isHovered,\n}: {\n positionOffset: any\n footprint: string\n rotationOffset?: [number, number, number]\n componentId: string\n name: string\n onHover: (id: string | null) => void\n isHovered: boolean\n}) => {\n // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>\n const jscadPlan = useMemo(() => {\n if (!footprint) return null\n const jscadPlan: any[] = []\n const root = createJSCADRoot(jscadPlan)\n root.render(<Footprinter3d footprint={footprint} />)\n return jscadPlan\n }, [footprint])\n\n if (!jscadPlan) return null\n\n return (\n <>\n {jscadPlan.map((plan, index) => (\n <JscadModel\n // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n key={index}\n positionOffset={positionOffset}\n rotationOffset={rotationOffset}\n jscadPlan={plan}\n componentId={componentId}\n name={name}\n onHover={onHover}\n isHovered={isHovered}\n />\n ))}\n </>\n )\n}\n","export const tuple = <T extends any[]>(...args: T): T => args\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_jsx_runtime","import_drei","import_fiber","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","jscadPlan","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.42",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"prepublish": "npm run build",
|
|
13
13
|
"preview": "vite preview",
|
|
14
14
|
"storybook": "storybook dev -p 6006",
|
|
15
|
-
"build-storybook": "storybook build"
|
|
15
|
+
"build-storybook": "storybook build",
|
|
16
|
+
"format": "biome format . --write"
|
|
16
17
|
},
|
|
17
18
|
"dependencies": {
|
|
18
19
|
"@jscad/modeling": "^2.12.2",
|