bpy 在全局范围内有效,但在flask 应用程序中无效

问题描述

我一直在使用 javascript,最近开始使用 python 来使用 Blender-python 库。(bpy) 所以这个问题可能是我的一些误解,因为缺乏语言行为的知识。

这个函数使用bpy。我测试过,它成功地将 .gltf 文件转换为 .fbx。

import os
import bpy

path = os.getcwd()
UPLOAD_FOLDER = os.path.join(path,'uploads')
DOWNLOAD_FOLDER = os.path.join(path,'downloads')

def gltf_to_fbx(filename):
    path = os.path.join(UPLOAD_FOLDER,filename)
    bpy.ops.import_scene.gltf(filepath = path)
    portion = os.path.splitext(filename)
    newname = portion[0] + ".fbx"
    path_to_file = os.path.join(DOWNLOAD_FOLDER,newname)
    bpy.ops.export_scene.fbx(filepath = path_to_file)
    bpy.ops.object.delete()

gltf_to_fbx("1.gltf")

但是,当我像这样在 Flask 应用路由器中运行它时,它会引发错误

from flask import Flask,flash,request

app = Flask(__name__)

@app.route('/',methods=['POST'])
def upload_file():
    file = request.files['model']
    filename = secure_filename(file.filename)
    save_path = os.path.join(UPLOAD_FOLDER,filename)
    file.save(save_path)
    gltf_to_fbx(filename)
    flash('File successfully uploaded')
    return "Success"

if __name__ == "__main__":
    app.run(host="localhost",port = 5000)

这是错误信息

...
  File "index.py",line 62,in upload_file
    gltf_to_fbx("1_1.gltf")
  File "index.py",line 32,in gltf_to_fbx
    bpy.ops.import_scene.gltf(filepath = path)
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\modules\bpy\ops.py",line 201,in __call__       
    ret = op_call(self.idname_py(),None,kw)
RuntimeError: Error: Traceback (most recent call last):
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\addons\io_scene_gltf2\__init__.py",line 850,in 
execute
    return self.import_gltf2(context)
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\addons\io_scene_gltf2\__init__.py",line 869,in 
import_gltf2
    return self.unit_import(self.filepath,import_settings)
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\addons\io_scene_gltf2\__init__.py",line 887,in 
unit_import
    BlenderGlTF.create(self.gltf_importer)
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\addons\io_scene_gltf2\blender\imp\gltf2_blender_gltf.py",line 41,in create
    BlenderScene.create(gltf,scene_idx)
  File "C:\ProgramData\Blender Foundation\Blender\2.82\scripts\addons\io_scene_gltf2\blender\imp\gltf2_blender_scene.py",line 53,in create
    bpy.context.window.scene = bpy.data.scenes[gltf.blender_scene]
AttributeError: 'nonetype' object has no attribute 'scene'

location: C:\ProgramData\Blender Foundation\Blender\2.82\scripts\modules\bpy\ops.py:201

错误信息似乎是说它无法导入文件,因为它是...错误?但它没有意义,因为它在flask应用程序之外运行时没有抛出错误

我想也许文件在 bpy 尝试加载它之前没有保存,但没有。我还尝试使用已保存的文件路径运行 gltf_to_fbx 函数,但它仍然抛出相同的错误我能想象的唯一原因是 bpy 在全局范围内有效,但在flask应用程序中无效。这对我来说听起来很奇怪。

任何形式的意见表示赞赏。谢谢!

编辑 我刚刚注释掉了 bpy 模块中的错误行。然后它抛出了另一个错误,我也将其注释掉了。现在它起作用了!不过,我并不为这种解决方案感到自豪。我的假设是 bpy 仅设计为在 Blender 控制台上运行。所以 import_scene.gltf 函数假设系统运行了 Blender 上下文,在这种情况下它没有。(仍然存在问题;它是如何在全局范围内没有错误地运行的?)我发现这个文档解释了如何在 Blender 之外构建一个看起来很有希望的模块。 https://wiki.blender.org/wiki/Building_Blender/Windows

解决方法

path = os.getcwd() 函数行 gltf_to_fbx 中覆盖全局名称 path = os.path.join(UPLOAD_FOLDER,filename) 的可能问题,因为 UPLOAD_FOLDER 正在使用 path = os.getcwd() 生成路径,尝试更改为file_path 像这样 file_path = os.path.join(UPLOAD_FOLDER,filename) 然后将这个 file_path 传递给 bpy 像这样 bpy.ops.import_scene.gltf(filepath=file_path)

这可能会有所帮助,因为错误表明 NoneType 没有属性 scene,这对于提供给 bpy 的错误路径可能是正确的。

bpy.context.window.scene = bpy.data.scenes[gltf.blender_scene]
AttributeError: 'NoneType' object has no attribute 'scene'
,

我意识到我安装的 bpy 模块不正确。我认为 bpy 应该作为一个完整的模块工作,因为我在 pip 中找到了它(我使用 pip install bpy 安装),但实际上它假设该模块在 Blender 的应用内控制台上运行。因此,不是通过 python index.py 运行应用程序,而是先在后台运行 Blender 并在其上运行 python 解决了问题。 blender --background python index.py