![見出し画像](https://assets.st-note.com/production/uploads/images/124863917/rectangle_large_type_2_da2b86f9321ea38d676697dac13394bd.png?width=1200)
【Blender】Pythonスクリプトでオブジェクトの作成や配置を行ってみる
KuMA Advent Calendar 2023 18日目の記事です.
BlenderでPythonスクリプトが使えるということは以前から知っていたのですが,使ったことがなかったので,ChatGPTに教えてもらいながら使ってみました.
使ったBlenderバージョンは2.83です.
Layout, Modelingとかのタブの一番右に「Scripting」がありました.いつも見てるのに知らなかったw
![](https://assets.st-note.com/img/1702838957951-Et1xJhRK1T.png?width=1200)
ChatGPTに書いてもらった,Cubeを2つ配置するシンプルなスクリプトです.新規→プログラムを入力して,実行ボタンを押してみます.
import bpy
from math import radians
# 新しいオブジェクトを作成して配置する関数
def create_object(name, location):
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=location)
obj = bpy.context.active_object
obj.name = name
return obj
# オブジェクトの作成と配置
obj1 = create_object("Cube1", (0, 0, 0))
obj2 = create_object("Cube2", (3, 3, 3))
# オブジェクトの回転
obj2.rotation_euler = (radians(45), radians(45), radians(45))
無事,オブジェクトをシーンに追加できました.
![](https://assets.st-note.com/img/1702838422944-cAGHqCPaBL.png?width=1200)
次は,星形を作ってみます.
import bpy
import bmesh
from math import sin, cos, pi
def create_star(name, radius_outer, radius_inner, num_points, location=(0,0,0)):
# 星のメッシュとオブジェクトを生成
mesh = bpy.data.meshes.new(name)
star_object = bpy.data.objects.new(name, mesh)
# オブジェクトをシーンにリンク
bpy.context.collection.objects.link(star_object)
bpy.context.view_layer.objects.active = star_object
star_object.select_set(True)
# メッシュの編集を開始
bm = bmesh.new()
# 星の頂点を生成
for i in range(num_points * 2):
angle = i * pi / num_points
if i % 2 == 0:
# 外側の頂点
vert = bm.verts.new((cos(angle) * radius_outer, sin(angle) * radius_outer, 0))
else:
# 内側の頂点
vert = bm.verts.new((cos(angle) * radius_inner, sin(angle) * radius_inner, 0))
# 頂点のルックアップテーブルを更新
bm.verts.ensure_lookup_table()
# 頂点をエッジで接続
for i in range(len(bm.verts)):
bm.edges.new((bm.verts[i], bm.verts[(i+1) % len(bm.verts)]))
# メッシュを閉じるためのフェイスを作成
bm.faces.new(bm.verts)
# メッシュを更新して頂点とエッジを確定
bm.to_mesh(mesh)
bm.free()
# オブジェクトを移動
star_object.location = location
# 星の設定
name = "Star"
radius_outer = 1.0 # 外側の半径
radius_inner = 0.5 # 内側の半径(外側の半径の約半分)
num_points = 5 # 星の角の数
location = (0, 0, 0) # 配置する場所
# 星を生成
create_star(name, radius_outer, radius_inner, num_points, location)
良い感じにできました.
こういう幾何学的な図形は,プログラムでも表現しやすくて,ChatGPTも得意そうです.
![](https://assets.st-note.com/img/1702838491414-kJ1zORpNyG.png?width=1200)
最後に,シーン中のオブジェクトをいじってみます.
前に作ったパピモッチを,たくさん増やすスクリプトをかいてもらいました.
![](https://assets.st-note.com/img/1702838549359-AugB1WXiAl.png?width=1200)
すでにある「Body」というオブジェクトを取得して,XY平面上にランダムに15個配置するスクリプトです.
import bpy
import random
# 既存の「Body」という名前のオブジェクトを取得
original_body = bpy.data.objects.get('Body')
# オブジェクトが見つからない場合は終了
if not original_body:
print("There is no object named 'Body' in the scene.")
else:
# 配置したいオブジェクトの数
number_of_copies = 15 # 必要な数に応じて変更してください
# 配置する範囲の指定(1メートル四方のスペースを考慮)
range_x = (-5, 5)
range_y = (-5, 5)
spacing = 0.5 # オブジェクト間の最小距離
# コピーを配置する前にリストを初期化
positions = []
# オブジェクトを指定された数だけコピーして配置
for i in range(number_of_copies):
attempt = 0
while attempt < 100:
# ランダムな位置を生成
loc_x = random.uniform(range_x[0] + spacing, range_x[1] - spacing)
loc_y = random.uniform(range_y[0] + spacing, range_y[1] - spacing)
loc_z = 0 # xy平面上に配置するため、z座標は0に
position = (loc_x, loc_y, loc_z)
# 他のオブジェクトと重ならないかをチェック
if all([((loc_x - pos[0])**2 + (loc_y - pos[1])**2)**0.5 > spacing for pos in positions]):
positions.append(position)
# オリジナルのオブジェクトをコピー
new_body = original_body.copy()
new_body.data = original_body.data.copy()
new_body.location = position
# Z軸に沿ったランダムな回転を加える
random_angle = random.uniform(0, 360)
new_body.rotation_euler[2] = random_angle
# 新しいオブジェクトをシーンにリンク
bpy.context.collection.objects.link(new_body)
break # 位置が決まったら次のオブジェクトに移る
attempt += 1
# オリジナルのオブジェクトは非表示にするか、必要に応じて削除
original_body.hide_viewport = True
original_body.hide_render = True
# 必要であれば、シーンを更新
bpy.context.view_layer.update()
実行したら,良い感じに配置できました!
パピモッチがたくさんでかわいいです.
![](https://assets.st-note.com/img/1702838685176-eTDoiRCN2F.png?width=1200)
大分満足したので,これで終わります.
前からBlenderのスクリプトを触ってみたかったので,試せてよかったです.
結構簡単で楽しかったです.
モデリングするときにスクリプトを上手に使えると,制作がはかどりそうだなと思いました.
ここまで読んでいただきありがとうございました.
いいなと思ったら応援しよう!
![T2](https://assets.st-note.com/production/uploads/images/8998924/profile_5ae1600285d2446495ba1e4cf3297726.jpg?width=600&crop=1:1,smart)