[3d] refactor legacy code by using new vue style (#3161)

This commit is contained in:
Terry Jia
2025-03-20 10:28:35 -04:00
committed by GitHub
parent cc8dc3dbfb
commit afdb94f12f
12 changed files with 64 additions and 35 deletions

View File

@@ -7,7 +7,7 @@
<Load3DScene <Load3DScene
ref="load3DSceneRef" ref="load3DSceneRef"
:node="node" :node="node"
:type="type" :inputSpec="inputSpec"
:backgroundColor="backgroundColor" :backgroundColor="backgroundColor"
:showGrid="showGrid" :showGrid="showGrid"
:lightIntensity="lightIntensity" :lightIntensity="lightIntensity"
@@ -30,6 +30,7 @@
@edgeThresholdChange="listenEdgeThresholdChange" @edgeThresholdChange="listenEdgeThresholdChange"
/> />
<Load3DControls <Load3DControls
:inputSpec="inputSpec"
:backgroundColor="backgroundColor" :backgroundColor="backgroundColor"
:showGrid="showGrid" :showGrid="showGrid"
:showPreview="showPreview" :showPreview="showPreview"
@@ -42,7 +43,6 @@
:hasBackgroundImage="hasBackgroundImage" :hasBackgroundImage="hasBackgroundImage"
:upDirection="upDirection" :upDirection="upDirection"
:materialMode="materialMode" :materialMode="materialMode"
:isAnimation="false"
:edgeThreshold="edgeThreshold" :edgeThreshold="edgeThreshold"
@updateBackgroundImage="handleBackgroundImageUpdate" @updateBackgroundImage="handleBackgroundImageUpdate"
@switchCamera="switchCamera" @switchCamera="switchCamera"

View File

@@ -7,7 +7,7 @@
<Load3DAnimationScene <Load3DAnimationScene
ref="load3DAnimationSceneRef" ref="load3DAnimationSceneRef"
:node="node" :node="node"
:type="type" :inputSpec="inputSpec"
:backgroundColor="backgroundColor" :backgroundColor="backgroundColor"
:showGrid="showGrid" :showGrid="showGrid"
:lightIntensity="lightIntensity" :lightIntensity="lightIntensity"
@@ -35,6 +35,7 @@
/> />
<div class="absolute top-0 left-0 w-full h-full pointer-events-none"> <div class="absolute top-0 left-0 w-full h-full pointer-events-none">
<Load3DControls <Load3DControls
:inputSpec="inputSpec"
:backgroundColor="backgroundColor" :backgroundColor="backgroundColor"
:showGrid="showGrid" :showGrid="showGrid"
:showPreview="showPreview" :showPreview="showPreview"
@@ -47,7 +48,6 @@
:hasBackgroundImage="hasBackgroundImage" :hasBackgroundImage="hasBackgroundImage"
:upDirection="upDirection" :upDirection="upDirection"
:materialMode="materialMode" :materialMode="materialMode"
:isAnimation="true"
@updateBackgroundImage="handleBackgroundImageUpdate" @updateBackgroundImage="handleBackgroundImageUpdate"
@switchCamera="switchCamera" @switchCamera="switchCamera"
@toggleGrid="toggleGrid" @toggleGrid="toggleGrid"

View File

@@ -1,7 +1,7 @@
<template> <template>
<Load3DScene <Load3DScene
:node="node" :node="node"
:type="type" :inputSpec="inputSpec"
:backgroundColor="backgroundColor" :backgroundColor="backgroundColor"
:showGrid="showGrid" :showGrid="showGrid"
:lightIntensity="lightIntensity" :lightIntensity="lightIntensity"
@@ -29,14 +29,14 @@ import Load3DScene from '@/components/load3d/Load3DScene.vue'
import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation' import Load3dAnimation from '@/extensions/core/load3d/Load3dAnimation'
import { import {
CameraType, CameraType,
Load3DAnimationNodeType,
MaterialMode, MaterialMode,
UpDirection UpDirection
} from '@/extensions/core/load3d/interfaces' } from '@/extensions/core/load3d/interfaces'
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
const props = defineProps<{ const props = defineProps<{
node: any node: any
type: Load3DAnimationNodeType inputSpec: CustomInputSpec
backgroundColor: string backgroundColor: string
showGrid: boolean showGrid: boolean
lightIntensity: number lightIntensity: number

View File

@@ -43,9 +43,9 @@
<ModelControls <ModelControls
v-if="activeCategory === 'model'" v-if="activeCategory === 'model'"
:inputSpec="inputSpec"
:upDirection="upDirection" :upDirection="upDirection"
:materialMode="materialMode" :materialMode="materialMode"
:isAnimation="isAnimation"
:edgeThreshold="edgeThreshold" :edgeThreshold="edgeThreshold"
@updateUpDirection="handleUpdateUpDirection" @updateUpDirection="handleUpdateUpDirection"
@updateMaterialMode="handleUpdateMaterialMode" @updateMaterialMode="handleUpdateMaterialMode"
@@ -101,10 +101,12 @@ import {
UpDirection UpDirection
} from '@/extensions/core/load3d/interfaces' } from '@/extensions/core/load3d/interfaces'
import { t } from '@/i18n' import { t } from '@/i18n'
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
const vTooltip = Tooltip const vTooltip = Tooltip
const props = defineProps<{ const props = defineProps<{
inputSpec: CustomInputSpec
backgroundColor: string backgroundColor: string
showGrid: boolean showGrid: boolean
showPreview: boolean showPreview: boolean
@@ -117,7 +119,6 @@ const props = defineProps<{
hasBackgroundImage?: boolean hasBackgroundImage?: boolean
upDirection: UpDirection upDirection: UpDirection
materialMode: MaterialMode materialMode: MaterialMode
isAnimation: boolean
edgeThreshold?: number edgeThreshold?: number
}>() }>()

View File

@@ -13,17 +13,16 @@ 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'
import { t } from '@/i18n' import { t } from '@/i18n'
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import { useLoad3dService } from '@/services/load3dService' import { useLoad3dService } from '@/services/load3dService'
const props = defineProps<{ const props = defineProps<{
node: LGraphNode node: LGraphNode
type: Load3DNodeType | Load3DAnimationNodeType inputSpec: CustomInputSpec
backgroundColor: string backgroundColor: string
showGrid: boolean showGrid: boolean
lightIntensity: number lightIntensity: number
@@ -135,7 +134,7 @@ onMounted(() => {
node.value as LGraphNode, node.value as LGraphNode,
// @ts-expect-error fixme ts strict error // @ts-expect-error fixme ts strict error
container.value, container.value,
props.type props.inputSpec
) )
handleEvents('add') handleEvents('add')
}) })

View File

@@ -100,13 +100,14 @@ import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { MaterialMode, UpDirection } from '@/extensions/core/load3d/interfaces' import { MaterialMode, UpDirection } from '@/extensions/core/load3d/interfaces'
import { t } from '@/i18n' import { t } from '@/i18n'
import type { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
const vTooltip = Tooltip const vTooltip = Tooltip
const props = defineProps<{ const props = defineProps<{
inputSpec: CustomInputSpec
upDirection: UpDirection upDirection: UpDirection
materialMode: MaterialMode materialMode: MaterialMode
isAnimation: boolean
edgeThreshold?: number edgeThreshold?: number
}>() }>()
@@ -141,7 +142,7 @@ const materialModes = computed(() => {
//'depth' disable for now //'depth' disable for now
] ]
if (!props.isAnimation) { if (!props.inputSpec.isAnimation && !props.inputSpec.isPreview) {
modes.push('lineart') modes.push('lineart')
} }

View File

@@ -75,7 +75,9 @@ useExtensionService().registerExtension({
const inputSpec: CustomInputSpec = { const inputSpec: CustomInputSpec = {
name: 'image', name: 'image',
type: 'Load3D' type: 'Load3D',
isAnimation: false,
isPreview: false
} }
const widget = new ComponentWidgetImpl({ const widget = new ComponentWidgetImpl({
@@ -117,7 +119,7 @@ useExtensionService().registerExtension({
const height = node.widgets?.find((w: IWidget) => w.name === 'height') const height = node.widgets?.find((w: IWidget) => w.name === 'height')
const sceneWidget = node.widgets?.find((w: IWidget) => w.name === 'image') const sceneWidget = node.widgets?.find((w: IWidget) => w.name === 'image')
if (modelWidget && width && height && cameraState && sceneWidget) { if (modelWidget && width && height && sceneWidget) {
config.configure('input', modelWidget, cameraState, width, height) config.configure('input', modelWidget, cameraState, width, height)
sceneWidget.serializeValue = async () => { sceneWidget.serializeValue = async () => {
@@ -213,7 +215,9 @@ useExtensionService().registerExtension({
const inputSpec: CustomInputSpec = { const inputSpec: CustomInputSpec = {
name: 'image', name: 'image',
type: 'Load3DAnimation' type: 'Load3DAnimation',
isAnimation: true,
isPreview: false
} }
const widget = new ComponentWidgetImpl({ const widget = new ComponentWidgetImpl({
@@ -254,7 +258,7 @@ useExtensionService().registerExtension({
const width = node.widgets?.find((w: IWidget) => w.name === 'width') const width = node.widgets?.find((w: IWidget) => w.name === 'width')
const height = node.widgets?.find((w: IWidget) => w.name === 'height') const height = node.widgets?.find((w: IWidget) => w.name === 'height')
if (modelWidget && width && height && cameraState && sceneWidget) { if (modelWidget && width && height && sceneWidget) {
const config = new Load3DConfiguration(load3d) const config = new Load3DConfiguration(load3d)
config.configure('input', modelWidget, cameraState, width, height) config.configure('input', modelWidget, cameraState, width, height)
@@ -306,7 +310,9 @@ useExtensionService().registerExtension({
PREVIEW_3D(node) { PREVIEW_3D(node) {
const inputSpec: CustomInputSpec = { const inputSpec: CustomInputSpec = {
name: 'image', name: 'image',
type: 'Preview3D' type: 'Preview3D',
isAnimation: false,
isPreview: true
} }
const widget = new ComponentWidgetImpl({ const widget = new ComponentWidgetImpl({
@@ -381,7 +387,9 @@ useExtensionService().registerExtension({
PREVIEW_3D_ANIMATION(node) { PREVIEW_3D_ANIMATION(node) {
const inputSpec: CustomInputSpec = { const inputSpec: CustomInputSpec = {
name: 'image', name: 'image',
type: 'Preview3DAnimation' type: 'Preview3DAnimation',
isAnimation: true,
isPreview: true
} }
const widget = new ComponentWidgetImpl({ const widget = new ComponentWidgetImpl({

View File

@@ -1,6 +1,8 @@
import { LGraphNode } from '@comfyorg/litegraph' import { LGraphNode } from '@comfyorg/litegraph'
import * as THREE from 'three' import * as THREE from 'three'
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import { CameraManager } from './CameraManager' import { CameraManager } from './CameraManager'
import { ControlsManager } from './ControlsManager' import { ControlsManager } from './ControlsManager'
import { EventManager } from './EventManager' import { EventManager } from './EventManager'
@@ -43,7 +45,8 @@ class Load3d {
constructor( constructor(
container: Element | HTMLElement, container: Element | HTMLElement,
options: Load3DOptions = { options: Load3DOptions = {
node: {} as LGraphNode node: {} as LGraphNode,
inputSpec: {} as CustomInputSpec
} }
) { ) {
this.node = options.node || ({} as LGraphNode) this.node = options.node || ({} as LGraphNode)
@@ -108,7 +111,8 @@ class Load3d {
this.renderer, this.renderer,
this.eventManager, this.eventManager,
this.getActiveCamera.bind(this), this.getActiveCamera.bind(this),
this.setupCamera.bind(this) this.setupCamera.bind(this),
options
) )
this.loaderManager = new LoaderManager(this.modelManager, this.eventManager) this.loaderManager = new LoaderManager(this.modelManager, this.eventManager)
@@ -123,7 +127,7 @@ class Load3d {
this.viewHelperManager.createViewHelper(container) this.viewHelperManager.createViewHelper(container)
this.viewHelperManager.init() this.viewHelperManager.init()
if (options && options.createPreview) { if (options && !options.inputSpec?.isPreview) {
this.previewManager.createCapturePreview(container) this.previewManager.createCapturePreview(container)
this.previewManager.init() this.previewManager.init()
} }

View File

@@ -12,6 +12,7 @@ import { ConditionalLineMaterial } from './conditional-lines/Lines2/ConditionalL
import { ConditionalLineSegmentsGeometry } from './conditional-lines/Lines2/ConditionalLineSegmentsGeometry' import { ConditionalLineSegmentsGeometry } from './conditional-lines/Lines2/ConditionalLineSegmentsGeometry'
import { import {
EventManagerInterface, EventManagerInterface,
Load3DOptions,
MaterialMode, MaterialMode,
ModelManagerInterface, ModelManagerInterface,
UpDirection UpDirection
@@ -41,6 +42,7 @@ export class ModelManager implements ModelManagerInterface {
private activeCamera: THREE.Camera private activeCamera: THREE.Camera
private setupCamera: (size: THREE.Vector3) => void private setupCamera: (size: THREE.Vector3) => void
private lineartModel: THREE.Group private lineartModel: THREE.Group
private createLineartModel: boolean = false
LIGHT_MODEL = 0xffffff LIGHT_MODEL = 0xffffff
LIGHT_LINES = 0x455a64 LIGHT_LINES = 0x455a64
@@ -56,7 +58,8 @@ export class ModelManager implements ModelManagerInterface {
renderer: THREE.WebGLRenderer, renderer: THREE.WebGLRenderer,
eventManager: EventManagerInterface, eventManager: EventManagerInterface,
getActiveCamera: () => THREE.Camera, getActiveCamera: () => THREE.Camera,
setupCamera: (size: THREE.Vector3) => void setupCamera: (size: THREE.Vector3) => void,
options: Load3DOptions
) { ) {
this.scene = scene this.scene = scene
this.renderer = renderer this.renderer = renderer
@@ -64,6 +67,14 @@ export class ModelManager implements ModelManagerInterface {
this.activeCamera = getActiveCamera() this.activeCamera = getActiveCamera()
this.setupCamera = setupCamera this.setupCamera = setupCamera
if (
options &&
!options.inputSpec?.isPreview &&
!options.inputSpec?.isAnimation
) {
this.createLineartModel = true
}
this.normalMaterial = new THREE.MeshNormalMaterial({ this.normalMaterial = new THREE.MeshNormalMaterial({
flatShading: false, flatShading: false,
side: THREE.DoubleSide, side: THREE.DoubleSide,
@@ -657,7 +668,9 @@ export class ModelManager implements ModelManagerInterface {
this.setupCamera(size) this.setupCamera(size)
this.setupLineartModel() if (this.createLineartModel) {
this.setupLineartModel()
}
} }
setupLineartModel(): void { setupLineartModel(): void {

View File

@@ -8,6 +8,8 @@ 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'
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
export type Load3DNodeType = 'Load3D' | 'Preview3D' export type Load3DNodeType = 'Load3D' | 'Preview3D'
export type Load3DAnimationNodeType = 'Load3DAnimation' | 'Preview3DAnimation' export type Load3DAnimationNodeType = 'Load3DAnimation' | 'Preview3DAnimation'
@@ -33,8 +35,8 @@ export interface EventCallback {
} }
export interface Load3DOptions { export interface Load3DOptions {
createPreview?: boolean
node?: LGraphNode node?: LGraphNode
inputSpec?: CustomInputSpec
} }
export interface CaptureResult { export interface CaptureResult {

View File

@@ -24,7 +24,9 @@ useExtensionService().registerExtension({
PREVIEW_3D(node) { PREVIEW_3D(node) {
const inputSpec: CustomInputSpec = { const inputSpec: CustomInputSpec = {
name: 'image', name: 'image',
type: 'Preview3D' type: 'Preview3D',
isAnimation: false,
isPreview: true
} }
const widget = new ComponentWidgetImpl({ const widget = new ComponentWidgetImpl({
@@ -66,8 +68,6 @@ useExtensionService().registerExtension({
if (load3d && modelWidget) { if (load3d && modelWidget) {
const filePath = fileInfo['subfolder'] + '/' + fileInfo['filename'] const filePath = fileInfo['subfolder'] + '/' + fileInfo['filename']
console.log(filePath)
modelWidget.value = filePath modelWidget.value = filePath
const config = new Load3DConfiguration(load3d) const config = new Load3DConfiguration(load3d)

View File

@@ -3,6 +3,7 @@ import { toRaw } from 'vue'
import Load3d from '@/extensions/core/load3d/Load3d' 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'
export class Load3dService { export class Load3dService {
private static instance: Load3dService private static instance: Load3dService
@@ -20,7 +21,7 @@ export class Load3dService {
registerLoad3d( registerLoad3d(
node: LGraphNode, node: LGraphNode,
container: HTMLElement, container: HTMLElement,
type: 'Load3D' | 'Load3DAnimation' | 'Preview3D' | 'Preview3DAnimation' inputSpec: CustomInputSpec
) { ) {
const rawNode = toRaw(node) const rawNode = toRaw(node)
@@ -28,15 +29,15 @@ export class Load3dService {
this.removeLoad3d(rawNode) this.removeLoad3d(rawNode)
} }
const type = inputSpec.type
const isAnimation = type.includes('Animation') const isAnimation = type.includes('Animation')
const Load3dClass = isAnimation ? Load3dAnimation : Load3d const Load3dClass = isAnimation ? Load3dAnimation : Load3d
const isPreview = type.includes('Preview')
const instance = new Load3dClass(container, { const instance = new Load3dClass(container, {
createPreview: !isPreview, node: rawNode,
node: rawNode inputSpec: inputSpec
}) })
rawNode.onMouseEnter = function () { rawNode.onMouseEnter = function () {