-Blender Python で剛体をいっぱい作成-

1. オブジェクトの配置

ここは、Python でスクリプトを組んで、オブジェクトの配置や増減を制御したいというときの、スクリプトの組み方のメモです。

■基本環境

とりあえず画面上のレイアウトをスクリプト作成のモードにします。
スクリプトを実行したときのメッセージやエラーは、基本的に上部のインフォ画面に出てくるのですが、
中にはシステムコンソールに出てくるエラーメッセージがあります。
ウィンドウズ版は、システムコンソールは最初は隠れているので、必要に応じて表示させておきます。

(DOS窓のような別ウィンドウが出てきます)
import bpy

for item in bpy.context.scene.objects:
    if item.type == 'MESH':
        bpy.context.scene.objects.unlink(item)
for item in bpy.data.objects:
    if item.type == 'MESH':
        bpy.data.objects.remove(item)
for item in bpy.data.meshes:
    bpy.data.meshes.remove(item)
for item in bpy.data.materials:
    bpy.data.materials.remove(item)
テキストエディタ上で新規テキストを作成します。
スクリプトを組んで、右下の Run Script ボタンを押すとスクリプトが実行されます。

import bpy によって、blenderを制御するために必要な一連のコマンドが読み込まれます。

左のスクリプトは、通常のオブジェクトを全部クリアするためのスクリプトです。
「スクリプトを実行するたびに、どんどんオブジェクトが追加で増えていく」
という事態を防ぐために、少なくとも練習中は最初にコピーしておいておくと良いでしょう。

■オブジェクト配置

オブジェクト(球)を2つ配置するスクリプトを組んでみます。

基本は球を配置するコマンドを2行です。
obj = []    
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions = 3, size = 0.5, location=(0,0,0))
obj.append(bpy.context.scene.objects.active)
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions = 3, size = 0.5, location=(1,0,0))
obj.append(bpy.context.scene.objects.active)

後で便利なように、最初に obj という空のリストを作成して
球を作るたびに、append で obj に追加しています。
(appendでは作成直後は球がアクティブ状態になることを利用しています)
import math
n = 12
r = 4
obj = []

for i in range(n):
    t = 2.0 * math.pi * i / n
    x = r * math.cos(t)
    y = r * math.sin(t)
    bpy.ops.mesh.primitive_ico_sphere_add(subdivisions = 3, size = 0.5, location=(x,y,0))
    obj.append(bpy.context.scene.objects.active)
    
bpy.context.scene.objects.active = obj[0]
bpy.ops.rigidbody.object_add()
発展としてループを使い複数の球を配置してみます。

最初の球に対して、剛体シミュレーションを ON にする操作を適用します。
今のところオブジェククトに対して直接操作するコマンドは存在せず、
対象のオブジェクトをアクティブにして、アクティブなオブジェクトに対して剛体を適用する

bpy.ops.rigidbody.object_add()

を使うしかないそうです。
アニメーションを再生(alt+A)すると、球がひとつ落下してゆくようになりました。

■キーフレーム配置

剛体に初速度を与えるためには、最初にアニメーションに従うようにして(animated)おきます。
最初のフレームと次のフレームで位置を設定して、その次のフレームでアニメーションをoffにして物理法則に従うようにすれば良いわけです。
3つのキーフレームを設定してみます。

※)GUI上では アニメーションに従うかどうかは animated と表記されていますが、実際の変数の名前は kinematic となっているので注意が必要です。

for i in range(n):
    t = 2.0 * math.pi * i / n
    x = 0.5 * r * math.cos(t)
    y = 0.5 * r * math.sin(t)
    bpy.ops.mesh.primitive_ico_sphere_add(subdivisions = 3, size = 0.5, location=(x,y,0))
    obj.append(bpy.context.scene.objects.active)
    bpy.ops.rigidbody.object_add()
    obj[i].rigid_body.kinematic = True
    
    bpy.context.scene.frame_set(1)
    obj[i].keyframe_insert( data_path='location' )
    obj[i].rigid_body.keyframe_insert( data_path='kinematic' )
    
    bpy.context.scene.frame_set(2)
    obj[i].location = (x*1.03, y*1.03, 0.1)
    obj[i].keyframe_insert( data_path='location' )
    
    bpy.context.scene.frame_set(3)
    obj[i].rigid_body.kinematic = False
    obj[i].rigid_body.keyframe_insert( data_path='kinematic' )
すべての球に対して、剛体を設定しました。

bpy.context.scene.frame_set() で時間を設定して、
位置や kinematicの値を設定します。

そして、キーフレームを打ちたい要素に対して、keyframe_insertを実行することで、キーフレームが打たれます。

床を設定して動かしてみます。

いったん元になるスクリプトさえ作ってしまえば、こういった式で書きやすい配置は、手動でオブジェクトを配置するよりずっと楽に配置することができます。
(初期速度の設定の仕方が、今一つ直感的ではないのが残念ですが…)

スクリプトダウンロード

inserted by FC2 system