Repository: jupytercad/JupyterCAD (language: python)

Issue:
Update ThreeJS
We should update ThreeJS and ThreeJS typings. This will allow us to get rid of a couple of `@ts-ignore`s in the mainview.


Discussion / hints:
We may also update `three-mesh-bvh` too

Fix patch:
diff --git a/packages/base/package.json b/packages/base/package.json
index 9291f201..d620c5ff 100644
--- a/packages/base/package.json
+++ b/packages/base/package.json
@@ -60,18 +60,17 @@
     "@naisutech/react-tree": "^3.0.1",
     "@rjsf/core": "^4.2.0",
     "@types/d3-color": "^3.1.0",
-    "@types/three": "^0.134.0",
     "d3-color": "^3.1.0",
     "react": "^18.0.1",
     "styled-components": "^5.3.6",
-    "three": "^0.135.0",
-    "three-mesh-bvh": "^0.5.17",
+    "three": "^0.168.0",
+    "three-mesh-bvh": "^0.7.8",
     "uuid": "^8.3.2"
   },
   "devDependencies": {
     "@apidevtools/json-schema-ref-parser": "^9.0.9",
     "@types/node": "^18.15.11",
-    "@types/three": "^0.135.0",
+    "@types/three": "^0.168.0",
     "rimraf": "^3.0.2",
     "typescript": "^5"
   },
diff --git a/packages/base/src/3dview/helpers.ts b/packages/base/src/3dview/helpers.ts
index 15ecd305..a519a6d7 100644
--- a/packages/base/src/3dview/helpers.ts
+++ b/packages/base/src/3dview/helpers.ts
@@ -36,7 +36,7 @@ export const SELECTED_MESH_COLOR = new THREE.Color(
 
 export type BasicMesh = THREE.Mesh<
   THREE.BufferGeometry,
-  THREE.MeshBasicMaterial
+  THREE.MeshBasicMaterial | THREE.MeshPhongMaterial
 >;
 
 /**
@@ -230,8 +230,7 @@ export function buildShape(options: {
   for (const edge of edgeList) {
     const edgeMaterial = new LineMaterial({
       linewidth: DEFAULT_LINEWIDTH,
-      // @ts-ignore Missing typing in ThreeJS
-      color: DEFAULT_EDGE_COLOR,
+      color: new THREE.Color(DEFAULT_EDGE_COLOR).getHex(),
       clippingPlanes,
       // Depth offset so that lines are most always on top of faces
       polygonOffset: true,
diff --git a/packages/base/src/3dview/mainview.tsx b/packages/base/src/3dview/mainview.tsx
index fde5c94d..5e631007 100644
--- a/packages/base/src/3dview/mainview.tsx
+++ b/packages/base/src/3dview/mainview.tsx
@@ -65,6 +65,10 @@ interface IStates {
   wireframe: boolean;
 }
 
+interface ILineIntersection extends THREE.Intersection {
+  pointOnLine?: THREE.Vector3;
+}
+
 export class MainView extends React.Component<IProps, IStates> {
   constructor(props: IProps) {
     super(props);
@@ -94,11 +98,7 @@ export class MainView extends React.Component<IProps, IStates> {
     this._mainViewModel.renderSignal.connect(this._requestRender, this);
     this._mainViewModel.workerBusy.connect(this._workerBusyHandler, this);
 
-    // @ts-ignore Missing ThreeJS typing
-    this._raycaster.params.Line2 = {};
-    // Is this threshold in pixels? It looks like it
-    // @ts-ignore Missing ThreeJS typing
-    this._raycaster.params.Line2.threshold = 50;
+    this._raycaster.params.Line = { threshold: 50 };
 
     this.state = {
       id: this._mainViewModel.id,
@@ -218,7 +218,8 @@ export class MainView extends React.Component<IProps, IStates> {
 
       this._renderer = new THREE.WebGLRenderer({
         alpha: true,
-        antialias: true
+        antialias: true,
+        stencil: true
       });
       // this._renderer.setPixelRatio(window.devicePixelRatio);
       this._renderer.setClearColor(0x000000, 0);
@@ -286,7 +287,11 @@ export class MainView extends React.Component<IProps, IStates> {
           this._model.syncCamera(
             {
               position: this._camera.position.toArray([]),
-              rotation: this._camera.rotation.toArray([]),
+              rotation: [
+                this._camera.rotation.x,
+                this._camera.rotation.y,
+                this._camera.rotation.z
+              ],
               up: this._camera.up.toArray([])
             },
             this._mainViewModel.id
@@ -381,10 +386,10 @@ export class MainView extends React.Component<IProps, IStates> {
         this.divRef.current.clientHeight,
         false
       );
-      if (this._camera.type === 'PerspectiveCamera') {
+      if (this._camera instanceof THREE.PerspectiveCamera) {
         this._camera.aspect =
           this.divRef.current.clientWidth / this.divRef.current.clientHeight;
-      } else {
+      } else if (this._camera instanceof THREE.OrthographicCamera) {
         this._camera.left = this.divRef.current.clientWidth / -2;
         this._camera.right = this.divRef.current.clientWidth / 2;
         this._camera.top = this.divRef.current.clientHeight / 2;
@@ -478,7 +483,7 @@ export class MainView extends React.Component<IProps, IStates> {
 
     if (intersects.length > 0) {
       // Find the first intersection with a visible object
-      for (const intersect of intersects) {
+      for (const intersect of intersects as ILineIntersection[]) {
         // Object is hidden
         if (!intersect.object.visible || !intersect.object.parent?.visible) {
           continue;
@@ -502,11 +507,7 @@ export class MainView extends React.Component<IProps, IStates> {
           : intersect.object;
         return {
           mesh: intersectMesh as BasicMesh,
-          // @ts-ignore Missing threejs typing
-          position: intersect.pointOnLine
-            ? // @ts-ignore Missing threejs typing
-              intersect.pointOnLine
-            : intersect.point
+          position: intersect.pointOnLine ?? intersect.point
         };
       }
     }
@@ -685,6 +686,7 @@ export class MainView extends React.Component<IProps, IStates> {
       wireframe: this.state.wireframe
     });
     this._clippingPlaneMesh = new THREE.Mesh(planeGeom, planeMat);
+    this._clippingPlaneMesh.visible = this._clipSettings.enabled;
     this._clippingPlaneMesh.onAfterRender = renderer => {
       renderer.clearStencil();
     };
@@ -823,6 +825,9 @@ export class MainView extends React.Component<IProps, IStates> {
                 pos.postShape = exported as any;
                 resolve();
               },
+              () => {
+                // Intentionally empty: no error handling needed for this case
+              }, // Empty function to handle errors
               options
             );
           });
@@ -886,10 +891,12 @@ export class MainView extends React.Component<IProps, IStates> {
       if (selectedMesh.material?.color) {
         selectedMesh.material.color = originalColor;
       }
-      // @ts-ignore
-      if (selectedMesh.material?.linewidth) {
-        // @ts-ignore
-        selectedMesh.material.linewidth = DEFAULT_LINEWIDTH;
+
+      const material = selectedMesh.material as THREE.Material & {
+        linewidth?: number;
+      };
+      if (material?.linewidth) {
+        material.linewidth = DEFAULT_LINEWIDTH;
       }
     }
 
@@ -914,10 +921,12 @@ export class MainView extends React.Component<IProps, IStates> {
       if (selectedMesh?.material?.color) {
         selectedMesh.material.color = SELECTED_MESH_COLOR;
       }
-      // @ts-ignore
-      if (selectedMesh?.material?.linewidth) {
-        // @ts-ignore
-        selectedMesh.material.linewidth = SELECTED_LINEWIDTH;
+
+      const material = selectedMesh.material as THREE.Material & {
+        linewidth?: number;
+      };
+      if (material?.linewidth) {
+        material.linewidth = SELECTED_LINEWIDTH;
       }
     }
   }
@@ -1255,11 +1264,17 @@ export class MainView extends React.Component<IProps, IStates> {
       this._transformControls.enabled = true;
       this._transformControls.visible = true;
       this._clippingPlaneMeshControl.visible = this._clipSettings.showClipPlane;
+      if (this._clippingPlaneMesh) {
+        this._clippingPlaneMesh.visible = true;
+      }
     } else {
       this._renderer.localClippingEnabled = false;
       this._transformControls.enabled = false;
       this._transformControls.visible = false;
       this._clippingPlaneMeshControl.visible = false;
+      if (this._clippingPlaneMesh) {
+        this._clippingPlaneMesh.visible = false;
+      }
     }
   }
 
diff --git a/yarn.lock b/yarn.lock
index 95c41c88..68f5976c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -918,13 +918,13 @@ __metadata:
     "@rjsf/core": ^4.2.0
     "@types/d3-color": ^3.1.0
     "@types/node": ^18.15.11
-    "@types/three": ^0.135.0
+    "@types/three": ^0.168.0
     d3-color: ^3.1.0
     react: ^18.0.1
     rimraf: ^3.0.2
     styled-components: ^5.3.6
-    three: ^0.135.0
-    three-mesh-bvh: ^0.5.17
+    three: ^0.168.0
+    three-mesh-bvh: ^0.7.8
     typescript: ^5
     uuid: ^8.3.2
   languageName: unknown
@@ -3563,6 +3563,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@tweenjs/tween.js@npm:~23.1.3":
+  version: 23.1.3
+  resolution: "@tweenjs/tween.js@npm:23.1.3"
+  checksum: 2f8a908b275bb6729bde4b863c277bf7411d2e0302ceb0455369479077b89eaf8380cd9206b91ff574416418a95c6f06db4e1ddea732a286d0db0ba8e7c093d3
+  languageName: node
+  linkType: hard
+
 "@types/create-react-class@npm:*":
   version: 15.6.8
   resolution: "@types/create-react-class@npm:15.6.8"
@@ -3712,10 +3719,24 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/three@npm:^0.135.0":
-  version: 0.135.0
-  resolution: "@types/three@npm:0.135.0"
-  checksum: 85977e55cc3d7a14be88816a50bcec4eb0f141876d3cdc6dd7870f72122605af87462d7583e950cd0ee6ab21949b8c1b8304a88174d536648deb8ef97968fa1b
+"@types/stats.js@npm:*":
+  version: 0.17.3
+  resolution: "@types/stats.js@npm:0.17.3"
+  checksum: 4f84a012f630532877f62959b6335d3fa081ccaac15ce3f1f916741db265bda22b9c927d7efc9cc3389ffd60919a370673cb0b4e7221d580c571031e94b689fd
+  languageName: node
+  linkType: hard
+
+"@types/three@npm:^0.168.0":
+  version: 0.168.0
+  resolution: "@types/three@npm:0.168.0"
+  dependencies:
+    "@tweenjs/tween.js": ~23.1.3
+    "@types/stats.js": "*"
+    "@types/webxr": "*"
+    "@webgpu/types": "*"
+    fflate: ~0.8.2
+    meshoptimizer: ~0.18.1
+  checksum: 2f4e36689170617ec8b8b085d20257adc5c69278265c040836e5cf4d336fa055fcec3a91d5e0de760abfb38953aee74e874fd1682bb61e31787514425eaa5182
   languageName: node
   linkType: hard
 
@@ -3730,6 +3751,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/webxr@npm:*":
+  version: 0.5.20
+  resolution: "@types/webxr@npm:0.5.20"
+  checksum: 8085c291ca8a8adfe03245725384234e62d61cc0f5f7b9985c2a0ba2b2a794cac538861c4904d8fcd28e3e381f0a4ecc5d4514d143dbf3fc0cf3193dc1cc7a54
+  languageName: node
+  linkType: hard
+
 "@typescript-eslint/eslint-plugin@npm:5.55.0":
   version: 5.55.0
   resolution: "@typescript-eslint/eslint-plugin@npm:5.55.0"
@@ -4002,6 +4030,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@webgpu/types@npm:*":
+  version: 0.1.46
+  resolution: "@webgpu/types@npm:0.1.46"
+  checksum: 8dd5fb8a5993e83cb910c6d7bd7d47b941f631b47a77f1280740b245556be615cc84a87de65dceea07aa6629e4bd392b4b6c53e238514958f985f3f5e999db1a
+  languageName: node
+  linkType: hard
+
 "@webpack-cli/configtest@npm:^2.1.1":
   version: 2.1.1
   resolution: "@webpack-cli/configtest@npm:2.1.1"
@@ -6400,6 +6435,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"fflate@npm:~0.8.2":
+  version: 0.8.2
+  resolution: "fflate@npm:0.8.2"
+  checksum: 29470337b85d3831826758e78f370e15cda3169c5cd4477c9b5eea2402261a74b2975bae816afabe1c15d21d98591e0d30a574f7103aa117bff60756fa3035d4
+  languageName: node
+  linkType: hard
+
 "figures@npm:3.2.0, figures@npm:^3.0.0":
   version: 3.2.0
   resolution: "figures@npm:3.2.0"
@@ -8815,6 +8857,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"meshoptimizer@npm:~0.18.1":
+  version: 0.18.1
+  resolution: "meshoptimizer@npm:0.18.1"
+  checksum: 101dbed8abd4cf167cdb7a0bc13db90dd0743332c689e43b18cc5254d238f0766750752432401fa63dc7e9e32399ef68daacf48f0d89db1484042c1761c7362d
+  languageName: node
+  linkType: hard
+
 "micromatch@npm:^4.0.0, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
   version: 4.0.8
   resolution: "micromatch@npm:4.0.8"
@@ -11945,19 +11994,19 @@ __metadata:
   languageName: node
   linkType: hard
 
-"three-mesh-bvh@npm:^0.5.17":
-  version: 0.5.24
-  resolution: "three-mesh-bvh@npm:0.5.24"
+"three-mesh-bvh@npm:^0.7.8":
+  version: 0.7.8
+  resolution: "three-mesh-bvh@npm:0.7.8"
   peerDependencies:
-    three: ">= 0.123.0"
-  checksum: 5a5e356111756869cfd00870bca2d881d3019b55e71142b5eee544a2e6bcc3546a340b0defa29c3ebe7ed4cfe99e7ee6addd5671bb89852841107189c0f98157
+    three: ">= 0.151.0"
+  checksum: 3023a7d1ccdf033e08eba5c6437b4c3dd31a6ec83cb54cfadfca2d6aa22c74c7895c5b0d6e943897ac411a64b86d9bf78b3f6c3a902efd8b8bfd3cf0afd9a18e
   languageName: node
   linkType: hard
 
-"three@npm:^0.135.0":
-  version: 0.135.0
-  resolution: "three@npm:0.135.0"
-  checksum: bd7e195932587a5be0c887947adf2b3898c6fa71722800432562aed10beddb2f448d0f237d937824805eebf90e625fc22ed57054618121f47811a8e82b528507
+"three@npm:^0.168.0":
+  version: 0.168.0
+  resolution: "three@npm:0.168.0"
+  checksum: 1f186006ad5c8df348d4a2bcdccc078f0454f196b8ccc450d405cdf8c88436ff773e545725ef1122891b5552b5cf03add8394288b58985a0c3ebe66b588cab2f
   languageName: node
   linkType: hard
 


Test patch:
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-0-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-0-linux.png
index 88ff5cc4..2010885a 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-0-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-0-linux.png differ
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-2-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-2-linux.png
index 17b375b0..219935d1 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-2-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-2-linux.png differ
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-3-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-3-linux.png
index c1fb3f07..da193eec 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-3-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/dark-Notebook-ipynb-cell-3-linux.png differ
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-0-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-0-linux.png
index 74e18b95..7e5dd287 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-0-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-0-linux.png differ
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-2-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-2-linux.png
index 117fcf24..621b57f8 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-2-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-2-linux.png differ
diff --git a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-3-linux.png b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-3-linux.png
index 89975483..776ff5a5 100644
Binary files a/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-3-linux.png and b/ui-tests/tests/notebook.spec.ts-snapshots/light-Notebook-ipynb-cell-3-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Console-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Console-linux.png
index 96e4a9ac..0915c59c 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Console-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Console-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Modified-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Modified-linux.png
index 95816b72..46dacdb4 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Modified-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Modified-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Redo-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Redo-linux.png
index a3bdf0fb..c46baaf1 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Redo-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/JCAD-Redo-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-Cut-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-Cut-test-jcad-linux.png
index c99972b3..b586693d 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-Cut-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-Cut-test-jcad-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-test-jcad-linux.png
index 84c6bb59..a58f894a 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/MultiSelect-test-jcad-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Add-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Add-test-jcad-linux.png
index 6aeac87b..b740fa0c 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Add-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Add-test-jcad-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Edit-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Edit-test-jcad-linux.png
index 0513dae4..750ab812 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Edit-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Edit-test-jcad-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Remove-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Remove-test-jcad-linux.png
index 5f88f4e4..595b1561 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/Operator-Remove-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/Operator-Remove-test-jcad-linux.png differ
diff --git a/ui-tests/tests/ui.spec.ts-snapshots/Render-test-jcad-linux.png b/ui-tests/tests/ui.spec.ts-snapshots/Render-test-jcad-linux.png
index 5f88f4e4..8fb3f57b 100644
Binary files a/ui-tests/tests/ui.spec.ts-snapshots/Render-test-jcad-linux.png and b/ui-tests/tests/ui.spec.ts-snapshots/Render-test-jcad-linux.png differ