MRが楽しい

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

Blender2.8で利用可能なpythonスクリプトを作る その63(頂点グループのウェイト削除)

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

頂点グループのウェイト削除

指定オブジェクトの頂点グループ名のウェイト削除を行います。
・Script_ops_weightclear_object_vertexgroup.py

# bpyインポート
import bpy

# 指定オブジェクトのウェイト付けを削除する
# 1.指定オブジェクトに対象の頂点グループがあるか確認する
# 2.対象の頂点グループがない場合、処理しない
# 3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
# 4.ウェイト 0 の設定を除去するため、クリーン操作を実行する
def ops_weightclear_object_vertexgroup(
  arg_object:bpy.types.Object, arg_vertexgroup_name:str) -> bool:
    """指定オブジェクトのウェイト付けを削除する
    1.指定オブジェクトに対象の頂点グループがあるか確認する
    2.対象の頂点グループがない場合、処理しない
    3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
    4.ウェイト 0 の設定を除去するため、クリーン操作を実行する

    Args:
        arg_object (bpy.types.Object): 指定オブジェクト
        arg_vertexgroup_name (str): 追加頂点グループ名

    Returns:
        bool: 実行正否
    """

    # オブジェクトの頂点グループを取得する(get関数は対象が存在しない場合 None が返る)
    vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name)

    # 対象の頂点グループが存在しない場合は処理しない
    if vertexgroup == None:
        # 処理終了
        return True

    # 対象の頂点グループをアクティブにする
    arg_object.vertex_groups.active_index = vertexgroup.index

    # 編集モードに移行する
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    # 全頂点を選択状態にする
    bpy.ops.mesh.select_all(action='SELECT')

    # 頂点グループの設定ウェイト値を 0 にする
    bpy.context.scene.tool_settings.vertex_group_weight=0.0

    # 頂点グループのウェイト値を選択頂点に割り当てる
    bpy.ops.object.vertex_group_assign()

    # ウェイト 0 を除去するクリーン操作を実行する
    bpy.ops.object.vertex_group_clean(group_select_mode='ALL', limit=0.0, keep_single=False)

    # オブジェクトモードに戻る
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

    return True

# 関数の実行例
target_obj = bpy.data.objects.get("Cube")
vertexgroup_name = "CubeGroup"
ops_weightclear_object_vertexgroup(
    arg_object=target_obj,
    arg_vertexgroup_name=vertexgroup_name
)

f:id:bluebirdofoz:20200825065707j:plain

Operatorを利用しない頂点グループのウェイト削除

指定オブジェクトの頂点グループ名のウェイト削除を行います。
スクリプトは Operator を利用せず、ウェイト削除を行います。
・Script_weightclear_object_vertexgroup.py

# bpyインポート
import bpy

# 指定オブジェクトのウェイト付けを削除する
# 1.指定オブジェクトに対象の頂点グループがあるか確認する
# 2.対象の頂点グループがない場合、処理しない
# 3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
# 4.ウェイト 0 の設定を除去するため、クリーン操作を実行する
def weightclear_object_vertexgroup(
  arg_object:bpy.types.Object, arg_vertexgroup_name:str) -> bool:
    """指定オブジェクトのウェイト付けを削除する
    1.指定オブジェクトに対象の頂点グループがあるか確認する
    2.対象の頂点グループがない場合、処理しない
    3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
    4.ウェイト 0 の設定を除去するため、クリーン操作を実行する

    Args:
        arg_object (bpy.types.Object): 指定オブジェクト
        arg_vertexgroup_name (str): 追加頂点グループ名

    Returns:
        bool: 実行正否
    """

    # オブジェクトの頂点グループを取得する(get関数は対象が存在しない場合 None が返る)
    vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name)

    # 対象の頂点グループが存在しない場合は処理しない
    if vertexgroup == None:
        # 処理終了
        return True

    # 対象の頂点グループが存在しない場合は新規作成する
    # 頂点グループ操作のマニュアル
    # (https://docs.blender.org/api/current/bpy.types.VertexGroup.html)
    if vertexgroup == None:
        # オブジェクトに新規頂点グループを追加する
        vertexgroup = arg_object.vertex_groups.new(name=arg_vertexgroup_name)

    # 全ての頂点を走査する
    # 頂点操作のマニュアル
    # (https://docs.blender.org/api/current/bpy.types.MeshVertex.html)
    for vert in arg_object.data.vertices:
        # 頂点グループの各頂点インデックスの位置のウェイトを削除する
        # (https://docs.blender.org/api/current/bpy.types.VertexGroup.html#bpy.types.VertexGroup.remove)
        vertexgroup.remove([vert.index])

    return True

# 関数の実行例
target_obj = bpy.data.objects.get("Cube")
vertexgroup_name = "CubeGroup"
weightclear_object_vertexgroup(
    arg_object=target_obj,
    arg_vertexgroup_name=vertexgroup_name
)

f:id:bluebirdofoz:20200825065723j:plain

Operatorを利用しない頂点グループの空ウェイト削除

指定オブジェクトの頂点グループ名の空ウェイトの削除を行います。
スクリプトは Operator を利用せず、ウェイト削除を行います。
・Script_weightclean_object_vertexgroup.py

# bpyインポート
import bpy

# 指定オブジェクトの空ウェイトを削除する
# 1.指定オブジェクトに対象の頂点グループがあるか確認する
# 2.対象の頂点グループがない場合、処理しない
# 3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
# 4.ウェイト 0 の設定を除去するため、クリーン操作を実行する
def weightclean_object_vertexgroup(
  arg_object:bpy.types.Object, arg_vertexgroup_name:str) -> bool:
    """指定オブジェクトの空ウェイトを削除する
    1.指定オブジェクトに対象の頂点グループがあるか確認する
    2.対象の頂点グループがない場合、処理しない
    3.指定オブジェクトの全頂点にウェイト 0 を割り当てる
    4.ウェイト 0 の設定を除去するため、クリーン操作を実行する

    Args:
        arg_object (bpy.types.Object): 指定オブジェクト
        arg_vertexgroup_name (str): 追加頂点グループ名

    Returns:
        bool: 実行正否
    """

    # オブジェクトの頂点グループを取得する(get関数は対象が存在しない場合 None が返る)
    vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name)

    # 対象の頂点グループが存在しない場合は処理しない
    if vertexgroup == None:
        # 処理終了
        return True

    # 対象の頂点グループが存在しない場合は新規作成する
    # 頂点グループ操作のマニュアル
    # (https://docs.blender.org/api/current/bpy.types.VertexGroup.html)
    if vertexgroup == None:
        # オブジェクトに新規頂点グループを追加する
        vertexgroup = arg_object.vertex_groups.new(name=arg_vertexgroup_name)

    # 全ての頂点を走査する
    # 頂点操作のマニュアル
    # (https://docs.blender.org/api/current/bpy.types.MeshVertex.html)
    for vert in arg_object.data.vertices:
        # 頂点グループの各頂点インデックスの位置のウェイトを確認する
        # (https://docs.blender.org/api/current/bpy.types.VertexGroup.html#bpy.types.VertexGroup.weight)
        if vertexgroup.weight(vert.index) == 0.0:
            # ウェイト値が 0.0 の場合、ウェイトを削除する
            # (https://docs.blender.org/api/current/bpy.types.VertexGroup.html#bpy.types.VertexGroup.remove)
            vertexgroup.remove([vert.index])

    return True

# 関数の実行例
target_obj = bpy.data.objects.get("Cube")
vertexgroup_name = "CubeGroup"
weightclean_object_vertexgroup(
    arg_object=target_obj,
    arg_vertexgroup_name=vertexgroup_name
)

f:id:bluebirdofoz:20200825065738j:plain