Open6
[メモ]blender python apiを使ったクリエイティブコーディングの練習
ほぼ毎回わすれるのでメモ。
blender ver3.6.
ランダムに立方体配置
ランダムに立方体を配置する。
import bpy
import os
import sys
import argparse
import addon_utils
import random
# 立方体のサイズ
cube_size = 1.0
# 生成する立方体の数
num_cubes = 10
# ランダムな位置と回転を取得するための関数
def get_random_transform():
# 位置
location = (
random.uniform(-10.0, 10.0),
random.uniform(-10.0, 10.0),
random.uniform(-10.0, 10.0),
)
# 回転
rotation = (
random.uniform(-180.0, 180.0),
random.uniform(-180.0, 180.0),
random.uniform(-180.0, 180.0),
)
return location, rotation
# 立方体を生成する
for i in range(num_cubes):
# ランダムな位置と回転を取得
location, rotation = get_random_transform()
# 立方体を作成
bpy.ops.mesh.primitive_cube_add(size=cube_size, location=location, rotation=rotation)
# オブジェクトを選択
bpy.ops.object.select_all(action='SELECT')
# ビューポートを更新
bpy.context.view_layer.update()
ランダムに生成するときはimport random
しないとエラー。
bpy.ops.mesh.primitive_cube_add
関数でメッシュを新規作成できる。
アニメーションを自動作成したい
先ほど作成したランダムな立方体をつかって、アニメーションのキーフレームを自動で生成してほしい。
import bpy
#目標の座標を指定する
positions = ((0, 3, 2), (4, 1, 6), (3, -5, 1), (3, 10, 1), (1, 8, 1))
#(0,3,2),(4,1,6),(3,-5,1),(3,10,1),(1,8,1)
#開始時の座標を指定する
start_pos = (0,0,0)
#変数obに3D viewportにあるオブジェクトを代入する
#ob = bpy.data.objects["Cube"]のようにして特定のものを動かすことも可能
def set_frame(ob):
#開始のフレームを指定する
frame_num = 0
#目標の座標に移動する処理を繰り返す
for p in positions:
#開始のフレームを設定する
bpy.context.scene.frame_set(frame_num)
#変数locationに目標の座標の値を代入する
ob.location = p
#キーフレームの挿入を行う
ob.keyframe_insert(data_path = "location",index = -1)
#フレームを20ずらす
frame_num += 20
# シーン内のすべてのオブジェクトを取得
objects = bpy.data.objects
# オブジェクトをループ処理
for obj in objects:
# オブジェクトの種類が立方体の場合は選択
if obj.type == 'MESH' :#$and re.search(r'Cube$', obj.name):
ob = bpy.data.objects[obj.name]
set_frame(ob)
なんでか知らないが、re.searchを使ったパターンはうまくいかなかった。
今回は立方体しかmeshがないのでいったんこれで進める。
アニメーションの作成参考:
print文はpython consoleや情報タブではなく、システムコンソールから出力されてる。
立方体の自動配置からキーフレーム自動生成まで
クリエイティブコーディングをしたい。
グリッド上に立方体を配置してサインカーブで上下させたい。
import bpy
import math
def frame_scale():
# シーン内のすべてのオブジェクトを取得
objects = bpy.data.objects
# オブジェクトをループ処理
count = 0
for obj in objects:
# オブジェクトの種類が立方体の場合は選択
if obj.type == 'MESH':
ob = bpy.data.objects[obj.name]
set_frame(ob,count)
count += 1
#変数obに3D viewportにあるオブジェクトを代入する
#ob = bpy.data.objects["Cube"]のようにして特定のものを動かすことも可能
def set_frame(ob,count):
#開始のフレームを指定する
frame_num = 0
positions = [(ob.location.x, ob.location.y, math.sin(n+count)) for n in range(12)]
#目標の座標に移動する処理を繰り返す
for p in positions:
#開始のフレームを設定する
bpy.context.scene.frame_set(frame_num)
#変数locationに目標の座標の値を代入する
ob.location = p
#キーフレームの挿入を行う
ob.keyframe_insert(data_path = "location",index = -1)
#フレームを20ずらす
frame_num += 20
def cube_add():
num = 10
# 立方体を生成する
for i in range(num):
for j in range(num):
location = (i+0.5*i,j+0.5*j,0)
rotation = (0,0,0)
# 立方体を作成
bpy.ops.mesh.primitive_cube_add(size=1.0, location=location, rotation=rotation)
cube_add()
frame_scale()
とりあえずできた。
ランダムにオブジェクトにカラーを設定したい
まずはマテリアルの種類を取得できるようにする。
import bpy
import math
# シーンすべてのマテリアルを取得
def frame_scale():
objects = bpy.data.materials
mats = list()
for obj in objects:
if obj.name != 'Dots Stroke':
mats.append(obj.name)
frame_scale()
次に前書いたコードの次に動かせるよう調整する。
import bpy
import math
import random
# シーンすべてのマテリアルを取得
def frame_scale():
objects = bpy.data.materials
mats = list()
for obj in objects:
if obj.name != 'Dots Stroke':
mats.append(obj.name)
objects = bpy.data.objects
for obj in objects:
# オブジェクトの種類が立方体の場合は選択
if obj.type == 'MESH':
ob = bpy.data.objects[obj.name]
rand = random.randint(0,len(mats)-1)
print(rand)
ob.data.materials.append(bpy.data.materials[mats[rand]])
frame_scale()
謎に'Dots Stroke'なるマテリアルが存在していたので排除した。
上記コードで一応マテリアル自動付与できるけど、なぜかvalue errorをはく。
最終的にはこんな感じにできた。