LoginSignup
7
0

More than 1 year has passed since last update.

Blenderでの繰り返し作業をPythonで効率化する

Last updated at Posted at 2022-12-10

この記事の概要

Blenderの練習をしていて、こちらの動画を見つけました。

ピタゴラスイッチの「きょうのスレスレ」みたいで見ていて楽しく、難しい計算をせずとも作れるので面白かったです。
ただ、動画の5分頃から8分頃までで説明しているように、ひたすら人力でコピペを繰り返していたのでミスってしまいそうだなあと思いました。

というわけで、Pythonを使って自動化します。

この記事の内容で問題なく動作はするのですが、スピードが非常に遅いです。
高速化まで至れなかったのですが一旦記事にしました。

Scriptingの説明

Pythonを使う、といっても特別な準備が必要なわけではありません。
BlenderにはScriptingという機能があるので簡単に始められます。

普段よく使うのはLayoutタブなどだと思いますが、Scriptingタブを選ぶとText EditorやConsoleが表示されます。
ウインドウ右側の、緑で囲ったエリアにコードを書いて実行します。

Layoutタブの表示 Scriptingタブの表示

環境

Blender 3.3.1
Python (Blender内のもの) 3.10

完成形

最初に完成形を示します。

import bpy

pole = bpy.data.objects['Pole']
wall = bpy.data.objects['Wall']

start_frame = 129
end_frame = 233

def apply_boolean(object1, object2):
    boolean = object1.modifiers.new(type="BOOLEAN", name="Boolean")
    boolean.operation = 'DIFFERENCE'
    boolean.object = object2
    bpy.ops.object.modifier_apply(modifier="Boolean")

bpy.context.scene.frame_set(start_frame)

for i in range(start_frame, end_frame + 1):
    bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1)
    apply_boolean(wall, pole)

bpyというモジュールが用意されていて、この中に色々なメソッドが用意されています。

import bpy

今回でいうと、スレスレで通る棒をPoleと名付けて、壁をWallと名付けています。
自分の名付けた通りに指定します。

pole = bpy.data.objects['Pole']
wall = bpy.data.objects['Wall']

壁に棒が触れるタイミングが129フレーム目で、完全に通り終わるのが233フレーム目だったのでここで定義しています。
アニメーションの長さや回転スピード、メッシュの配置で変わってきます。

start_frame = 129
end_frame = 233

今回のキモです。

  • object1object2を引数にとる関数
    • object1にBooleanモディファイアを追加
    • 棒で壁をくり抜きたいので、Intersect, Union, Differenceのうち、Differenceを指定
    • object2をBoolean対象に指定
    • object1のモディファイアを適用
def apply_boolean(object1, object2):
    boolean = object1.modifiers.new(type="BOOLEAN", name="Boolean")
    boolean.object = object2
    boolean.operation = 'DIFFERENCE'
    bpy.ops.object.modifier_apply(modifier="Boolean")

フレームをstart_frameにあわせます。
手動で合わせても大して手間は変わりませんが、念の為。

bpy.context.scene.frame_set(start_frame)

start_frameから1フレームずつ進めて、その度にモディファイアを作成→適用を繰り返します。

for i in range(start_frame, end_frame + 1):
    bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1)
    apply_boolean(wall, pole)

最後に

これにて無事にアニメーションが作成できました。

記事冒頭にも書きましたが、処理スピードが速くなるともっと気楽に使えるのですが……。
とりあえず、コードによりミスがなくなったという意味で良しとします。


最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!

Devトークでのお話してくださる方も募集中です!

7
0
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
7
0