mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 08:30:06 +00:00
[3d] initial version of 3d viewer (#3968)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
import { toRaw } from 'vue'
|
||||
|
||||
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
|
||||
import Load3d from '@/extensions/core/load3d/Load3d'
|
||||
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { NodeId } from '@/schemas/comfyWorkflowSchema'
|
||||
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
|
||||
type Load3dReadyCallback = (load3d: Load3d | Load3dAnimation) => void
|
||||
|
||||
const viewerInstances = new Map<NodeId, any>()
|
||||
|
||||
export class Load3dService {
|
||||
private static instance: Load3dService
|
||||
private nodeToLoad3dMap = new Map<LGraphNode, Load3d | Load3dAnimation>()
|
||||
@@ -126,6 +130,110 @@ export class Load3dService {
|
||||
}
|
||||
this.pendingCallbacks.clear()
|
||||
}
|
||||
|
||||
getOrCreateViewer(node: LGraphNode) {
|
||||
if (!viewerInstances.has(node.id)) {
|
||||
viewerInstances.set(node.id, useLoad3dViewer(node))
|
||||
}
|
||||
|
||||
return viewerInstances.get(node.id)
|
||||
}
|
||||
|
||||
removeViewer(node: LGraphNode) {
|
||||
const viewer = viewerInstances.get(node.id)
|
||||
|
||||
if (viewer) {
|
||||
viewer.cleanup()
|
||||
}
|
||||
|
||||
viewerInstances.delete(node.id)
|
||||
}
|
||||
|
||||
async copyLoad3dState(source: Load3d, target: Load3d | Load3dAnimation) {
|
||||
const sourceModel = source.modelManager.currentModel
|
||||
|
||||
if (sourceModel) {
|
||||
const modelClone = sourceModel.clone()
|
||||
|
||||
target.getModelManager().currentModel = modelClone
|
||||
target.getSceneManager().scene.add(modelClone)
|
||||
|
||||
target.getModelManager().materialMode =
|
||||
source.getModelManager().materialMode
|
||||
|
||||
target.getModelManager().currentUpDirection =
|
||||
source.getModelManager().currentUpDirection
|
||||
|
||||
target.setMaterialMode(source.getModelManager().materialMode)
|
||||
target.setUpDirection(source.getModelManager().currentUpDirection)
|
||||
|
||||
if (source.getModelManager().appliedTexture) {
|
||||
target.getModelManager().appliedTexture =
|
||||
source.getModelManager().appliedTexture
|
||||
}
|
||||
}
|
||||
|
||||
const sourceCameraType = source.getCurrentCameraType()
|
||||
const sourceCameraState = source.getCameraState()
|
||||
|
||||
target.toggleCamera(sourceCameraType)
|
||||
target.setCameraState(sourceCameraState)
|
||||
|
||||
target.setBackgroundColor(source.getSceneManager().currentBackgroundColor)
|
||||
|
||||
target.toggleGrid(source.getSceneManager().gridHelper.visible)
|
||||
|
||||
const sourceBackgroundInfo = source
|
||||
.getSceneManager()
|
||||
.getCurrentBackgroundInfo()
|
||||
if (sourceBackgroundInfo.type === 'image') {
|
||||
const sourceNode = this.getNodeByLoad3d(source)
|
||||
const backgroundPath = sourceNode?.properties?.[
|
||||
'Background Image'
|
||||
] as string
|
||||
if (backgroundPath) {
|
||||
await target.setBackgroundImage(backgroundPath)
|
||||
}
|
||||
}
|
||||
|
||||
target.setLightIntensity(
|
||||
source.getLightingManager().lights[1]?.intensity || 1
|
||||
)
|
||||
|
||||
if (sourceCameraType === 'perspective') {
|
||||
target.setFOV(source.getCameraManager().perspectiveCamera.fov)
|
||||
}
|
||||
|
||||
const sourceNode = this.getNodeByLoad3d(source)
|
||||
if (sourceNode?.properties?.['Edge Threshold']) {
|
||||
target.setEdgeThreshold(sourceNode.properties['Edge Threshold'] as number)
|
||||
}
|
||||
}
|
||||
|
||||
handleViewportRefresh(load3d: Load3d | null) {
|
||||
if (!load3d) return
|
||||
|
||||
load3d.handleResize()
|
||||
|
||||
const currentType = load3d.getCurrentCameraType()
|
||||
|
||||
load3d.toggleCamera(
|
||||
currentType === 'perspective' ? 'orthographic' : 'perspective'
|
||||
)
|
||||
load3d.toggleCamera(currentType)
|
||||
|
||||
load3d.getControlsManager().controls.update()
|
||||
}
|
||||
|
||||
async handleViewerClose(node: LGraphNode) {
|
||||
const viewer = useLoad3dService().getOrCreateViewer(node)
|
||||
|
||||
if (viewer.needApplyChanges.value) {
|
||||
await viewer.applyChanges()
|
||||
}
|
||||
|
||||
useLoad3dService().removeViewer(node)
|
||||
}
|
||||
}
|
||||
|
||||
export const useLoad3dService = () => {
|
||||
|
||||
Reference in New Issue
Block a user