MRが楽しい

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

Blender3.0で利用可能なpythonスクリプトを作る その94(頂点グループを指定してポリゴン数削減モディファイアを適用する)

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

頂点グループを指定してポリゴン数削減モディファイアを適用する

ポリゴン数削減モディファイアでは頂点グループを指定してリダクションを行うことができます。
ただし頂点グループの指定を利用できるのは削減のタイプが COLLAPSE である場合に限ります。
docs.blender.org

またリダクションの比率は頂点グループ内の比率ではなく、オブジェクト全体に対しての削減比率で計算が行われる点に注意が必要です。

サンプルスクリプト

頂点グループを指定するポリゴン数削減モディファイアを適用するサンプルスクリプトを作成しました。
選択した頂点を頂点グループに登録して、頂点グループ名をモディファイア指定します。
・Script_decimate_vertexgroup.py

# bpyインポート
import bpy

def apply_decimate_vertexgroup(
    arg_object:bpy.types.Object,
    arg_vertexgroup_name:str,
    arg_decimateratio=1.0) -> bool:
    """頂点グループを指定してポリゴン数削減モディファイアを適用する

    Keyword Arguments:
        arg_object (bpy.types.Object): 指定オブジェクト
        arg_vertexgroup_name {str} -- 指定の頂点グループ名
        arg_decimateratio {float}} -- 削減比率

    Returns:
        bool -- 実行成否
    """

    # 指定オブジェクトに指定の頂点グループが含まれるかチェックする
    check_vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name)
    if check_vertexgroup == None:
        return 0
    
    # 指定オブジェクトがメッシュか確認する
    if arg_object.type != 'MESH':
        # メッシュが存在しない場合は処理しない
        return False

    # 変更オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = arg_object
    
    # 「ポリゴン数削減」モディファイアを追加する
    # モディファイア追加の種類とマニュアル
    # (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.gpencil_modifier_add)
    # ポリゴン数削減モディファイアのインタフェース
    # (https://docs.blender.org/api/current/bpy.types.DecimateModifier.html)
    bpy.ops.object.modifier_add(type='DECIMATE')

    # 追加されたモディファイアを取得する
    decimate_modifier = arg_object.modifiers[-1]

    # 削減のタイプを COLLAPSE に指定する
    decimate_modifier.decimate_type = 'COLLAPSE'

    # 削減の比率を設定する
    decimate_modifier.ratio = arg_decimateratio

    # 頂点グループを指定する
    decimate_modifier.vertex_group = arg_vertexgroup_name

    # 「ポリゴン数削減」モディファイアを適用する
    bpy.ops.object.modifier_apply(modifier=decimate_modifier.name)
    
    # 実行成否を返却する
    return True

# オブジェクトモードへの移行
# モード切替のマニュアル
# (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.mode_set)
def set_mode_object() -> bool:
    """オブジェクトモードへの移行

    Returns:
        bool -- 実行の正否
    """

    # オブジェクトモードに移行する
    # モード切替のマニュアル
    # (https://docs.blender.org/api/current/bpy.ops.object.html#bpy.ops.object.mode_set)
    # mode:OBJECT オブジェクトモードに切り替え
    # toggle:True の場合、既に編集モードの時、オブジェクトモードに戻る
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

    return True

# 選択中の頂点から新規頂点グループを作成してグループ名を取得する
def make_vertexgroup() -> str:
    """選択中の頂点から新規頂点グループを作成してグループ名を取得する

    Keyword Arguments:

    Returns:
        str -- 新規頂点グループ名
    """

    # 現在のモードが「編集モード(EDIT_MESH)」かチェックする
    if check_viewmode('EDIT_MESH') == False :
        return ""

    # 編集中のアクティブオブジェクトを取得する
    active_object = bpy.context.view_layer.objects.active

    # 選択中の頂点に新規頂点グループを割り当てる
    bpy.ops.object.vertex_group_assign_new()

    # 作成した頂点グループのインデックス番号を取得する
    make_index = active_object.vertex_groups.active_index

    # 作成した頂点グループのグループ名を返却する
    return active_object.vertex_groups[make_index].name

# 現在のモードが指定のモードかチェックする
def check_viewmode(arg_checktype:str) -> bool:
    """現在のモードが指定のモードかチェックする

    Keyword Arguments:
        arg_checktype {str} -- 比較するモード名

    Returns:
        str -- 現在のモード
    """

    # 現在のモードをチェックする
    # (https://docs.blender.org/api/current/bpy.context.html#bpy.context.mode)
    modetype = bpy.context.mode

    return (arg_checktype == modetype)

# 関数の実行例
# 選択中の頂点から新規頂点グループを作成してグループ名を取得する
make_groupname = make_vertexgroup()
# モディファイアを設定するためオブジェクトモードに切り替える
set_mode_object()
# リダクションを行う
apply_decimate_vertexgroup(bpy.context.view_layer.objects.active, make_groupname, 0.8)

・実行前
f:id:bluebirdofoz:20220102231103j:plain
・実行後
f:id:bluebirdofoz:20220102231112j:plain