mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-22 23:39:45 +00:00
Compare commits
3 Commits
pr5-list-v
...
v1.20.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d9d5e5061 | ||
|
|
be1d6d776a | ||
|
|
ada7dde51c |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@comfyorg/comfyui-frontend",
|
"name": "@comfyorg/comfyui-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.20.4",
|
"version": "1.20.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"repository": "https://github.com/Comfy-Org/ComfyUI_frontend",
|
"repository": "https://github.com/Comfy-Org/ComfyUI_frontend",
|
||||||
"homepage": "https://comfy.org",
|
"homepage": "https://comfy.org",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { LGraphNode } from '@comfyorg/litegraph'
|
import { LGraphNode } from '@comfyorg/litegraph'
|
||||||
import { onMounted, onUnmounted, ref, toRaw, watch, watchEffect } from 'vue'
|
import { onMounted, onUnmounted, ref, toRaw, watch } from 'vue'
|
||||||
|
|
||||||
import LoadingOverlay from '@/components/load3d/LoadingOverlay.vue'
|
import LoadingOverlay from '@/components/load3d/LoadingOverlay.vue'
|
||||||
import Load3d from '@/extensions/core/load3d/Load3d'
|
import Load3d from '@/extensions/core/load3d/Load3d'
|
||||||
@@ -76,18 +76,71 @@ const eventConfig = {
|
|||||||
emit('recordingStatusChange', value)
|
emit('recordingStatusChange', value)
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
watchEffect(() => {
|
watch(
|
||||||
if (load3d.value) {
|
() => props.showPreview,
|
||||||
const rawLoad3d = toRaw(load3d.value) as Load3d
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
rawLoad3d.setBackgroundColor(props.backgroundColor)
|
rawLoad3d.togglePreview(newValue)
|
||||||
rawLoad3d.toggleGrid(props.showGrid)
|
}
|
||||||
rawLoad3d.setLightIntensity(props.lightIntensity)
|
|
||||||
rawLoad3d.setFOV(props.fov)
|
|
||||||
rawLoad3d.toggleCamera(props.cameraType)
|
|
||||||
rawLoad3d.togglePreview(props.showPreview)
|
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.cameraType,
|
||||||
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
|
rawLoad3d.toggleCamera(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.fov,
|
||||||
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
|
rawLoad3d.setFOV(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.lightIntensity,
|
||||||
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
|
rawLoad3d.setLightIntensity(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.showGrid,
|
||||||
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
|
rawLoad3d.toggleGrid(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.backgroundColor,
|
||||||
|
(newValue) => {
|
||||||
|
if (load3d.value) {
|
||||||
|
const rawLoad3d = toRaw(load3d.value) as Load3d
|
||||||
|
|
||||||
|
rawLoad3d.setBackgroundColor(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.backgroundImage,
|
() => props.backgroundImage,
|
||||||
@@ -164,12 +217,13 @@ const handleEvents = (action: 'add' | 'remove') => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
load3d.value = useLoad3dService().registerLoad3d(
|
if (container.value) {
|
||||||
node.value as LGraphNode,
|
load3d.value = useLoad3dService().registerLoad3d(
|
||||||
// @ts-expect-error fixme ts strict error
|
node.value as LGraphNode,
|
||||||
container.value,
|
container.value,
|
||||||
props.inputSpec
|
props.inputSpec
|
||||||
)
|
)
|
||||||
|
}
|
||||||
handleEvents('add')
|
handleEvents('add')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ useExtensionService().registerExtension({
|
|||||||
LOAD_3D(node) {
|
LOAD_3D(node) {
|
||||||
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,.fbx,.stl'
|
||||||
fileInput.style.display = 'none'
|
fileInput.style.display = 'none'
|
||||||
|
|
||||||
fileInput.onchange = async () => {
|
fileInput.onchange = async () => {
|
||||||
@@ -195,9 +195,7 @@ useExtensionService().registerExtension({
|
|||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
const load3d = useLoad3dService().getLoad3d(node)
|
useLoad3dService().waitForLoad3d(node, (load3d) => {
|
||||||
|
|
||||||
if (load3d) {
|
|
||||||
let cameraState = node.properties['Camera Info']
|
let cameraState = node.properties['Camera Info']
|
||||||
|
|
||||||
const config = new Load3DConfiguration(load3d)
|
const config = new Load3DConfiguration(load3d)
|
||||||
@@ -256,7 +254,7 @@ useExtensionService().registerExtension({
|
|||||||
return returnVal
|
return returnVal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -346,67 +344,65 @@ useExtensionService().registerExtension({
|
|||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
const sceneWidget = node.widgets?.find((w) => w.name === 'image')
|
useLoad3dService().waitForLoad3d(node, (load3d) => {
|
||||||
|
const sceneWidget = node.widgets?.find((w) => w.name === 'image')
|
||||||
|
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
||||||
|
let cameraState = node.properties['Camera Info']
|
||||||
|
const width = node.widgets?.find((w) => w.name === 'width')
|
||||||
|
const height = node.widgets?.find((w) => w.name === 'height')
|
||||||
|
|
||||||
const load3d = useLoad3dService().getLoad3d(node) as Load3dAnimation
|
if (modelWidget && width && height && sceneWidget && load3d) {
|
||||||
|
const config = new Load3DConfiguration(load3d)
|
||||||
|
|
||||||
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
config.configure('input', modelWidget, cameraState, width, height)
|
||||||
|
|
||||||
let cameraState = node.properties['Camera Info']
|
sceneWidget.serializeValue = async () => {
|
||||||
|
node.properties['Camera Info'] = load3d.getCameraState()
|
||||||
|
|
||||||
const width = node.widgets?.find((w) => w.name === 'width')
|
const load3dAnimation = load3d as Load3dAnimation
|
||||||
const height = node.widgets?.find((w) => w.name === 'height')
|
load3dAnimation.toggleAnimation(false)
|
||||||
|
|
||||||
if (modelWidget && width && height && sceneWidget && load3d) {
|
if (load3dAnimation.isRecording()) {
|
||||||
const config = new Load3DConfiguration(load3d)
|
load3dAnimation.stopRecording()
|
||||||
|
}
|
||||||
|
|
||||||
config.configure('input', modelWidget, cameraState, width, height)
|
const {
|
||||||
|
scene: imageData,
|
||||||
|
mask: maskData,
|
||||||
|
normal: normalData
|
||||||
|
} = await load3dAnimation.captureScene(
|
||||||
|
width.value as number,
|
||||||
|
height.value as number
|
||||||
|
)
|
||||||
|
|
||||||
sceneWidget.serializeValue = async () => {
|
const [data, dataMask, dataNormal] = await Promise.all([
|
||||||
node.properties['Camera Info'] = load3d.getCameraState()
|
Load3dUtils.uploadTempImage(imageData, 'scene'),
|
||||||
|
Load3dUtils.uploadTempImage(maskData, 'scene_mask'),
|
||||||
load3d.toggleAnimation(false)
|
Load3dUtils.uploadTempImage(normalData, 'scene_normal')
|
||||||
|
|
||||||
if (load3d.isRecording()) {
|
|
||||||
load3d.stopRecording()
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
scene: imageData,
|
|
||||||
mask: maskData,
|
|
||||||
normal: normalData
|
|
||||||
} = await load3d.captureScene(
|
|
||||||
width.value as number,
|
|
||||||
height.value as number
|
|
||||||
)
|
|
||||||
|
|
||||||
const [data, dataMask, dataNormal] = await Promise.all([
|
|
||||||
Load3dUtils.uploadTempImage(imageData, 'scene'),
|
|
||||||
Load3dUtils.uploadTempImage(maskData, 'scene_mask'),
|
|
||||||
Load3dUtils.uploadTempImage(normalData, 'scene_normal')
|
|
||||||
])
|
|
||||||
|
|
||||||
load3d.handleResize()
|
|
||||||
|
|
||||||
const returnVal = {
|
|
||||||
image: `threed/${data.name} [temp]`,
|
|
||||||
mask: `threed/${dataMask.name} [temp]`,
|
|
||||||
normal: `threed/${dataNormal.name} [temp]`,
|
|
||||||
camera_info: node.properties['Camera Info'],
|
|
||||||
recording: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const recordingData = load3d.getRecordingData()
|
|
||||||
if (recordingData) {
|
|
||||||
const [recording] = await Promise.all([
|
|
||||||
Load3dUtils.uploadTempImage(recordingData, 'recording', 'mp4')
|
|
||||||
])
|
])
|
||||||
returnVal['recording'] = `threed/${recording.name} [temp]`
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnVal
|
load3dAnimation.handleResize()
|
||||||
|
|
||||||
|
const returnVal = {
|
||||||
|
image: `threed/${data.name} [temp]`,
|
||||||
|
mask: `threed/${dataMask.name} [temp]`,
|
||||||
|
normal: `threed/${dataNormal.name} [temp]`,
|
||||||
|
camera_info: node.properties['Camera Info'],
|
||||||
|
recording: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const recordingData = load3dAnimation.getRecordingData()
|
||||||
|
if (recordingData) {
|
||||||
|
const [recording] = await Promise.all([
|
||||||
|
Load3dUtils.uploadTempImage(recordingData, 'recording', 'mp4')
|
||||||
|
])
|
||||||
|
returnVal['recording'] = `threed/${recording.name} [temp]`
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnVal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -467,19 +463,19 @@ useExtensionService().registerExtension({
|
|||||||
useToastStore().addAlert(msg)
|
useToastStore().addAlert(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
const load3d = useLoad3dService().getLoad3d(node)
|
|
||||||
|
|
||||||
let cameraState = message.result[1]
|
let cameraState = message.result[1]
|
||||||
|
|
||||||
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
useLoad3dService().waitForLoad3d(node, (load3d) => {
|
||||||
|
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
||||||
|
|
||||||
if (load3d && modelWidget) {
|
if (modelWidget) {
|
||||||
modelWidget.value = filePath.replaceAll('\\', '/')
|
modelWidget.value = filePath.replaceAll('\\', '/')
|
||||||
|
|
||||||
const config = new Load3DConfiguration(load3d)
|
const config = new Load3DConfiguration(load3d)
|
||||||
|
|
||||||
config.configure('output', modelWidget, cameraState)
|
config.configure('output', modelWidget, cameraState)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -543,16 +539,16 @@ useExtensionService().registerExtension({
|
|||||||
|
|
||||||
let cameraState = message.result[1]
|
let cameraState = message.result[1]
|
||||||
|
|
||||||
const load3d = useLoad3dService().getLoad3d(node)
|
useLoad3dService().waitForLoad3d(node, (load3d) => {
|
||||||
|
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
||||||
|
if (modelWidget) {
|
||||||
|
modelWidget.value = filePath.replaceAll('\\', '/')
|
||||||
|
|
||||||
const modelWidget = node.widgets?.find((w) => w.name === 'model_file')
|
const config = new Load3DConfiguration(load3d)
|
||||||
if (load3d && modelWidget) {
|
|
||||||
modelWidget.value = filePath.replaceAll('\\', '/')
|
|
||||||
|
|
||||||
const config = new Load3DConfiguration(load3d)
|
config.configure('output', modelWidget, cameraState)
|
||||||
|
}
|
||||||
config.configure('output', modelWidget, cameraState)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -486,6 +486,14 @@ class Load3d {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public remove(): void {
|
public remove(): void {
|
||||||
|
this.renderer.forceContextLoss()
|
||||||
|
const canvas = this.renderer.domElement
|
||||||
|
const event = new Event('webglcontextlost', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true
|
||||||
|
})
|
||||||
|
canvas.dispatchEvent(event)
|
||||||
|
|
||||||
if (this.animationFrameId !== null) {
|
if (this.animationFrameId !== null) {
|
||||||
cancelAnimationFrame(this.animationFrameId)
|
cancelAnimationFrame(this.animationFrameId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,14 @@ export class PreviewManager implements PreviewManagerInterface {
|
|||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
if (this.previewRenderer) {
|
if (this.previewRenderer) {
|
||||||
|
this.previewRenderer.forceContextLoss()
|
||||||
|
const canvas = this.previewRenderer.domElement
|
||||||
|
const event = new Event('webglcontextlost', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true
|
||||||
|
})
|
||||||
|
canvas.dispatchEvent(event)
|
||||||
|
|
||||||
this.previewRenderer.dispose()
|
this.previewRenderer.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3403,7 +3403,7 @@
|
|||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
"height": {
|
"height": {
|
||||||
"name": "altura"
|
"name": "alto"
|
||||||
},
|
},
|
||||||
"image": {
|
"image": {
|
||||||
"name": "imagen"
|
"name": "imagen"
|
||||||
@@ -3417,20 +3417,26 @@
|
|||||||
"name": "ancho"
|
"name": "ancho"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "imagen"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "mask"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "ruta_malla"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "normal"
|
"name": "normal"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "lineart"
|
"name": "lineart"
|
||||||
},
|
},
|
||||||
{
|
"5": {
|
||||||
"name": "camera_info"
|
"name": "info_cámara"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "Cargar 3D - Animación",
|
"display_name": "Cargar 3D - Animación",
|
||||||
@@ -3438,7 +3444,7 @@
|
|||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
"height": {
|
"height": {
|
||||||
"name": "altura"
|
"name": "alto"
|
||||||
},
|
},
|
||||||
"image": {
|
"image": {
|
||||||
"name": "imagen"
|
"name": "imagen"
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "ancho"
|
"name": "ancho"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "imagen"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "mask"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "ruta_malla"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "normal"
|
"name": "normal"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "camera_info"
|
"name": "info_cámara"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "CargarAudio",
|
"display_name": "CargarAudio",
|
||||||
|
|||||||
@@ -3417,20 +3417,26 @@
|
|||||||
"name": "largeur"
|
"name": "largeur"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "image"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "masque"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "chemin_maillage"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "normale"
|
"name": "normale"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "ligne artistique"
|
"name": "lineart"
|
||||||
},
|
},
|
||||||
{
|
"5": {
|
||||||
"name": "informations caméra"
|
"name": "info_caméra"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "Charger 3D - Animation",
|
"display_name": "Charger 3D - Animation",
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "largeur"
|
"name": "largeur"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "image"
|
||||||
null,
|
|
||||||
{
|
|
||||||
"name": "normal"
|
|
||||||
},
|
},
|
||||||
{
|
"1": {
|
||||||
"name": "camera_info"
|
"name": "masque"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "chemin_maillage"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "normale"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"name": "info_caméra"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "ChargerAudio",
|
"display_name": "ChargerAudio",
|
||||||
|
|||||||
@@ -3417,23 +3417,29 @@
|
|||||||
"name": "幅"
|
"name": "幅"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "画像"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "マスク"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "メッシュパス"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "法線"
|
"name": "法線"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "線画"
|
"name": "線画"
|
||||||
},
|
},
|
||||||
{
|
"5": {
|
||||||
"name": "カメラ情報"
|
"name": "カメラ情報"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "3Dを読み込む - アニメーション",
|
"display_name": "3D読み込み - アニメーション",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "幅"
|
"name": "幅"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "画像"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "マスク"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "メッシュパス"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "法線"
|
"name": "法線"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "カメラ情報"
|
"name": "カメラ情報"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "音声を読み込む",
|
"display_name": "音声を読み込む",
|
||||||
|
|||||||
@@ -3398,7 +3398,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Load3D": {
|
"Load3D": {
|
||||||
"display_name": "3D 로드",
|
"display_name": "3D 불러오기",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
@@ -3417,23 +3417,29 @@
|
|||||||
"name": "너비"
|
"name": "너비"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "이미지"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "마스크"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "메시 경로"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "노멀"
|
"name": "노멀"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "라인아트"
|
"name": "라인아트"
|
||||||
},
|
},
|
||||||
{
|
"5": {
|
||||||
"name": "카메라 정보"
|
"name": "카메라 정보"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "3D 로드 - 애니메이션",
|
"display_name": "3D 불러오기 - 애니메이션",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "너비"
|
"name": "너비"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "이미지"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "마스크"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "메시 경로"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "노멀"
|
"name": "노멀"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "카메라 정보"
|
"name": "카메라 정보"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "오디오 로드",
|
"display_name": "오디오 로드",
|
||||||
|
|||||||
@@ -3409,7 +3409,7 @@
|
|||||||
"name": "изображение"
|
"name": "изображение"
|
||||||
},
|
},
|
||||||
"model_file": {
|
"model_file": {
|
||||||
"name": "файл_модели"
|
"name": "файл модели"
|
||||||
},
|
},
|
||||||
"upload 3d model": {
|
"upload 3d model": {
|
||||||
},
|
},
|
||||||
@@ -3417,23 +3417,29 @@
|
|||||||
"name": "ширина"
|
"name": "ширина"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "изображение"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "mask"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "путь к mesh"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "нормаль"
|
"name": "нормаль"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "линеарт"
|
"name": "линейный рисунок"
|
||||||
},
|
},
|
||||||
{
|
"5": {
|
||||||
"name": "информация_камеры"
|
"name": "информация о камере"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "Загрузить 3D — Анимация",
|
"display_name": "Загрузить 3D - Анимация",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"clear": {
|
"clear": {
|
||||||
},
|
},
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "ширина"
|
"name": "ширина"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "изображение"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "mask"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "путь_к_модели"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "нормаль"
|
"name": "нормаль"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "информация_камеры"
|
"name": "информация_о_камере"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "Загрузить аудио",
|
"display_name": "Загрузить аудио",
|
||||||
|
|||||||
@@ -3417,20 +3417,26 @@
|
|||||||
"name": "宽度"
|
"name": "宽度"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "image"
|
||||||
null,
|
|
||||||
{
|
|
||||||
"name": "法线"
|
|
||||||
},
|
},
|
||||||
{
|
"1": {
|
||||||
"name": "线稿"
|
"name": "mask"
|
||||||
},
|
},
|
||||||
{
|
"2": {
|
||||||
"name": "相机信息"
|
"name": "mesh_path"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "normal"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"name": "lineart"
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"name": "camera_info"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"Load3DAnimation": {
|
"Load3DAnimation": {
|
||||||
"display_name": "加载3D动画",
|
"display_name": "加载3D动画",
|
||||||
@@ -3452,17 +3458,23 @@
|
|||||||
"name": "宽度"
|
"name": "宽度"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": {
|
||||||
null,
|
"0": {
|
||||||
null,
|
"name": "图像"
|
||||||
null,
|
},
|
||||||
{
|
"1": {
|
||||||
|
"name": "遮罩"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "mesh_path"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
"name": "法线"
|
"name": "法线"
|
||||||
},
|
},
|
||||||
{
|
"4": {
|
||||||
"name": "相机信息"
|
"name": "相机信息"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
"LoadAudio": {
|
"LoadAudio": {
|
||||||
"display_name": "加载音频",
|
"display_name": "加载音频",
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ import Load3d from '@/extensions/core/load3d/Load3d'
|
|||||||
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
||||||
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||||
|
|
||||||
|
type Load3dReadyCallback = (load3d: Load3d | Load3dAnimation) => void
|
||||||
|
|
||||||
export class Load3dService {
|
export class Load3dService {
|
||||||
private static instance: Load3dService
|
private static instance: Load3dService
|
||||||
private nodeToLoad3dMap = new Map<LGraphNode, Load3d | Load3dAnimation>()
|
private nodeToLoad3dMap = new Map<LGraphNode, Load3d | Load3dAnimation>()
|
||||||
|
private pendingCallbacks = new Map<LGraphNode, Load3dReadyCallback[]>()
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
@@ -60,6 +63,13 @@ export class Load3dService {
|
|||||||
|
|
||||||
this.nodeToLoad3dMap.set(rawNode, instance)
|
this.nodeToLoad3dMap.set(rawNode, instance)
|
||||||
|
|
||||||
|
const callbacks = this.pendingCallbacks.get(rawNode)
|
||||||
|
|
||||||
|
if (callbacks) {
|
||||||
|
callbacks.forEach((callback) => callback(instance))
|
||||||
|
this.pendingCallbacks.delete(rawNode)
|
||||||
|
}
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +79,24 @@ export class Load3dService {
|
|||||||
return this.nodeToLoad3dMap.get(rawNode) || null
|
return this.nodeToLoad3dMap.get(rawNode) || null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitForLoad3d(node: LGraphNode, callback: Load3dReadyCallback): void {
|
||||||
|
const rawNode = toRaw(node)
|
||||||
|
|
||||||
|
const existingInstance = this.nodeToLoad3dMap.get(rawNode)
|
||||||
|
|
||||||
|
if (existingInstance) {
|
||||||
|
callback(existingInstance)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.pendingCallbacks.has(rawNode)) {
|
||||||
|
this.pendingCallbacks.set(rawNode, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingCallbacks.get(rawNode)!.push(callback)
|
||||||
|
}
|
||||||
|
|
||||||
getNodeByLoad3d(load3d: Load3d | Load3dAnimation): LGraphNode | null {
|
getNodeByLoad3d(load3d: Load3d | Load3dAnimation): LGraphNode | null {
|
||||||
for (const [node, instance] of this.nodeToLoad3dMap) {
|
for (const [node, instance] of this.nodeToLoad3dMap) {
|
||||||
if (instance === load3d) {
|
if (instance === load3d) {
|
||||||
@@ -88,12 +116,15 @@ export class Load3dService {
|
|||||||
|
|
||||||
this.nodeToLoad3dMap.delete(rawNode)
|
this.nodeToLoad3dMap.delete(rawNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.pendingCallbacks.delete(rawNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
for (const [node] of this.nodeToLoad3dMap) {
|
for (const [node] of this.nodeToLoad3dMap) {
|
||||||
this.removeLoad3d(node)
|
this.removeLoad3d(node)
|
||||||
}
|
}
|
||||||
|
this.pendingCallbacks.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user