From 8fb9751f4c6be505f8a8af103418c7a675c0a4cd Mon Sep 17 00:00:00 2001 From: Terry Jia Date: Thu, 2 Oct 2025 20:40:03 -0400 Subject: [PATCH 1/3] [refactor] refactor load3d --- src/components/load3d/Load3D.vue | 376 ++------ src/components/load3d/Load3DAnimation.vue | 336 ------- .../load3d/Load3DAnimationScene.vue | 208 ----- src/components/load3d/Load3DControls.vue | 252 +---- src/components/load3d/Load3DScene.vue | 267 ++---- src/components/load3d/Load3dViewerContent.vue | 63 ++ src/components/load3d/LoadingOverlay.vue | 33 +- .../AnimationControls.vue} | 39 +- .../load3d/controls/CameraControls.vue | 64 +- .../load3d/controls/LightControls.vue | 37 +- .../load3d/controls/ModelControls.vue | 113 +-- .../load3d/controls/RecordingControls.vue | 65 +- .../load3d/controls/SceneControls.vue | 44 +- src/composables/useLoad3d.ts | 544 +++++++++++ src/composables/useLoad3dViewer.ts | 198 ++-- src/extensions/core/load3d.ts | 346 ++----- .../core/load3d/AnimationManager.ts | 24 +- src/extensions/core/load3d/CameraManager.ts | 12 +- src/extensions/core/load3d/ControlsManager.ts | 15 +- src/extensions/core/load3d/LightingManager.ts | 2 + .../core/load3d/Load3DConfiguration.ts | 198 ++-- src/extensions/core/load3d/Load3d.ts | 211 +++-- src/extensions/core/load3d/Load3dAnimation.ts | 131 --- src/extensions/core/load3d/PreviewManager.ts | 416 --------- .../core/load3d/RecordingManager.ts | 86 +- src/extensions/core/load3d/SceneManager.ts | 77 +- .../core/load3d/SceneModelManager.ts | 416 +-------- .../core/load3d/ViewHelperManager.ts | 17 +- .../ColoredShadowMaterial.js | 163 ---- .../ConditionalEdgesGeometry.js | 126 --- .../ConditionalEdgesShader.js | 96 -- .../Lines2/ConditionalLineMaterial.js | 379 -------- .../Lines2/ConditionalLineSegmentsGeometry.js | 43 - src/extensions/core/load3d/interfaces.ts | 53 +- src/extensions/core/saveMesh.ts | 35 +- src/locales/en/main.json | 17 +- src/locales/en/nodeDefs.json | 54 +- .../widgets/registry/widgetRegistry.ts | 5 +- src/schemas/apiSchema.ts | 1 - src/services/load3dService.ts | 115 +-- tests-ui/tests/composables/useLoad3d.test.ts | 880 ++++++++++++++++++ .../tests/composables/useLoad3dViewer.test.ts | 79 +- 42 files changed, 2464 insertions(+), 4172 deletions(-) delete mode 100644 src/components/load3d/Load3DAnimation.vue delete mode 100644 src/components/load3d/Load3DAnimationScene.vue rename src/components/load3d/{Load3DAnimationControls.vue => controls/AnimationControls.vue} (57%) create mode 100644 src/composables/useLoad3d.ts delete mode 100644 src/extensions/core/load3d/Load3dAnimation.ts delete mode 100644 src/extensions/core/load3d/PreviewManager.ts delete mode 100644 src/extensions/core/load3d/conditional-lines/ColoredShadowMaterial.js delete mode 100644 src/extensions/core/load3d/conditional-lines/ConditionalEdgesGeometry.js delete mode 100644 src/extensions/core/load3d/conditional-lines/ConditionalEdgesShader.js delete mode 100644 src/extensions/core/load3d/conditional-lines/Lines2/ConditionalLineMaterial.js delete mode 100644 src/extensions/core/load3d/conditional-lines/Lines2/ConditionalLineSegmentsGeometry.js create mode 100644 tests-ui/tests/composables/useLoad3d.test.ts diff --git a/src/components/load3d/Load3D.vue b/src/components/load3d/Load3D.vue index 23245edc94..dd88bcaa80 100644 --- a/src/components/load3d/Load3D.vue +++ b/src/components/load3d/Load3D.vue @@ -3,69 +3,46 @@ class="relative w-full h-full" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" + @pointerdown.stop + @pointermove.stop + @pointerup.stop > - +
+ + +
- +
diff --git a/src/components/load3d/Load3DAnimation.vue b/src/components/load3d/Load3DAnimation.vue deleted file mode 100644 index 9d29c1ed14..0000000000 --- a/src/components/load3d/Load3DAnimation.vue +++ /dev/null @@ -1,336 +0,0 @@ - - - diff --git a/src/components/load3d/Load3DAnimationScene.vue b/src/components/load3d/Load3DAnimationScene.vue deleted file mode 100644 index 38cbd7169b..0000000000 --- a/src/components/load3d/Load3DAnimationScene.vue +++ /dev/null @@ -1,208 +0,0 @@ - - diff --git a/src/components/load3d/Load3DControls.vue b/src/components/load3d/Load3DControls.vue index eea5208b32..2b41e0a30c 100644 --- a/src/components/load3d/Load3DControls.vue +++ b/src/components/load3d/Load3DControls.vue @@ -1,6 +1,10 @@ diff --git a/src/components/load3d/Load3dViewerContent.vue b/src/components/load3d/Load3dViewerContent.vue index fa22865d6a..2082b5a108 100644 --- a/src/components/load3d/Load3dViewerContent.vue +++ b/src/components/load3d/Load3dViewerContent.vue @@ -11,7 +11,20 @@ ref="containerRef" class="absolute w-full h-full comfy-load-3d-viewer" @resize="viewer.handleResize" + @dragover.prevent.stop="handleDragOver" + @dragleave.stop="handleDragLeave" + @drop.prevent.stop="handleDrop" /> +
+
+ {{ dragMessage }} +
+
@@ -77,6 +90,7 @@ import ModelControls from '@/components/load3d/controls/viewer/ViewerModelContro import SceneControls from '@/components/load3d/controls/viewer/ViewerSceneControls.vue' import { t } from '@/i18n' import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' +import { useToastStore } from '@/platform/updates/common/toastStore' import { useLoad3dService } from '@/services/load3dService' import { useDialogStore } from '@/stores/dialogStore' @@ -84,6 +98,16 @@ const props = defineProps<{ node: LGraphNode }>() +// Drag and drop state +const isDragging = ref(false) +const dragMessage = ref('') +const SUPPORTED_EXTENSIONS = ['.gltf', '.glb', '.obj', '.fbx', '.stl'] + +function isValidModelFile(file: File): boolean { + const fileName = file.name.toLowerCase() + return SUPPORTED_EXTENSIONS.some((ext) => fileName.endsWith(ext)) +} + const viewerContentRef = ref() const containerRef = ref() const mainContentRef = ref() @@ -92,6 +116,45 @@ const mutationObserver = ref(null) const viewer = useLoad3dService().getOrCreateViewer(toRaw(props.node)) +function handleDragOver(event: DragEvent) { + if (viewer.isPreview.value) return + + if (!event.dataTransfer) return + + const hasFiles = event.dataTransfer.types.includes('Files') + + if (!hasFiles) return + + isDragging.value = true + + event.dataTransfer.dropEffect = 'copy' + dragMessage.value = t('load3d.dropToLoad') +} + +function handleDragLeave() { + isDragging.value = false +} + +async function handleDrop(event: DragEvent) { + isDragging.value = false + + if (viewer.isPreview.value) return + + if (!event.dataTransfer) return + + const files = Array.from(event.dataTransfer.files) + + if (files.length === 0) return + + const modelFile = files.find(isValidModelFile) + + if (modelFile) { + await viewer.handleModelDrop(modelFile) + } else { + useToastStore().addAlert(t('load3d.unsupportedFileType')) + } +} + onMounted(async () => { const source = useLoad3dService().getLoad3d(props.node) if (source && containerRef.value) { diff --git a/src/components/load3d/LoadingOverlay.vue b/src/components/load3d/LoadingOverlay.vue index 361718d9ea..0da3edaeeb 100644 --- a/src/components/load3d/LoadingOverlay.vue +++ b/src/components/load3d/LoadingOverlay.vue @@ -1,13 +1,13 @@