bpy(Blender Python API)を用いたメッシュ操作において、
  • メッシュ移動
  • スケーリング
  • マテリアル割り当て
  • UV展開時のシーム
など、あらゆる操作で面や辺、頂点の選択が必要となるので、処理を関数にまとめて簡単化しておきます。


動作確認環境 : Blender 4.2


インデックスを用いた要素の選択


ある特定の面、辺、頂点を選択する際には下の画像のように、要素に対して割り当てられているインデックスを用いて要素を選択状態にします。

Blenderの初期設定では、このようにインデックスは3D Viewに表示されないので、こちらのbpyによる初期設定を見て、設定を行うことでこれらが表示されるようになります。

▼ テキストベースモデリングのための初期化処理



Python :
# 面、辺、頂点選択
def element_select(
        element_list                # インデックスリスト
,       select_mode                 # VERT/EDGE/FACE
,       object_name_list=["NaN"]    # オブジェクト名リスト
,       loop_select=False           # ループ選択
):
    # 現在のモード保存
    current_mode = bpy.context.object.mode
    if (object_name_list[0] != "NaN"):
        # オブジェクトアクティブ化
        for i in range(len(object_name_list)):
            object_name = object_name_list[i]
            obj = bpy.data.objects.get(object_name)
            if obj:
                obj.select_set(True)
                bpy.context.view_layer.objects.active = obj
    # アクティブオブジェクト取得
    obj = bpy.context.object
    # メッシュオブジェクト確認
    if obj and obj.type == 'MESH':
        mesh = obj.data
        # モード切り替え
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_mode(type=select_mode)
        # 全要素選択解除
        bpy.ops.mesh.select_all(action='DESELECT')
        # モード切り替え
        bpy.ops.object.mode_set(mode='OBJECT')
        # 要素選択(3D View:要素インデックス)
        if ((len(element_list) >= 1) and (element_list[0] == "all")):
            # 全選択
            bpy.ops.object.mode_set(mode='EDIT')
            bpy.ops.mesh.select_mode(type=select_mode)
            bpy.ops.mesh.select_all(action='SELECT')
        else:
            # 特定要素選択
            for i in range(len(element_list)):
                target_ele_index = element_list[i]
                if (select_mode == "FACE"):
                    mesh.polygons[target_ele_index].select = True
                elif (select_mode == "EDGE"):
                    mesh.edges[target_ele_index].select = True
                elif (select_mode == "VERT"):
                    mesh.vertices[target_ele_index].select = True
        # モード切り替え
        bpy.ops.object.mode_set(mode='EDIT')
        if (loop_select == True):
            # ループ選択(Alt+Click)
            bpy.ops.mesh.loop_multi_select(ring=False)
    else:
        print("No mesh object selected.")
    # モードを戻す
    bpy.ops.object.mode_set(mode=current_mode)

9行目, 54行目
実行時のモードを保存して、処理を抜けるときに実行時のモードに戻る

10行目~17行目
指定オブジェクト名が無い場合、現在アクティブなオブジェクトを対象とする

31行目~35行目
インデックスリストに"all"が入力された場合、全要素を選択

36行目~45行目
インデックスリストから特定の要素を線選択

47行目~50行目
loop_select=Trueのとき選択した要素に基づいてループ選択


インデックスを使用した要素選択の使用例


次のように使用し、
  • あるオブジェクトの要素をインデックスで指定
  • 指定した要素に対して変更を加える
のように処理することができます。

Python:
def Base_create():
    # Mode 切り替え
    bpy.ops.object.mode_set(mode='OBJECT')

    # 立方体生成
    bpy.ops.mesh.primitive_cube_add(
        size=2              # 1ペンの長さ
    ,   location=(0, 0, 0)  # 配置場所
    ,   scale=(1,1,1)       # x, y, y サイズ x軸方向に1倍, y軸方向に1倍, z軸方向に1倍
    )
    bpy.context.object.name = "MyCube_001"

    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_mode(type='FACE')

    # 要素選択
    element_select(
        element_list=[5, 3]
    ,   select_mode="FACE"
    ,   object_name_list=["MyCube_001"]
    )

    # 移動
    bpy.ops.transform.translate(
        value=(0, 0, -1.0)
    ,   orient_type='GLOBAL'
    )

Base_create()


インデックスが含まれるすべての辺を選択


あるインデックスが含まれる一連のオブジェクト中の辺を選択します。

Python :
# 1辺が含まれるすべての辺を選択
bpy.ops.mesh.select_linked_pick(
    deselect=False          # False:リンクされた要素を選択, True:すでに選択されているリンクを解除
,   delimit=set()           # 制限なしでリンクを選択
,   object_index=0          # オブジェクトインデックス (通常は省略可)
,   index=1                 # インデックスの基点
)



1つ飛ばしに頂点を選択


1つ飛ばしに選択したいループ上の頂点をすべて選択した状態で、次の処理を行うと、頂点が1つ飛ばしで選択された状態になります。

Python :
# Mode切り替え
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='VERT')

# チェッカー選択解除(一つ置きに選択にする)
# Select -> Checker Deselect
bpy.ops.mesh.select_nth(skip=1)


以上

このエントリーをはてなブックマークに追加
コメントを閉じる

コメント

コメントフォーム
記事の評価
  • リセット
  • リセット