本日は Blender の技術調査枠です。
Blender3.0で利用可能なpythonスクリプトを作ります。
指定の頂点グループに所属している頂点の数を取得する
頂点と頂点グループの関連情報は Vertex データ側に情報が保持されています。
docs.blender.org
このため、頂点グループに所属している頂点の数を計算するには通常、以下のように頂点側の情報から算出する必要があります。
# 指定オブジェクトの全頂点を走査する for vert in arg_object.data.vertices: # 頂点が所属している頂点グループのインデックスリストを取得する for groupinfo in vert.groups: # 指定の頂点グループに所属していればカウントアップする if groupinfo.group == check_vertexgroup_index: result_count = result_count + 1
もし頂点グループ側から頂点の数を計算する場合は以下のようにエラーをキャッチする必要があります。
# 指定オブジェクトの全頂点を走査する for vert in arg_object.data.vertices: try: # ウェイト情報を参照できるならカウントアップする check_vertexgroup.weight(vert.index) result_count = result_count + 1 except RuntimeError: # 頂点グループに所属していない場合はエラーが発生するのでパスする pass
サンプルスクリプト
前述の2つの方法を利用して作成した頂点グループの頂点の数を計算するサンプルスクリプトを作成しました。
・Script_count_vertexgroup_pattern01.py
# bpyインポート import bpy def count_weight_vertexgroup( arg_object:bpy.types.Object, arg_vertexgroup_name:str) -> int: """指定の頂点グループに所属している頂点の数を取得する(頂点の参照から算出) Keyword Arguments: arg_object {bpy.types.Object} -- 指定オブジェクト arg_vertexgroupname {str} -- 指定の頂点グループ名 Returns: int -- 頂点グループに含まれる頂点数 """ # 指定オブジェクトに指定の頂点グループが含まれるかチェックする check_vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name) if check_vertexgroup == None: return 0 # カウント用変数 result_count = 0 # 指定の頂点グループについて頂点グループリストでのインデックス番号を取得する check_vertexgroup_index = check_vertexgroup.index # 指定オブジェクトの全頂点を走査する for vert in arg_object.data.vertices: # 頂点が所属している頂点グループのインデックスリストを取得する for groupinfo in vert.groups: # 指定の頂点グループに所属していればカウントアップする if groupinfo.group == check_vertexgroup_index: result_count = result_count + 1 # カウント結果を返却する return result_count # オブジェクトモードへの移行 # モード切替のマニュアル # (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() # 頂点データから頂点グループに所属している頂点数を算出つする vertexgroup_count = count_weight_vertexgroup(bpy.context.view_layer.objects.active,make_groupname) # 結果をコンソールに表示する print("VertexGroup count : " + str(vertexgroup_count))
・Script_count_vertexgroup_pattern02.py
# bpyインポート import bpy def count_weight_vertexgroup( arg_object:bpy.types.Object, arg_vertexgroup_name:str) -> int: """指定の頂点グループに所属している頂点の数を取得する(頂点グループの参照から算出) Keyword Arguments: arg_object {bpy.types.Object} -- 指定オブジェクト arg_vertexgroup_name {str} -- 指定の頂点グループ名 Returns: int -- 頂点グループに含まれる頂点数 """ # 指定オブジェクトに指定の頂点グループが含まれるかチェックする check_vertexgroup = arg_object.vertex_groups.get(arg_vertexgroup_name) if check_vertexgroup == None: return 0 # カウント用変数 result_count = 0 # 指定の頂点グループについて頂点グループリストでのインデックス番号を取得する check_vertexgroup_index = check_vertexgroup.index # 指定オブジェクトの全頂点を走査する for vert in arg_object.data.vertices: try: # ウェイト情報を参照できるならカウントアップする check_vertexgroup.weight(vert.index) result_count = result_count + 1 except RuntimeError: # 頂点グループに所属していない場合はエラーが発生するのでパスする pass # カウント結果を返却する return result_count # 選択中の頂点から新規頂点グループを作成してグループ名を取得する 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() # 頂点グループの参照から頂点グループに所属している頂点数を算出つする vertexgroup_count = count_weight_vertexgroup(bpy.context.view_layer.objects.active,make_groupname) # 結果をコンソールに表示する print("VertexGroup count : " + str(vertexgroup_count))