ソフトウェアで作業していると複数のファイルを一括処理したいことがあり
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)
"""
サンプルでは開いたファイルのアクティブなオブジェクトの名前を出力します
ここを調整することで色々できることは多いと思います