MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8で利用可能なpythonスクリプトを作る その22(シェーダーノードの追加と削除)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

空ノードの新規マテリアルを作成する

指定オブジェクトに空ノードの新規マテリアルを作成します。
シェーダの設定がないため、プレビューには紫のマテリアルで表示されます。
・make_material_emptynode.py

# bpyインポート
import bpy

# 指定オブジェクトに空ノードの新規マテリアルを作成する
def make_material_emptynode(arg_objectname="Default", arg_materialname="DefaultMaterial") -> bool:
    """指定オブジェクトの指定マテリアル内の指定ノードを削除する

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})
        arg_materialname {str} -- 作成マテリアル名 (default: {"DefaultMaterial"})

    Returns:
        Bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 指定オブジェクトがメッシュオブジェクトか確認する
    if selectob.type != 'MESH':
        # メッシュオブジェクトでない場合は処理しない
        return False

    # オブジェクトをアクティブにする
    bpy.context.view_layer.objects.active = selectob

    # 新規マテリアルを作成する
    newmaterial = bpy.data.materials.new(arg_materialname)

    # マテリアルスロットを追加する
    bpy.ops.object.material_slot_add()

    # 追加したマテリアルスロットに新規マテリアルを設定する
    selectob.active_material = newmaterial

    # ノードを使用する
    newmaterial.use_nodes = True

    # 新規マテリアルのノード参照を取得する
    mat_nodes = newmaterial.node_tree.nodes

    # マテリアル内の全ノードを走査する
    for delete_node in mat_nodes:
        # ノードを削除する
        mat_nodes.remove(delete_node)

    return True

# 関数の実行例
make_material_emptynode(arg_objectname = "Sphere", arg_materialname = "SphereMaterial")

f:id:bluebirdofoz:20200428205244j:plain

プリンシプルBSDFを使った基本的なノードを作成する

指定オブジェクトの指定マテリアル内にプリンシプルBSDFを使った基本的なノードを作成します。
スクリプトでは不要なノードの削除を行わないので、予め不要なノードを削除しておく必要があります。
・make_shadernode_BSDF.py

# bpyインポート
import bpy

# 指定オブジェクトの指定マテリアル内にプリンシプルBSDFを使った基本的なノードを作成する
# (予め不要なノードは削除しておくこと)
def make_shadernode_BSDF(arg_objectname="Default", arg_materialslotname="DefaultMaterial") -> bool:
    """指定オブジェクトの指定マテリアル内にPrincipled BSDFを使った基本的なノードを作成する
    (予め不要なノードは削除しておくこと)

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})
        arg_materialslotname {str} -- 対象マテリアルスロット名 (default: {"DefaultMaterial"})

    Returns:
        Bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 指定オブジェクトがメッシュオブジェクトか確認する
    if selectob.type != 'MESH':
        # メッシュオブジェクトでない場合は処理しない
        return False

    # オブジェクトをアクティブにする
    bpy.context.view_layer.objects.active = selectob

    # 指定のマテリアルスロットを取得する
    deletematerial_slot = selectob.material_slots.get(arg_materialslotname)

    # 指定マテリアルが存在するか確認する
    if deletematerial_slot == None:
        # 指定マテリアルが存在しない場合は処理しない
        return False
        
    # 指定マテリアルスロットのマテリアル参照を取得する
    target_mat = deletematerial_slot.material

    # ターゲットマテリアルのノード参照を取得する
    mat_nodes = target_mat.node_tree.nodes

    # プリンシプルBSDFノードを追加する
    bsdf_node = mat_nodes.new(type="ShaderNodeBsdfPrincipled")

    # 出力ノードを追加する
    output_node = mat_nodes.new(type="ShaderNodeOutputMaterial")

    # ターゲットマテリアルのノードリンク参照を取得する
    mat_link = target_mat.node_tree.links

    # プリンシプルBSDFノードのBSDFと出力ノードのサーフェスを接続する
    mat_link.new(bsdf_node.outputs[0], output_node.inputs[0])

    return True

# 関数の実行例
make_shadernode_BSDF(arg_objectname = "Sphere", arg_materialslotname = "SphereMaterial")

f:id:bluebirdofoz:20200428205300j:plain

ノードを指定して削除する

指定オブジェクトの指定マテリアル内の指定ノードを削除します。
・delete_shadernode_target.py

# bpyインポート
import bpy

# 指定オブジェクトの指定マテリアル内の指定ノードを削除する
def delete_shadernode_target(arg_objectname="Default",
      arg_materialslotname="DefaultMaterial", arg_shadernodename="DeleteNode") -> bool:
    """指定オブジェクトの指定マテリアル内の指定ノードを削除する

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})
        arg_materialslotname {str} -- 対象マテリアルスロット名 (default: {"DefaultMaterial"})
        arg_shadernodename {str} -- 削除ノード名 (default: {"DeleteNode"})

    Returns:
        Bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 指定オブジェクトがメッシュオブジェクトか確認する
    if selectob.type != 'MESH':
        # メッシュオブジェクトでない場合は処理しない
        return False

    # オブジェクトをアクティブにする
    bpy.context.view_layer.objects.active = selectob

    # 指定のマテリアルスロットを取得する
    deletematerial_slot = selectob.material_slots.get(arg_materialslotname)

    # 指定マテリアルが存在するか確認する
    if deletematerial_slot == None:
        # 指定マテリアルが存在しない場合は処理しない
        return False
        
    # 指定マテリアルスロットのマテリアル参照を取得する
    target_mat = deletematerial_slot.material

    # ターゲットマテリアルのノード参照を取得する
    mat_nodes = target_mat.node_tree.nodes

    # 削除ノードを取得する
    delete_node = mat_nodes[arg_shadernodename]

    # ノードを削除する
    mat_nodes.remove(delete_node)

    return True

# 関数の実行例
delete_shadernode_target(
    arg_objectname = "Sphere",
    arg_materialslotname = "SphereMaterial",
    arg_shadernodename="Principled BSDF"
)

f:id:bluebirdofoz:20200428205311j:plain