ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【Blender】剛体破壊シミュレーションの方法

 今までBlenderで剛体のシミュレーションの記事は書きましたが、今回は破壊させるシミュレーションをやってみたのでその備忘録です。

 また、以下の記事の最後の方にある私が自作したアドオンを有効にしておくと今回の作業が楽になります。
【Blender/python】Blenderの自作アドオンの作り方(その3) - ソースに絡まるエスカルゴ

 ちなみにこんな感じのものを作ります。
f:id:rikoubou:20180421000305g:plain

 それでは説明していきます。


1:必要なアドオンを有効にする
 今回の剛体破壊シミュレーションには「Cell Fracture」アドオンを使用します。

 Blenderを起動させたら「File」→「User Preferences」を選択します。
f:id:rikoubou:20180419020010p:plain

「Add-ons」タブを開き、検索のところに「cell」と入力して出てきた「Cell Fracture」にチェックを入れます。そして「Save User Settings」ボタンを押して設定を保存します。
f:id:rikoubou:20180419154920p:plain

 これでBlenderを再起動させてもこのアドオンは有効になったままになります。


2:必要なオブジェクトを作成して色をつける
 まずは必要なオブジェクトを作成してわかりやすいように色をつけます。

 Blenderを起動したら出てくる「Cube」を選択した状態で「Objectアイコン」を左クリックし、LocationのZの値に「1」を入力します。
f:id:rikoubou:20180419153010p:plain

 次に左側にある「Create」→「Plane」を選択します。
f:id:rikoubou:20180419155318p:plain

「Plane」が追加されるので「Objectアイコン」を選択してScaleを調節します。ここでは全て8にしました。
f:id:rikoubou:20180420210155p:plain

 続いて左側にある「Create」→「UV Sphere」を選択します。
f:id:rikoubou:20180420210246p:plain

Sphere」が追加されますが、Cubeに隠れて見えないのでぶつけたい位置にまで移動させます。
f:id:rikoubou:20180420210431p:plain

 これで必要なオブジェクトは揃ったのでわかりやすいように各オブジェクトに色をつけていきます。

Sphere」を選択した状態で「Materialアイコン」を選択して「New」ボタンを左クリックします。
f:id:rikoubou:20180420210851p:plain

 するとMaterialが追加されるので「Diffuse」のパレット部分を左クリックします。
f:id:rikoubou:20180420210940p:plain

 色の選択ができるので色を選択します。ここでは赤っぽい色にしました。
f:id:rikoubou:20180420211033p:plain

 やらなくてもよいですが、管理しやすいようにMaterialの名前をダブルクリックして「sphere」に変更しました。
f:id:rikoubou:20180420211226p:plain

 同様のやり方で「Cube」と「Plane」にもMaterialを追加して色をつけます。

 以下のように「Cube」は青、「Plane」は白っぽい色に設定しました。
f:id:rikoubou:20180420211444p:plain


3:ぶつけるオブジェクトを破壊対象のオブジェクトの子にする
 今回は「Sphere」を「Cube」にぶつけて破壊したいので、「Sphere」を選択した状態で「Shift+右クリック」で「Cube」を選択します。
 その状態で「Ctrl+Pキー」から「Object」を選択します。
f:id:rikoubou:20180420212435p:plain

 これで破壊対象のオブジェクト(Cube)が親、ぶつけるオブジェクト(Sphere)が子という関係になりました。
f:id:rikoubou:20180420212622p:plain


4:Cell Fractureアドオンを使って破片を作成する
 3までできたら「Cube」のみを選択した状態で左側の「Tool」→「Cell Fracture」を選択します。
f:id:rikoubou:20180420212957p:plain

 設定画面が表示されるので「Child Verts」タブを開いて「Source Limit」を153、「Noise」を1に設定して「OK」ボタンを押します。
f:id:rikoubou:20180420213158p:plain

 するとアウトライナーに「Cube_cell.001」というような名前でオブジェクトがたくさん追加されます。
f:id:rikoubou:20180420213423p:plain

 この状態で3D Viewの下にある画像の部分を左クリックしてレイヤーを切り替えます。
f:id:rikoubou:20180420213710p:plain

 レイヤーを切り替えるとこのように破片のオブジェクトが表示されました。アドオンを使って作成された破片は別のレイヤーに作成されていたことになります。
f:id:rikoubou:20180420213818p:plain


5:破片の剛体設定を行う
 破片のレイヤーに切り替えた状態で破片のうちの一つ(どこでもよい)を右クリックで選択します。
 その状態で「Physicsアイコン」から「Rigid Body」を選択します。
f:id:rikoubou:20180420214055p:plain

 追加して出てきた中のスクロールさせた先にある「Rigid body Dynamics」の「Enable Deactivation」と「Start Deactivated」にチェックを入れます。
f:id:rikoubou:20180420214426p:plain

 設定が終わったら3D Veiw上で「Aキー」を2回押して破片全てを選択した状態にします。
f:id:rikoubou:20180420214547p:plain

 破片全てを選択した状態で左側の「Physics」→「Copy from Active」を選択します。
f:id:rikoubou:20180420214713p:plain

 すると破片全てが緑の枠になり、一つだけやった剛体の設定が全部に適応されます。
f:id:rikoubou:20180420214736p:plain


6:他のオブジェクトの剛体設定を行う
 破片の設定が終わったので、元のレイヤーに戻るために3D Viewの下にある画像の部分を左クリックします。
f:id:rikoubou:20180420214943p:plain

 元のレイヤーに戻ったら「Sphere」のみを選択した状態で「Physicsアイコン」→「Rigid Body」を選択します。
f:id:rikoubou:20180420215320p:plain

「Rigid Body」の「Animated」にチェックを入れます。
f:id:rikoubou:20180420215402p:plain

 次に「Plane」のみを選択した選択した状態で「Physicsアイコン」→「Rigid Body」を選択します。
f:id:rikoubou:20180420215526p:plain

「Rigid Body」のプルダウンから「Passive」を選択します。
f:id:rikoubou:20180420215732p:plain
f:id:rikoubou:20180420215824p:plain

 これで全てのオブジェクトの剛体設定が終わりました。


6:ぶつけるオブジェクトの位置をキーフレームに登録する
 キーフレームを見やすくするために左下から「Dope Sheet」を選択します。
f:id:rikoubou:20180420220031p:plain

 キーフレームを1に合わせます。
f:id:rikoubou:20180420220149p:plain

 この状態で「Sphere」のみを選択し、初期位置としたいところまで移動させます。
f:id:rikoubou:20180420220340p:plain

 移動させたら3D View上で「iキー」を押して「Location」を選択して現在位置をキーフレームに登録します。
f:id:rikoubou:20180420220457p:plain

 1フレーム目にキーフレームが登録されました。
f:id:rikoubou:20180420220550p:plain

 同様の方法で20フレーム目で「Sphere」を移動させてから現在位置をキーフレームに登録します。
f:id:rikoubou:20180420220806p:plain

 ここまでできたら左下のところから「Timeline」に切り替えます。
f:id:rikoubou:20180420220929p:plain

 切り替えたら破片のあるレイヤーを「Shift+左クリック」で選択します。これで破片のレイヤーも同時に表示されるようになります。
f:id:rikoubou:20180420221034p:plain

 この状態でタイムラインの「▶︎」ボタンで再生してみます。
f:id:rikoubou:20180420221159p:plain

 すると以下のように球体がぶつかると破片が飛び散る動きができました。
f:id:rikoubou:20180420221410g:plain

 Cubeが残ったままですが、単に破壊シミュレーションを行うだけであればこれで終わりです。
 Cubeを残したままにしたくない、レンダリングもちゃんとしたいという場合は以下の手順が必要です。


7:破壊対象の元の形を残さないようにしてレンダリングする
 破壊対象の元の形が残っている理由は「ずっと見えるようにしているから」というだけです。
 要は「ぶつかる直前までは元の形のみを表示、ぶつかったあとは破片のみを表示」という風にすれば良いのです。

 6で動きを確認したら、左下のところから再び「Dope Sheet」を選択します。
f:id:rikoubou:20180420222023p:plain

 フレームを動かして破壊対象に接触する直前のフレームと直後のフレームを割り出します。移動量やぶつけるフレーム数などによって違ってくるので各自で確認してください。
 自分の場合は9フレーム目までは当たっておらず、10フレーム目から破片が飛び散っていることがわかりました。つまり「9フレーム目までは元の形を表示、10フレーム目以降は破片のみを表示」すれば良いということになります。
f:id:rikoubou:20180420222419p:plain
f:id:rikoubou:20180420222519p:plain

 フレームの確認ができたら、まずは元の形のCubeのレンダリング時の表示、非表示を設定します。

 今は両方のレイヤーが表示されているので、破片のレイヤーのみを左クリックして無効にします。
f:id:rikoubou:20180420232352p:plain

 9フレーム目であることを確認し「Cube」を選択した状態でアウトライナーの「カメラアイコン」にマウスカーソルを乗せた状態で「iキー」を押してキーフレームに登録します。キーフレームに登録されると黄色になります。
f:id:rikoubou:20180420233050p:plain

 次に1フレーム目まで移動させ同じように「Cube」の「カメラアイコン」にマウスカーソルを乗せた状態で「iキー」を押してキーフレームに登録します。
f:id:rikoubou:20180420233207p:plain

 続いて10フレーム目まで移動させ「Cube」を選択した状態でアウトライナーの「カメラアイコン」を左クリックして無効化します。
f:id:rikoubou:20180420233446p:plain

 この状態で同じようにマウスカーソルを乗せた状態で「iキー」を押してキーフレームに登録します。

 これでレンダリング時に1から9フレーム目までは「Cube」を表示、10フレーム以降は非表示という設定になりました。

 同様に破片についても1から9フレーム目までは非表示、10フレーム以降は表示にする設定を行います。

 破片のレイヤーをクリックして切り替えます。
f:id:rikoubou:20180420233654p:plain

 9フレーム目まで移動させ、3D View上で「Aキー」を押して破片全てを選択します。
f:id:rikoubou:20180420233820p:plain

 この状態で「Cube_cell.001」の「カメラアイコン」のところにマウスカーソルを持っていき「Alt+左クリック」をして選択中の全ての破片のカメラアイコンを無効にします。
f:id:rikoubou:20180420234310p:plain

 これをキーフレームに登録していくのですが、破片の一つ一つのカメラアイコンを「iキー」を押して登録していくのは疲れるので、最初にのせてある記事の自作アドオンを使います。

 全ての破片を選択した状態で「Object」→「Insert Restrict rendering」を選択します。
f:id:rikoubou:20180420234539p:plain

 選択したあとにフレームを少し動かすとキーフレームが登録されているのを確認できます。
f:id:rikoubou:20180420234727p:plain

 次に1フレーム目に移動して同じように「Object」→「Insert Restrict rendering」を選択してキーフレームを登録します。
f:id:rikoubou:20180420234849p:plain

 続いて10フレーム目に移動して「Cube_cell.001」の「カメラアイコン」のところにマウスカーソルを持っていき「Alt+左クリック」で有効に戻します。
f:id:rikoubou:20180420235021p:plain

 そして同様に「Object」→「Insert Restrict rendering」を選択してキーフレームを登録します。
f:id:rikoubou:20180420235146p:plain

 最後にレイヤーのところを「Shift+左クリック」でどちらも有効にします。
f:id:rikoubou:20180420235510p:plain

 これでレンダリング時の表示/非表示の設定が終わりました。あとはカメラの位置や動画の長さを調節してレンダリングするだけです。

 カメラを調節して動画として出力すると以下のようになります。元の形が残ることなく破壊されているのがわかると思います。
f:id:rikoubou:20180421000305g:plain
 

 以上が剛体破壊シミュレーションの方法です。詳しく説明しているので長々となっていますが、順番さえ覚えれば10分程度でできるようになると思います。
 また自分が作成したアドオンを使えば表示、非表示のキーフレーム登録がかなり楽にできると思うのでよければ使ってください。


・参考資料
www.youtube.com

【Blender/python】Blenderの自作アドオンの作り方(その3)

rikoubou.hatenablog.com

 前回はアドオンの保存場所と2通りのデバッグ方法を確認しました。
 今回はいよいよアドオンの中身について触れていきます。また自分が作成したアドオンのソースコードについても紹介しつつ説明していきたいと思います。


1:アドオンの基本的な構成
 より詳しい説明は参考にさせていただいた以下のページを参照してください。
2-1. アドオン開発の基礎を身につける | はじめてのBlenderアドオン開発

 アドオンを自作する時の基本的な構成は以下のようになります。

・example.py

import bpy # ①BlenderのpythonAPI

# ②自作アドオンについての説明
bl_info = {
    "name": "sample: add-onTest",
    "author": "ssss",
    "version": (2, 0),
    "blender": (2, 79, 0),
    "location": "location",
    "description": "sample",
    "warning": "warning",
    "support": "TESTING",
    "wiki_url": "http://hogehoge.com",
    "tracker_url": "http://hogehoge2.com",
    "category": "Object"
}

# ③追加したいアドオンのクラス
class AddSphere(bpy.types.Operator):

    bl_idname = "object.add_shhere_object" # ID
    bl_label = "Sphere" # メニューに追加されるラベル
    bl_description = "Add Sphere" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} # 処理の属性

    # ④実際の処理
    def execute(self, context):
        bpy.ops.mesh.primitive_ico_sphere_add()
        print("Add Sphere End") # コンソールにログ出力
        self.report({'INFO'}, "Add Sphere End") # ⑤Blenderのログに出力
        return {'FINISHED'}

# ⑥メニューを構築する関数
def menu_fn(self, context):
    self.layout.separator()
    self.layout.operator(AddSphere.bl_idname)


# ⑦アドオン有効化時の処理
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_object.append(menu_fn)
    print("Add-on:ON")


# ⑧アドオン無効化時の処理
def unregister():
    bpy.types.VIEW3D_MT_object.remove(menu_fn)
    bpy.utils.unregister_module(__name__)
    print("Add-on:OFF")

# ⑨メイン関数
if __name__ == "__main__":
    register()

 ではソースコードのそれぞれの解説です。

BlenderのpythonAPI

import bpy # ①BlenderのpythonAPI

 これはBlenderpython APIを読み込んで使えるようにしています。この一文がなければBlenderの機能をpythonを使って制御できないので必須になります。

②自作アドオンについての説明

# ②自作アドオンについての説明
bl_info = {
    "name": "sample: add-onTest",
    "author": "ssss",
    "version": (2, 0),
    "blender": (2, 79, 0),
    "location": "location",
    "description": "sample",
    "warning": "warning",
    "support": "TESTING",
    "wiki_url": "http://hogehoge.com",
    "tracker_url": "http://hogehoge2.com",
    "category": "Object"
}

 これは「User Preferences」画面のアドオンに表示される各情報の記述です。各キーの内容は以下のようになります。

キー 内容
name 文字列 アドオンの名前
author 文字列 アドオンの作者名
version タプル アドオンのバージョン
blender タプル アドオンが動作する最古のBlenderバージョン
location 文字列 アドオンが提供する機能が存在する場所
description 文字列 アドオンの説明
warning 文字列 アドオン使用時の注意点やバグ情報
support 文字列 アドオンのサポートレベル
wiki_url 文字列 アドオンに関するドキュメントURL
tracker_url 文字列 アドオンのサポートサイトURL
category 文字列 アドオンのカテゴリー

 それぞれがAdd-onsの画面とどう対応しているかは以下を参照してください。
f:id:rikoubou:20180419091726p:plain

③追加したいアドオンのクラス

# ③追加したいアドオンのクラス
class AddSphere(bpy.types.Operator):

    bl_idname = "object.add_shhere_object" # ID
    bl_label = "Sphere" # メニューに追加されるラベル
    bl_description = "Add Sphere" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} #処理の属性

    # 実際の処理を行う関数
    def execute(self, context):
        # 処理を記述する
        return {'FINISHED'}

 追加したいアドオンのオペレータクラスです。Blenderでは何かしらの処理をするのにオベレータクラスを作成して処理を記述します。
 実際の処理を行う関数の前にクラス変数を定義しています。このクラス変数は以下のような内容です。

変数名 内容
bl_idname 文字列 Blender内部で扱うID。(カテゴリ).(任意の文字列)という形式。
bl_label 文字列 メニューに追加されるラベル
bl_description 文字列 関数の説明
bl_options 集合型 処理の属性

 それぞれがどこに対応しているかは以下の画像を参照してください。
f:id:rikoubou:20180419093106p:plain

④実際の処理

    # ④実際の処理
    def execute(self, context):
        bpy.ops.mesh.primitive_ico_sphere_add()
        print("Add Sphere End") # コンソールにログ出力
        self.report({'INFO'}, "Add Sphere End")
        return {'FINISHED'}

 ③のクラス内に「def execute(self, context)」関数を作成してそこにBlenderで行いたい処理を記述します。この関数の引数は以下のようになっています。

引数 説明
self 呼びだされた execute() メソッドを定義しているクラス オペレータクラスのインスタンス
context bpy_types.Context execute() メソッド実行時のコンテキスト

「bpy.ops.mesh.primitive_ico_sphere_add()」という一行で球体を作成しています。他にどういう処理ができるかはBlenderのpythonAPIを参照してください。

 関数の最後は「return {'FINISHED'}」と処理を確定させる値を返しています。詳しい説明は冒頭で上げた参考資料のページを参照してください。
 またprint関数を記述することによりコンソールに表示させることができます。

Blenderのログに出力

self.report({'INFO'}, "Add Sphere End") # ⑤Blenderのログに出力

 この記述で前回説明したBlenderのコンソールに情報を表示させることができます。

⑥メニューを構築する関数

# ⑥メニューを構築する関数
def menu_fn(self, context):
    self.layout.separator()
    self.layout.operator(AddSphere.bl_idname)

 最初の2行は定型文で「self.layout.operator(クラス名.bl_idname)」でオベレータクラスで作成したメニューを追加します。

⑦アドオン有効化時の処理

# ⑦アドオン有効化時の処理
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_object.append(menu_fn)
    print("Add-on:ON")

「bpy.utils.register_module」はBlender内で引数のモジュールを使えるようにするための関数です。メイン関数である「__name__」を指定しています。
 2行目の「bpy.types.VIEW3D_MT_object.append」で引数のものをメニューに追加をしています。引数にメニューを追加する「menu_fn」関数を指定しています。
 ここでの「VIEW3D_MT_object」は以下の画像のところに追加するという意味です。詳しい内容はBlenderのpythonAPIから調べてください。
f:id:rikoubou:20180419094656p:plain
 最後にprint関数でアドオンが有効になったことをコンソールに表示させています。

⑧アドオン無効化時の処理

# ⑧アドオン無効化時の処理
def unregister():
    bpy.types.VIEW3D_MT_object.remove(menu_fn)
    bpy.utils.unregister_module(__name__)
    print("Add-on:OFF")

「bpy.types.VIEW3D_MT_object.remove」で追加したメニューを削除しています。
 2行目でBlenderでモジュールを使えないようにしています。
 最後にprint関数でアドオンが無効になったことをコンソールに表示させています。

⑨メイン関数

# ⑨メイン関数
if __name__ == "__main__":
    register()

 メイン関数です。定型文だと思ってつけておいてください。

 以上が基本的なアドオンの構成になります。


■今回作成したアドオン
 アドオンの説明が終わったのでようやく今回自作したアドオンの紹介です。今までの説明からソースコードの内容はなんとなくわかると思います。

 今回作成したアドオンの内容としてはBlenderの以下の部分(目のアイコンもしくはカメラのアイコン)をまとめてキーフレームに登録したり削除したりする」というものです。
f:id:rikoubou:20180419013446p:plain

 作成したアドオンのソースコードは以下の通りです。

・insertDeleteHideAndRender.py

# 選択されているオブジェクトの表示/非表示、レンダー時の表示/非表示を
# まとめてキーフレームに登録するためのアドオン

import bpy # BlenderのpythonAPI

bl_info = {
    "name": "Insert/Delete hide and render", # アドオン一覧に表示される名前
    "author": "whip",  # 作者
    "version": (1, 0), # アドオンのバージョン
    "blender": (2, 79, 0), # 対応するBlenderのバージョン
    "location": "",
    "description": "Insert/Delete keyframe of hide or render", # アドオンの説明
    "warning": "",
    "support": "TESTING", # アドオンの分類
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object" # カテゴリー
}

# Restrict renderingの項目をキーフレームに登録するクラス
class insertRestrictRendering(bpy.types.Operator):
    bl_idname = "object.insert_restrict_rendering" # ID
    bl_label = "Insert Restrict rendering" # メニューに表示される名前
    bl_description = "Insert keyframe of Restrict rendering of selected objects" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} # オブション

    # 実際の処理
    def execute(self, context):
        selected_objs = context.selected_objects # 選択されているオブジェクトを全て取得
        currentFrame = bpy.context.scene.frame_current # 現在のキーフレームを取得
        self.report({'INFO'}, "frame:%s" % currentFrame) # Blenderのログに出力
        # 取得したオブジェクト分繰り返す
        for obj in selected_objs:
            obj.keyframe_insert('hide_render',frame=currentFrame) # レンダー時の表示/非表示を登録
            self.report({'INFO'}, "%s render:%s" % (obj.name, obj.hide_render)) # Blenderのログに出力
        return {'FINISHED'}

# Restrict renderingの項目をキーフレームから削除するクラス
class deleteRestrictRendering(bpy.types.Operator):
    bl_idname = "object.delete_restrict_rendering" # ID
    bl_label = "Delete Restrict rendering" # メニューに表示される名前
    bl_description = "Delete keyframe of Restrict rendering of selected objects" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} # オブション

    # 実際の処理
    def execute(self, context):
        selected_objs = context.selected_objects # 選択されているオブジェクトを全て取得
        currentFrame = bpy.context.scene.frame_current # 現在のキーフレームを取得
        # 取得したオブジェクト分繰り返す
        for obj in selected_objs:
            # 登録されているかの判定
            if obj.animation_data is not None and obj.animation_data.action is not None:
                obj.keyframe_delete('hide_render',frame=currentFrame) # レンダー時の表示/非表示を削除
        self.report({'INFO'}, "frame:%s render deleted" % currentFrame) # Blenderのログに出力
        return {'FINISHED'}

# Visibllityの項目をキーフレームに登録するクラス
class insertVisibllity(bpy.types.Operator):
    bl_idname = "object.insert_visibllity" # ID
    bl_label = "Insert Visibllity" # メニューに表示される名前
    bl_description = "Insert keyframe of Visibllity of selected objects" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} # オブション

    # 実際の処理
    def execute(self, context):
        selected_objs = context.selected_objects # 選択されているオブジェクトを全て取得
        currentFrame = bpy.context.scene.frame_current # 現在のキーフレームを取得
        self.report({'INFO'}, "frame:%s" % currentFrame) # Blenderのログに出力
        # 取得したオブジェクト分繰り返す
        for obj in selected_objs:
            obj.keyframe_insert('hide',frame=currentFrame) # 表示/非表示を登録
            self.report({'INFO'}, "%s hide:%s" % (obj.name, obj.hide)) # Blenderのログに出力
        return {'FINISHED'}

# Visibllityの項目をキーフレームから削除するクラス
class deleteVisibllity(bpy.types.Operator):
    bl_idname = "object.delete_visibllity" # ID
    bl_label = "Delete Visibllity" # メニューに表示される名前
    bl_description = "Delete keyframe of Visibllity of selected objects" # 関数の説明
    bl_options = {'REGISTER', 'UNDO'} # オブション

    def execute(self, context):
        selected_objs = context.selected_objects # 選択されているオブジェクトを全て取得
        currentFrame = bpy.context.scene.frame_current # 現在のキーフレームを取得
        # 取得したオブジェクト分繰り返す
        for obj in selected_objs:
            # 登録されているかの判定
            if obj.animation_data is not None and obj.animation_data.action is not None:
                obj.keyframe_delete('hide',frame=currentFrame) # 表示/非表示を削除
        self.report({'INFO'}, "frame:%s hide deleted" % currentFrame) # Blenderのログに出力
        return {'FINISHED'}

# メニューに追加する関数
def menu_fn(self, context):
    self.layout.separator()

    # 先に追加されたものが下にくる
    self.layout.operator(deleteVisibllity.bl_idname)
    self.layout.operator(insertVisibllity.bl_idname)
    self.layout.operator(deleteRestrictRendering.bl_idname)
    self.layout.operator(insertRestrictRendering.bl_idname)

# アドオンが有効化された時の関数
def register():
    bpy.utils.register_module(__name__) # 
    bpy.types.VIEW3D_MT_object.append(menu_fn)
    print("Insert/Delete hide and render:Available") # コンソールにログを出力

# アドオンが無効化された時の関数
def unregister():
    bpy.types.VIEW3D_MT_object.remove(menu_fn)
    bpy.utils.unregister_module(__name__)
    print("Insert/Delete hide and render:Anavailable") # コンソールにログを出力

# メイン関数
if __name__ == "__main__":
    register()

 使い方としては、オブジェクトを複数選択した状態で「Object」→「Insert Restrict rendering」を選択すると、選択したオブジェクトのレンダー時の表示/非表示を現在のキーフレームに登録することができます。
 同じようにオブジェクトを複数選択した状態で「Object」→「Insert Visibllity」を選択すると、選択したオブジェクトの画面上の表示/非表示を現在のキーフレームに登録することができます。
 またキーフレームに登録したものをまとめて削除する「Delete Restrict rendering」、「Delete Visibllity」もあります。

 このアドオンをBlenderに読み込ませて実際に使うと以下のようになります。


 以上がBlenderの自作アドオンを作ってみた備忘録です。
 pythonもそんなに書いたことない上に初めてBlenderのアドオンを作ってみたのでわからないことだらけでした。

 けれど今回やってみたことでBlenderのアドオンを作成する方法がわかったので「ちょっとこの処理を自動化したい」と思った場合には気軽に作れるようになったと思います。(作るのが楽とは言っていない)

 もしかしたら今回やろうとしていたことがBlenderのショートカットキーですでに実装されているのであれば、操作方法を教えていただきたいです。

 長々となってしまいましたが、自作アドオンの作り方についての記事はこれで終わりです。ありがとうございました。


・参考資料

【Blender/python】Blenderの自作アドオンの作り方(その2)

rikoubou.hatenablog.com

 前回の続きです。前回は大まかな自作アドオン作成の流れを説明しました。

 今回はアドオンの保存先やデバッグ方法についてです。


1:読み込んだ自作アドオンの保存先
 自作アドオンを「Install Add-on from File」でBlenderに読み込みました。この読み込んだファイルの保存先は以下のようになっています。

OS 保存先
Windows C:\Users\(ユーザ名)\AppData\Roaming\Blender Foundation\Blender\(Blenderのバージョン)\scripts\addons
Mac /Users/(ユーザ名)/Library/Application Support/Blender/(Blenderのバージョン)/scripts/addons
Linux /home/(ユーザ名)/.config/blender/(Blenderのバージョン)/scripts/addons

 私の環境はMacなので該当の保存先へ移動すると、前回読み込んだ「test.py」が保存されていることがわかります。
f:id:rikoubou:20180419023417p:plain


2:自作アドオンの修正方法
 前回の記事の方法で元のファイルを修正してまた読み込ませて…みたいな方法でも良いですが、基本的には1の保存先にあるファイルを直接編集した方が楽です。なので別のエディタを使ってファイルを修正して上書き保存してしまいましょう。

 Blenderを起動させた状態のままでも自作アドオンファイルの修正はできます。

 修正したアドオンファイルを再び読み込ませる時は「File」→「User Preferences」を開き「Add-ons」のところにある自作アドオンのチェックを外してから「Refresh」ボタンを左クリックします。
f:id:rikoubou:20180419024231p:plain

「Refresh」ボタンを押すとアドオンがリロードされるので、もう一度自作アドオンにチェックを入れます。
f:id:rikoubou:20180419024421p:plain

 これでBlenderを起動したままでも自作アドオンファイルの修正した内容が反映されます。


3:自作アドオンのデバッグ方法(その1)
 pythonのprint関数でコンソールに色々表示させながらデバッグさせたいときは以下のように行います。

Windowsの場合(blender.exeのパスがC:\path\blender.exeであるとする)
 コンソールを立ち上げて以下のコマンドを実行する。

$ C:\path\blender.exe

Macの場合(blender.appのパスが/path/blender.appであるとする)
 ターミナルを立ち上げて以下のコマンドを実行する。

$ /path/blender.app/Contents/MacOS/blender

Linuxの場合(blender.のパスが/path/blenderであるとする)
 ターミナルを立ち上げて以下のコマンドを実行する。

$ /path/blender

 上記の方法でコンソール画面からBlenderを起動できます。アドオン内で記述したprint関数の内容はこのコンソールに表示されます。


4:自作アドオンのデバッグ方法(その2)
 もうひとつアドオン内のエラーなどを確認する方法があります。それはBlender自体のログ画面です。

 以下のように画面上部の枠線あたりにマウスカーソルを合わせ、下へと左ドラッグしながら引っ張るとログ画面が出てきます。
f:id:rikoubou:20180419030806p:plain
f:id:rikoubou:20180419030641g:plain

 このBlenderのログ画面への出力方法は以下の記述できます。詳しい解説は別の記事で行います。

self.report({'INFO'}, "hogehoge") # Blenderのログに出力


 以上がアドオンの保存先とデバッグ方法です。
 説明することが多すぎてなかなか進まないですが、次はようやくアドオンの中身についての説明になると思います。


・参考資料


・次の記事
rikoubou.hatenablog.com

【Blender/python】Blenderの自作アドオンの作り方(その1)

 今回はBlenderで使う自作アドオンの作り方です。

 とある単純な処理の繰り返しをするのが非常に面倒だったので「アドオンである程度自動化できないかな」と思い、色々調べてとりあえずは作ることができたのでその備忘録です。少しはプログラムを書いたことのある自分でもなかなかつらかったので誰かの助けになれば幸いです。

 ただ説明すべきことが多すぎるので、今回は自作アドオンの作り方の簡単な流れだけ説明します。


■簡単なBlenderアドオンについての説明
 Blenderにはpython APIが用意されており、以下のサイトからどのような関数があるかなどを検索することができます。
Blender Documentation Contents — Blender 2.79.0 855d2955c49 - API documentation

 つまり自分でpythonのプログラムを作成してBlenderに取り込むことでBlenderをカスタマイズすることができるのです。

 それでは自作アドオンの作り方を説明していきます。

自作アドオンの作り方

 基本的には「アドオンのpythonファイルを作成」→「Blenderに登録」という流れになります。


1:自作アドオン作成
 正直別のエディタでもなんでもよいのですが、今回はBlenderにあるエディタを使って作成します。

 Blenderを起動させ左下にあるところから「Text Editor」を選択します。
f:id:rikoubou:20180419014502p:plain

「Text Editor」を開くと真っ白な画面になるので下の方にある「New」を左クリックします。
f:id:rikoubou:20180419014643p:plain

 すると文字が打てるようになるのでプログラムを記述していきます。
f:id:rikoubou:20180419014813p:plain

 今回はテストコードとして以下のプログラムを記述しました、

bl_info = {
    "name": "sample: add-onTest",
    "author": "ssss",
    "version": (2, 0),
    "blender": (2, 79, 0),
    "location": "",
    "description": "sample",
    "warning": "",
    "support": "TESTING",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"
}

def register():
    print("sample: add-onTest ON")

def unregister():
    print("sample: add-onTest OFF")

if __name__ == "__main__":
    register()

 左下にある「Run Script」ボタンを押すとプログラムを実行することができるので、実際に動かしながら記述することもできます。
f:id:rikoubou:20180419015747p:plain

 プログラムの記述が終わったら右下にある「Text」→「Save As」で名前をつけて保存します。
f:id:rikoubou:20180419015130p:plain

 ファイル名の最後には必ずpythonの拡張子である「.py」をつけてください。今回は「test.py」という名前で保存しました。
 保存場所はどこでもよいですが日本語名がファイルパスに入らない場所にしてください。日本語名がパスまたはファイル名に入っていると開けない場合があります。
 

2:自作アドオンの読み込み
 1で作成した自作アドオンをBlenderに読み込んで使えるようにします。

「File」→「User Preferences」を選択します。
f:id:rikoubou:20180419020010p:plain

「Add-ons」のタブを開き「Install Add-on from File」のボタンを押します。
f:id:rikoubou:20180419020658p:plain

 作成した自作アドオンを選択し右上にある「Install Add-on from File」のボタンを押して読み込みます。
f:id:rikoubou:20180419020647p:plain

 今回のテストコードではsupportを「TESTING」にしているので、左側の「Testing」のみを選択した状態にすると読み込んだアドオンが表示されます。
f:id:rikoubou:20180419021117p:plain

 このアドオンにチェックを入れればアドオンが有効になります。「Save User Settings」ボタンを押すことでBlenderを閉じてもアドオンを有効にした状態のままにすることも可能です。
f:id:rikoubou:20180419021123p:plain


 基本的な自作アドオン作成の流れは以上です。

 デバッグや自作アドオンが格納される場所などの詳しい情報についてはまた今度まとめようと思います。


・参考資料


・次の記事
rikoubou.hatenablog.com

【Blender】親子関係のオブジェクトをまとめて表示/非表示させる方法

「オブジェクトをまとめて表示/非表示させたりできないのかな?」と思っていたらやり方を教えていただいたので即記事にまとめた次第です。

・2018/04/19追記
 色々操作して確かめていたら別に親子関係にしていなくても「Shift+右クリック」やグループ全体を選択している状態で同じ動作をやってもまとめて表示/非表示の設定ができました。


1:親子関係を作成する
 とりあえず適当にこのように親子関係を作りました。3D View上で一番下にある「Cube1」が全体の親になります。
f:id:rikoubou:20180417125340p:plain


2:アウトライナーにあるアイコンを「Ctrl+左クリック」でまとめて適用させる
 親のオブジェクトを選択した状態でアウトライナーにある「目のアイコン」を「Ctrl+左クリック」(MacでもControlキー+左クリック)すると全ての子オブジェクトに対して適用されます。
f:id:rikoubou:20180417125731g:plain


 以上が親子関係のオブジェクトをまとめて表示/非表示させる方法です。

 破壊シミュレーションをやる場合は破片ひとつひとつを表示/非表示させたりするのは面倒だと思うので、この方法を使って破片全体を表示/非表示できるようにすれば効率が上がりそうです。
 教えていただいた方、ありがとうございました。

・参考資料

【Blender】トゥーンレンダリングをする方法

 ネットで検索したら割とすぐに出てきたので、今回はトゥーンレンダリング (アニメ調の画面にする)を行う方法の備忘録です。
 基本的にはBlenderの設定値をいじるだけで割とそれっぽいレンダリング結果になります。


1:モデルを作成または読み込む
 どんな題材でも良いですが、今回はBlenderにデフォルトで入っている「Monkey」を例にしていきます。
 Blenderを立ち上げてデフォルトのCubeを消したら左側の「Create」から「Monkey」を選びます。
f:id:rikoubou:20180416162504p:plain

 すると猿の顔の「Suzanne」というオブジェクトが追加されます。
f:id:rikoubou:20180416162639p:plain

 また今回照明として「Lamp」ではなく「Sun」を使いたいので「Lamp」を選択した状態で「右クリック」→「Delete」で削除します。
f:id:rikoubou:20180416163311p:plain

Lamp」を削除したら左側の「Create」から「Sun」を選びます。
f:id:rikoubou:20180416163415p:plain

 これで「Sun」が追加されました。「Sun」は全体を照らす照明でどこに置いても光源として影響はありません。
f:id:rikoubou:20180416163608p:plain


2:レンダリング時に輪郭線を追加する
 1が終わった状態で一度レンダリング結果を見てみましょう。
 3D Viewの左下にある「Viewpoint Shading」から「Rendered」を選択します。
f:id:rikoubou:20180416163913p:plain

 すると以下のように輪郭線は表示されていません。
f:id:rikoubou:20180416163953p:plain

 では輪郭線を表示させていきます。
「Rendered」の状態のままで「Renderボタン(カメラのようなボタン)」をクリックし、少しスクロールした先にある「Post Processing」を開き「Edge」にチェックを入れます。
f:id:rikoubou:20180416164146p:plain

 すると猿のオブジェクトに輪郭線が追加されます。
f:id:rikoubou:20180416164322p:plain

「Edge」の下にある「Threshold」の値を大きくすると、より輪郭線が多くなります。また「Threshold」の下の色部分をクリックして輪郭線の色を変えることも可能です。
f:id:rikoubou:20180416164613p:plain
f:id:rikoubou:20180416164622p:plain

 オブジェクトに輪郭線を追加するだけならこれで十分ですが、次は色についての設定です。


3:MaterialのToon設定を行う
 2の輪郭線の設定値はなんでもよいですが、とりあえず以下のようにします。
f:id:rikoubou:20180416165140p:plain
f:id:rikoubou:20180416165149p:plain

 猿のオブジェクトにMaterialで色をつけていきます。
「Rendered」の状態のまま「Suzanne」を選択し「Materialボタン(丸いアイコン)」をクリックし、出てきた画面で「New」をクリックします。
f:id:rikoubou:20180416165331p:plain

 すると「Material.001」という名前でMaterialが追加されるので「Diffuse」のパレット部分をクリックします。
f:id:rikoubou:20180416165543p:plain

 色が選択できるので適当な色に変更します。
f:id:rikoubou:20180416165723p:plain

 今回は黄色というかベージュっぽい色に変更しました。
f:id:rikoubou:20180416165845p:plain

 適当に色をつけたらパレットの右側にあるプルダウンから「Toon」を選択します。
f:id:rikoubou:20180416170114p:plain

 出てきた各設定値「Intensity」を1、「Size」を1.54、「Smooth」を0に設定します。
f:id:rikoubou:20180416170224p:plain

 すると猿のオブジェクトは以下のようになります。この時点でも割とアニメ調に近づいていると思います。
f:id:rikoubou:20180416170345p:plain

 次に「Specular」のプルダウンから「Toon」を選択します。
f:id:rikoubou:20180416170512p:plain

 出てきた各設定値「Intensity」を0.9、「Size」を0.3、「Smooth」を0に設定します。
f:id:rikoubou:20180416170758p:plain


4:完成
 これで完成です。最初の状態と比較すると色が付いているとはいえ、かなりアニメ調な感じになったと思います。

・トゥーンレンダリングをしたもの
f:id:rikoubou:20180416170827p:plain

・何もしない状態のもの
f:id:rikoubou:20180416163953p:plain

 また実際にレンダリングした結果の画面については3D Viewの左下から「UV/Image Editor」を選択すると実際にレンダリングした後の出力画面が表示されます。こっちの方がよりアニメ調になっているのがわかると思います。
f:id:rikoubou:20180416171537p:plain
f:id:rikoubou:20180416171708p:plain


 以上がBlenderでトゥーンレンダリングをした結果です。今回の設定値は自分なりに色々いじってみた結果の値なので、各自で値を調節して適切な値を見つけるのが良いと思います。


・参考資料

【Blender】オブジェクトを回転連動させる方法

 今日も今日とてBlenderに関する内容です。以前の記事で以下のようにロボットアームもどきのモデルを作成し、アニメーションをさせました。

rikoubou.hatenablog.com
rikoubou.hatenablog.com

 ロボットアームの関節というか、回転軸の数だけ一つ一つ角度を指定してアニメーションさせるというかなり面倒なことをやっていたのですが今回は「1つのオブジェクトを動かすとそれに連動して別のオブジェクトも動く」というオブジェクトの連動させる設定方法の紹介です。


1:以前作成したロボットアームのモデルを読み込む
 題材として使うのはなんでもよいのですが、以前作成したロボットアームを使いまわします。

【Blender】別のBlenderファイルを読み込む方法 - ソースに絡まるエスカルゴ
 ↑の記事にあるように「Append」からモデルを読み込みます。
f:id:rikoubou:20180413170337p:plain

 このままではグリッパー部分は片方ずつしか動かず、連動はしません。
f:id:rikoubou:20180413170637g:plain

 これだとアニメーションづけが面倒なのと、左右で同じだけ開かせるということが難しいので連動できるように設定していきます。


2:連動させたいオブジェクトに「Copy Rotation」を追加する
 今回は以下のように正面右のグリッパを動かすと左側のグリッパが連動するようにします。
f:id:rikoubou:20180413171119p:plain

 最初に連動して欲しいオブジェクトである左側のグリッパを選択し、「Constraintアイコン」から「Add Object Constraint」を選び「Copy Rotation」を追加します。
f:id:rikoubou:20180413171243p:plain

「Target」のアイコンの所をクリックし、連動元のオブジェクト(ここでは07_tsumeL)を選択します。
f:id:rikoubou:20180413171505p:plain

 グリッパ部分はZ軸方向の回転しか行わないので、X、Yのチェックを外します。また爪は左右で逆方向に連動して欲しいのでZの「Invert」にチェックを入れます。
f:id:rikoubou:20180413171900p:plain

 次に「Space」のプルダウンを両方とも「Local Space」に変更します。
f:id:rikoubou:20180413172021p:plain

 これで連動の設定は完了です。


3:連動していることを確認する
 2の手順で設定を終えたら実際に連動するかを試してみます。

 以下のように正面右側のグリッパを選択して回転させると、もう片側の方も連動しました。また正面左側を選択して移動させようとしても、連動元が動いていないので動かすことができません。
f:id:rikoubou:20180413172353g:plain

また親オブジェクトを動かして角度や位置がずれても「Local Space」に設定しているため、破綻することなく連動します。
f:id:rikoubou:20180413172800g:plain

 ちなみに両方とも「World Space」に設定した場合は、絶対座標として計算されるらしく、親オブジェクトが移動するとおかしな動きになります。なので基本的には両方とも「Local Space」に設定しておく方が良いと思います。
f:id:rikoubou:20180413173022g:plain


以上がオブジェクトを回転連動させる方法です。
「Add Object Constraint」で出てくる中には位置やサイズの連動もできる項目があったので、同じような方法で位置やサイズも連動できると思います。


・参考資料