Spaces:
Running
Running
Commit
•
9c554be
1
Parent(s):
b95cc56
support topology-only outputs
Browse files
src/routes/Vote.svelte
CHANGED
@@ -212,29 +212,31 @@
|
|
212 |
<p>vertex count: {viewerA.vertexCount}</p>
|
213 |
{/if}
|
214 |
</div>
|
215 |
-
|
216 |
-
<
|
217 |
-
<
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
<
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
|
|
|
|
238 |
</div>
|
239 |
<div bind:this={containerB} class="canvas-container">
|
240 |
<div bind:this={overlayB} class="loading-overlay">
|
@@ -249,29 +251,31 @@
|
|
249 |
<p>vertex count: {viewerB.vertexCount}</p>
|
250 |
{/if}
|
251 |
</div>
|
252 |
-
|
253 |
-
<
|
254 |
-
<
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
<
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
|
|
|
|
275 |
</div>
|
276 |
</div>
|
277 |
{#if !voteOverlay}
|
|
|
212 |
<p>vertex count: {viewerA.vertexCount}</p>
|
213 |
{/if}
|
214 |
</div>
|
215 |
+
{#if viewerA && !viewerA.topoOnly}
|
216 |
+
<div class="mode-toggle">
|
217 |
+
<label>
|
218 |
+
<input
|
219 |
+
type="radio"
|
220 |
+
name="modeA"
|
221 |
+
value="default"
|
222 |
+
checked
|
223 |
+
bind:this={normalToggleA}
|
224 |
+
on:change={() => setRenderMode(viewerA, "default")}
|
225 |
+
/>
|
226 |
+
<Cube class="mode-toggle-icon" />
|
227 |
+
</label>
|
228 |
+
<label>
|
229 |
+
<input
|
230 |
+
type="radio"
|
231 |
+
name="modeA"
|
232 |
+
value="wireframe"
|
233 |
+
bind:this={wireframeToggleA}
|
234 |
+
on:change={() => setRenderMode(viewerA, "wireframe")}
|
235 |
+
/>
|
236 |
+
<WatsonHealth3DPrintMesh class="mode-toggle-icon" />
|
237 |
+
</label>
|
238 |
+
</div>
|
239 |
+
{/if}
|
240 |
</div>
|
241 |
<div bind:this={containerB} class="canvas-container">
|
242 |
<div bind:this={overlayB} class="loading-overlay">
|
|
|
251 |
<p>vertex count: {viewerB.vertexCount}</p>
|
252 |
{/if}
|
253 |
</div>
|
254 |
+
{#if viewerB && !viewerB.topoOnly}
|
255 |
+
<div class="mode-toggle">
|
256 |
+
<label>
|
257 |
+
<input
|
258 |
+
type="radio"
|
259 |
+
name="modeB"
|
260 |
+
value="default"
|
261 |
+
checked
|
262 |
+
bind:this={normalToggleB}
|
263 |
+
on:change={() => setRenderMode(viewerB, "default")}
|
264 |
+
/>
|
265 |
+
<Cube class="mode-toggle-icon" />
|
266 |
+
</label>
|
267 |
+
<label>
|
268 |
+
<input
|
269 |
+
type="radio"
|
270 |
+
name="modeB"
|
271 |
+
value="wireframe"
|
272 |
+
bind:this={wireframeToggleB}
|
273 |
+
on:change={() => setRenderMode(viewerB, "wireframe")}
|
274 |
+
/>
|
275 |
+
<WatsonHealth3DPrintMesh class="mode-toggle-icon" />
|
276 |
+
</label>
|
277 |
+
</div>
|
278 |
+
{/if}
|
279 |
</div>
|
280 |
</div>
|
281 |
{#if !voteOverlay}
|
src/routes/viewers/BabylonViewer.ts
CHANGED
@@ -11,6 +11,7 @@ export class BabylonViewer implements IViewer {
|
|
11 |
camera: BABYLON.ArcRotateCamera;
|
12 |
|
13 |
vertexCount: number = 0;
|
|
|
14 |
|
15 |
private _originalMaterials: Map<BABYLON.AbstractMesh, BABYLON.Material> = new Map();
|
16 |
private _originalVertexColors: Map<BABYLON.AbstractMesh, BABYLON.Nullable<BABYLON.FloatArray>> = new Map();
|
@@ -54,7 +55,6 @@ export class BabylonViewer implements IViewer {
|
|
54 |
this._wireframeMaterial = new BABYLON.StandardMaterial("wireframe", this.scene);
|
55 |
this._wireframeMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
|
56 |
this._wireframeMaterial.emissiveColor = new BABYLON.Color3(0.7, 0.7, 0.7);
|
57 |
-
this._wireframeMaterial.zOffset = 1;
|
58 |
this._wireframeMaterial.disableLighting = true;
|
59 |
this._wireframeMaterial.wireframe = true;
|
60 |
|
@@ -71,7 +71,9 @@ export class BabylonViewer implements IViewer {
|
|
71 |
this.engine.resize();
|
72 |
}
|
73 |
|
74 |
-
async loadScene(url: string, loadingBarCallback?: (progress: number) => void) {
|
|
|
|
|
75 |
// Load scene
|
76 |
await BABYLON.SceneLoader.AppendAsync("", url, this.scene, (event) => {
|
77 |
const progress = event.loaded / event.total;
|
@@ -131,6 +133,10 @@ export class BabylonViewer implements IViewer {
|
|
131 |
parentNode.position = center.scale(-1 * scaleFactor);
|
132 |
parentNode.scaling.scaleInPlace(scaleFactor);
|
133 |
|
|
|
|
|
|
|
|
|
134 |
// Run render loop
|
135 |
this.engine.runRenderLoop(() => {
|
136 |
this.scene.render();
|
|
|
11 |
camera: BABYLON.ArcRotateCamera;
|
12 |
|
13 |
vertexCount: number = 0;
|
14 |
+
topoOnly: boolean = false;
|
15 |
|
16 |
private _originalMaterials: Map<BABYLON.AbstractMesh, BABYLON.Material> = new Map();
|
17 |
private _originalVertexColors: Map<BABYLON.AbstractMesh, BABYLON.Nullable<BABYLON.FloatArray>> = new Map();
|
|
|
55 |
this._wireframeMaterial = new BABYLON.StandardMaterial("wireframe", this.scene);
|
56 |
this._wireframeMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
|
57 |
this._wireframeMaterial.emissiveColor = new BABYLON.Color3(0.7, 0.7, 0.7);
|
|
|
58 |
this._wireframeMaterial.disableLighting = true;
|
59 |
this._wireframeMaterial.wireframe = true;
|
60 |
|
|
|
71 |
this.engine.resize();
|
72 |
}
|
73 |
|
74 |
+
async loadScene(url: string, loadingBarCallback?: (progress: number) => void, topoOnly?: boolean) {
|
75 |
+
this.topoOnly = topoOnly ?? false;
|
76 |
+
|
77 |
// Load scene
|
78 |
await BABYLON.SceneLoader.AppendAsync("", url, this.scene, (event) => {
|
79 |
const progress = event.loaded / event.total;
|
|
|
133 |
parentNode.position = center.scale(-1 * scaleFactor);
|
134 |
parentNode.scaling.scaleInPlace(scaleFactor);
|
135 |
|
136 |
+
if (this.topoOnly) {
|
137 |
+
this.setRenderMode("wireframe");
|
138 |
+
}
|
139 |
+
|
140 |
// Run render loop
|
141 |
this.engine.runRenderLoop(() => {
|
142 |
this.scene.render();
|
src/routes/viewers/IViewer.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
export interface IViewer {
|
2 |
vertexCount: number;
|
3 |
-
|
|
|
4 |
dispose(): void;
|
5 |
capture(): Promise<string | null>;
|
6 |
setRenderMode(mode: string): void;
|
|
|
1 |
export interface IViewer {
|
2 |
vertexCount: number;
|
3 |
+
topoOnly: boolean;
|
4 |
+
loadScene(url: string, onProgress?: (progress: number) => void, topoOnly?: boolean): Promise<void>;
|
5 |
dispose(): void;
|
6 |
capture(): Promise<string | null>;
|
7 |
setRenderMode(mode: string): void;
|
src/routes/viewers/SplatViewer.ts
CHANGED
@@ -11,6 +11,7 @@ export class SplatViewer implements IViewer {
|
|
11 |
splat: SPLAT.Splat | null;
|
12 |
|
13 |
disposed: boolean = false;
|
|
|
14 |
|
15 |
vertexCount: number = 0;
|
16 |
|
@@ -29,7 +30,9 @@ export class SplatViewer implements IViewer {
|
|
29 |
this.handleResize = this.handleResize.bind(this);
|
30 |
}
|
31 |
|
32 |
-
async loadScene(url: string, loadingBarCallback?: (progress: number) => void) {
|
|
|
|
|
33 |
if (url.endsWith(".splat")) {
|
34 |
this.splat = await SPLAT.Loader.LoadAsync(url, this.scene, (progress) => {
|
35 |
loadingBarCallback?.(progress);
|
|
|
11 |
splat: SPLAT.Splat | null;
|
12 |
|
13 |
disposed: boolean = false;
|
14 |
+
topoOnly: boolean = false;
|
15 |
|
16 |
vertexCount: number = 0;
|
17 |
|
|
|
30 |
this.handleResize = this.handleResize.bind(this);
|
31 |
}
|
32 |
|
33 |
+
async loadScene(url: string, loadingBarCallback?: (progress: number) => void, topoOnly?: boolean) {
|
34 |
+
this.topoOnly = topoOnly ?? false;
|
35 |
+
|
36 |
if (url.endsWith(".splat")) {
|
37 |
this.splat = await SPLAT.Loader.LoadAsync(url, this.scene, (progress) => {
|
38 |
loadingBarCallback?.(progress);
|
src/routes/viewers/ViewerFactory.ts
CHANGED
@@ -18,6 +18,7 @@ export async function createViewer(
|
|
18 |
} else {
|
19 |
throw new Error("Unsupported file format");
|
20 |
}
|
21 |
-
|
|
|
22 |
return viewer;
|
23 |
}
|
|
|
18 |
} else {
|
19 |
throw new Error("Unsupported file format");
|
20 |
}
|
21 |
+
const topoOnly: boolean = url.endsWith(".obj");
|
22 |
+
await viewer.loadScene(url, onProgress, topoOnly);
|
23 |
return viewer;
|
24 |
}
|