@tscircuit/3d-viewer 0.0.11 → 0.0.12

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 CHANGED
@@ -507,7 +507,7 @@ var CubeWithLabeledSides = ({}) => {
507
507
  // package.json
508
508
  var package_default = {
509
509
  name: "@tscircuit/3d-viewer",
510
- version: "0.0.10",
510
+ version: "0.0.11",
511
511
  main: "./dist/index.js",
512
512
  files: [
513
513
  "dist"
@@ -715,15 +715,13 @@ function MixedStlModel({
715
715
  rotation
716
716
  }) {
717
717
  const obj = useGlobalObjLoader(url);
718
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
719
- "group",
720
- {
721
- rotation,
722
- position,
723
- children: obj && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("primitive", { object: obj })
724
- },
725
- Boolean(obj).toString()
726
- );
718
+ if (!obj) {
719
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("mesh", { position, children: [
720
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("boxGeometry", { args: [0.5, 0.5, 0.5] }),
721
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("meshStandardMaterial", { transparent: true, color: "red", opacity: 0.25 })
722
+ ] });
723
+ }
724
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("primitive", { rotation, position, object: obj });
727
725
  }
728
726
 
729
727
  // src/CadViewer.tsx
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/@tscircuit/soup-util/index.ts","../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/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../src/three-components/cube-with-labeled-sides.tsx","../package.json","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx"],"sourcesContent":["import type {\n AnySoupElement,\n AnySoupElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"@tscircuit/soup\"\n\ntype SoupOps<\n K extends AnySoupElement[\"type\"],\n T extends AnySoupElement | AnySoupElementInput\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type SoupUtilObject = {\n [K in AnySoupElement[\"type\"]]: SoupOps<K, AnySoupElement>\n}\nexport type SoupInputUtilObject = {\n [K in AnySoupElementInput[\"type\"]]: SoupOps<K, AnySoupElementInput>\n}\n\nexport type GetSoupUtilObject = ((soup: AnySoupElement[]) => SoupUtilObject) & {\n unparsed: (soup: AnySoupElementInput[]) => SoupInputUtilObject\n}\n\nexport const su: GetSoupUtilObject = ((soup: AnySoupElement[]) => {\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, component_type: string) => {\n return {\n get: (id: string) =>\n soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\"\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key]\n )\n if (!joiner) return null\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`]\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key])\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return soup.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key])\n )\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\")\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!))\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id\n )\n } else if (component_type === \"schematic_port\") {\n return soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id\n )\n }\n }\n },\n }\n },\n }\n )\n\n return su\n}) as any\nsu.unparsed = su as any\n\nexport default su\n","export { CadViewer } from \"./CadViewer\"\n","import type { AnySoupElement } from \"@tscircuit/soup\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnySoupElement[]\n) => {\n // TODO convert children if defined\n\n return defaultSoup!\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 } 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\"\n\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n soup ??= useConvertChildrenToSoup(children, soup)\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 url = cad_component.model_obj_url ?? cad_component.model_stl_url\n if (!url) return null\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={\n cad_component.rotation\n ? new Euler(\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 />\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 } 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\"\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\n const plated_holes = su(soup).pcb_plated_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 = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: 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 as any).shape) plated_hole.shape = \"circle\"\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 boardGeom = subtract(boardGeom, cyGeom)\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 pad of pads) {\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, 1.2 / 2 + 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, 1.2 / 2 + 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\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n for (const via of mixedRoute.filter((p) => p.route_type === \"via\")) {\n if (via.route_type !== \"via\") continue // TODO remove when ts is smart\n\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: 0.8,\n outer_diameter: 1.6,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n })\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 })\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 { 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 { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext\n): Geom3 => {\n if (!(plated_hole as any).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 } 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 { 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 {\n Canvas,\n useFrame,\n extend,\n useThree,\n useLoader,\n} from \"@react-three/fiber\"\nimport { Suspense, useEffect, useMemo, useRef, useState } from \"react\"\nimport { OrbitControls, Grid, Outlines } from \"@react-three/drei\"\nimport * as THREE from \"three\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport soup from \"./bug-pads-and-traces.json\"\n// import soup from \"./plated-hole-board.json\"\nimport stlSerializer from \"@jscad/stl-serializer\"\n// import { STLLoader } from \"three/examples/jsm/loaders/STLLoader\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\nimport packageJson from \"../package.json\"\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 >\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","import React, { useRef } from \"react\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport { OrbitControls, Text } from \"@react-three/drei\"\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","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.10\",\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.107.2\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@types/three\": \"^0.165.0\",\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 \"@tscircuit/soup\": \"^0.0.39\",\n \"@tscircuit/soup-util\": \"^0.0.11\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.1\",\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 { 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 {\n const [obj, setObj] = useState<Group | null>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n\n async function loadAndParseObj() {\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 }\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 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 setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n // Cleanup function\n return () => setObj(null)\n }, [url])\n\n return obj\n}\n","import { useEffect, useState } from \"react\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport { Euler, Vector3 } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n}) {\n // const group = useLoader(OBJLoader, url)\n // const materials = useLoader(MTLLoader, url)\n // const obj = useLoader(OBJLoader, url)\n\n // const [obj, setObj] = useState<any | null>(null)\n // useEffect(() => {\n // if (!url) return\n // async function loadUrlContent() {\n // const response = await fetch(url)\n // const text = await response.text()\n\n // // Extract all the sections of the file that have newmtl...endmtl to\n // // separate into mtlContent and objContent\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 // // Grayscale the colors, for some reason everything from JLCPCB is\n // // a bit red, it doesn't look right. The grayscale version looks OK,\n // // it's a HACK because we only take the second color rather than\n // // averaging the colors\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 // setObj(objLoader.parse(objContent))\n // }\n // loadUrlContent().catch((e) => {\n // console.log(\"Failed to load model for url: \", url)\n // console.error(e)\n // })\n // }, [url])\n const obj = useGlobalObjLoader(url)\n\n return (\n <group\n rotation={rotation}\n position={position}\n key={Boolean(obj).toString()}\n >\n {obj && <primitive object={obj} />}\n </group>\n )\n}\n"],"mappings":"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","names":["__export","su","module","__toCommonJS","import_soup_util","import_react","import_primitives","import_colors","import_booleans","stlSerializer","import_react","import_fiber","import_drei","import_react","import_fiber","import_jsx_runtime","import_jsx_runtime","import_react","import_three_stdlib","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../node_modules/@tscircuit/soup-util/index.ts","../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/hooks/use-stls-from-geom.ts","../src/three-components/STLModel.tsx","../src/CadViewerContainer.tsx","../src/three-components/cube-with-labeled-sides.tsx","../package.json","../src/hooks/use-global-obj-loader.ts","../src/three-components/MixedStlModel.tsx"],"sourcesContent":["import type {\n AnySoupElement,\n AnySoupElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"@tscircuit/soup\"\n\ntype SoupOps<\n K extends AnySoupElement[\"type\"],\n T extends AnySoupElement | AnySoupElementInput\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type SoupUtilObject = {\n [K in AnySoupElement[\"type\"]]: SoupOps<K, AnySoupElement>\n}\nexport type SoupInputUtilObject = {\n [K in AnySoupElementInput[\"type\"]]: SoupOps<K, AnySoupElementInput>\n}\n\nexport type GetSoupUtilObject = ((soup: AnySoupElement[]) => SoupUtilObject) & {\n unparsed: (soup: AnySoupElementInput[]) => SoupInputUtilObject\n}\n\nexport const su: GetSoupUtilObject = ((soup: AnySoupElement[]) => {\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, component_type: string) => {\n return {\n get: (id: string) =>\n soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\"\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key]\n )\n if (!joiner) return null\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`]\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key])\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return soup.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key])\n )\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\")\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!))\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id\n )\n } else if (component_type === \"schematic_port\") {\n return soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id\n )\n }\n }\n },\n }\n },\n }\n )\n\n return su\n}) as any\nsu.unparsed = su as any\n\nexport default su\n","export { CadViewer } from \"./CadViewer\"\n","import type { AnySoupElement } from \"@tscircuit/soup\"\n\nexport const useConvertChildrenToSoup = (\n children?: any,\n defaultSoup?: AnySoupElement[]\n) => {\n // TODO convert children if defined\n\n return defaultSoup!\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 } 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\"\n\ninterface Props {\n soup?: AnySoupElement[]\n children?: any\n}\n\nexport const CadViewer = ({ soup, children }: Props) => {\n soup ??= useConvertChildrenToSoup(children, soup)\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 url = cad_component.model_obj_url ?? cad_component.model_stl_url\n if (!url) return null\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={\n cad_component.rotation\n ? new Euler(\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 />\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 } 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\"\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\n const plated_holes = su(soup).pcb_plated_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 = cuboid({ size: [board.width, board.height, 1.2] })\n\n const platedHoleGeoms: 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 as any).shape) plated_hole.shape = \"circle\"\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 boardGeom = subtract(boardGeom, cyGeom)\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 pad of pads) {\n if (pad.shape === \"rect\") {\n const padGeom = colorize(\n colors.copper,\n cuboid({\n center: [pad.x, pad.y, 1.2 / 2 + 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, 1.2 / 2 + 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\n traceGeom = colorize(colors.fr4GreenSolderWithMask, traceGeom)\n\n traceGeoms.push(traceGeom)\n }\n for (const via of mixedRoute.filter((p) => p.route_type === \"via\")) {\n if (via.route_type !== \"via\") continue // TODO remove when ts is smart\n\n addPlatedHole({\n x: via.x,\n y: via.y,\n hole_diameter: 0.8,\n outer_diameter: 1.6,\n shape: \"circle\",\n layers: [\"top\", \"bottom\"],\n type: \"pcb_plated_hole\",\n })\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 })\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 { 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 { GeomContext } from \"../GeomContext\"\n\nexport const platedHole = (\n plated_hole: PCBPlatedHole,\n ctx: GeomContext\n): Geom3 => {\n if (!(plated_hole as any).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 } 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 { 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 {\n Canvas,\n useFrame,\n extend,\n useThree,\n useLoader,\n} from \"@react-three/fiber\"\nimport { Suspense, useEffect, useMemo, useRef, useState } from \"react\"\nimport { OrbitControls, Grid, Outlines } from \"@react-three/drei\"\nimport * as THREE from \"three\"\nimport { CubeWithLabeledSides } from \"./three-components/cube-with-labeled-sides\"\nimport { createBoardGeomFromSoup } from \"./soup-to-3d\"\nimport soup from \"./bug-pads-and-traces.json\"\n// import soup from \"./plated-hole-board.json\"\nimport stlSerializer from \"@jscad/stl-serializer\"\n// import { STLLoader } from \"three/examples/jsm/loaders/STLLoader\"\nimport { MTLLoader, OBJLoader, STLLoader } from \"three-stdlib\"\nimport packageJson from \"../package.json\"\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 >\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","import React, { useRef } from \"react\"\nimport { Canvas, useFrame } from \"@react-three/fiber\"\nimport { OrbitControls, Text } from \"@react-three/drei\"\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","{\n \"name\": \"@tscircuit/3d-viewer\",\n \"version\": \"0.0.11\",\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.107.2\",\n \"@react-three/fiber\": \"^8.16.8\",\n \"@types/three\": \"^0.165.0\",\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 \"@tscircuit/soup\": \"^0.0.39\",\n \"@tscircuit/soup-util\": \"^0.0.11\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react\": \"^4.3.1\",\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 { 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 {\n const [obj, setObj] = useState<Group | null>(null)\n\n useEffect(() => {\n if (!url) return\n\n const cache = window.TSCIRCUIT_OBJ_LOADER_CACHE\n\n async function loadAndParseObj() {\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 }\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 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 setObj(result)\n })\n .catch((error) => {\n console.error(error)\n })\n\n // Cleanup function\n return () => setObj(null)\n }, [url])\n\n return obj\n}\n","import { useEffect, useState } from \"react\"\nimport { useGlobalObjLoader } from \"src/hooks/use-global-obj-loader\"\nimport { Euler, Vector3 } from \"three\"\nimport { MTLLoader, OBJLoader } from \"three-stdlib\"\n\nexport function MixedStlModel({\n url,\n position,\n rotation,\n}: {\n url: string\n position?: Vector3 | [number, number, number]\n rotation?: Euler | [number, number, number]\n}) {\n // const group = useLoader(OBJLoader, url)\n // const materials = useLoader(MTLLoader, url)\n // const obj = useLoader(OBJLoader, url)\n\n // const [obj, setObj] = useState<any | null>(null)\n // useEffect(() => {\n // if (!url) return\n // async function loadUrlContent() {\n // const response = await fetch(url)\n // const text = await response.text()\n\n // // Extract all the sections of the file that have newmtl...endmtl to\n // // separate into mtlContent and objContent\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 // // Grayscale the colors, for some reason everything from JLCPCB is\n // // a bit red, it doesn't look right. The grayscale version looks OK,\n // // it's a HACK because we only take the second color rather than\n // // averaging the colors\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 // setObj(objLoader.parse(objContent))\n // }\n // loadUrlContent().catch((e) => {\n // console.log(\"Failed to load model for url: \", url)\n // console.error(e)\n // })\n // }, [url])\n const obj = useGlobalObjLoader(url)\n\n if (!obj) {\n return (\n <mesh position={position}>\n <boxGeometry args={[0.5, 0.5, 0.5]} />\n <meshStandardMaterial transparent color=\"red\" opacity={0.25} />\n </mesh>\n )\n }\n\n return <primitive rotation={rotation} position={position} object={obj} />\n}\n"],"mappings":"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","names":["__export","su","module","__toCommonJS","import_soup_util","import_react","import_primitives","import_colors","import_booleans","stlSerializer","import_react","import_fiber","import_drei","import_react","import_fiber","import_jsx_runtime","import_jsx_runtime","import_react","import_three_stdlib","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.11",
3
+ "version": "0.0.12",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"