芋出し画像

blender 4.4 Python を䜿っおみよう

blender は python むンタプリタを内蔵しおいるので、モデリングなどの操䜜をほがすべお python によるスクリプトでも実行するこずができたす。
ここでは、おもに python を含むプログラミング蚀語のごく初心者に向けお、最䜎限の知識ず、かんたんな応甚䟋を玹介したす。


環境 Blender 4.4.1 , Mac Mini M1 OS 14.4



なぜ Python 


blender の操䜜だけでもじゅうぶんややこしいのに、そのうえプログラミングなんおムリだ、ず思われる方も倚いだろう。たしかにプログラムにはそれなりの孊習コストがかかるこずは明らかだが、近幎、AI の普及によっお、以前よりもすこし意味合いが異なっおきおいる。プログラムそのものは、ChatGPT などの AI に曞いおもらえばよいのだ。

ただし、AI に曞いおもらったプログラムの内容を「おがろげながら」でも理解できるだけの知識はやはり必芁で、ここでは、そのためのごく基本知識のいく぀かを玹介しおみたい。

たた、3D オブゞェクトの操䜜によるビゞュアルな効果をすぐに確認できるずいう点で、これから Python を孊習しおみたい、ずいうプログラミング初心者にも実は blender は最適のツヌルのひず぀だず思う。ずもかく、すこし觊っおみよう。


Scripting


デフォルトのシヌンで、Scripting タブをクリックし、Scripting ワヌクスペヌスに切り替える。

巊偎のりィンドりは、䞊は 3D ビュヌポヌト、Python コン゜ヌル、情報りィンドり で、右偎はテキスト゚ディタヌだ。基本的には、テキスト゚ディタヌでプログラムを蚘述し、その実行結果を 3D ビュヌポヌト で確認する、ずいう流れになる。

基瀎だけでも Pyhon の抂芁を理解しおおきたい、ずいう堎合は、巊䞭段の Pyhon コン゜ヌル でかんたんなプログラムも実行できる。
Pyhon公匏チュヌトリアル - 3. 圢匏ばらない Python の玹介

Python のプロンプト実行文を盎接入力しお、実行できる。


基本セットアップ


  • テキスト゚ディタヌの New新芏を抌し、テキストを䜜成

  • Textテキスト > Save保存で、ファむルずしお保存する

ここでは、保存ファむル名は、myFirst.py ずした。
  • テキスト゚ディタヌに、import bpy ず入力する

bpy は blender の Python 甚ラむブラリ拡匵機胜のこずで、これをむンポヌトしないず、blender での操䜜が行えない。

  • 3D ビュヌポヌトで、A キヌを抌し、オブゞェクトを党遞択

  • X キヌを抌し、すべおを削陀する

巊䞋の情報りィンドりに、䞊で行った操䜜の実行文が衚瀺される。

  • コピヌし 、テキスト゚ディタヌ䞊ぞペヌストする

3D ビュヌポヌトでなんらかの操䜜を行うず、それに察応する Python 実行文が衚瀺される。コピペできるので䟿利だ。

埌述のように、スクリプトでオブゞェクトを加える操䜜を行うず、既存のオブゞェクトの䞊に加えられるので、ここでは、ビュヌポヌト䞊の既存のオブゞェクトを、スクリプトを実行するたびに、最初に党削陀されるようにしおいる。

  • デフォルトの立方䜓オブゞェクトを远加し、同様に、実行文をコピペする

スクリプト党䜓は以䞋のようになる。

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), scale=(1, 1, 1))

立方䜓を加える実行文は、必芁な情報のみをピックアップし修正した。

実行ボタンを抌しお、スクリプトを実行

この堎合、みためは倉わらないが、スクリプトに蚘述されたこれたでの操䜜が再珟されおいる。

たずえば、䞊の、bpy.ops.object.delete(
) のような実行文は、bbyblender拡匵ラむブラリのなかの、opsoperations、操䜜、object カテゎリのなかの、delete ずいう呜什関数を実行しなさい、ずいう意味になる。blender 甚の実行文はほがすべおこの圢匏なので、おがえおおこう。

このように、Python では、通垞、テキスト゚ディタヌに呜什文を蚘述し、それに察応した 3D ビュヌポヌトでの結果を確認する、ずいう流れになる。ファむルに保存しおいるので、埌にい぀でも開いお実行するこずができ、䞊の操䜜だけでも、䞀皮のマクロスクリプトずしおも䜿える。



Python の基瀎


もちろん Python を始めプログラミング蚀語には、倚数の抂念や呜什文があるが、ここでは、これだけを抑えおおけば圓座はなんずかなる、ずいう、4 ぀の基瀎、倉数、繰り返し、分岐、関数、を玹介する。

Variable - 倉数


倉数は、数倀や文字列などのデヌタを入れおおくための箱のような存圚で、䟋倖はあるが、い぀でもその箱のなかみを倉曎したり、取り出しお利甚するこずができる。

v = 5
t = "Hello"

v ずいう倉数箱に、5 を入れる。
t ずいう倉数に「Hello」ずいう文字列を入れる。

v = 5
v = v + 10

䞊の堎合、1 行目では、v には 5 が入り、2 行目では、5 + 10 の 15 が入る。

むコヌルずいうよりは、v ← 5 , v ← v + 10 のように、右から巊ぞの矢印を考えるずわかりやすい。

䞊の、myFirst.py の蚘述を以䞋のように倉曎しおみる。

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), scale=(1, 1, 1))
a = 4
bpy.ops.mesh.primitive_cube_add(location=(a, 0, 0), scale=(1, 1, 1))
a = a + 4
bpy.ops.mesh.primitive_cube_add(location=(a, 0, 0), scale=(1, 1, 1))

2、3 番目の立方䜓远加行には、location の x 軞の倀に、倉数 a を指定しおいる。このため、2 番目の立方䜓の x 䜍眮は、4 が、3 番目の立方䜓の x 䜍眮は、8 が適甚される。

実行結果


Loop - 繰り返し


䞊のように、同じ操䜜立方䜓を远加するを、䜕回か繰り返したい堎合、for 文によるルヌプがスマヌトな方法で、プログラミング蚀語の基本のひず぀だ。

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

for i in range(1 , 5):
    a = i * 4
    bpy.ops.mesh.primitive_cube_add(location=(a, 0, 0), scale=(1, 1, 1))

䞊の䟋では、for(range)文で、1 〜 4 たでの繰り返しを行っおいる。繰り返しの回数は i 倉数に入るので、4倍しお a 倉数に入れ、立方䜓の x 䜍眮に適甚しおいる。なお、繰り返したい文は、tab キヌで字䞋げする

実行結果 4 個の x 䜍眮の異なる立方䜓が䜜成された。
import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

for i in range(1 , 5):
    a = i * 4
    bpy.ops.mesh.primitive_cube_add(location=(a, 0, 0), scale=(1, i, i))

さらに、繰り返しの i を、立方䜓の scaleスケヌルの、y および z に適甚

結果 繰り返しの数が倧きい立方䜓ほどスケヌルが倧きくなる。

配列モディファむアのような操䜜だが、もちろん、応甚範囲は広い。


if - 分岐


プログラミング蚀語の基本のひず぀で、もし 
 ならば、  をしなさい、ずいう操䜜になる。

たずえば、䞊の繰り返しを䜿ったスクリプト

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

for i in range(1 , 10):    
    bpy.ops.mesh.primitive_cube_add(rotation=(0, 0, 0), location=(0, 0, i), scale=(2, 2, 0.1))

z 軞に平たくした立方䜓を 䞋から䞊ぞ、9 個䞊べおいる。なお、次で䜿甚するために、立方䜓の回転を指定する rotation 属性を加えおいる。

実行結果

たずえば、もし、繰り返しの数が 5 より倧きいならば䞊半分の立方䜓、z 軞に 箄 45床の回転を䞎えたい堎合。

import bpy

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

for i in range(1 , 10):
    r = 0
    
    if i > 5:
        r = 0.78
    bpy.ops.mesh.primitive_cube_add(rotation=(0, 0, r), location=(0, 0, i), scale=(2, 2, 0.1))

回転倀 r はデフォルトでれロだが、もし i が 5 より倧きいならば、r は 0.57 ずし、立方䜓の rotationの z 軞に䞎えおいる。

結果。䞊半分の 4 立方䜓のみ、z 軞に 箄 45 床回転しおいる。

ちなみに、ランダムに 45床以内で、回転するパタヌン。

import bpy
import random

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

for i in range(1 , 10):
    r = random.uniform(0, 0.57)
    bpy.ops.mesh.primitive_cube_add(rotation=(0, 0, r), location=(0, 0, i), scale=(2, 2, 0.1))

random 関数を䜿甚するには、random 拡匵機胜を import2行目する。

結果

プログラムは、おおよそ、繰り返しず分岐でできおいる、ずいっおも過蚀ではないず思う。



Function - 関数


関数は、なんらかの倀を䞎えられるず、関数内の操䜜に察応した倀を出力したり、凊理を行う機胜。スクリプト内で頻出する凊理をたずめる際に䟿利だ。

たずえば、䞊の凊理にあるように、Python で䜿われる回転の単䜍は、通垞の床degreeではなく、ラゞアンradianになる。人間的にはすこしわかりづらいので、床による倀を、ラゞアンに倉換するかんたんな関数を曞いおみよう。

def toRadian(degree):
    return degree * ( math.pi / 180)

床をラゞアンに倉換するには、degree x (PI / 180) ずいう匏なので、䞊の関数 toRadian では、床degreeが䞎えられるずその匏で蚈算されたラゞアン倀を返す。たずえば、toRadian(90)ならば、1.5707 ずいう倀が出力される。

import bpy
import math

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

def toRadian(degree):
    return degree * ( math.pi / 180)


for i in range(1 , 19):
    bpy.ops.mesh.primitive_cube_add(rotation=(0, 0, toRadian(i * 10)), location=(0, 0, i), scale=(2, 2, 0.1))
   

繰り返しの数1 〜 18によっお、その 10 倍の 10 〜 180床の回転を、toRadian関数でラゞアンに倉換しお䞎えた。

実行結果。立方䜓が 10 床づ぀回転しおいる



AI ずの連携


もちろん、さらに Python を孊習しお、より進んだ blender の操䜜を行うこずもできるが、近幎、AI の登堎により、ChatGPTなどの AI ず連携する方法も出おきた。

たずえば、10 個のオブゞェクトにランダムなカラヌを割り圓おたい堎合、シェヌダヌ偎で䞋のノヌドを蚭定するこずで実珟できる。

たた、単䜓のオブゞェクトで、同様に 10 個の球で構成されおいる堎合、cycles ならば䞋のシェヌダヌノヌドでランダムカラヌが実珟できるが、EEVEE では察応しおいない。

cycles レンダヌプレビュヌ

そこで、EEVEE でも同様の機胜を実珟するための python スクリプトを曞きたいが、やや荷が重いため、ChatGPT に曞いおもらった。

「ひず぀のオブゞェクト内の構造的に分離したパヌツそれぞれにランダムなカラヌを割り圓おるblender のスクリプトを曞いおください」
Can you write a script which set different random color to each loose parts in a object of blender?

import bpy
import bmesh
import random
import mathutils

# Ensure an object is selected and in object mode
obj = bpy.context.object
if obj is None or obj.type != 'MESH':
    raise Exception("Please select a mesh object.")

# Duplicate the original object (optional for safety)
bpy.ops.object.duplicate()
obj = bpy.context.object
obj.name = "ColoredLooseParts"

# Go to edit mode to separate loose parts
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.mode_set(mode='OBJECT')

# Get new separated objects
parts = bpy.context.selected_objects

# Function to create a random material
def create_random_material(name):
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    bsdf = mat.node_tree.nodes.get("Principled BSDF")
    if bsdf:
        bsdf.inputs['Base Color'].default_value = [random.random(), random.random(), random.random(), 1]
        color_obj = mathutils.Color()
        color_obj.hsv = (random.random(), 1, 1)
    return mat

# Assign random materials to each loose part
for i, part in enumerate(parts):
    mat = create_random_material(f"RandomColor_{i}")
    if part.data.materials:
        part.data.materials[0] = mat
    else:
        part.data.materials.append(mat)

# Optional: join all parts back together
bpy.context.view_layer.objects.active = parts[0]
bpy.ops.object.join()

print(f"{len(parts)} loose parts found and colored.")

すこし長いが、基本的にこれたでに玹介した、倉数、繰り返し、分岐、関数のみでできおいるこずがわかる。詳现はよくわからないずしおも、「おがろげながら」各行でなにを行っおいるのか理解できるだろう。

オブゞェクトを遞択し、スクリプト実行。EEVEE レンダヌプレビュヌ

やや各色圩が淡めに蚭定されるので、プロンプトを倉曎。

「ひず぀のオブゞェクト内の構造的に分離したパヌツそれぞれに、HSV カラヌのランダムな色盞を割り圓おるblender のスクリプトを曞いおください」
Can you write a script which set different random hue of HSV color to each loose parts in a object of blender?

import bpy
import bmesh
import random
from mathutils import Color

def assign_random_hue_materials_to_loose_parts(obj):
    # Make sure we're in Object mode
    if bpy.context.object.mode != 'OBJECT':
        bpy.ops.object.mode_set(mode='OBJECT')

    # Duplicate object to work on mesh data without affecting original
    bpy.ops.object.duplicate()
    dup_obj = bpy.context.active_object
    bpy.ops.object.convert(target='MESH')

    # Enter Edit mode to separate loose parts
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.mesh.separate(type='LOOSE')
    bpy.ops.object.mode_set(mode='OBJECT')

    # Delete the original duplicated object
    bpy.data.objects.remove(dup_obj, do_unlink=True)

    # Get new objects (the separated parts)
    parts = [obj for obj in bpy.context.selected_objects if obj.type == 'MESH']

    for part in parts:
        # Generate random hue
        hue = random.random()
        color = Color()
        color.hsv = (hue, 1, 1)

        # Create a new material
        mat = bpy.data.materials.new(name=f"RandomColor_{hue:.2f}")
        mat.use_nodes = True
        bsdf = mat.node_tree.nodes.get("Principled BSDF")
        if bsdf:
            bsdf.inputs["Base Color"].default_value = (color.r, color.g, color.b, 1.0)

        # Assign the material to the object
        if len(part.data.materials) > 0:
            part.data.materials[0] = mat
        else:
            part.data.materials.append(mat)
            
    # Optional: join all parts back together
    bpy.context.view_layer.objects.active = parts[0]
    bpy.ops.object.join()

# Make sure an object is selected
if bpy.context.object and bpy.context.object.type == 'MESH':
    assign_random_hue_materials_to_loose_parts(bpy.context.object)
else:
    print("Please select a mesh object.")

生成されたスクリプトを若干倉曎し、実行。

オブゞェクトを遞択し、スクリプト実行。

ひずむかしたえなら、自力でいちから曞かなければならなかった。䟿利な䞖の䞭だ。


たずめ


このように、Python による操䜜によっお、モディファむアやゞオメトリノヌドでは実珟がむ぀かしいモデリングやマテリアルの操䜜等が、ずくに AI ずの連携を図るこずで、比范的容易に実珟できるこずがわかりたす。

ある意味、AI に䞊手に意図を䌝えるこずで、自分だけのオヌダヌメむドのアドオンを手軜に䜜れるずいうこずにもなりたす。実際、配垃されおいるアドオンは Python で䜜られおいたす

ただその際も、Python のごく基本的な知識があるず、デバッグや必芁なカスタマむズも可胜で、応甚の幅が広がりたす。䞀皮のホビヌずしおもずおもおもしろいツヌルです。ぜひいちどトラむしおみおください。参考たで。


䞭孊生のころ、はじめお BASIC ずいうプログラミング蚀語を習ったずき、A = A + 5 ずいう呜什文を最初は理解できたせんでした。たずえば、A が 3 ならば、3 = 8 っおおかしいじゃないか、ず。  しかしたあ、思えば遠い昔のこずになりたした。そのころはただ、未来は SF 的に明るい、ず信じおおりたした。

いいなず思ったら応揎しよう