Skip to content

Commit

Permalink
Add error card when generated model is empty (#96)
Browse files Browse the repository at this point in the history
* Add UI error state if generated model is empty

* Remove console.log for demo
  • Loading branch information
franknoirot authored Jan 11, 2024
1 parent 8c18f04 commit 6623941
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 21 deletions.
43 changes: 28 additions & 15 deletions src/components/ModelViewer.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { T, useThrelte } from '@threlte/core'
import { GLTF, OrbitControls, interactivity, useGltf } from '@threlte/extras'
import { createEventDispatcher } from 'svelte'
import { Box3, Color, Vector3, Scene, Mesh } from 'three'
export let dataUrl: string
Expand All @@ -9,12 +10,14 @@
let readyToRender = false
const { size: threlteSize } = useThrelte()
const dispatch = createEventDispatcher()
interactivity()
let shouldAutoRotate = true
const AUTO_ROTATE_PAUSE = 5000
// This allows autorotate to be paused when the user is interacting with the model
let autorotateTimeout: ReturnType<typeof setTimeout> | undefined
const disableAutoRotate = () => {
if (!pausable) return
Expand All @@ -32,22 +35,32 @@
let maxDistance = 0
$: if (dataUrl && $loadedModel) {
;($loadedModel.scene as Scene).traverse((child) => {
if ('isMesh' in child && child.isMesh) {
const material = (child as Mesh).material
if (material instanceof Array && 'color' in material[0]) {
material[0].color = new Color(0x29ffa4)
} else if ('color' in material) {
material.color = new Color(0x29ffa4)
// If the model is empty, we need to tell the parent component
// to show the empty scene error card
if (Object.values($loadedModel.nodes).length === 0) {
dispatch('emptyscene')
} else {
// Otherwise we'll traverse each mesh and set the color to green
;($loadedModel.scene as Scene).traverse((child) => {
if ('isMesh' in child && child.isMesh) {
const material = (child as Mesh).material
if (material instanceof Array && 'color' in material[0]) {
material[0].color = new Color(0x29ffa4)
} else if ('color' in material) {
material.color = new Color(0x29ffa4)
}
}
}
})
const size = new Vector3()
const boundingBox = new Box3()
boundingBox.setFromObject($loadedModel.scene)
boundingBox.getSize(size)
maxDistance = Math.max(size.x, size.y, size.z)
readyToRender = true
})
// Then we'll calculate the max distance of the bounding box
// and set that as the camera's position
const size = new Vector3()
const boundingBox = new Box3()
boundingBox.setFromObject($loadedModel.scene)
boundingBox.getSize(size)
maxDistance = Math.max(size.x, size.y, size.z)
readyToRender = true
}
}
</script>

Expand Down
28 changes: 22 additions & 6 deletions src/routes/(sidebarLayout)/view/[modelId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
import { browser } from '$app/environment'
import ErrorCard from 'components/ErrorCard.svelte'
import { combinedGenerations, unreadGenerations } from '$lib/stores'
import { invalidateAll } from '$app/navigation'
import { invalidateAll, onNavigate } from '$app/navigation'
import { navigating } from '$app/stores'
export let data: Models['TextToCad_type']
$: status = $combinedGenerations.find((g) => g.id === data.id)?.status ?? data.status
let isSceneEmpty = false
onNavigate(() => {
isSceneEmpty = false
})
$: if (browser && (status === 'completed' || status === 'failed')) {
unreadGenerations.update((g) => g.filter((id) => id !== data.id))
Expand Down Expand Up @@ -66,11 +71,22 @@
{/if}
</div>
{#if data.outputs && data.status === 'completed'}
<div class="relative flex-grow min-h-[500px]">
<Canvas>
<ModelViewer dataUrl={gltfUrl} />
</Canvas>
</div>
{#if !isSceneEmpty}
<div class="relative flex-grow min-h-[500px]">
<Canvas>
<ModelViewer
on:emptyscene={() => {
isSceneEmpty = true
}}
dataUrl={gltfUrl}
/>
</Canvas>
</div>
{:else}
<div class="grid flex-grow place-content-center p-4">
<ErrorCard error={'Model generated an empty scene.'} />
</div>
{/if}
{:else if data.status === 'failed' && data.error}
<div class="grid flex-grow place-content-center p-4">
<ErrorCard error={data.error} />
Expand Down

0 comments on commit 6623941

Please sign in to comment.