Files
ComfyUI_frontend/src/components/load3d/controls/ModelControls.vue
Terry Jia afa10f7a1e [refactor] refactor load3d (#5765)
Summary

Fully Refactored the Load3D module to improve architecture and
maintainability by consolidating functionality into a
centralized composable pattern and simplifying component structure. and
support VueNodes system

  Changes

- Architecture: Introduced new useLoad3d composable to centralize 3D
loading logic and state
  management
- Component Simplification: Removed redundant components
(Load3DAnimation.vue, Load3DAnimationScene.vue,
  PreviewManager.ts) 
- Support VueNodes
- improve config store
- remove lineart output due Animation doesnot support it, may add it
back later
- remove Preview screen and keep scene in fixed ratio in load3d (not
affect preview3d)
- improve record video feature which will already record video by same
ratio as scene
Need BE change https://github.com/comfyanonymous/ComfyUI/pull/10025


https://github.com/user-attachments/assets/9e038729-84a0-45ad-b0f2-11c57d7e0c9a



┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5765-refactor-refactor-load3d-2796d73d365081728297cc486e2e9052)
by [Unito](https://www.unito.io)
2025-10-31 16:19:35 -04:00

145 lines
3.4 KiB
Vue

<template>
<div class="flex flex-col">
<div class="show-up-direction relative">
<Button class="p-button-rounded p-button-text" @click="toggleUpDirection">
<i
v-tooltip.right="{
value: t('load3d.upDirection'),
showDelay: 300
}"
class="pi pi-arrow-up text-lg text-white"
/>
</Button>
<div
v-show="showUpDirection"
class="absolute top-0 left-12 rounded-lg bg-black/50 shadow-lg"
>
<div class="flex flex-col">
<Button
v-for="direction in upDirections"
:key="direction"
class="p-button-text text-white"
:class="{ 'bg-blue-500': upDirection === direction }"
@click="selectUpDirection(direction)"
>
{{ direction.toUpperCase() }}
</Button>
</div>
</div>
</div>
<div class="show-material-mode relative">
<Button
class="p-button-rounded p-button-text"
@click="toggleMaterialMode"
>
<i
v-tooltip.right="{
value: t('load3d.materialMode'),
showDelay: 300
}"
class="pi pi-box text-lg text-white"
/>
</Button>
<div
v-show="showMaterialMode"
class="absolute top-0 left-12 rounded-lg bg-black/50 shadow-lg"
>
<div class="flex flex-col">
<Button
v-for="mode in materialModes"
:key="mode"
class="p-button-text whitespace-nowrap text-white"
:class="{ 'bg-blue-500': materialMode === mode }"
@click="selectMaterialMode(mode)"
>
{{ formatMaterialMode(mode) }}
</Button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import Button from 'primevue/button'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import type {
MaterialMode,
UpDirection
} from '@/extensions/core/load3d/interfaces'
import { t } from '@/i18n'
const materialMode = defineModel<MaterialMode>('materialMode')
const upDirection = defineModel<UpDirection>('upDirection')
const showUpDirection = ref(false)
const showMaterialMode = ref(false)
const upDirections: UpDirection[] = [
'original',
'-x',
'+x',
'-y',
'+y',
'-z',
'+z'
]
const materialModes = computed(() => {
const modes: MaterialMode[] = [
'original',
'normal',
'wireframe'
//'depth' disable for now
]
return modes
})
const toggleUpDirection = () => {
showUpDirection.value = !showUpDirection.value
showMaterialMode.value = false
}
const selectUpDirection = (direction: UpDirection) => {
upDirection.value = direction
showUpDirection.value = false
}
const toggleMaterialMode = () => {
showMaterialMode.value = !showMaterialMode.value
showUpDirection.value = false
}
const selectMaterialMode = (mode: MaterialMode) => {
materialMode.value = mode
showMaterialMode.value = false
}
const formatMaterialMode = (mode: MaterialMode) => {
return t(`load3d.materialModes.${mode}`)
}
const closeSceneSlider = (e: MouseEvent) => {
const target = e.target as HTMLElement
if (!target.closest('.show-up-direction')) {
showUpDirection.value = false
}
if (!target.closest('.show-material-mode')) {
showMaterialMode.value = false
}
}
onMounted(() => {
document.addEventListener('click', closeSceneSlider)
})
onUnmounted(() => {
document.removeEventListener('click', closeSceneSlider)
})
</script>