python - 如何让 Blender 导出器脚本从命令行运行?

标签 python command-line export blender

我正在尝试将一些对象从 blender 导出为专有格式。我希望我编写的脚本能够从 File 下拉列表和命令行中导出 blender 中的对象。我在 ubuntu 12.04 LTS 上使用 blender 2.66。以下是我目前正在尝试运行的文件。

# Required Blender information.
bl_info = {
           "name": "My Exporter",
           "author": "",
           "version": (1, 0),
           "blender": (2, 65, 0),
           "location": "File > Export > Test (.tst)",
           "description": "",
           "warning": "",
           "wiki_url": "",
           "tracker_url": "",
           "category": "Import-Export"
          }

# Import the Blender required namespaces.
import bpy
from bpy_extras.io_utils import ExportHelper


# The main exporter class.
class MyExporter(bpy.types.Operator, ExportHelper):
   bl_idname       = "test.tst";
   bl_label        = "My Exporter";
   bl_options      = {'PRESET'};

   filename_ext    = ".tst";

   object_count    = 0;

   def __init__(self):
      pass

   def execute(self, context):
      print("Execute was called.");

      # Parse all the objects in the scene.
      return {'FINISHED'};

   def export_object(self, gameObject):
      if (gameObject.type != "MESH"):
         print("Object was not of type mesh.");
      else:
         object_count += 1;

      return;


# Define a function to create the menu option for exporting.
def create_menu(self, context):
   self.layout.operator(MyExporter.bl_idname,text="test (.tst)");

# Define the Blender required registration functions.
def register():
   """
   Handles the registration of the Blender Addon.
   """
   bpy.utils.register_module(__name__);
   bpy.types.INFO_MT_file_export.append(create_menu);

def unregister():
   """
   Handles the unregistering of this Blender Addon.
   """
   bpy.utils.unregister_module(__name__);
   bpy.types.INFO_MT_file_export.remove(create_menu);

# Handle running the script from Blender's text editor.
if (__name__ == "__main__"):
   print("Registering.");
   register();

   print("Executing.");

   # I have tried with these lines uncommented to force it to run
   # the execute function, but I get an error saying:
   #    exporter = MyExporter();
   #    TypeError: bpy_struct.__new__(type): expected a single argument

   #exporter = MyExporter();
   #exporter.execute(bpy.context.scene);

我试过以下命令:

blender model.blend --background --python myexporter.py

我从中得到以下输出:

Note: No (valid) '~/.config/blender/2.66/config/startup.blend' found,
      fall back to built-in default.

Read new prefs: ~/.config/blender/2.66/config/userpref.blend
found bundled python: ~/blender/2.66/python
read blend: ~/model.blend
Registering.
Executing.

Blender quit

MyExporter 类中的执行函数似乎从未被调用过。我什至尝试直接调用执行函数,但如果您阅读该区域上方的评论,我似乎也遗漏了一些东西。

当脚本作为附加组件添加到 blender 时,一切正常。它调用完美执行。所以至少我有一半的工作。

提前感谢您能给我的任何帮助。如果我犯了一个愚蠢的错误,我深表歉意,我在编写此脚本的同时正在学习 Python。

最佳答案

我终于弄明白了,认为回来分享答案是个好主意。首先是有效的文件。

# Required Blender information.
bl_info = {
           "name": "My Exporter",
           "author": "",
           "version": (1, 0),
           "blender": (2, 65, 0),
           "location": "File > Export > Test (.tst)",
           "description": "",
           "warning": "",
           "wiki_url": "",
           "tracker_url": "",
           "category": "Import-Export"
          }

# Import the Blender required namespaces.
import sys, getopt

import bpy
from bpy_extras.io_utils import ExportHelper



# The main exporter class.
class MyExporter(bpy.types.Operator, ExportHelper):
   bl_idname       = "export_scene.my_exporter";
   bl_label        = "My Exporter";
   bl_options      = {'PRESET'};

   filename_ext    = ".tst";

   object_count    = 0;

   def __init__(self):
      pass

   def execute(self, context):
      print("Execute was called.");

      self.parse_command_line_options();

      if (self.filepath == ""):
         print("No sutable filename was provided to save to.");
         return {'FINISHED'};

      # Get all the mesh objects in the scene.
      objList = [object for object in bpy.context.scene.objects if object.type == 'MESH'];

      # Now process all the objects that we found.
      for gameObject in objList:
         self.export_object(gameObject);

      # Parse all the objects in the scene.
      return {'FINISHED'};


   def export_object(self, gameObject):
      if (gameObject.type != "MESH"):
         print("Object was not of type mesh.");
      else:
         self.object_count += 1;

      return;


   def parse_command_line_options(self):
      modelFile = "";
      myArgs = [];
      argsStartPos = 0;

      if (("--" in sys.argv) == False):
         return;

      argsStartPos = sys.argv.index("--");
      argsStartPos += 1;
      myArgs = sys.argv[argsStartPos:];

      try:
         opts, args = getopt.getopt(myArgs, 'hm:', ["help", "model-file="]);
      except getOpt.GetoptError:
         print("Opt Error.");
         return;

      for opt, arg in opts:
         if (opt in ("-h", "--help")):
            print("Run this as the following blender command.");
            print("\tblender <blend file> --background --python <script file> -- -m <output file>");
         elif (opt in ("-m", "--model-file")):
            modelFile = arg;

      if (modelFile != ""):
         self.filepath = modelFile;



# Define a function to create the menu option for exporting.
def create_menu(self, context):
   self.layout.operator(MyExporter.bl_idname,text="test (.tst)");

# Define the Blender required registration functions.
def register():
   """
   Handles the registration of the Blender Addon.
   """
   bpy.utils.register_module(__name__);
   bpy.types.INFO_MT_file_export.append(create_menu);

def unregister():
   """
   Handles the unregistering of this Blender Addon.
   """
   bpy.utils.unregister_module(__name__);
   bpy.types.INFO_MT_file_export.remove(create_menu);


# Handle running the script from Blender's text editor.
if (__name__ == "__main__"):
   print("Registering.");
   register();

   print("Executing.");
   bpy.ops.export_scene.my_exporter();

我遗漏的关键是错误地为我的导出器类设置了 bl_idname,然后调用了 bpy.ops.export_scene.my_exporter();

有关我搞砸的内容的更多信息可以在这里找到:http://www.blender.org/documentation/blender_python_api_2_66_release/bpy.ops.html

现在因为我还希望它从命令行运行而不仅仅是文件下拉菜单,我添加了一个解析函数来解析发送到 Blender 的命令行选项。 Blender 有一个开关 '--' 定义了 blender 参数输入的结尾,所以如果检测到该开关,那么我会在它之后获取任何参数并将它们解析为我的脚本参数。到目前为止,这似乎完美无缺。

目前模型文件支持-h打印一些帮助信息和-m指定保存转换数据的文件。

好吧,我希望这些信息可以帮助其他人。祝你好运。

更新:如果您在运行脚本时在命令行中看到如下一条或多条消息,请使用此 question 中的答案来解决这个问题。

skipping driver 'alpha * auto', automatic scripts are disabled

关于python - 如何让 Blender 导出器脚本从命令行运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17079106/

相关文章:

shell - ZSH 在打开应用程序选项卡自动完成时挂起

wordpress - 导出wordpress中的特定页面

python - `np.ix_` 中的尾随下划线

python - 将 MKL 链接到 Anaconda 中已安装的 Numpy?

python - Selenium:如何获取 <td> 标记中的文本,然后单击它的同级标记的 Javascript 链接?

Python - 模糊测试

linux - CMake,构建选项

command-line - 手动停止构建时 Gradle .lock 文件未删除

php - 无需访问服务器或 phpMyADMIN 即可导出 SQL 表的简便方法

linux - 如何在 ksh 中导出函数?没有全局声明或使用自动加载