【Blender】スクリプトで設定を変更して自動でベイクする

投稿者: | 2023-05-19

ChatGPTを使って、Blenderでベイクのための設定とベイクを自動で行うスクリプトを作ってみました。ベイクが終わったらテキストを出力します。

スクリプト

指示を箇条書きにしてChatGPTに送りました。

以下を実装した、BlenderのPythonスクリプトを作ってください。

1、複数のオブジェクトが選択されていることを確認する。選択されていなければ終了する。
2、RenderプロパティのRender Engineを確認して、Cycles意外であればCyclesにする。
3、RenderプロパティのDeviceを「GPU Compute」に設定する。
4、BakeパネルのBake Typeを列挙体の値によって変更する。列挙体は以下の通り。
class TextureMapType(Enum):
Albedo = 'Base Color'
Metallic = 'Metallic'
Roughness = 'Roughness'
Normal = 'Normal'
Albedo、Metallic、Roughnessの場合は「Emit」に設定。Normalの場合は「Normal」に設定。
5、Selected to Activeのチェックを入れる。
6、Cageのチェックを入れる。
7、Cage Objectにオブジェクトを設定。「現在アクティブ状態で選択されているオブジェクトの名前 + _Cage」という名前のオブジェクトを設定する。なければ、Cage Objectには何も設定せずに、Cage Extrutionの値を5cmにする。
8、Clear Imageのチェックをはずす。
9、Bakeボタンを押してテクスチャのベイクを始める。
10、ベイクが終わったら、その旨をprintで出力。

何度かエラーがあり修正されました。指示も若干修正しています。スクリプトに名前も付けてもらいました。

import bpy
from enum import Enum


class TextureMapType(Enum):
    Albedo = 'Base Color'
    Metallic = 'Metallic'
    Roughness = 'Roughness'
    Normal = 'Normal'


# 1. 複数のオブジェクトが選択されていることを確認
selected_objects = bpy.context.selected_objects
if len(selected_objects) < 2:
    raise ValueError("Error: Select at least two objects.")


# 2. RenderプロパティのRender EngineをCyclesに変更
render_engine = bpy.context.scene.render.engine
if render_engine != 'CYCLES':
    bpy.context.scene.render.engine = 'CYCLES'


# 3. RenderプロパティのDeviceを「GPU Compute」に設定する
bpy.context.preferences.addons['cycles'].preferences.get_devices()
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'CUDA'
bpy.context.scene.cycles.device = 'GPU'
bpy.context.scene.cycles.use_cuda = True


# 4. BakeパネルのBake Typeを列挙体の値によって変更する
bake_type = TextureMapType.Albedo  # 任意の列挙体の値を設定
if bake_type == TextureMapType.Albedo or bake_type == TextureMapType.Metallic or bake_type == TextureMapType.Roughness:
    bpy.context.scene.cycles.bake_type = 'EMIT'
elif bake_type == TextureMapType.Normal:
    bpy.context.scene.cycles.bake_type = 'NORMAL'


# 5. Selected to Activeのチェックを入れる
bpy.context.scene.render.bake.use_selected_to_active = True


# 6. Cageのチェックを入れる
bpy.context.scene.render.bake.use_cage = True


# 7. Cage Objectにオブジェクトを設定
cage_object_name = bpy.context.active_object.name + "_Cage"
cage_object = bpy.data.objects.get(cage_object_name)
if cage_object:
    bpy.context.scene.render.bake.cage_object = cage_object
else:
    bpy.context.scene.render.bake.use_cage = False
    bpy.context.scene.render.bake.cage_extrusion = 0.05


# 8. Clear Imageのチェックをはずす
bpy.context.scene.render.bake.use_clear = False


# 9. Bakeボタンを押してテクスチャのベイクを始める
bpy.ops.object.bake(type=bpy.context.scene.cycles.bake_type)


# 10. ベイクが終わったら、その旨をprintで出力
print("テクスチャのベイクが完了しました。")

Cubeを3つ作り「High」「Low」「Low_Cage」を名前をつけました。ベイク用にマテリアルを設定して、Lowがアクティブになるように、HighとLowを同時選択します。

テキストエディタの再生アイコンを押すと、テクスチャがベイクされました。

Renderプロパティの設定も正しく変更されています。

列挙体の値を変えるとノーマルマップもベイクできました。

bake_type = TextureMapType.Normal  # 任意の列挙体の値を設定
if bake_type == TextureMapType.Albedo or bake_type == TextureMapType.Metallic or bake_type == TextureMapType.Roughness:
    bpy.context.scene.cycles.bake_type = 'EMIT'
elif bake_type == TextureMapType.Normal:
    bpy.context.scene.cycles.bake_type = 'NORMAL'

エラーメッセージ

2つ以上のオブジェクトを選択していないときは、Infoエディタにエラーが表示されます。

GPUを使用

デバイスをCPUからGPUに変更する処理も何度か修正しました。GPUに設定できると、ベイクしている間、GPUメモリの使用量が上昇するようになりました。

print関数

システムコンソールにもメッセージが出力されています。

bpy.ops.object.bake関数

ベイクが終わったことをどうやって判定しているか質問すると説明してくれました。

bpy.ops.object.bake関数自体は非同期で実行されるため、直接的な終了の判定は提供されていません。しかし、ベイクが完了した後に実行されるコードブロックを追加することで、ベイクの完了を間接的に判定することができます。 以下に、スクリプトにベイク完了の判定と処理を追加した例を示します。
# 9. Bakeボタンを押してテクスチャのベイクを始める
bpy.ops.object.bake(type=bake_type.value)

# ベイク完了の判定と処理
while bpy.context.scene.render.bake.in_progress:
    pass  # ベイク中は待機

print("Bake completed.")
# ベイク完了後の追加処理をここに記述する

bakeメソッドの直前にprint文を入れると、再生アイコンを押してすぐに表示され、数秒後にベイク完了のテキストが表示されました。

print("テクスチャのベイクを開始")

# 9. Bakeボタンを押してテクスチャのベイクを始める
bpy.ops.object.bake(type=bpy.context.scene.cycles.bake_type)


# 10. ベイクが終わったら、その旨をprintで出力
print("テクスチャのベイクが完了しました。")

これで、Pythonスクリプトでベイクのための設定をして、自動でテクスチャのベイクができました。

コメントを残す

メールアドレスが公開されることはありません。