【注目】Creality初のマルチカラー3Dプリンター「K2 Plus Combo」がついに正式発売!(詳細をチェック!)

【コピペ可能】BlenderとPythonを使って簡単に物理シミュレーションを実行してみよう!【バージョン4以降対応】

〜景品表示法に基づく表記:本サイトのコンテンツにはプロモーションが含まれている場合があります〜

こんにちは、管理人のウノケンです。

今回は、Blender Python APIで物理演算を実行する方法について解説していきます。

Blenderは、3Dモデリングやアニメーション制作などに利用されるオープンソースの3Dアプリケーションです。Pythonとの親和性も高く、うまく使いこなすことができれば手作業による面倒な反復作業を自動化することが可能です。

この記事では、Pythonスクリプトを使ったBlenderの操作について、「物理演算」にフォーカスして解説していきます。3Dモデリング初心者の方や、Pythonになじみのない方でもコピペで操作を実行することができるので、ぜひ自分でも操作して自動化の利便性を感じてみてください。

なお、Blender Python APIについての解説や、Pythonスクリプトを使ったBlenderの基本操作については以下の記事で解説しています。

【2024最新】コピペ可能!Blenderによる3DモデリングをPythonで自動化する方法【バージョン4対応】
今回はBlenderをPythonで簡単に操作する方法について、画像を豊富に用いて初心者向けに解説していきます。紹介しているスクリプトの例は、3Dモデリング初心者の方や、Pythonになじみのない方でもコピペで操作を実行することが可能です。ぜひ自分でも操作して自動化の利便性を感じてみてください。

それでは見ていきましょう!

この記事に記載の内容は最新(2024年8月時点)のBlender4.2以降に対応します。以下に記載のPythonスクリプトは、すべてバージョン4.2で機能することを確認しています。


YouTubeでも動画でわかりやすく解説しています!

この記事の内容は、YouTubeでより詳しく解説しています。記事とあわせて活用してみてください。




Blender Python APIを使った物理演算モディファイアの設定

Blenderには様々な物理演算モディファイアが存在します。ここでは、主要な物理演算モディファイアとその基本的な使用方法について、Blender Python APIを使ったスクリプトと共に解説します。

クロス(Cloth)

クロス(Cloth)モディファイアは、布や衣服の動きをシミュレートするために使用されます。風や重力などの外部要因によって影響を受ける物体に適用できます。

import bpy

cloth_mod = obj.modifiers.new("Cloth", 'CLOTH')

このモディファイアを使ったデモンストレーションについては【デモ1】をご覧ください。

以降のスクリプトではbpyモジュールのインポートに関する記述(import bpy)を省略します。

コリジョン(Collision)

コリジョン(Collision)モディファイアは、オブジェクト同士の衝突をシミュレートするために使用されます。これにより、オブジェクトが互いに影響を与えることができます。

collision_mod = obj.modifiers.new("Collision", 'COLLISION')

このモディファイアを使ったデモンストレーションについては【デモ1】をご覧ください。

ダイナミックペイント(Dynamic Paint)

ダイナミックペイント(Dynamic Paint)モディファイアは、オブジェクトが互いに接触することで色や形状の変化をシミュレートするために使用されます。湿った足跡やペイントの跡を表現するのに適しています。

dynamic_paint_mod = obj.modifiers.new("DynamicPaint", 'DYNAMIC_PAINT')

爆発(Explode)

爆発(Explode)モディファイアは、オブジェクトを小さな破片に分解し、それらを爆発させる効果をシミュレートするために使用されます。壊れるガラスや爆発するオブジェクトの表現に適しています。

explode_mod = obj.modifiers.new("Explode", 'EXPLODE')

このモディファイアを使ったデモンストレーションについては【デモ2】をご覧ください。

流体(Fluid)

流体(Fluid)モディファイアは、液体や気体の流れをシミュレートするために使用されます。水や煙などの動きを再現できます。

fluid_mod = obj.modifiers.new("Fluid", 'FLUID')

このモディファイアを使ったデモンストレーションについては【デモ3】をご覧ください。

海洋(Ocean)

海洋(Ocean)モディファイアは、海や大きな水面の波動をシミュレートするために使用されます。現実的な水の動きを表現するのに適しています。

ocean_mod = obj.modifiers.new("Ocean", 'OCEAN')

このモディファイアを使ったデモンストレーションについては【デモ4】をご覧ください。

パーティクルシステム(Particle System)

パーティクルシステム(Particle System)モディファイアは、大量のパーティクルを生成し、それらの動きを制御するために使用されます。雨や炎、髪の毛などの表現に適用できます。

particle_system = obj.modifiers.new("ParticleSystem", 'PARTICLE_SYSTEM')

このモディファイアを使ったデモンストレーションについては【デモ2】をご覧ください。

パーティクルインスタンス(Particle Instance)

パーティクルインスタンス(Particle Instance)モディファイアは、パーティクルシステムに基づいてオブジェクトを複製するために使用されます。大量のオブジェクトを効率的に配置するのに適しています。

particle_instance_mod = obj.modifiers.new("ParticleInstance", 'PARTICLE_INSTANCE')

ソフトボディ(Soft Body)

ソフトボディ(Soft Body)モディファイアは、柔らかい物体の動きをシミュレートするために使用されます。布やゼリーのような柔らかさを持つオブジェクトに適用できます。

soft_body_mod = obj.modifiers.new("SoftBody", 'SOFT_BODY')

このモディファイアを使ったデモンストレーションについては【デモ5】をご覧ください。

 



【コピペ可】BlenderとPythonを使った物理シミュレーションのデモ5選

ここからは、より実践的な物理演算モディファイアーの使い方について、実例を交えながら確認していきましょう。

コピペ可能なコードと、どのように動作するのかを示す動画と共に解説していきます。

【準備】物理演算シミュレーションの実行方法

まずは、物理演算シミュレーション(アニメーション)の実行方法について確認しておきましょう。

物理演算の設定が完了したら、以下の手順でシミュレーションを実行できます。

  1. タイムラインウィンドウで、フレームを1に戻します。これにより、シミュレーションが開始時点から実行されるようになります。ちなみに、後述するPythonスクリプトにおいては、bpy.context.scene.frame_set(1)で設定することができます。
  2. シミュレーションを実行するには、タイムラインウィンドウの再生ボタンを押すか、ビューポートで スペースキーを押して再生します。進行中のシミュレーションは、ビューポートでリアルタイムに観察することができます。
  3. シミュレーションを停止するには、タイムラインウィンドウの停止ボタンを押すか、ビューポートでスペースキーをもう一度押してください。
  4. シミュレーション結果を確認し、必要に応じて設定を調整して再度実行します。シミュレーションの設定を変更した場合は、手順1に戻ってフレームを1に戻してから再度実行してください。

シミュレーションが終了したら、結果をレンダリングして動画や静止画として出力することができます。レンダリング設定は、プロパティウィンドウの「レンダリング」タブで行います。

【デモ1】「クロス」「コリジョン」を使ったスクリプト【コピペ可能】

このスクリプトでは、平面メッシュを追加し、それにクロスモディファイアを適用して布のような動きをシミュレートします。同時に、UV球にコリジョンモディファイアを設定しています。

import bpy

# 平面メッシュを追加
bpy.ops.mesh.primitive_plane_add(size=4, location=(0, 0, 1))
plane = bpy.context.active_object
plane.name = "Cloth"

# 高密度のメッシュに変換
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.subdivide(number_cuts=30)
bpy.ops.object.mode_set(mode='OBJECT')

# クロスモディファイアを追加
cloth_mod = plane.modifiers.new("Cloth", 'CLOTH')
cloth_mod.settings.use_dynamic_mesh = True
cloth_mod.settings.pin_stiffness = 1.0

# 頂点グループを作成し、上端の頂点をアサイン
plane.vertex_groups.new(name="PinGroup")
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')

for vertex in plane.data.vertices:
    if vertex.co.z > 1.95:
        vertex.select = True
        plane.vertex_groups["PinGroup"].add([vertex.index], 1.0, 'REPLACE')

# クロスモディファイアのピン設定を更新
cloth_mod.settings.vertex_group_mass = "PinGroup"

# コリジョンオブジェクトを追加(球)
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, -1))
sphere = bpy.context.active_object
sphere.name = "CollisionSphere"

collision_mod = sphere.modifiers.new("Collision", 'COLLISION')

# シミュレーションを実行
bpy.context.scene.frame_set(1)
bpy.ops.screen.animation_play()

このスクリプトでは、平面メッシュを追加し、高密度のメッシュに変換して布の動きをよりリアルに表現します。また、上端の頂点をピンを設定し、下に吊るされた布のように動作させます。さらに、球形のコリジョンオブジェクトを追加し、布がそれに接触するようにします。

このスクリプトを実行すると、布の動きをシミュレートし、球とのコリジョンが確認できます。

【デモ2】「爆発」「パーティクルシステム」を使ったスクリプト【コピペ可能】

続いて、爆発とパーティクルシステムを使ったデモンストレーションを行っていきます。

import bpy

# 球体を追加
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 1))
sphere = bpy.context.active_object
sphere.name = "Sphere"

# 球体にパーティクルシステムを追加
bpy.ops.object.particle_system_add()
particle_system = sphere.particle_systems[0]
particle_settings = particle_system.settings

# パーティクルシステムの設定
particle_settings.type = 'EMITTER'
particle_settings.count = 2000
particle_settings.frame_start = 1
particle_settings.frame_end = 10
particle_settings.lifetime = 50
particle_settings.emit_from = 'FACE'
particle_settings.physics_type = 'NEWTON'
particle_settings.mass = 0.1
particle_settings.normal_factor = 10

# Explodeモディファイアを追加
explode_mod = sphere.modifiers.new(name="Explode", type="EXPLODE")
explode_mod.use_edge_cut = True
explode_mod.show_unborn = False
explode_mod.show_alive = True
explode_mod.show_dead = True
explode_mod.particle_uv = "UVMap"

# アニメーションを開始
bpy.context.scene.frame_set(1)
bpy.ops.screen.animation_play()

このスクリプトでは、まず球体を作成し、その表面から粒子を放出するように設定します。次に、Explodeモディファイアを追加して、粒子に応じてオブジェクトを破片に分解します。アニメーションを再生すると、爆発エフェクトが確認できます。

【デモ3】「流体」を使ったスクリプト【コピペ可能】

流体モディファイアを使ったデモンストレーションも見ていきます。

以下のスクリプトでは、まずドメインオブジェクト(シミュレーション空間を定義するオブジェクト)と流体オブジェクト(流体を放出するオブジェクト)を作成します。その後、両方のオブジェクトにFluidモディファイアを追加し、ドメインと流体の設定を行います。

import bpy

# ドメインオブジェクトを追加
bpy.ops.mesh.primitive_cube_add(size=6, location=(0, 0, 3))
domain = bpy.context.active_object
domain.name = "FluidDomain"

# ドメインオブジェクトにFluidモディファイアを追加して設定
domain_mod = domain.modifiers.new(name="FluidDomain", type="FLUID")
domain_mod.fluid_type = "DOMAIN"
domain_mod.domain_settings.domain_type = "LIQUID"

# 流体オブジェクトを追加
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 5))
fluid_obj = bpy.context.active_object
fluid_obj.name = "FluidObj"

# 流体オブジェクトにFluidモディファイアを追加して設定
fluid_mod = fluid_obj.modifiers.new(name="FluidObj", type="FLUID")
fluid_mod.fluid_type = "FLOW"
fluid_mod.flow_settings.flow_type = "LIQUID"
fluid_mod.flow_settings.flow_behavior = "INFLOW"
fluid_mod.flow_settings.use_absolute = True
fluid_mod.flow_settings.velocity_factor = 2.0

# アニメーションの設定
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 100

# アニメーションを開始
bpy.context.scene.frame_set(1)
bpy.ops.screen.animation_play()

アニメーションを再生すると、流体オブジェクトから流体が流れ出し、ドメイン内でシミュレーションが行われます。

【デモ4】「海洋」を使ったスクリプト【コピペ可能】

海洋モディファイアを使って、海のようなオブジェクトを生成し、パラメータを調整してみましょう。

import bpy

# オブジェクトを選択し、アクティブにする
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.mesh.primitive_plane_add(size=20, enter_editmode=False, align='WORLD', location=(0, 0, 0))
ocean_obj = bpy.context.active_object
ocean_obj.name = "Ocean"

# オブジェクトにOceanモディファイアを追加
ocean_mod = ocean_obj.modifiers.new(name="Ocean", type="OCEAN")

# オーシャンモディファイアのパラメータを調整
ocean_mod.resolution = 4
ocean_mod.spatial_size = 50
ocean_mod.wind_velocity = 12
ocean_mod.depth = 200
ocean_mod.choppiness = 1
ocean_mod.wave_scale = 2.0  # 波の高さを変更
ocean_mod.wave_scale_min = 0.01
ocean_mod.wave_direction = 45.0  # 波の方向を変更 (角度で指定)
ocean_mod.damping = 0.25
ocean_mod.random_seed = 0

# マテリアルを作成
ocean_material = bpy.data.materials.new("OceanMaterial")
ocean_material.use_nodes = True
nodes = ocean_material.node_tree.nodes

# プリンシプルBSDFノードを見つける
principled_bsdf = nodes.get('Principled BSDF')

# カラーを青に設定
principled_bsdf.inputs[0].default_value = (0.01, 0.25, 0.65, 1)  # Base Colorを青に設定

# ノードリンクを取得
links = ocean_material.node_tree.links

# マッピングノードを追加
mapping_node = nodes.new("ShaderNodeMapping")
mapping_node.location = (-300, 300)

# テクスチャ座標ノードを追加
tex_coord_node = nodes.new("ShaderNodeTexCoord")
tex_coord_node.location = (-500, 300)

# ノイズテクスチャノードを追加
noise_node = nodes.new("ShaderNodeTexNoise")
noise_node.location = (-100, 300)

# リンクを作成
links.new(tex_coord_node.outputs["Generated"], mapping_node.inputs["Vector"])
links.new(mapping_node.outputs["Vector"], noise_node.inputs["Vector"])
links.new(noise_node.outputs["Fac"], principled_bsdf.inputs[1])  # Metallicにリンク

# 輝きの強度を調整
noise_node.inputs["Scale"].default_value = 100
noise_node.inputs["Detail"].default_value = 16
noise_node.inputs["Roughness"].default_value = 0.5

# 反射を設定
principled_bsdf.inputs[12].default_value = 0.5  # Specular IOR Level
principled_bsdf.inputs[2].default_value = 0.2  # Roughness

# オブジェクトにマテリアルを適用
ocean_obj.data.materials.append(ocean_material)

# シミュレーション設定
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 100

def update_ocean_time(scene):
    obj = bpy.data.objects.get("Ocean")
    if obj is not None:
        obj.modifiers["Ocean"].time = scene.frame_current / 30

bpy.app.handlers.frame_change_pre.append(update_ocean_time)

# アニメーションを再生
bpy.ops.screen.animation_play()

スクリプトの後半では、水面を表すためにマテリアルの設定を行っています。より海らしくしたい方は各パラメータを調整してみてください。

【デモ5】「ソフトボディ」を使ったスクリプト【コピペ可能】

ソフトボディモディファイアを使ったデモンストレーションを実施します。立方体がSoft Bodyオブジェクトとして落下し、床に接触して反応します。

import bpy

# シーンの設定
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = 100

# ソフトボディ用の立方体を追加
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 3))
softbody_obj = bpy.context.active_object
softbody_obj.name = "SoftBodyCube"

# ソフトボディモディファイアを追加
bpy.ops.object.modifier_add(type='SOFT_BODY')
softbody_mod = softbody_obj.modifiers["Softbody"]
softbody_mod.settings.friction = 5.0
softbody_mod.settings.mass = 1 # 質量
softbody_mod.settings.use_edges = True
softbody_mod.settings.use_goal = False

# ソフトボディの柔らかさを調整
softbody_mod.settings.bend = 0.5
softbody_mod.settings.push = 0.3
softbody_mod.settings.pull = 0.3

# ソフトボディのダンピングを増やす
softbody_mod.settings.damping = 0.5

# 衝突用の平面を追加
bpy.ops.mesh.primitive_plane_add(size=10, enter_editmode=False, align='WORLD', location=(0, 0, 0))
collision_obj = bpy.context.active_object
collision_obj.name = "CollisionPlane"

# 衝突モディファイアを追加
bpy.ops.object.modifier_add(type='COLLISION')

# アニメーションを再生
bpy.ops.screen.animation_play()

質量やベンド、プッシュ、プル、ダンピング等の値を変更すると、「ソフト感」を変更することができます。

まとめ:BlenderとPythonで視覚的に物理シミュレーションしてみよう!

本記事では、Blenderのさまざまな物理演算をPythonスクリプトで自動化する方法について解説しました。

Blenderで適用できる物理演算モディファイアの種類から、具体的なスクリプトの書き方までしっかり理解できたのではないでしょうか?

Blender初心者やPythonに不慣れな方も、本記事の内容を参考にして、Blenderのモディファイアを活用した自動化処理を試してみてください。

体系的に学びたい方は、Python×Blenderの専門書籍を使った学習もオススメです。

created by Rinker
¥3,386 (2024/11/21 15:05:16時点 Amazon調べ-詳細)
タイトルとURLをコピーしました