【问题标题】:How do I get a Blender exporter script to run from the command line?如何让 Blender 导出器脚本从命令行运行?
【发布时间】:2013-06-09 08:50:48
【问题描述】:

我正在尝试将一些对象从搅拌机导出为专有格式。我希望我编写的脚本能够从文件下拉列表和命令行中从搅拌机中导出对象。我在 ubuntu 12.04 LTS 上使用搅拌机 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 类的执行函数似乎永远不会被调用。我什至尝试直接调用执行函数,但是,如果您阅读了该区域上方的评论,我似乎也遗漏了一些内容。

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

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

【问题讨论】:

    标签: python command-line export blender


    【解决方案1】:

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

    # 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 有一个开关“--”,它定义了搅拌机参数输入的结束,所以如果检测到该开关,那么我会抓取它之后的任何参数并将它们解析为我的脚本参数。到目前为止,这似乎工作得很好。

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

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

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

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

    【讨论】:

    • 嗨@Jason Smith,这真的很棒,我们想把这个脚本放在搅拌机中,我们如何运行它?
    • 嗯,我是从命令行运行的,正如标题所述,所以我使用了这样的东西:blender --background --python Exporter.py
    • 如果你想从搅拌机内部运行它作为一个附加组件也是可能的。为此,我请您参考这里。 wiki.blender.org/index.php/Doc:2.6/Manual/Extensions/Python/…
    • 嗨@Jason Smith,谢谢你的提示,我想知道如何将文件作为参数传递给这个python脚本?
    • @JothiKannan 我刚刚重新阅读了您的评论,上面有几篇文章:如果您收到错误“没有提供可保存的文件名”。然后你只需要传递命令行标志 -m 来告诉它在哪里保存模型。 "blender --background --python Exporter.py -- -m "
    猜你喜欢
    • 2022-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多