mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 03:01:54 +00:00
[3d] apply new vue desige (#3018)
This commit is contained in:
@@ -61,16 +61,22 @@ import Load3DScene from '@/components/load3d/Load3DScene.vue'
|
|||||||
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
||||||
import {
|
import {
|
||||||
CameraType,
|
CameraType,
|
||||||
|
Load3DNodeType,
|
||||||
MaterialMode,
|
MaterialMode,
|
||||||
UpDirection
|
UpDirection
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
|
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||||
|
import type { ComponentWidget } from '@/scripts/domWidget'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { widget } = defineProps<{
|
||||||
node: any
|
widget: ComponentWidget<string[]>
|
||||||
type: 'Load3D' | 'Preview3D'
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const node = ref(props.node)
|
const inputSpec = widget.inputSpec as CustomInputSpec
|
||||||
|
|
||||||
|
const node = widget.node
|
||||||
|
const type = inputSpec.type as Load3DNodeType
|
||||||
|
|
||||||
const backgroundColor = ref('#000000')
|
const backgroundColor = ref('#000000')
|
||||||
const showGrid = ref(true)
|
const showGrid = ref(true)
|
||||||
const showPreview = ref(false)
|
const showPreview = ref(false)
|
||||||
@@ -86,7 +92,7 @@ const materialMode = ref<MaterialMode>('original')
|
|||||||
const edgeThreshold = ref(85)
|
const edgeThreshold = ref(85)
|
||||||
|
|
||||||
const showPreviewButton = computed(() => {
|
const showPreviewButton = computed(() => {
|
||||||
return !props.type.includes('Preview')
|
return !type.includes('Preview')
|
||||||
})
|
})
|
||||||
|
|
||||||
const switchCamera = () => {
|
const switchCamera = () => {
|
||||||
@@ -95,68 +101,68 @@ const switchCamera = () => {
|
|||||||
|
|
||||||
showFOVButton.value = cameraType.value === 'perspective'
|
showFOVButton.value = cameraType.value === 'perspective'
|
||||||
|
|
||||||
node.value.properties['Camera Type'] = cameraType.value
|
node.properties['Camera Type'] = cameraType.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const togglePreview = (value: boolean) => {
|
const togglePreview = (value: boolean) => {
|
||||||
showPreview.value = value
|
showPreview.value = value
|
||||||
|
|
||||||
node.value.properties['Show Preview'] = showPreview.value
|
node.properties['Show Preview'] = showPreview.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleGrid = (value: boolean) => {
|
const toggleGrid = (value: boolean) => {
|
||||||
showGrid.value = value
|
showGrid.value = value
|
||||||
|
|
||||||
node.value.properties['Show Grid'] = showGrid.value
|
node.properties['Show Grid'] = showGrid.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateLightIntensity = (value: number) => {
|
const handleUpdateLightIntensity = (value: number) => {
|
||||||
lightIntensity.value = value
|
lightIntensity.value = value
|
||||||
|
|
||||||
node.value.properties['Light Intensity'] = lightIntensity.value
|
node.properties['Light Intensity'] = lightIntensity.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBackgroundImageUpdate = async (file: File | null) => {
|
const handleBackgroundImageUpdate = async (file: File | null) => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
hasBackgroundImage.value = false
|
hasBackgroundImage.value = false
|
||||||
backgroundImage.value = ''
|
backgroundImage.value = ''
|
||||||
node.value.properties['Background Image'] = ''
|
node.properties['Background Image'] = ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundImage.value = await Load3dUtils.uploadFile(file)
|
backgroundImage.value = await Load3dUtils.uploadFile(file)
|
||||||
|
|
||||||
node.value.properties['Background Image'] = backgroundImage.value
|
node.properties['Background Image'] = backgroundImage.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateFOV = (value: number) => {
|
const handleUpdateFOV = (value: number) => {
|
||||||
fov.value = value
|
fov.value = value
|
||||||
|
|
||||||
node.value.properties['FOV'] = fov.value
|
node.properties['FOV'] = fov.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateEdgeThreshold = (value: number) => {
|
const handleUpdateEdgeThreshold = (value: number) => {
|
||||||
edgeThreshold.value = value
|
edgeThreshold.value = value
|
||||||
|
|
||||||
node.value.properties['Edge Threshold'] = edgeThreshold.value
|
node.properties['Edge Threshold'] = edgeThreshold.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBackgroundColorChange = (value: string) => {
|
const handleBackgroundColorChange = (value: string) => {
|
||||||
backgroundColor.value = value
|
backgroundColor.value = value
|
||||||
|
|
||||||
node.value.properties['Background Color'] = value
|
node.properties['Background Color'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateUpDirection = (value: UpDirection) => {
|
const handleUpdateUpDirection = (value: UpDirection) => {
|
||||||
upDirection.value = value
|
upDirection.value = value
|
||||||
|
|
||||||
node.value.properties['Up Direction'] = value
|
node.properties['Up Direction'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateMaterialMode = (value: MaterialMode) => {
|
const handleUpdateMaterialMode = (value: MaterialMode) => {
|
||||||
materialMode.value = value
|
materialMode.value = value
|
||||||
|
|
||||||
node.value.properties['Material Mode'] = value
|
node.properties['Material Mode'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const listenMaterialModeChange = (mode: MaterialMode) => {
|
const listenMaterialModeChange = (mode: MaterialMode) => {
|
||||||
|
|||||||
@@ -74,16 +74,22 @@ import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
|||||||
import {
|
import {
|
||||||
AnimationItem,
|
AnimationItem,
|
||||||
CameraType,
|
CameraType,
|
||||||
|
Load3DAnimationNodeType,
|
||||||
MaterialMode,
|
MaterialMode,
|
||||||
UpDirection
|
UpDirection
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
|
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||||
|
import type { ComponentWidget } from '@/scripts/domWidget'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { widget } = defineProps<{
|
||||||
node: any
|
widget: ComponentWidget<string[]>
|
||||||
type: 'Load3DAnimation' | 'Preview3DAnimation'
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const node = ref(props.node)
|
const inputSpec = widget.inputSpec as CustomInputSpec
|
||||||
|
|
||||||
|
const node = widget.node
|
||||||
|
const type = inputSpec.type as Load3DAnimationNodeType
|
||||||
|
|
||||||
const backgroundColor = ref('#000000')
|
const backgroundColor = ref('#000000')
|
||||||
const showGrid = ref(true)
|
const showGrid = ref(true)
|
||||||
const showPreview = ref(false)
|
const showPreview = ref(false)
|
||||||
@@ -101,7 +107,7 @@ const selectedAnimation = ref(0)
|
|||||||
const backgroundImage = ref('')
|
const backgroundImage = ref('')
|
||||||
|
|
||||||
const showPreviewButton = computed(() => {
|
const showPreviewButton = computed(() => {
|
||||||
return !props.type.includes('Preview')
|
return !type.includes('Preview')
|
||||||
})
|
})
|
||||||
|
|
||||||
const switchCamera = () => {
|
const switchCamera = () => {
|
||||||
@@ -110,44 +116,44 @@ const switchCamera = () => {
|
|||||||
|
|
||||||
showFOVButton.value = cameraType.value === 'perspective'
|
showFOVButton.value = cameraType.value === 'perspective'
|
||||||
|
|
||||||
node.value.properties['Camera Type'] = cameraType.value
|
node.properties['Camera Type'] = cameraType.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const togglePreview = (value: boolean) => {
|
const togglePreview = (value: boolean) => {
|
||||||
showPreview.value = value
|
showPreview.value = value
|
||||||
|
|
||||||
node.value.properties['Show Preview'] = showPreview.value
|
node.properties['Show Preview'] = showPreview.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleGrid = (value: boolean) => {
|
const toggleGrid = (value: boolean) => {
|
||||||
showGrid.value = value
|
showGrid.value = value
|
||||||
|
|
||||||
node.value.properties['Show Grid'] = showGrid.value
|
node.properties['Show Grid'] = showGrid.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateLightIntensity = (value: number) => {
|
const handleUpdateLightIntensity = (value: number) => {
|
||||||
lightIntensity.value = value
|
lightIntensity.value = value
|
||||||
|
|
||||||
node.value.properties['Light Intensity'] = lightIntensity.value
|
node.properties['Light Intensity'] = lightIntensity.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBackgroundImageUpdate = async (file: File | null) => {
|
const handleBackgroundImageUpdate = async (file: File | null) => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
hasBackgroundImage.value = false
|
hasBackgroundImage.value = false
|
||||||
backgroundImage.value = ''
|
backgroundImage.value = ''
|
||||||
node.value.properties['Background Image'] = ''
|
node.properties['Background Image'] = ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundImage.value = await Load3dUtils.uploadFile(file)
|
backgroundImage.value = await Load3dUtils.uploadFile(file)
|
||||||
|
|
||||||
node.value.properties['Background Image'] = backgroundImage.value
|
node.properties['Background Image'] = backgroundImage.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateFOV = (value: number) => {
|
const handleUpdateFOV = (value: number) => {
|
||||||
fov.value = value
|
fov.value = value
|
||||||
|
|
||||||
node.value.properties['FOV'] = fov.value
|
node.properties['FOV'] = fov.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const materialMode = ref<MaterialMode>('original')
|
const materialMode = ref<MaterialMode>('original')
|
||||||
@@ -156,19 +162,19 @@ const upDirection = ref<UpDirection>('original')
|
|||||||
const handleUpdateUpDirection = (value: UpDirection) => {
|
const handleUpdateUpDirection = (value: UpDirection) => {
|
||||||
upDirection.value = value
|
upDirection.value = value
|
||||||
|
|
||||||
node.value.properties['Up Direction'] = value
|
node.properties['Up Direction'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpdateMaterialMode = (value: MaterialMode) => {
|
const handleUpdateMaterialMode = (value: MaterialMode) => {
|
||||||
materialMode.value = value
|
materialMode.value = value
|
||||||
|
|
||||||
node.value.properties['Material Mode'] = value
|
node.properties['Material Mode'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBackgroundColorChange = (value: string) => {
|
const handleBackgroundColorChange = (value: string) => {
|
||||||
backgroundColor.value = value
|
backgroundColor.value = value
|
||||||
|
|
||||||
node.value.properties['Background Color'] = value
|
node.properties['Background Color'] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const togglePlay = (value: boolean) => {
|
const togglePlay = (value: boolean) => {
|
||||||
|
|||||||
@@ -28,13 +28,14 @@ import { ref, watch } from 'vue'
|
|||||||
import Load3DScene from '@/components/load3d/Load3DScene.vue'
|
import Load3DScene from '@/components/load3d/Load3DScene.vue'
|
||||||
import {
|
import {
|
||||||
CameraType,
|
CameraType,
|
||||||
|
Load3DAnimationNodeType,
|
||||||
MaterialMode,
|
MaterialMode,
|
||||||
UpDirection
|
UpDirection
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
node: any
|
node: any
|
||||||
type: 'Load3DAnimation' | 'Preview3DAnimation'
|
type: Load3DAnimationNodeType
|
||||||
backgroundColor: string
|
backgroundColor: string
|
||||||
showGrid: boolean
|
showGrid: boolean
|
||||||
lightIntensity: number
|
lightIntensity: number
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="container" class="w-full h-full relative">
|
<div ref="container" class="w-full h-full relative comfy-load-3d">
|
||||||
<LoadingOverlay ref="loadingOverlayRef" />
|
<LoadingOverlay ref="loadingOverlayRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -13,6 +13,8 @@ import Load3d from '@/extensions/core/load3d/Load3d'
|
|||||||
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
||||||
import {
|
import {
|
||||||
CameraType,
|
CameraType,
|
||||||
|
Load3DAnimationNodeType,
|
||||||
|
Load3DNodeType,
|
||||||
MaterialMode,
|
MaterialMode,
|
||||||
UpDirection
|
UpDirection
|
||||||
} from '@/extensions/core/load3d/interfaces'
|
} from '@/extensions/core/load3d/interfaces'
|
||||||
@@ -20,8 +22,8 @@ import { t } from '@/i18n'
|
|||||||
import { useLoad3dService } from '@/services/load3dService'
|
import { useLoad3dService } from '@/services/load3dService'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
node: any
|
node: LGraphNode
|
||||||
type: 'Load3D' | 'Load3DAnimation' | 'Preview3D' | 'Preview3DAnimation'
|
type: Load3DNodeType | Load3DAnimationNodeType
|
||||||
backgroundColor: string
|
backgroundColor: string
|
||||||
showGrid: boolean
|
showGrid: boolean
|
||||||
lightIntensity: number
|
lightIntensity: number
|
||||||
|
|||||||
@@ -1,65 +1,27 @@
|
|||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import { IWidget } from '@comfyorg/litegraph'
|
import { IWidget } from '@comfyorg/litegraph'
|
||||||
import { IStringWidget } from '@comfyorg/litegraph/dist/types/widgets'
|
import { IStringWidget } from '@comfyorg/litegraph/dist/types/widgets'
|
||||||
import PrimeVue from 'primevue/config'
|
import { nextTick } from 'vue'
|
||||||
import { createApp, h, nextTick, render } from 'vue'
|
|
||||||
|
|
||||||
import Load3D from '@/components/load3d/Load3D.vue'
|
import Load3D from '@/components/load3d/Load3D.vue'
|
||||||
import Load3DAnimation from '@/components/load3d/Load3DAnimation.vue'
|
import Load3DAnimation from '@/components/load3d/Load3DAnimation.vue'
|
||||||
import Load3DConfiguration from '@/extensions/core/load3d/Load3DConfiguration'
|
import Load3DConfiguration from '@/extensions/core/load3d/Load3DConfiguration'
|
||||||
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
||||||
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
||||||
|
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
|
import { ComponentWidgetImpl, addWidget } from '@/scripts/domWidget'
|
||||||
import { useLoad3dService } from '@/services/load3dService'
|
import { useLoad3dService } from '@/services/load3dService'
|
||||||
import { useToastStore } from '@/stores/toastStore'
|
import { useToastStore } from '@/stores/toastStore'
|
||||||
|
import { generateUUID } from '@/utils/formatUtil'
|
||||||
|
|
||||||
app.registerExtension({
|
app.registerExtension({
|
||||||
name: 'Comfy.Load3D',
|
name: 'Comfy.Load3D',
|
||||||
|
|
||||||
getCustomWidgets(app) {
|
getCustomWidgets() {
|
||||||
return {
|
return {
|
||||||
LOAD_3D(node, inputName) {
|
LOAD_3D(node) {
|
||||||
node.addProperty('Camera Info', '')
|
|
||||||
|
|
||||||
const container = document.createElement('div')
|
|
||||||
container.classList.add('comfy-load-3d')
|
|
||||||
|
|
||||||
/* Hold off for now
|
|
||||||
const mountComponent = () => {
|
|
||||||
const vnode = h(Load3D, {
|
|
||||||
node: node,
|
|
||||||
type: 'Load3D'
|
|
||||||
})
|
|
||||||
|
|
||||||
render(vnode, container)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
let controlsApp = createApp(Load3D, {
|
|
||||||
node: node,
|
|
||||||
type: 'Load3D'
|
|
||||||
})
|
|
||||||
|
|
||||||
controlsApp.mount(container)
|
|
||||||
|
|
||||||
const origOnRemoved = node.onRemoved
|
|
||||||
|
|
||||||
node.onRemoved = function () {
|
|
||||||
/*
|
|
||||||
render(null, container)
|
|
||||||
|
|
||||||
container.remove()
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (controlsApp) {
|
|
||||||
controlsApp.unmount()
|
|
||||||
controlsApp = null
|
|
||||||
}
|
|
||||||
|
|
||||||
origOnRemoved?.apply(this, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileInput = document.createElement('input')
|
const fileInput = document.createElement('input')
|
||||||
fileInput.type = 'file'
|
fileInput.type = 'file'
|
||||||
fileInput.accept = '.gltf,.glb,.obj,.mtl,.fbx,.stl'
|
fileInput.accept = '.gltf,.glb,.obj,.mtl,.fbx,.stl'
|
||||||
@@ -112,11 +74,23 @@ app.registerExtension({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
//mountComponent()
|
const inputSpec: CustomInputSpec = {
|
||||||
|
name: 'image',
|
||||||
return {
|
type: 'Load3D'
|
||||||
widget: node.addDOMWidget(inputName, 'LOAD_3D', container)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const widget = new ComponentWidgetImpl({
|
||||||
|
id: generateUUID(),
|
||||||
|
node,
|
||||||
|
name: inputSpec.name,
|
||||||
|
component: Load3D,
|
||||||
|
inputSpec,
|
||||||
|
options: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
addWidget(node, widget)
|
||||||
|
|
||||||
|
return { widget }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -130,8 +104,6 @@ app.registerExtension({
|
|||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
const sceneWidget = node.widgets.find((w: IWidget) => w.name === 'image')
|
|
||||||
|
|
||||||
const load3d = useLoad3dService().getLoad3d(node)
|
const load3d = useLoad3dService().getLoad3d(node)
|
||||||
|
|
||||||
const modelWidget = node.widgets.find(
|
const modelWidget = node.widgets.find(
|
||||||
@@ -147,6 +119,8 @@ app.registerExtension({
|
|||||||
|
|
||||||
config.configure('input', modelWidget, cameraState, width, height)
|
config.configure('input', modelWidget, cameraState, width, height)
|
||||||
|
|
||||||
|
const sceneWidget = node.widgets.find((w: IWidget) => w.name === 'image')
|
||||||
|
|
||||||
sceneWidget.serializeValue = async () => {
|
sceneWidget.serializeValue = async () => {
|
||||||
node.properties['Camera Info'] = load3d.getCameraState()
|
node.properties['Camera Info'] = load3d.getCameraState()
|
||||||
|
|
||||||
@@ -173,52 +147,9 @@ app.registerExtension({
|
|||||||
app.registerExtension({
|
app.registerExtension({
|
||||||
name: 'Comfy.Load3DAnimation',
|
name: 'Comfy.Load3DAnimation',
|
||||||
|
|
||||||
getCustomWidgets(app) {
|
getCustomWidgets() {
|
||||||
return {
|
return {
|
||||||
LOAD_3D_ANIMATION(node, inputName) {
|
LOAD_3D_ANIMATION(node) {
|
||||||
node.addProperty('Camera Info', '')
|
|
||||||
|
|
||||||
const container = document.createElement('div')
|
|
||||||
|
|
||||||
container.classList.add('comfy-load-3d-animation')
|
|
||||||
|
|
||||||
/*
|
|
||||||
const mountComponent = () => {
|
|
||||||
const vnode = h(Load3DAnimation, {
|
|
||||||
node: node,
|
|
||||||
type: 'Load3DAnimation'
|
|
||||||
})
|
|
||||||
|
|
||||||
render(vnode, container)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
let controlsApp = createApp(Load3DAnimation, {
|
|
||||||
node: node,
|
|
||||||
type: 'Load3DAnimation'
|
|
||||||
})
|
|
||||||
|
|
||||||
controlsApp.use(PrimeVue)
|
|
||||||
|
|
||||||
controlsApp.mount(container)
|
|
||||||
|
|
||||||
const origOnRemoved = node.onRemoved
|
|
||||||
|
|
||||||
node.onRemoved = function () {
|
|
||||||
/*
|
|
||||||
render(null, container)
|
|
||||||
|
|
||||||
container.remove()
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (controlsApp) {
|
|
||||||
controlsApp.unmount()
|
|
||||||
controlsApp = null
|
|
||||||
}
|
|
||||||
|
|
||||||
origOnRemoved?.apply(this, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileInput = document.createElement('input')
|
const fileInput = document.createElement('input')
|
||||||
fileInput.type = 'file'
|
fileInput.type = 'file'
|
||||||
fileInput.accept = '.fbx,glb,gltf'
|
fileInput.accept = '.fbx,glb,gltf'
|
||||||
@@ -269,11 +200,23 @@ app.registerExtension({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
//mountComponent()
|
const inputSpec: CustomInputSpec = {
|
||||||
|
name: 'image',
|
||||||
return {
|
type: 'Load3DAnimation'
|
||||||
widget: node.addDOMWidget(inputName, 'LOAD_3D_ANIMATION', container)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const widget = new ComponentWidgetImpl({
|
||||||
|
id: generateUUID(),
|
||||||
|
node,
|
||||||
|
name: inputSpec.name,
|
||||||
|
component: Load3DAnimation,
|
||||||
|
inputSpec,
|
||||||
|
options: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
addWidget(node, widget)
|
||||||
|
|
||||||
|
return { widget }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -333,62 +276,32 @@ app.registerExtension({
|
|||||||
name: 'Comfy.Preview3D',
|
name: 'Comfy.Preview3D',
|
||||||
|
|
||||||
async beforeRegisterNodeDef(nodeType, nodeData) {
|
async beforeRegisterNodeDef(nodeType, nodeData) {
|
||||||
if (
|
if ('Preview3D' === nodeData.name) {
|
||||||
// @ts-expect-error ComfyNode
|
|
||||||
['Preview3D'].includes(nodeType.comfyClass)
|
|
||||||
) {
|
|
||||||
// @ts-expect-error InputSpec is not typed correctly
|
// @ts-expect-error InputSpec is not typed correctly
|
||||||
nodeData.input.required.image = ['PREVIEW_3D']
|
nodeData.input.required.image = ['PREVIEW_3D']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCustomWidgets(app) {
|
getCustomWidgets() {
|
||||||
return {
|
return {
|
||||||
PREVIEW_3D(node, inputName) {
|
PREVIEW_3D(node) {
|
||||||
const container = document.createElement('div')
|
const inputSpec: CustomInputSpec = {
|
||||||
|
name: 'image',
|
||||||
container.classList.add('comfy-preview-3d')
|
|
||||||
|
|
||||||
/*
|
|
||||||
const mountComponent = () => {
|
|
||||||
const vnode = h(Load3D, {
|
|
||||||
node: node,
|
|
||||||
type: 'Preview3D'
|
|
||||||
})
|
|
||||||
|
|
||||||
render(vnode, container)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
let controlsApp = createApp(Load3D, {
|
|
||||||
node: node,
|
|
||||||
type: 'Preview3D'
|
type: 'Preview3D'
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = new ComponentWidgetImpl({
|
||||||
|
id: generateUUID(),
|
||||||
|
node,
|
||||||
|
name: inputSpec.name,
|
||||||
|
component: Load3D,
|
||||||
|
inputSpec,
|
||||||
|
options: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
controlsApp.mount(container)
|
addWidget(node, widget)
|
||||||
|
|
||||||
const origOnRemoved = node.onRemoved
|
return { widget }
|
||||||
|
|
||||||
node.onRemoved = function () {
|
|
||||||
/*
|
|
||||||
render(null, container)
|
|
||||||
|
|
||||||
container.remove()
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (controlsApp) {
|
|
||||||
controlsApp.unmount()
|
|
||||||
controlsApp = null
|
|
||||||
}
|
|
||||||
|
|
||||||
origOnRemoved?.apply(this, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
//mountComponent()
|
|
||||||
|
|
||||||
return {
|
|
||||||
widget: node.addDOMWidget(inputName, 'PREVIEW_3D', container)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -436,55 +349,32 @@ app.registerExtension({
|
|||||||
name: 'Comfy.Preview3DAnimation',
|
name: 'Comfy.Preview3DAnimation',
|
||||||
|
|
||||||
async beforeRegisterNodeDef(nodeType, nodeData) {
|
async beforeRegisterNodeDef(nodeType, nodeData) {
|
||||||
if (
|
if ('Preview3DAnimation' === nodeData.name) {
|
||||||
// @ts-expect-error ComfyNode
|
|
||||||
['Preview3DAnimation'].includes(nodeType.comfyClass)
|
|
||||||
) {
|
|
||||||
// @ts-expect-error InputSpec is not typed correctly
|
// @ts-expect-error InputSpec is not typed correctly
|
||||||
nodeData.input.required.image = ['PREVIEW_3D_ANIMATION']
|
nodeData.input.required.image = ['PREVIEW_3D_ANIMATION']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCustomWidgets(app) {
|
getCustomWidgets() {
|
||||||
return {
|
return {
|
||||||
PREVIEW_3D_ANIMATION(node, inputName) {
|
PREVIEW_3D_ANIMATION(node) {
|
||||||
const container = document.createElement('div')
|
const inputSpec: CustomInputSpec = {
|
||||||
|
name: 'image',
|
||||||
container.classList.add('comfy-preview-3d-animation')
|
|
||||||
|
|
||||||
let controlsApp = createApp(Load3DAnimation, {
|
|
||||||
node: node,
|
|
||||||
type: 'Preview3DAnimation'
|
type: 'Preview3DAnimation'
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = new ComponentWidgetImpl({
|
||||||
|
id: generateUUID(),
|
||||||
|
node,
|
||||||
|
name: inputSpec.name,
|
||||||
|
component: Load3DAnimation,
|
||||||
|
inputSpec,
|
||||||
|
options: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
controlsApp.use(PrimeVue)
|
addWidget(node, widget)
|
||||||
|
|
||||||
controlsApp.mount(container)
|
return { widget }
|
||||||
|
|
||||||
const origOnRemoved = node.onRemoved
|
|
||||||
|
|
||||||
node.onRemoved = function () {
|
|
||||||
/*
|
|
||||||
render(null, container)
|
|
||||||
|
|
||||||
container.remove()
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (controlsApp) {
|
|
||||||
controlsApp.unmount()
|
|
||||||
controlsApp = null
|
|
||||||
}
|
|
||||||
|
|
||||||
origOnRemoved?.apply(this, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
widget: node.addDOMWidget(
|
|
||||||
inputName,
|
|
||||||
'PREVIEW_3D_ANIMATION',
|
|
||||||
container
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'
|
|||||||
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
|
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
|
||||||
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
|
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
|
||||||
|
|
||||||
|
export type Load3DNodeType = 'Load3D' | 'Preview3D'
|
||||||
|
|
||||||
|
export type Load3DAnimationNodeType = 'Load3DAnimation' | 'Preview3DAnimation'
|
||||||
|
|
||||||
export type MaterialMode =
|
export type MaterialMode =
|
||||||
| 'original'
|
| 'original'
|
||||||
| 'normal'
|
| 'normal'
|
||||||
|
|||||||
Reference in New Issue
Block a user