@gradio/model3d 0.14.6 → 0.14.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @gradio/model3d
2
2
 
3
+ ## 0.14.7
4
+
5
+ ### Features
6
+
7
+ - [#10847](https://github.com/gradio-app/gradio/pull/10847) [`d5fde7c`](https://github.com/gradio-app/gradio/commit/d5fde7c390004ce5394072100b059f545d2d4eae) - Babylon update for model3D. Thanks @CedricGuillemet!
8
+
9
+ ### Dependency updates
10
+
11
+ - @gradio/wasm@0.18.1
12
+ - @gradio/client@1.14.1
13
+ - @gradio/upload@0.15.7
14
+
3
15
  ## 0.14.6
4
16
 
5
17
  ### Dependency updates
@@ -1,12 +1,6 @@
1
1
  <script>import { onMount } from "svelte";
2
- import * as BABYLON from "babylonjs";
3
- import * as BABYLON_LOADERS from "babylonjs-loaders";
4
2
  import { resolve_wasm_src } from "@gradio/wasm/svelte";
5
- $: {
6
- if (BABYLON_LOADERS.OBJFileLoader != void 0 && !BABYLON_LOADERS.OBJFileLoader.IMPORT_VERTEX_COLORS) {
7
- BABYLON_LOADERS.OBJFileLoader.IMPORT_VERTEX_COLORS = true;
8
- }
9
- }
3
+ let BABYLON_VIEWER;
10
4
  export let value;
11
5
  export let display_mode;
12
6
  export let clear_color;
@@ -32,146 +26,83 @@ $: {
32
26
  }
33
27
  }
34
28
  let canvas;
35
- let scene;
36
- let engine;
37
- let point_cloud_system = null;
29
+ let viewer;
30
+ let viewerDetails;
38
31
  let mounted = false;
39
32
  onMount(() => {
40
- engine = new BABYLON.Engine(canvas, true);
41
- scene = new BABYLON.Scene(engine);
42
- scene.createDefaultCameraOrLight();
43
- scene.useRightHandedSystem = true;
44
- scene.clearColor = scene.clearColor = new BABYLON.Color4(...clear_color);
45
- engine.runRenderLoop(() => {
46
- scene.render();
47
- });
48
- function onWindowResize() {
49
- engine.resize();
50
- }
51
- window.addEventListener("resize", onWindowResize);
52
- mounted = true;
33
+ const initViewer = async () => {
34
+ BABYLON_VIEWER = await import("@babylonjs/viewer");
35
+ BABYLON_VIEWER.createViewerForCanvas(canvas, {
36
+ clearColor: clear_color,
37
+ useRightHandedSystem: true,
38
+ cameraAutoOrbit: { enabled: false },
39
+ onInitialized: (details) => {
40
+ viewerDetails = details;
41
+ }
42
+ }).then((promiseViewer) => {
43
+ viewer = promiseViewer;
44
+ mounted = true;
45
+ });
46
+ };
47
+ initViewer();
53
48
  return () => {
54
- scene.dispose();
55
- engine.dispose();
56
- window.removeEventListener("resize", onWindowResize);
49
+ viewer?.dispose();
57
50
  };
58
51
  });
59
52
  $:
60
53
  mounted && load_model(resolved_url);
54
+ function setRenderingMode(pointsCloud, wireframe) {
55
+ viewerDetails.scene.forcePointsCloud = pointsCloud;
56
+ viewerDetails.scene.forceWireframe = wireframe;
57
+ }
61
58
  function load_model(url2) {
62
- if (scene) {
63
- scene.meshes.forEach((mesh) => {
64
- mesh.dispose();
65
- });
66
- if (point_cloud_system) {
67
- point_cloud_system.dispose();
68
- point_cloud_system = null;
69
- }
59
+ if (viewer) {
70
60
  if (url2) {
71
- BABYLON.SceneLoader.ShowLoadingScreen = false;
72
- BABYLON.SceneLoader.Append(
73
- url2,
74
- "",
75
- scene,
76
- () => {
77
- if (display_mode === "point_cloud") {
78
- create_point_cloud(scene);
79
- } else if (display_mode === "wireframe") {
80
- create_wireframe(scene);
81
- } else {
82
- create_camera(scene, camera_position, zoom_speed, pan_speed);
61
+ viewer.loadModel(url2, {
62
+ pluginOptions: {
63
+ obj: {
64
+ importVertexColors: true
83
65
  }
84
- },
85
- void 0,
86
- void 0,
87
- "." + value.path.split(".").pop()
88
- );
66
+ }
67
+ }).then(() => {
68
+ if (display_mode === "point_cloud") {
69
+ setRenderingMode(true, false);
70
+ } else if (display_mode === "wireframe") {
71
+ setRenderingMode(false, true);
72
+ } else {
73
+ update_camera(camera_position, zoom_speed, pan_speed);
74
+ }
75
+ });
76
+ } else {
77
+ viewer.resetModel();
89
78
  }
90
79
  }
91
80
  }
92
- function create_camera(scene2, camera_position2, zoom_speed2, pan_speed2) {
93
- scene2.createDefaultCamera(true, true, true);
94
- var helperCamera = scene2.activeCamera;
81
+ function update_camera(camera_position2, zoom_speed2, pan_speed2) {
82
+ viewer.resetCamera();
83
+ const camera = viewerDetails.camera;
95
84
  if (camera_position2[0] !== null) {
96
- helperCamera.alpha = BABYLON.Tools.ToRadians(camera_position2[0]);
85
+ camera.alpha = camera_position2[0] * Math.PI / 180;
97
86
  }
98
87
  if (camera_position2[1] !== null) {
99
- helperCamera.beta = BABYLON.Tools.ToRadians(camera_position2[1]);
88
+ camera.beta = camera_position2[1] * Math.PI / 180;
100
89
  }
101
90
  if (camera_position2[2] !== null) {
102
- helperCamera.radius = camera_position2[2];
91
+ camera.radius = camera_position2[2];
103
92
  }
104
- helperCamera.lowerRadiusLimit = 0.1;
93
+ camera.lowerRadiusLimit = 0.1;
105
94
  const updateCameraSensibility = () => {
106
- helperCamera.wheelPrecision = 250 / (helperCamera.radius * zoom_speed2);
107
- helperCamera.panningSensibility = 1e4 * pan_speed2 / helperCamera.radius;
95
+ camera.wheelPrecision = 250 / (camera.radius * zoom_speed2);
96
+ camera.panningSensibility = 1e4 * pan_speed2 / camera.radius;
108
97
  };
109
98
  updateCameraSensibility();
110
- helperCamera.attachControl(true);
111
- helperCamera.onAfterCheckInputsObservable.add(updateCameraSensibility);
99
+ camera.onAfterCheckInputsObservable.add(updateCameraSensibility);
112
100
  }
113
101
  export function reset_camera_position(camera_position2, zoom_speed2, pan_speed2) {
114
- if (scene) {
115
- scene.removeCamera(scene.activeCamera);
116
- create_camera(scene, camera_position2, zoom_speed2, pan_speed2);
102
+ if (viewerDetails) {
103
+ update_camera(camera_position2, zoom_speed2, pan_speed2);
117
104
  }
118
105
  }
119
- function create_point_cloud(scene2) {
120
- const meshes = scene2.meshes;
121
- const pointPositions = [];
122
- meshes.forEach((mesh) => {
123
- if (mesh instanceof BABYLON.Mesh) {
124
- const positions = mesh.getVerticesData(
125
- BABYLON.VertexBuffer.PositionKind
126
- );
127
- if (positions) {
128
- for (let i = 0; i < positions.length; i += 3) {
129
- pointPositions.push(
130
- new BABYLON.Vector3(
131
- positions[i],
132
- positions[i + 1],
133
- positions[i + 2]
134
- )
135
- );
136
- }
137
- }
138
- mesh.setEnabled(false);
139
- }
140
- });
141
- point_cloud_system = new BABYLON.PointsCloudSystem(
142
- "point_cloud_system",
143
- 1,
144
- scene2
145
- );
146
- point_cloud_system.addPoints(
147
- pointPositions.length,
148
- (particle, i) => {
149
- particle.position = pointPositions[i];
150
- particle.color = new BABYLON.Color4(
151
- Math.random(),
152
- Math.random(),
153
- Math.random(),
154
- 1
155
- );
156
- }
157
- );
158
- point_cloud_system.buildMeshAsync().then((mesh) => {
159
- mesh.alwaysSelectAsActiveMesh = true;
160
- create_camera(scene2, camera_position, zoom_speed, pan_speed);
161
- });
162
- }
163
- function create_wireframe(scene2) {
164
- scene2.meshes.forEach((mesh) => {
165
- if (mesh instanceof BABYLON.Mesh) {
166
- mesh.material = new BABYLON.StandardMaterial(
167
- "wireframeMaterial",
168
- scene2
169
- );
170
- mesh.material.wireframe = true;
171
- }
172
- create_camera(scene2, camera_position, zoom_speed, pan_speed);
173
- });
174
- }
175
106
  </script>
176
107
 
177
108
  <canvas bind:this={canvas}></canvas>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/model3d",
3
- "version": "0.14.6",
3
+ "version": "0.14.7",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -8,17 +8,16 @@
8
8
  "private": false,
9
9
  "dependencies": {
10
10
  "@types/babylon": "^6.16.6",
11
- "babylonjs": "^7.25.1",
12
- "babylonjs-loaders": "^7.25.1",
11
+ "@babylonjs/viewer": "^7.54.0",
13
12
  "dequal": "^2.0.2",
14
13
  "gsplat": "^1.0.5",
15
- "@gradio/atoms": "^0.14.1",
16
- "@gradio/client": "^1.14.0",
14
+ "@gradio/client": "^1.14.1",
15
+ "@gradio/icons": "^0.10.0",
17
16
  "@gradio/statustracker": "^0.10.6",
17
+ "@gradio/atoms": "^0.14.1",
18
+ "@gradio/upload": "^0.15.7",
18
19
  "@gradio/utils": "^0.10.1",
19
- "@gradio/icons": "^0.10.0",
20
- "@gradio/upload": "^0.15.6",
21
- "@gradio/wasm": "^0.18.0"
20
+ "@gradio/wasm": "^0.18.1"
22
21
  },
23
22
  "devDependencies": {
24
23
  "@gradio/preview": "^0.13.0"
@@ -1,18 +1,10 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from "svelte";
3
- import * as BABYLON from "babylonjs";
4
- import * as BABYLON_LOADERS from "babylonjs-loaders";
5
3
  import type { FileData } from "@gradio/client";
6
4
  import { resolve_wasm_src } from "@gradio/wasm/svelte";
5
+ import type { Viewer, ViewerDetails } from "@babylonjs/viewer";
7
6
 
8
- $: {
9
- if (
10
- BABYLON_LOADERS.OBJFileLoader != undefined &&
11
- !BABYLON_LOADERS.OBJFileLoader.IMPORT_VERTEX_COLORS
12
- ) {
13
- BABYLON_LOADERS.OBJFileLoader.IMPORT_VERTEX_COLORS = true;
14
- }
15
- }
7
+ let BABYLON_VIEWER: typeof import("@babylonjs/viewer");
16
8
 
17
9
  export let value: FileData;
18
10
  export let display_mode: "solid" | "point_cloud" | "wireframe";
@@ -50,104 +42,90 @@
50
42
  }
51
43
  }
52
44
 
53
- /* BabylonJS engine and scene management */
54
45
  let canvas: HTMLCanvasElement;
55
- let scene: BABYLON.Scene;
56
- let engine: BABYLON.Engine;
57
- let point_cloud_system: BABYLON.PointsCloudSystem | null = null;
46
+ let viewer: Viewer;
47
+ let viewerDetails: Readonly<ViewerDetails>;
58
48
  let mounted = false;
59
49
 
60
50
  onMount(() => {
61
- // Initialize BabylonJS engine and scene
62
- engine = new BABYLON.Engine(canvas, true);
63
- scene = new BABYLON.Scene(engine);
64
-
65
- scene.createDefaultCameraOrLight();
66
- scene.useRightHandedSystem = true;
67
- scene.clearColor = scene.clearColor = new BABYLON.Color4(...clear_color);
68
-
69
- engine.runRenderLoop(() => {
70
- scene.render();
71
- });
72
-
73
- function onWindowResize(): void {
74
- engine.resize();
75
- }
76
- window.addEventListener("resize", onWindowResize);
51
+ const initViewer = async (): Promise<void> => {
52
+ BABYLON_VIEWER = await import("@babylonjs/viewer");
53
+ BABYLON_VIEWER.createViewerForCanvas(canvas, {
54
+ clearColor: clear_color,
55
+ useRightHandedSystem: true,
56
+ cameraAutoOrbit: { enabled: false },
57
+ onInitialized: (details: any) => {
58
+ viewerDetails = details;
59
+ }
60
+ }).then((promiseViewer: any) => {
61
+ viewer = promiseViewer;
62
+ mounted = true;
63
+ });
64
+ };
77
65
 
78
- mounted = true;
66
+ initViewer();
79
67
 
80
68
  return () => {
81
- scene.dispose();
82
- engine.dispose();
83
- window.removeEventListener("resize", onWindowResize);
69
+ viewer?.dispose();
84
70
  };
85
71
  });
86
72
 
87
73
  $: mounted && load_model(resolved_url);
88
74
 
89
- function load_model(url: string | undefined): void {
90
- if (scene) {
91
- // Dispose of the previous model before loading a new one
92
- scene.meshes.forEach((mesh) => {
93
- mesh.dispose();
94
- });
95
-
96
- if (point_cloud_system) {
97
- point_cloud_system.dispose();
98
- point_cloud_system = null;
99
- }
75
+ function setRenderingMode(pointsCloud: boolean, wireframe: boolean): void {
76
+ viewerDetails.scene.forcePointsCloud = pointsCloud;
77
+ viewerDetails.scene.forceWireframe = wireframe;
78
+ }
100
79
 
101
- // Load the new model
80
+ function load_model(url: string | undefined): void {
81
+ if (viewer) {
102
82
  if (url) {
103
- BABYLON.SceneLoader.ShowLoadingScreen = false;
104
- BABYLON.SceneLoader.Append(
105
- url,
106
- "",
107
- scene,
108
- () => {
83
+ viewer
84
+ .loadModel(url, {
85
+ pluginOptions: {
86
+ obj: {
87
+ importVertexColors: true
88
+ }
89
+ }
90
+ })
91
+ .then(() => {
109
92
  if (display_mode === "point_cloud") {
110
- create_point_cloud(scene);
93
+ setRenderingMode(true, false);
111
94
  } else if (display_mode === "wireframe") {
112
- create_wireframe(scene);
95
+ setRenderingMode(false, true);
113
96
  } else {
114
- create_camera(scene, camera_position, zoom_speed, pan_speed);
97
+ update_camera(camera_position, zoom_speed, pan_speed);
115
98
  }
116
- },
117
- undefined,
118
- undefined,
119
- "." + value.path.split(".").pop()
120
- );
99
+ });
100
+ } else {
101
+ viewer.resetModel();
121
102
  }
122
103
  }
123
104
  }
124
105
 
125
- function create_camera(
126
- scene: BABYLON.Scene,
106
+ function update_camera(
127
107
  camera_position: [number | null, number | null, number | null],
128
108
  zoom_speed: number,
129
109
  pan_speed: number
130
110
  ): void {
131
- scene.createDefaultCamera(true, true, true);
132
- var helperCamera = scene.activeCamera! as BABYLON.ArcRotateCamera;
111
+ viewer.resetCamera();
112
+ const camera = viewerDetails.camera;
133
113
  if (camera_position[0] !== null) {
134
- helperCamera.alpha = BABYLON.Tools.ToRadians(camera_position[0]);
114
+ camera.alpha = (camera_position[0] * Math.PI) / 180;
135
115
  }
136
116
  if (camera_position[1] !== null) {
137
- helperCamera.beta = BABYLON.Tools.ToRadians(camera_position[1]);
117
+ camera.beta = (camera_position[1] * Math.PI) / 180;
138
118
  }
139
119
  if (camera_position[2] !== null) {
140
- helperCamera.radius = camera_position[2];
120
+ camera.radius = camera_position[2];
141
121
  }
142
- helperCamera.lowerRadiusLimit = 0.1;
122
+ camera.lowerRadiusLimit = 0.1;
143
123
  const updateCameraSensibility = (): void => {
144
- helperCamera.wheelPrecision = 250 / (helperCamera.radius * zoom_speed);
145
- helperCamera.panningSensibility =
146
- (10000 * pan_speed) / helperCamera.radius;
124
+ camera.wheelPrecision = 250 / (camera.radius * zoom_speed);
125
+ camera.panningSensibility = (10000 * pan_speed) / camera.radius;
147
126
  };
148
127
  updateCameraSensibility();
149
- helperCamera.attachControl(true);
150
- helperCamera.onAfterCheckInputsObservable.add(updateCameraSensibility);
128
+ camera.onAfterCheckInputsObservable.add(updateCameraSensibility);
151
129
  }
152
130
 
153
131
  export function reset_camera_position(
@@ -155,73 +133,10 @@
155
133
  zoom_speed: number,
156
134
  pan_speed: number
157
135
  ): void {
158
- if (scene) {
159
- scene.removeCamera(scene.activeCamera!);
160
- create_camera(scene, camera_position, zoom_speed, pan_speed);
136
+ if (viewerDetails) {
137
+ update_camera(camera_position, zoom_speed, pan_speed);
161
138
  }
162
139
  }
163
-
164
- function create_point_cloud(scene: BABYLON.Scene): void {
165
- const meshes = scene.meshes;
166
- const pointPositions: BABYLON.Vector3[] = [];
167
-
168
- meshes.forEach((mesh) => {
169
- if (mesh instanceof BABYLON.Mesh) {
170
- const positions = mesh.getVerticesData(
171
- BABYLON.VertexBuffer.PositionKind
172
- );
173
- if (positions) {
174
- for (let i = 0; i < positions.length; i += 3) {
175
- pointPositions.push(
176
- new BABYLON.Vector3(
177
- positions[i],
178
- positions[i + 1],
179
- positions[i + 2]
180
- )
181
- );
182
- }
183
- }
184
- mesh.setEnabled(false);
185
- }
186
- });
187
-
188
- point_cloud_system = new BABYLON.PointsCloudSystem(
189
- "point_cloud_system",
190
- 1,
191
- scene
192
- );
193
-
194
- point_cloud_system.addPoints(
195
- pointPositions.length,
196
- (particle: BABYLON.CloudPoint, i: number) => {
197
- particle.position = pointPositions[i];
198
- particle.color = new BABYLON.Color4(
199
- Math.random(),
200
- Math.random(),
201
- Math.random(),
202
- 1.0
203
- );
204
- }
205
- );
206
-
207
- point_cloud_system.buildMeshAsync().then((mesh) => {
208
- mesh.alwaysSelectAsActiveMesh = true;
209
- create_camera(scene, camera_position, zoom_speed, pan_speed);
210
- });
211
- }
212
-
213
- function create_wireframe(scene: BABYLON.Scene): void {
214
- scene.meshes.forEach((mesh) => {
215
- if (mesh instanceof BABYLON.Mesh) {
216
- mesh.material = new BABYLON.StandardMaterial(
217
- "wireframeMaterial",
218
- scene
219
- );
220
- mesh.material.wireframe = true;
221
- }
222
- create_camera(scene, camera_position, zoom_speed, pan_speed);
223
- });
224
- }
225
140
  </script>
226
141
 
227
142
  <canvas bind:this={canvas}></canvas>