diff --git a/src/extensions/core/load3d.ts b/src/extensions/core/load3d.ts index 40c0f4149..caa52c143 100644 --- a/src/extensions/core/load3d.ts +++ b/src/extensions/core/load3d.ts @@ -266,7 +266,7 @@ useExtensionService().registerExtension({ LOAD_3D_ANIMATION(node) { const fileInput = document.createElement('input') fileInput.type = 'file' - fileInput.accept = '.fbx,glb,gltf' + fileInput.accept = '.gltf,.glb,.fbx' fileInput.style.display = 'none' fileInput.onchange = async () => { if (fileInput.files?.length) { @@ -452,31 +452,43 @@ useExtensionService().registerExtension({ const onExecuted = node.onExecuted - node.onExecuted = function (message: any) { - onExecuted?.apply(this, arguments as any) + useLoad3dService().waitForLoad3d(node, (load3d) => { + const config = new Load3DConfiguration(load3d) - let filePath = message.result[0] + const modelWidget = node.widgets?.find((w) => w.name === 'model_file') - if (!filePath) { - const msg = t('toastMessages.unableToGetModelFilePath') - console.error(msg) - useToastStore().addAlert(msg) - } + if (modelWidget) { + const lastTimeModelFile = node.properties['Last Time Model File'] - let cameraState = message.result[1] + if (lastTimeModelFile) { + modelWidget.value = lastTimeModelFile - useLoad3dService().waitForLoad3d(node, (load3d) => { - const modelWidget = node.widgets?.find((w) => w.name === 'model_file') - - if (modelWidget) { - modelWidget.value = filePath.replaceAll('\\', '/') - - const config = new Load3DConfiguration(load3d) + const cameraState = node.properties['Camera Info'] config.configure('output', modelWidget, cameraState) } - }) - } + + node.onExecuted = function (message: any) { + onExecuted?.apply(this, arguments as any) + + let filePath = message.result[0] + + if (!filePath) { + const msg = t('toastMessages.unableToGetModelFilePath') + console.error(msg) + useToastStore().addAlert(msg) + } + + let cameraState = message.result[1] + + modelWidget.value = filePath.replaceAll('\\', '/') + + node.properties['Last Time Model File'] = modelWidget.value + + config.configure('output', modelWidget, cameraState) + } + } + }) } }) @@ -526,29 +538,42 @@ useExtensionService().registerExtension({ const onExecuted = node.onExecuted - node.onExecuted = function (message: any) { - onExecuted?.apply(this, arguments as any) + useLoad3dService().waitForLoad3d(node, (load3d) => { + const config = new Load3DConfiguration(load3d) - let filePath = message.result[0] + const modelWidget = node.widgets?.find((w) => w.name === 'model_file') - if (!filePath) { - const msg = t('toastMessages.unableToGetModelFilePath') - console.error(msg) - useToastStore().addAlert(msg) - } + if (modelWidget) { + const lastTimeModelFile = node.properties['Last Time Model File'] - let cameraState = message.result[1] + if (lastTimeModelFile) { + modelWidget.value = lastTimeModelFile - useLoad3dService().waitForLoad3d(node, (load3d) => { - const modelWidget = node.widgets?.find((w) => w.name === 'model_file') - if (modelWidget) { - modelWidget.value = filePath.replaceAll('\\', '/') - - const config = new Load3DConfiguration(load3d) + const cameraState = node.properties['Camera Info'] config.configure('output', modelWidget, cameraState) } - }) - } + + node.onExecuted = function (message: any) { + onExecuted?.apply(this, arguments as any) + + let filePath = message.result[0] + + if (!filePath) { + const msg = t('toastMessages.unableToGetModelFilePath') + console.error(msg) + useToastStore().addAlert(msg) + } + + let cameraState = message.result[1] + + modelWidget.value = filePath.replaceAll('\\', '/') + + node.properties['Last Time Model File'] = modelWidget.value + + config.configure('output', modelWidget, cameraState) + } + } + }) } }) diff --git a/src/extensions/core/load3d/LoaderManager.ts b/src/extensions/core/load3d/LoaderManager.ts index 6ea1c2477..7b7752337 100644 --- a/src/extensions/core/load3d/LoaderManager.ts +++ b/src/extensions/core/load3d/LoaderManager.ts @@ -132,6 +132,14 @@ export class LoaderManager implements LoaderManagerInterface { if (this.modelManager.materialMode === 'original') { const mtlUrl = url.replace(/(filename=.*?)\.obj/, '$1.mtl') + const subfolderMatch = url.match(/[?&]subfolder=([^&]*)/) + + const subfolder = subfolderMatch + ? decodeURIComponent(subfolderMatch[1]) + : '3d' + + this.mtlLoader.setSubfolder(subfolder) + try { const materials = await this.mtlLoader.loadAsync(mtlUrl) materials.preload() diff --git a/src/extensions/core/load3d/threejsOverride/OverrideMTLLoader.js b/src/extensions/core/load3d/threejsOverride/OverrideMTLLoader.js index 084e38425..47b7a7f05 100644 --- a/src/extensions/core/load3d/threejsOverride/OverrideMTLLoader.js +++ b/src/extensions/core/load3d/threejsOverride/OverrideMTLLoader.js @@ -38,6 +38,10 @@ class OverrideMTLLoader extends Loader { this.loadRootFolder = loadRootFolder } + setSubfolder(subfolder) { + this.subfolder = subfolder + } + /** * Starts loading from the given URL and passes the loaded MTL asset * to the `onLoad()` callback. @@ -135,7 +139,8 @@ class OverrideMTLLoader extends Loader { const materialCreator = new OverrideMaterialCreator( this.resourcePath || path, this.materialOptions, - this.loadRootFolder + this.loadRootFolder, + this.subfolder ) materialCreator.setCrossOrigin(this.crossOrigin) materialCreator.setManager(this.manager) @@ -155,7 +160,7 @@ class OverrideMTLLoader extends Loader { */ class OverrideMaterialCreator { - constructor(baseUrl = '', options = {}, loadRootFolder) { + constructor(baseUrl = '', options = {}, loadRootFolder, subfolder) { this.baseUrl = baseUrl this.options = options this.materialsInfo = {} @@ -164,6 +169,7 @@ class OverrideMaterialCreator { this.nameLookup = {} this.loadRootFolder = loadRootFolder + this.subfolder = subfolder this.crossOrigin = 'anonymous' @@ -283,16 +289,25 @@ class OverrideMaterialCreator { /** * Override for ComfyUI api url */ - function resolveURL(baseUrl, url, loadRootFolder) { + function resolveURL(baseUrl, url, loadRootFolder, subfolder) { if (typeof url !== 'string' || url === '') return '' + if (baseUrl.endsWith('/')) { + baseUrl = baseUrl.slice(0, -1) + } + + if (!baseUrl.endsWith('api')) { + baseUrl = '/api' + } + baseUrl = baseUrl + '/view?filename=' + url + '&type=' + loadRootFolder + - '&subfolder=3d' + '&subfolder=' + + subfolder return baseUrl } @@ -302,7 +317,12 @@ class OverrideMaterialCreator { const texParams = scope.getTextureParams(value, params) const map = scope.loadTexture( - resolveURL(scope.baseUrl, texParams.url, scope.loadRootFolder) + resolveURL( + scope.baseUrl, + texParams.url, + scope.loadRootFolder, + scope.subfolder + ) ) map.repeat.copy(texParams.scale)