@tscircuit/3d-viewer 0.0.406 → 0.0.407

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -47,6 +47,7 @@ interface ManifoldGeoms {
47
47
  board?: {
48
48
  geometry: THREE.BufferGeometry;
49
49
  color: THREE.Color;
50
+ material: PcbBoard["material"];
50
51
  };
51
52
  platedHoles?: Array<{
52
53
  key: string;
package/dist/index.js CHANGED
@@ -26100,7 +26100,7 @@ import * as THREE13 from "three";
26100
26100
  // package.json
26101
26101
  var package_default = {
26102
26102
  name: "@tscircuit/3d-viewer",
26103
- version: "0.0.405",
26103
+ version: "0.0.406",
26104
26104
  main: "./dist/index.js",
26105
26105
  module: "./dist/index.js",
26106
26106
  type: "module",
@@ -26879,7 +26879,7 @@ import { su as su2 } from "@tscircuit/circuit-json-util";
26879
26879
  var M = 0.01;
26880
26880
  var colors = {
26881
26881
  copper: [0.9, 0.6, 0.2],
26882
- fr4Green: [5 / 255, 163 / 255, 46 / 255],
26882
+ fr4Green: [0.04, 0.16, 0.08],
26883
26883
  fr4GreenSolderWithMask: [0 / 255, 152 / 255, 19 / 255],
26884
26884
  fr1Copper: [0.8, 0.4, 0.2],
26885
26885
  fr1CopperSolderWithMask: [0.9, 0.6, 0.2]
@@ -29708,7 +29708,8 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
29708
29708
  matColorArray[0],
29709
29709
  matColorArray[1],
29710
29710
  matColorArray[2]
29711
- )
29711
+ ),
29712
+ material: boardData.material
29712
29713
  };
29713
29714
  }
29714
29715
  const { smtPadGeoms } = processSmtPadsForManifold(
@@ -29787,17 +29788,53 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
29787
29788
  };
29788
29789
 
29789
29790
  // src/utils/manifold/create-three-geometry-meshes.ts
29791
+ import * as THREE25 from "three";
29792
+
29793
+ // src/utils/create-board-material.ts
29790
29794
  import * as THREE24 from "three";
29795
+ var DEFAULT_SIDE = THREE24.DoubleSide;
29796
+ var createBoardMaterial = ({
29797
+ material,
29798
+ color,
29799
+ side = DEFAULT_SIDE
29800
+ }) => {
29801
+ if (material === "fr4") {
29802
+ return new THREE24.MeshPhysicalMaterial({
29803
+ color,
29804
+ side,
29805
+ metalness: 0,
29806
+ roughness: 0.8,
29807
+ specularIntensity: 0.2,
29808
+ ior: 1.45,
29809
+ sheen: 0,
29810
+ clearcoat: 0,
29811
+ transparent: false,
29812
+ opacity: 1,
29813
+ flatShading: true
29814
+ });
29815
+ }
29816
+ return new THREE24.MeshStandardMaterial({
29817
+ color,
29818
+ side,
29819
+ flatShading: true,
29820
+ metalness: 0.1,
29821
+ roughness: 0.8,
29822
+ transparent: true,
29823
+ opacity: 0.9
29824
+ });
29825
+ };
29826
+
29827
+ // src/utils/manifold/create-three-geometry-meshes.ts
29791
29828
  function createGeometryMeshes(geoms) {
29792
29829
  const meshes = [];
29793
29830
  if (!geoms) return meshes;
29794
29831
  if (geoms.board && geoms.board.geometry) {
29795
- const mesh = new THREE24.Mesh(
29832
+ const mesh = new THREE25.Mesh(
29796
29833
  geoms.board.geometry,
29797
- new THREE24.MeshStandardMaterial({
29834
+ createBoardMaterial({
29835
+ material: geoms.board.material,
29798
29836
  color: geoms.board.color,
29799
- side: THREE24.DoubleSide,
29800
- flatShading: true
29837
+ side: THREE25.DoubleSide
29801
29838
  })
29802
29839
  );
29803
29840
  mesh.name = "board-geom";
@@ -29806,11 +29843,11 @@ function createGeometryMeshes(geoms) {
29806
29843
  const createMeshesFromArray = (geomArray) => {
29807
29844
  if (geomArray) {
29808
29845
  geomArray.forEach((comp) => {
29809
- const mesh = new THREE24.Mesh(
29846
+ const mesh = new THREE25.Mesh(
29810
29847
  comp.geometry,
29811
- new THREE24.MeshStandardMaterial({
29848
+ new THREE25.MeshStandardMaterial({
29812
29849
  color: comp.color,
29813
- side: THREE24.DoubleSide,
29850
+ side: THREE25.DoubleSide,
29814
29851
  flatShading: true
29815
29852
  // Consistent with board
29816
29853
  })
@@ -29828,21 +29865,21 @@ function createGeometryMeshes(geoms) {
29828
29865
  }
29829
29866
 
29830
29867
  // src/utils/manifold/create-three-texture-meshes.ts
29831
- import * as THREE25 from "three";
29868
+ import * as THREE26 from "three";
29832
29869
  function createTextureMeshes(textures, boardData, pcbThickness) {
29833
29870
  const meshes = [];
29834
29871
  if (!textures || !boardData || pcbThickness === null) return meshes;
29835
29872
  const createTexturePlane = (texture, yOffset, isBottomLayer, keySuffix) => {
29836
29873
  if (!texture) return null;
29837
- const planeGeom = new THREE25.PlaneGeometry(boardData.width, boardData.height);
29838
- const material = new THREE25.MeshBasicMaterial({
29874
+ const planeGeom = new THREE26.PlaneGeometry(boardData.width, boardData.height);
29875
+ const material = new THREE26.MeshBasicMaterial({
29839
29876
  map: texture,
29840
29877
  transparent: true,
29841
- side: THREE25.DoubleSide,
29878
+ side: THREE26.DoubleSide,
29842
29879
  depthWrite: false
29843
29880
  // Important for layers to avoid z-fighting issues with board itself
29844
29881
  });
29845
- const mesh = new THREE25.Mesh(planeGeom, material);
29882
+ const mesh = new THREE26.Mesh(planeGeom, material);
29846
29883
  mesh.position.set(boardData.center.x, boardData.center.y, yOffset);
29847
29884
  if (isBottomLayer) {
29848
29885
  mesh.rotation.set(Math.PI, 0, 0);
@@ -30498,11 +30535,11 @@ var CadViewer = (props) => {
30498
30535
  // src/convert-circuit-json-to-3d-svg.ts
30499
30536
  var import_debug = __toESM(require_browser(), 1);
30500
30537
  import { su as su14 } from "@tscircuit/circuit-json-util";
30501
- import * as THREE29 from "three";
30538
+ import * as THREE30 from "three";
30502
30539
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
30503
30540
 
30504
30541
  // src/utils/create-geometry-from-polygons.ts
30505
- import * as THREE26 from "three";
30542
+ import * as THREE27 from "three";
30506
30543
  import { BufferGeometry as BufferGeometry3, Float32BufferAttribute as Float32BufferAttribute2 } from "three";
30507
30544
  function createGeometryFromPolygons(polygons) {
30508
30545
  const geometry = new BufferGeometry3();
@@ -30516,12 +30553,12 @@ function createGeometryFromPolygons(polygons) {
30516
30553
  ...polygon3.vertices[i + 1]
30517
30554
  // Third vertex
30518
30555
  );
30519
- const v1 = new THREE26.Vector3(...polygon3.vertices[0]);
30520
- const v2 = new THREE26.Vector3(...polygon3.vertices[i]);
30521
- const v3 = new THREE26.Vector3(...polygon3.vertices[i + 1]);
30522
- const normal = new THREE26.Vector3().crossVectors(
30523
- new THREE26.Vector3().subVectors(v2, v1),
30524
- new THREE26.Vector3().subVectors(v3, v1)
30556
+ const v1 = new THREE27.Vector3(...polygon3.vertices[0]);
30557
+ const v2 = new THREE27.Vector3(...polygon3.vertices[i]);
30558
+ const v3 = new THREE27.Vector3(...polygon3.vertices[i + 1]);
30559
+ const normal = new THREE27.Vector3().crossVectors(
30560
+ new THREE27.Vector3().subVectors(v2, v1),
30561
+ new THREE27.Vector3().subVectors(v3, v1)
30525
30562
  ).normalize();
30526
30563
  normals.push(
30527
30564
  normal.x,
@@ -30544,10 +30581,10 @@ function createGeometryFromPolygons(polygons) {
30544
30581
  // src/utils/render-component.tsx
30545
30582
  var import_modeling3 = __toESM(require_src(), 1);
30546
30583
  var import_jscad_planner2 = __toESM(require_dist(), 1);
30547
- import * as THREE28 from "three";
30584
+ import * as THREE29 from "three";
30548
30585
 
30549
30586
  // src/utils/load-model.ts
30550
- import * as THREE27 from "three";
30587
+ import * as THREE28 from "three";
30551
30588
  import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
30552
30589
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
30553
30590
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -30555,12 +30592,12 @@ async function load3DModel(url) {
30555
30592
  if (url.endsWith(".stl")) {
30556
30593
  const loader = new STLLoader2();
30557
30594
  const geometry = await loader.loadAsync(url);
30558
- const material = new THREE27.MeshStandardMaterial({
30595
+ const material = new THREE28.MeshStandardMaterial({
30559
30596
  color: 8947848,
30560
30597
  metalness: 0.5,
30561
30598
  roughness: 0.5
30562
30599
  });
30563
- return new THREE27.Mesh(geometry, material);
30600
+ return new THREE28.Mesh(geometry, material);
30564
30601
  }
30565
30602
  if (url.endsWith(".obj")) {
30566
30603
  const loader = new OBJLoader2();
@@ -30593,9 +30630,9 @@ async function renderComponent(component, scene) {
30593
30630
  }
30594
30631
  if (component.rotation) {
30595
30632
  model.rotation.set(
30596
- THREE28.MathUtils.degToRad(component.rotation.x ?? 0),
30597
- THREE28.MathUtils.degToRad(component.rotation.y ?? 0),
30598
- THREE28.MathUtils.degToRad(component.rotation.z ?? 0)
30633
+ THREE29.MathUtils.degToRad(component.rotation.x ?? 0),
30634
+ THREE29.MathUtils.degToRad(component.rotation.y ?? 0),
30635
+ THREE29.MathUtils.degToRad(component.rotation.z ?? 0)
30599
30636
  );
30600
30637
  }
30601
30638
  scene.add(model);
@@ -30609,13 +30646,13 @@ async function renderComponent(component, scene) {
30609
30646
  );
30610
30647
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
30611
30648
  const threeGeom = convertCSGToThreeGeom(jscadObject);
30612
- const material2 = new THREE28.MeshStandardMaterial({
30649
+ const material2 = new THREE29.MeshStandardMaterial({
30613
30650
  color: 8947848,
30614
30651
  metalness: 0.5,
30615
30652
  roughness: 0.5,
30616
- side: THREE28.DoubleSide
30653
+ side: THREE29.DoubleSide
30617
30654
  });
30618
- const mesh2 = new THREE28.Mesh(threeGeom, material2);
30655
+ const mesh2 = new THREE29.Mesh(threeGeom, material2);
30619
30656
  if (component.position) {
30620
30657
  mesh2.position.set(
30621
30658
  component.position.x ?? 0,
@@ -30625,9 +30662,9 @@ async function renderComponent(component, scene) {
30625
30662
  }
30626
30663
  if (component.rotation) {
30627
30664
  mesh2.rotation.set(
30628
- THREE28.MathUtils.degToRad(component.rotation.x ?? 0),
30629
- THREE28.MathUtils.degToRad(component.rotation.y ?? 0),
30630
- THREE28.MathUtils.degToRad(component.rotation.z ?? 0)
30665
+ THREE29.MathUtils.degToRad(component.rotation.x ?? 0),
30666
+ THREE29.MathUtils.degToRad(component.rotation.y ?? 0),
30667
+ THREE29.MathUtils.degToRad(component.rotation.z ?? 0)
30631
30668
  );
30632
30669
  }
30633
30670
  scene.add(mesh2);
@@ -30643,17 +30680,17 @@ async function renderComponent(component, scene) {
30643
30680
  if (!geom || !geom.polygons && !geom.sides) {
30644
30681
  continue;
30645
30682
  }
30646
- const color = new THREE28.Color(geomInfo.color);
30683
+ const color = new THREE29.Color(geomInfo.color);
30647
30684
  color.convertLinearToSRGB();
30648
30685
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
30649
30686
  const threeGeom = convertCSGToThreeGeom(geomWithColor);
30650
- const material2 = new THREE28.MeshStandardMaterial({
30687
+ const material2 = new THREE29.MeshStandardMaterial({
30651
30688
  vertexColors: true,
30652
30689
  metalness: 0.2,
30653
30690
  roughness: 0.8,
30654
- side: THREE28.DoubleSide
30691
+ side: THREE29.DoubleSide
30655
30692
  });
30656
- const mesh2 = new THREE28.Mesh(threeGeom, material2);
30693
+ const mesh2 = new THREE29.Mesh(threeGeom, material2);
30657
30694
  if (component.position) {
30658
30695
  mesh2.position.set(
30659
30696
  component.position.x ?? 0,
@@ -30663,22 +30700,22 @@ async function renderComponent(component, scene) {
30663
30700
  }
30664
30701
  if (component.rotation) {
30665
30702
  mesh2.rotation.set(
30666
- THREE28.MathUtils.degToRad(component.rotation.x ?? 0),
30667
- THREE28.MathUtils.degToRad(component.rotation.y ?? 0),
30668
- THREE28.MathUtils.degToRad(component.rotation.z ?? 0)
30703
+ THREE29.MathUtils.degToRad(component.rotation.x ?? 0),
30704
+ THREE29.MathUtils.degToRad(component.rotation.y ?? 0),
30705
+ THREE29.MathUtils.degToRad(component.rotation.z ?? 0)
30669
30706
  );
30670
30707
  }
30671
30708
  scene.add(mesh2);
30672
30709
  }
30673
30710
  return;
30674
30711
  }
30675
- const geometry = new THREE28.BoxGeometry(0.5, 0.5, 0.5);
30676
- const material = new THREE28.MeshStandardMaterial({
30712
+ const geometry = new THREE29.BoxGeometry(0.5, 0.5, 0.5);
30713
+ const material = new THREE29.MeshStandardMaterial({
30677
30714
  color: 16711680,
30678
30715
  transparent: true,
30679
30716
  opacity: 0.25
30680
30717
  });
30681
- const mesh = new THREE28.Mesh(geometry, material);
30718
+ const mesh = new THREE29.Mesh(geometry, material);
30682
30719
  if (component.position) {
30683
30720
  mesh.position.set(
30684
30721
  component.position.x ?? 0,
@@ -30699,11 +30736,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
30699
30736
  padding = 20,
30700
30737
  zoom = 1.5
30701
30738
  } = options;
30702
- const scene = new THREE29.Scene();
30739
+ const scene = new THREE30.Scene();
30703
30740
  const renderer = new SVGRenderer();
30704
30741
  renderer.setSize(width10, height10);
30705
- renderer.setClearColor(new THREE29.Color(backgroundColor), 1);
30706
- const camera = new THREE29.OrthographicCamera();
30742
+ renderer.setClearColor(new THREE30.Color(backgroundColor), 1);
30743
+ const camera = new THREE30.OrthographicCamera();
30707
30744
  const aspect = width10 / height10;
30708
30745
  const frustumSize = 100;
30709
30746
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -30717,45 +30754,44 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
30717
30754
  camera.position.set(position.x, position.y, position.z);
30718
30755
  camera.up.set(0, 1, 0);
30719
30756
  const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
30720
- camera.lookAt(new THREE29.Vector3(lookAt.x, lookAt.y, lookAt.z));
30757
+ camera.lookAt(new THREE30.Vector3(lookAt.x, lookAt.y, lookAt.z));
30721
30758
  camera.updateProjectionMatrix();
30722
- const ambientLight = new THREE29.AmbientLight(16777215, Math.PI / 2);
30759
+ const ambientLight = new THREE30.AmbientLight(16777215, Math.PI / 2);
30723
30760
  scene.add(ambientLight);
30724
- const pointLight = new THREE29.PointLight(16777215, Math.PI / 4);
30761
+ const pointLight = new THREE30.PointLight(16777215, Math.PI / 4);
30725
30762
  pointLight.position.set(-10, -10, 10);
30726
30763
  scene.add(pointLight);
30727
30764
  const components = su14(circuitJson).cad_component.list();
30728
30765
  for (const component of components) {
30729
30766
  await renderComponent(component, scene);
30730
30767
  }
30768
+ const boardData = su14(circuitJson).pcb_board.list()[0];
30731
30769
  const boardGeom = createBoardGeomFromCircuitJson(circuitJson);
30732
30770
  if (boardGeom) {
30733
30771
  for (const geom of boardGeom) {
30734
30772
  const g = geom;
30735
30773
  if (!g.polygons || g.polygons.length === 0) continue;
30736
30774
  const geometry = createGeometryFromPolygons(g.polygons);
30737
- const material = new THREE29.MeshStandardMaterial({
30738
- color: new THREE29.Color(
30739
- g.color?.[0] ?? 0,
30740
- g.color?.[1] ?? 0,
30741
- g.color?.[2] ?? 0
30742
- ),
30743
- metalness: 0.1,
30744
- roughness: 0.8,
30745
- opacity: 0.9,
30746
- transparent: true,
30747
- side: THREE29.DoubleSide
30775
+ const baseColor = new THREE30.Color(
30776
+ g.color?.[0] ?? 0,
30777
+ g.color?.[1] ?? 0,
30778
+ g.color?.[2] ?? 0
30779
+ );
30780
+ const material = createBoardMaterial({
30781
+ material: boardData?.material,
30782
+ color: baseColor,
30783
+ side: THREE30.DoubleSide
30748
30784
  });
30749
- const mesh = new THREE29.Mesh(geometry, material);
30785
+ const mesh = new THREE30.Mesh(geometry, material);
30750
30786
  scene.add(mesh);
30751
30787
  }
30752
30788
  }
30753
- const gridHelper = new THREE29.GridHelper(100, 100);
30789
+ const gridHelper = new THREE30.GridHelper(100, 100);
30754
30790
  gridHelper.rotation.x = Math.PI / 2;
30755
30791
  scene.add(gridHelper);
30756
- const box = new THREE29.Box3().setFromObject(scene);
30757
- const center = box.getCenter(new THREE29.Vector3());
30758
- const size2 = box.getSize(new THREE29.Vector3());
30792
+ const box = new THREE30.Box3().setFromObject(scene);
30793
+ const center = box.getCenter(new THREE30.Vector3());
30794
+ const size2 = box.getSize(new THREE30.Vector3());
30759
30795
  scene.position.sub(center);
30760
30796
  const maxDim = Math.max(size2.x, size2.y, size2.z);
30761
30797
  if (maxDim > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.406",
3
+ "version": "0.0.407",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",