MRが楽しい

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

Blender2.8で利用可能なpythonスクリプトを作る その23(頂点カラーでの表示)

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

頂点カラー表示のマテリアルを作成する

指定オブジェクトに頂点カラー表示のマテリアルを作成します。
その他のマテリアルは参照を切るため、プロジェクト保存には注意が必要です。
・make_material_vertexcolor.py

# bpyインポート
import bpy

# 指定オブジェクトに頂点カラー表示のマテリアルを作成する
# (その他のマテリアルは参照を切るため、プロジェクト保存には注意)
def make_material_vertexcolor(arg_objectname="Default", arg_materialname="VertexColorMaterial",
      arg_addnodename="ShaderNodeAttribute", arg_jointnodename="Principled BSDF") -> bool:
    """指定オブジェクトに頂点カラー表示のマテリアルを設定する
    (その他のマテリアルは参照を切るため、プロジェクト保存には注意)

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})
        arg_materialname {str} -- 追加マテリアル名 (default: {"NewMaterial"})
        arg_addnodename {str} -- 追加ノード名 (default: {"ShaderNodeAttribute"})
        arg_jointnodename {str} -- 接続ノード名 (default: {"Principled BSDF"})

    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

    # マテリアルスロットを走査する
    for material_slot in selectob.material_slots:

        # マテリアルスロットをアクティブにする
        selectob.active_material = material_slot.material

        # マテリアルスロットを削除する
        bpy.ops.object.material_slot_remove()
    
    # 新規マテリアルを作成する
    vertexmaterial = bpy.data.materials.new("VertexColor")

    # ノードを使用する
    vertexmaterial.use_nodes = True
    
    # マテリアルスロットを追加する
    bpy.ops.object.material_slot_add()

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

    # ノード参照を取得する
    mat_nodes = vertexmaterial.node_tree.nodes

    # 属性ノードを追加する
    attr_node = mat_nodes.new(type="ShaderNodeAttribute")

    # 属性ノードの名前を変更する
    attr_node.name = arg_addnodename

    # 属性ノードのアトリビュート名を Col (頂点カラー)に変更する
    attr_node.attribute_name = "Col"

    # ノードリンクを取得する
    mat_link = vertexmaterial.node_tree.links

    # 接続ノードを取得する
    joint_node = mat_nodes[arg_jointnodename]

    # 属性ノードのカラーと接続ノードのカラーを接続する
    mat_link.new(attr_node.outputs[0], joint_node.inputs[0])

    return True

# 関数の実行例
make_material_vertexcolor(
    arg_objectname="Sphere",
    arg_materialname="VertexColorMaterial",
    arg_addnodename="ShaderNodeAttribute"
)

f:id:bluebirdofoz:20200429071140j:plain

頂点カラーとエミッションを使ったシンプルなマテリアルを作成する

指定オブジェクトに頂点カラーとエミッションを使ったシンプルなマテリアルを作成します。
その他のマテリアルは参照を切るため、プロジェクト保存には注意が必要です。
・make_shadernode_BSDF.py

# bpyインポート
import bpy

# 指定オブジェクトに頂点カラーとエミッションを使ったシンプルなマテリアルを作成する
# (その他のマテリアルは参照を切るため、プロジェクト保存には注意)
def make_material_vertexemission(arg_objectname="Default", arg_materialname="DefaultMaterial") -> bool:
    """指定オブジェクトに頂点カラーとエミッションを使ったシンプルなマテリアルを作成する
    (その他のマテリアルは参照を切るため、プロジェクト保存には注意)

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

    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

    # マテリアルスロットを走査する
    for material_slot in selectob.material_slots:

        # マテリアルスロットをアクティブにする
        selectob.active_material = material_slot.material

        # マテリアルスロットを削除する
        bpy.ops.object.material_slot_remove()
    
    # 新規マテリアルを作成する
    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)

    # 属性ノードを追加する
    attr_node = mat_nodes.new(type="ShaderNodeAttribute")

    # 属性ノードのアトリビュート名を Col (頂点カラー)に変更する
    attr_node.attribute_name = "Col"

    # エミッションノードを追加する
    emit_node = mat_nodes.new(type="ShaderNodeEmission")

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

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

    # 属性ノードのカラーと放射ノードのカラーを接続する
    mat_link.new(attr_node.outputs[0], emit_node.inputs[0])

    # 放射ノードの放射と出力ノードのサーフェスを接続する
    mat_link.new(emit_node.outputs[0], output_node.inputs[0])

    return True

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

f:id:bluebirdofoz:20200429071152j:plain