2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

特定フォルダの.blendファイルを一括処理

Posted at

ソフトウェアで作業していると複数のファイルを一括処理したいことがあり
3DソフトのBlenderでも当然そういう場面に遭遇します。

Blenderもコマンドラインで操作可能ですが
アーティスト系の人は コマンド操作は極力したくないと思うでしょう
一度処理を書けばBlender上で操作が完結できるようにするスクリプトを作成してみました。

Blenderのテキストエディッタにコピペして使用するスクリプトです。
テキストエディッタの「スクリプト実行」ボタンを押すとファイルオープンダイアログが開くので
フォルダを指定すると そのフォルダ内にある.blendファイルに対して一括処理を加えます

このスクリプトのデフォルト状態では 画像をレンダリングしてPNGで保存します

process_dir.py
import bpy
import subprocess
from bpy.props import StringProperty
from bpy_extras.io_utils import ImportHelper
from pathlib import Path

#ディレクトリの指定
class PROCESS_OT_DIR(bpy.types.Operator, ImportHelper):
    bl_idname = "processing_dir.blfiles"
    bl_description = 'processing select directry'
    bl_label = "Select Directory"

    filepath: StringProperty(
            name="input file",
            subtype= 'DIR_PATH'
            )
    filename_ext : ".blend"
    filter_glob: StringProperty(
            default="*.blend",
            options={'HIDDEN'},
            )
    def execute(self, context):  
        # 対象ファイルの取得
        blend_list = self.get_blend(context)
        for blend_file in blend_list:
            # インフォエディッタに情報出力
            self.report( {'INFO'},("render:%s" % str(blend_file)) )
            call_subprocess(blend_file)
        return{'FINISHED'}
    def get_blend(self, context):
        """ディレクトリ内の.blendファイルを取得"""
        dir_path = Path(self.filepath)
        blend_list = list(dir_path.glob("*.blend"))
        return(blend_list)

def call_subprocess(blend_file):
    """指定したファイルをバックグラウンド処理"""
    # スクリプトを開いているBlenderのパス
    exe_path = bpy.app.binary_path
    # レンダリング用のコマンド
    command_txt = render_command(blend_file)
    # 開いたドキュメントでPythonを実行
    #command_txt = expr_command()
    # バックグラウンドでレンダリングを実行
    call_command = '%s -b %s  %s' % (exe_path, blend_file,command_txt)
    subprocess.call(call_command)
    return()

def render_command(blend_file):
    """ レンダリング用のコマンド """
    # 出力画像のタイプ(TGA RAWTGA JPEG IRIS IRIZ PNG BMP)
    img_type = "PNG"
    # 出力する画像ファイル名
    f_name = "%s_img" % blend_file.stem
    # 出力パス
    parent_dir = blend_file.resolve().parents[0]
    img_path = parent_dir.joinpath(f_name)
    command_txt = "-o %s -F %s -x 1 -f 1" % (img_path, img_type)
    return(command_txt)

# Pyhtonとして実行させるテキスト
script_text = """\
import bpy
print(bpy.context.active_object.name)
"""
def expr_command():
    command_txt = '--python-expr \"%s\"' % script_text
    return(command_txt)

def register():
    bpy.utils.register_class(PROCESS_OT_DIR)

def unregister():
    bpy.utils.unregister_class(PROCESS_OT_DIR)

if __name__ == "__main__":
    register()
    # test call
    bpy.ops.processing_dir.blfiles('INVOKE_DEFAULT')

バックグラウンドで動作するようになっていて
処理中は開いているウインドウは何も反応がなくなります。

最小限の変更で レンダリング以外の操作もできるようにしています

    # 開いたドキュメントでPythonを実行
    #command_txt = expr_command()

の行をコメントアウトすることで
script_textの部分に書いたpythonのコードを実行するようにできます

script_text = """\
import bpy
print(bpy.context.active_object.name)
"""

サンプルでは開いたファイルのアクティブなオブジェクトの名前を出力します

ここを調整することで色々できることは多いと思います

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?