diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22bb5f1c..087a54b2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -219,6 +219,7 @@ jobs: create-args: >- python=3.10 pip + empack=3 jupyterlite-core>=0.2.0,<0.3.0 jupyterlite-xeus>=0.1.2,<0.2 @@ -240,6 +241,7 @@ jobs: run: | set -eux mkdir -p content && cp ../examples/test.jcad ./content + cp ../jupytercad_lab/dist/jupytercad*.whl jupytercad_lab-1.0.0-py3-none-any.whl jupyter lite build --contents content --output-dir dist - name: Upload github-pages artifact diff --git a/lite/environment.yml b/lite/environment.yml index cf391c4e..ce336395 100644 --- a/lite/environment.yml +++ b/lite/environment.yml @@ -4,3 +4,11 @@ channels: - conda-forge dependencies: - xeus-python + - pydantic=2.7.4 + - ypywidgets + - yjs-widgets + - comm + - pip: + - ./jupytercad_lab-1.0.0-py3-none-any.whl + - jupyter-shared-drive-ui + - jupyter-shared-docprovider diff --git a/packages/base/package.json b/packages/base/package.json index d620c5ff..2f30ab11 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -65,6 +65,7 @@ "styled-components": "^5.3.6", "three": "^0.168.0", "three-mesh-bvh": "^0.7.8", + "three-viewport-gizmo": "^0.1.5", "uuid": "^8.3.2" }, "devDependencies": { diff --git a/packages/base/src/3dview/mainview.tsx b/packages/base/src/3dview/mainview.tsx index 5e631007..a4ea7ceb 100644 --- a/packages/base/src/3dview/mainview.tsx +++ b/packages/base/src/3dview/mainview.tsx @@ -50,6 +50,8 @@ import { } from './helpers'; import { MainViewModel } from './mainviewmodel'; import { Spinner } from './spinner'; +import { ViewportGizmo } from 'three-viewport-gizmo'; +import { GizmoOptions } from 'three-viewport-gizmo/dist/lib/types'; interface IProps { viewModel: MainViewModel; } @@ -226,6 +228,100 @@ export class MainView extends React.Component { this._renderer.setSize(500, 500, false); this.divRef.current.appendChild(this._renderer.domElement); // mount using React ref + const options: GizmoOptions = { + container: this._renderer.domElement.parentElement ?? undefined, + size: Math.min(window.innerWidth, window.innerHeight) * 0.2, + lineWidth: 3, + offset: { top: 0, left: 0, right: 0, bottom: 0 }, + font: { + family: 'helvetica', + weight: 900 + }, + resolution: 64, + backgroundSphere: { + enabled: true, + color: 0x000000, + opacity: 0.2 + }, + x: { + text: 'X', + drawLine: true, + border: false, + colors: { + main: '#ff7f9b', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + }, + y: { + text: 'Y', + drawLine: true, + border: false, + colors: { + main: '#c2ee00', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + }, + z: { + text: 'Z', + drawLine: true, + border: false, + colors: { + main: '#73c5ff', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + }, + nx: { + text: '-X', + drawLine: true, + border: false, + colors: { + main: '#ff7f9b', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + }, + ny: { + text: '-Y', + drawLine: true, + border: false, + colors: { + main: '#c2ee00', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + }, + nz: { + text: '-Z', + drawLine: true, + border: false, + colors: { + main: '#73c5ff', + hover: '#ffffff', + text: '#000000', + hoverText: '#000000' + } + } + }; + + this._viewportGizmo = new ViewportGizmo( + this._camera, + this._renderer, + options + ); + this._viewportGizmo.update(); + // @ts-ignore Accessing a private property + this._viewportGizmo._container = + this._renderer.domElement.parentElement?.parentElement; + console.log(this._viewportGizmo); + this._syncPointer = throttle( (position: THREE.Vector3 | undefined, parent: string | undefined) => { if (position && parent) { @@ -377,6 +473,7 @@ export class MainView extends React.Component { this._renderer.setRenderTarget(null); this._renderer.clearDepth(); this._renderer.render(this._scene, this._camera); + this._viewportGizmo.render(); }; resizeCanvasToDisplaySize = (): void => { @@ -403,6 +500,7 @@ export class MainView extends React.Component { this.sceneSetup(); this.animate(); this.resizeCanvasToDisplaySize(); + this._viewportGizmo.update(); }; private _updateAnnotation() { @@ -1291,6 +1389,7 @@ export class MainView extends React.Component { private _handleWindowResize = (): void => { this.resizeCanvasToDisplaySize(); this._updateAnnotation(); + this._viewportGizmo.update(); }; private _computeAnnotationPosition(annotation: IAnnotation): THREE.Vector2 { @@ -1408,6 +1507,7 @@ export class MainView extends React.Component { private _geometry: THREE.BufferGeometry; // Threejs BufferGeometry private _refLength: number | null = null; // Length of bounding box of current object private _sceneAxe: THREE.Object3D | null; // Array of X, Y and Z axe + private _viewportGizmo: ViewportGizmo; // Viewport gizmo private _controls: OrbitControls; // Mouse controls private _transformControls: TransformControls; // Mesh position/rotation controls private _pointer3D: IPointer | null = null; diff --git a/yarn.lock b/yarn.lock index 68f5976c..e0e55686 100644 --- a/yarn.lock +++ b/yarn.lock @@ -925,6 +925,7 @@ __metadata: styled-components: ^5.3.6 three: ^0.168.0 three-mesh-bvh: ^0.7.8 + three-viewport-gizmo: ^0.1.5 typescript: ^5 uuid: ^8.3.2 languageName: unknown @@ -4798,6 +4799,15 @@ __metadata: languageName: node linkType: hard +"camera-controls@npm:^2.8.3": + version: 2.9.0 + resolution: "camera-controls@npm:2.9.0" + peerDependencies: + three: ">=0.126.1" + checksum: 47e7150a72bb96310cc00dd82c8719b376e925fda963e58a13e5cc61e94d0d13a9065a423de739ad9f7e084854f891b6edf03990260a974ead869e28590fd109 + languageName: node + linkType: hard + "caniuse-lite@npm:^1.0.30001646": version: 1.0.30001662 resolution: "caniuse-lite@npm:1.0.30001662" @@ -12003,6 +12013,17 @@ __metadata: languageName: node linkType: hard +"three-viewport-gizmo@npm:^0.1.0, three-viewport-gizmo@npm:^0.1.5": + version: 0.1.5 + resolution: "three-viewport-gizmo@npm:0.1.5" + dependencies: + camera-controls: ^2.8.3 + three: ^0.162.0 + three-viewport-gizmo: ^0.1.0 + checksum: f00619a6d3ac0cf4bb310ef2f55739747b3f2ce4904802dfd7cda53a5b9e1d71c17cd8b536343143a3ad0d86ce9a4343285461cbc27bfdb00577bd3a190a27d0 + languageName: node + linkType: hard + "three@npm:^0.168.0": version: 0.168.0 resolution: "three@npm:0.168.0" @@ -12010,6 +12031,13 @@ __metadata: languageName: node linkType: hard +"three@npm:^0.162.0": + version: 0.162.0 + resolution: "three@npm:0.162.0" + checksum: f3ba4d518f7cb209b6e4f8818177c1230014fc1b3dcd66ab113a9babf8e2b522645a1eb144dfc0900bf194e8890bc5d04f358dd4a7f06ee8aa44db56224f88fc + languageName: node + linkType: hard + "through2@npm:^2.0.0, through2@npm:^2.0.1": version: 2.0.5 resolution: "through2@npm:2.0.5"